mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-08 06:09:58 +00:00
LibJS: Move bytecode executable cache to SharedFunctionInstanceData
This shrinks every Statement and ECMAScriptFunctionObject by one pointer, and puts the bytecode cache in the only place that actually makes use of it anyway: functions.
This commit is contained in:
parent
3a38040c82
commit
b712caf855
Notes:
github-actions[bot]
2025-10-27 20:15:48 +00:00
Author: https://github.com/awesomekling
Commit: b712caf855
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6604
3 changed files with 14 additions and 22 deletions
|
|
@ -176,12 +176,6 @@ public:
|
|||
: ASTNode(move(source_range))
|
||||
{
|
||||
}
|
||||
|
||||
Bytecode::Executable* bytecode_executable() const { return m_bytecode_executable; }
|
||||
void set_bytecode_executable(Bytecode::Executable* bytecode_executable) { m_bytecode_executable = make_root(bytecode_executable); }
|
||||
|
||||
private:
|
||||
GC::Root<Bytecode::Executable> m_bytecode_executable;
|
||||
};
|
||||
|
||||
// 14.13 Labelled Statements, https://tc39.es/ecma262/#sec-labelled-statements
|
||||
|
|
|
|||
|
|
@ -426,6 +426,7 @@ GC_DEFINE_ALLOCATOR(SharedFunctionInstanceData);
|
|||
void SharedFunctionInstanceData::visit_edges(Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_executable);
|
||||
}
|
||||
|
||||
SharedFunctionInstanceData::~SharedFunctionInstanceData() = default;
|
||||
|
|
@ -498,17 +499,15 @@ void ECMAScriptFunctionObject::initialize(Realm& realm)
|
|||
|
||||
ThrowCompletionOr<void> ECMAScriptFunctionObject::get_stack_frame_size(size_t& registers_and_constants_and_locals_count, size_t& argument_count)
|
||||
{
|
||||
if (!m_bytecode_executable) {
|
||||
if (!ecmascript_code().bytecode_executable()) {
|
||||
if (is_module_wrapper()) {
|
||||
const_cast<Statement&>(ecmascript_code()).set_bytecode_executable(TRY(Bytecode::compile(vm(), ecmascript_code(), kind(), name())));
|
||||
} else {
|
||||
const_cast<Statement&>(ecmascript_code()).set_bytecode_executable(TRY(Bytecode::compile(vm(), *this)));
|
||||
}
|
||||
auto& executable = shared_data().m_executable;
|
||||
if (!executable) {
|
||||
if (is_module_wrapper()) {
|
||||
executable = TRY(Bytecode::compile(vm(), ecmascript_code(), kind(), name()));
|
||||
} else {
|
||||
executable = TRY(Bytecode::compile(vm(), *this));
|
||||
}
|
||||
m_bytecode_executable = ecmascript_code().bytecode_executable();
|
||||
}
|
||||
registers_and_constants_and_locals_count = m_bytecode_executable->number_of_registers + m_bytecode_executable->constants.size() + m_bytecode_executable->local_variable_names.size();
|
||||
registers_and_constants_and_locals_count = executable->number_of_registers + executable->constants.size() + executable->local_variable_names.size();
|
||||
argument_count = max(argument_count, formal_parameters().size());
|
||||
return {};
|
||||
}
|
||||
|
|
@ -518,7 +517,7 @@ FLATTEN ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Executi
|
|||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
ASSERT(m_bytecode_executable);
|
||||
ASSERT(bytecode_executable());
|
||||
|
||||
// 1. Let callerContext be the running execution context.
|
||||
// NOTE: No-op, kept by the VM in its execution context stack.
|
||||
|
|
@ -563,7 +562,7 @@ FLATTEN ThrowCompletionOr<GC::Ref<Object>> ECMAScriptFunctionObject::internal_co
|
|||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
ASSERT(m_bytecode_executable);
|
||||
ASSERT(bytecode_executable());
|
||||
|
||||
// 1. Let callerContext be the running execution context.
|
||||
// NOTE: No-op, kept by the VM in its execution context stack.
|
||||
|
|
@ -652,7 +651,6 @@ void ECMAScriptFunctionObject::visit_edges(Visitor& visitor)
|
|||
visitor.visit(m_home_object);
|
||||
visitor.visit(m_name_string);
|
||||
visitor.visit(m_shared_data);
|
||||
visitor.visit(m_bytecode_executable);
|
||||
|
||||
if (m_class_data) {
|
||||
for (auto& field : m_class_data->fields) {
|
||||
|
|
@ -892,7 +890,7 @@ template void async_function_start(VM&, PromiseCapability const&, GC::Function<C
|
|||
// 15.8.4 Runtime Semantics: EvaluateAsyncFunctionBody, https://tc39.es/ecma262/#sec-runtime-semantics-evaluatefunctionbody
|
||||
ThrowCompletionOr<Value> ECMAScriptFunctionObject::ordinary_call_evaluate_body(VM& vm)
|
||||
{
|
||||
auto result_and_frame = vm.bytecode_interpreter().run_executable(*m_bytecode_executable, {});
|
||||
auto result_and_frame = vm.bytecode_interpreter().run_executable(*bytecode_executable(), {});
|
||||
|
||||
if (result_and_frame.value.is_error()) [[unlikely]] {
|
||||
return result_and_frame.value.release_error();
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ public:
|
|||
FunctionParsingInsights const&,
|
||||
Vector<LocalVariable> local_variables_names);
|
||||
|
||||
mutable GC::Ptr<Bytecode::Executable> m_executable;
|
||||
|
||||
RefPtr<FunctionParameters const> m_formal_parameters; // [[FormalParameters]]
|
||||
RefPtr<Statement const> m_ecmascript_code; // [[ECMAScriptCode]]
|
||||
|
||||
|
|
@ -142,7 +144,7 @@ public:
|
|||
|
||||
void set_is_class_constructor() { const_cast<SharedFunctionInstanceData&>(shared_data()).m_is_class_constructor = true; }
|
||||
|
||||
auto& bytecode_executable() const { return m_bytecode_executable; }
|
||||
auto& bytecode_executable() const { return shared_data().m_executable; }
|
||||
|
||||
Environment* environment() { return m_environment; }
|
||||
virtual Realm* realm() const override { return &shape().realm(); }
|
||||
|
|
@ -214,8 +216,6 @@ private:
|
|||
|
||||
GC::Ptr<PrimitiveString> m_name_string;
|
||||
|
||||
GC::Ptr<Bytecode::Executable> m_bytecode_executable;
|
||||
|
||||
// Internal Slots of ECMAScript Function Objects, https://tc39.es/ecma262/#table-internal-slots-of-ecmascript-function-objects
|
||||
GC::Ptr<Environment> m_environment; // [[Environment]]
|
||||
GC::Ptr<PrivateEnvironment> m_private_environment; // [[PrivateEnvironment]]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue