mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
LibJS: Remove derivable fields from ExecutionContext
Remove four fields that are trivially derivable from other fields already present in the ExecutionContext: - global_object (from realm) - global_declarative_environment (from realm) - identifier_table (from executable) - property_key_table (from executable) This shrinks ExecutionContext from 192 to 160 bytes (-17%). The asmint's GetGlobal/SetGlobal handlers now load through the realm pointer, taking advantage of the cached declarative environment pointer added in the previous commit.
This commit is contained in:
committed by
Andreas Kling
parent
e70f580e5c
commit
96d02d5249
Notes:
github-actions[bot]
2026-03-11 12:35:42 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/96d02d5249d Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8360 Reviewed-by: https://github.com/shannonbooth
@@ -1717,9 +1717,10 @@ end
|
||||
|
||||
# Inline cache fast path for global variable access via the global object.
|
||||
handler GetGlobal
|
||||
# Load global_declarative_environment and global_object
|
||||
load64 t1, [exec_ctx, EXECUTION_CONTEXT_GLOBAL_DECLARATIVE_ENVIRONMENT]
|
||||
load64 t2, [exec_ctx, EXECUTION_CONTEXT_GLOBAL_OBJECT]
|
||||
# Load global_declarative_environment and global_object via realm
|
||||
load64 t0, [exec_ctx, EXECUTION_CONTEXT_REALM]
|
||||
load64 t2, [t0, REALM_GLOBAL_OBJECT]
|
||||
load64 t1, [t0, REALM_GLOBAL_DECLARATIVE_ENVIRONMENT]
|
||||
# Get GlobalVariableCache* (direct pointer from instruction stream)
|
||||
load64 t3, [pb, pc, m_cache]
|
||||
# Check environment_serial_number matches
|
||||
@@ -1774,9 +1775,10 @@ end
|
||||
|
||||
# Inline cache fast path for global variable store via the global object.
|
||||
handler SetGlobal
|
||||
# Load global_declarative_environment and global_object
|
||||
load64 t1, [exec_ctx, EXECUTION_CONTEXT_GLOBAL_DECLARATIVE_ENVIRONMENT]
|
||||
load64 t2, [exec_ctx, EXECUTION_CONTEXT_GLOBAL_OBJECT]
|
||||
# Load global_declarative_environment and global_object via realm
|
||||
load64 t0, [exec_ctx, EXECUTION_CONTEXT_REALM]
|
||||
load64 t2, [t0, REALM_GLOBAL_OBJECT]
|
||||
load64 t1, [t0, REALM_GLOBAL_DECLARATIVE_ENVIRONMENT]
|
||||
# Get GlobalVariableCache* (direct pointer from instruction stream)
|
||||
load64 t3, [pb, pc, m_cache]
|
||||
# Check environment_serial_number matches
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <LibJS/Runtime/FunctionObject.h>
|
||||
#include <LibJS/Runtime/IndexedProperties.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibJS/Runtime/Shape.h>
|
||||
#include <LibJS/Runtime/TypedArray.h>
|
||||
|
||||
@@ -85,13 +86,17 @@ int main()
|
||||
// ExecutionContext layout
|
||||
outln("\n# ExecutionContext layout");
|
||||
EMIT_OFFSET(EXECUTION_CONTEXT_EXECUTABLE, ExecutionContext, executable);
|
||||
EMIT_OFFSET(EXECUTION_CONTEXT_GLOBAL_OBJECT, ExecutionContext, global_object);
|
||||
EMIT_OFFSET(EXECUTION_CONTEXT_GLOBAL_DECLARATIVE_ENVIRONMENT, ExecutionContext, global_declarative_environment);
|
||||
EMIT_OFFSET(EXECUTION_CONTEXT_REALM, ExecutionContext, realm);
|
||||
EMIT_OFFSET(EXECUTION_CONTEXT_LEXICAL_ENVIRONMENT, ExecutionContext, lexical_environment);
|
||||
EMIT_OFFSET(EXECUTION_CONTEXT_CALLER_FRAME, ExecutionContext, caller_frame);
|
||||
EMIT_OFFSET(EXECUTION_CONTEXT_PROGRAM_COUNTER, ExecutionContext, program_counter);
|
||||
EMIT_SIZEOF(SIZEOF_EXECUTION_CONTEXT, ExecutionContext);
|
||||
|
||||
// Realm layout
|
||||
outln("\n# Realm layout");
|
||||
EMIT_OFFSET(REALM_GLOBAL_OBJECT, Realm, m_global_object);
|
||||
EMIT_OFFSET(REALM_GLOBAL_DECLARATIVE_ENVIRONMENT, Realm, m_global_declarative_environment);
|
||||
|
||||
// Interpreter layout
|
||||
outln("\n# Interpreter layout");
|
||||
EMIT_OFFSET(INTERPRETER_RUNNING_EXECUTION_CONTEXT, Interpreter, m_running_execution_context);
|
||||
|
||||
@@ -316,11 +316,6 @@ ExecutionContext* Interpreter::push_inline_frame(
|
||||
// and global_declarative_environment, since the caller's realm may differ
|
||||
// in cross-realm calls (e.g. iframe <-> parent).
|
||||
callee_context->executable = callee_executable;
|
||||
auto& callee_realm = *callee_context->realm;
|
||||
callee_context->global_object = callee_realm.global_object();
|
||||
callee_context->global_declarative_environment = callee_realm.global_environment().declarative_record();
|
||||
callee_context->identifier_table = callee_executable.identifier_table->identifiers().data();
|
||||
callee_context->property_key_table = callee_executable.property_key_table->property_keys().data();
|
||||
|
||||
// Copy constants (memcpy avoids aliasing issues with the scalar loop).
|
||||
auto* values = callee_context->registers_and_constants_and_locals_and_arguments();
|
||||
@@ -808,12 +803,17 @@ void Interpreter::run_bytecode(size_t entry_point)
|
||||
|
||||
Utf16FlyString const& Interpreter::get_identifier(IdentifierTableIndex index) const
|
||||
{
|
||||
return m_running_execution_context->identifier_table[index.value];
|
||||
return m_running_execution_context->executable->get_identifier(index);
|
||||
}
|
||||
|
||||
PropertyKey const& Interpreter::get_property_key(PropertyKeyTableIndex index) const
|
||||
{
|
||||
return m_running_execution_context->property_key_table[index.value];
|
||||
return m_running_execution_context->executable->get_property_key(index);
|
||||
}
|
||||
|
||||
DeclarativeEnvironment& Interpreter::global_declarative_environment()
|
||||
{
|
||||
return realm().global_declarative_environment();
|
||||
}
|
||||
|
||||
ThrowCompletionOr<Value> Interpreter::run_executable(ExecutionContext& context, Executable& executable, Optional<size_t> entry_point)
|
||||
@@ -824,10 +824,6 @@ ThrowCompletionOr<Value> Interpreter::run_executable(ExecutionContext& context,
|
||||
TemporaryChange restore_running_execution_context { m_running_execution_context, &context };
|
||||
|
||||
context.executable = executable;
|
||||
context.global_object = realm().global_object();
|
||||
context.global_declarative_environment = realm().global_environment().declarative_record();
|
||||
context.identifier_table = executable.identifier_table->identifiers().data();
|
||||
context.property_key_table = executable.property_key_table->property_keys().data();
|
||||
|
||||
VERIFY(executable.registers_and_locals_count + executable.constants.size() == executable.registers_and_locals_and_constants_count);
|
||||
VERIFY(executable.registers_and_locals_and_constants_count <= context.registers_and_constants_and_locals_and_arguments_span().size());
|
||||
|
||||
@@ -27,8 +27,8 @@ public:
|
||||
~Interpreter();
|
||||
|
||||
[[nodiscard]] Realm& realm() { return *m_running_execution_context->realm; }
|
||||
[[nodiscard]] Object& global_object() { return *m_running_execution_context->global_object; }
|
||||
[[nodiscard]] DeclarativeEnvironment& global_declarative_environment() { return *m_running_execution_context->global_declarative_environment; }
|
||||
[[nodiscard]] Object& global_object() { return realm().global_object(); }
|
||||
[[nodiscard]] DeclarativeEnvironment& global_declarative_environment();
|
||||
static VM& vm() { return VM::the(); }
|
||||
|
||||
ThrowCompletionOr<Value> run(Script&, GC::Ptr<Environment> lexical_environment_override = nullptr);
|
||||
|
||||
Reference in New Issue
Block a user