Skip to content

Commit b712caf

Browse files
committed
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.
1 parent 3a38040 commit b712caf

File tree

3 files changed

+14
-22
lines changed

3 files changed

+14
-22
lines changed

Libraries/LibJS/AST.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,6 @@ class Statement : public ASTNode {
176176
: ASTNode(move(source_range))
177177
{
178178
}
179-
180-
Bytecode::Executable* bytecode_executable() const { return m_bytecode_executable; }
181-
void set_bytecode_executable(Bytecode::Executable* bytecode_executable) { m_bytecode_executable = make_root(bytecode_executable); }
182-
183-
private:
184-
GC::Root<Bytecode::Executable> m_bytecode_executable;
185179
};
186180

187181
// 14.13 Labelled Statements, https://tc39.es/ecma262/#sec-labelled-statements

Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ GC_DEFINE_ALLOCATOR(SharedFunctionInstanceData);
426426
void SharedFunctionInstanceData::visit_edges(Visitor& visitor)
427427
{
428428
Base::visit_edges(visitor);
429+
visitor.visit(m_executable);
429430
}
430431

431432
SharedFunctionInstanceData::~SharedFunctionInstanceData() = default;
@@ -498,17 +499,15 @@ void ECMAScriptFunctionObject::initialize(Realm& realm)
498499

499500
ThrowCompletionOr<void> ECMAScriptFunctionObject::get_stack_frame_size(size_t& registers_and_constants_and_locals_count, size_t& argument_count)
500501
{
501-
if (!m_bytecode_executable) {
502-
if (!ecmascript_code().bytecode_executable()) {
503-
if (is_module_wrapper()) {
504-
const_cast<Statement&>(ecmascript_code()).set_bytecode_executable(TRY(Bytecode::compile(vm(), ecmascript_code(), kind(), name())));
505-
} else {
506-
const_cast<Statement&>(ecmascript_code()).set_bytecode_executable(TRY(Bytecode::compile(vm(), *this)));
507-
}
502+
auto& executable = shared_data().m_executable;
503+
if (!executable) {
504+
if (is_module_wrapper()) {
505+
executable = TRY(Bytecode::compile(vm(), ecmascript_code(), kind(), name()));
506+
} else {
507+
executable = TRY(Bytecode::compile(vm(), *this));
508508
}
509-
m_bytecode_executable = ecmascript_code().bytecode_executable();
510509
}
511-
registers_and_constants_and_locals_count = m_bytecode_executable->number_of_registers + m_bytecode_executable->constants.size() + m_bytecode_executable->local_variable_names.size();
510+
registers_and_constants_and_locals_count = executable->number_of_registers + executable->constants.size() + executable->local_variable_names.size();
512511
argument_count = max(argument_count, formal_parameters().size());
513512
return {};
514513
}
@@ -518,7 +517,7 @@ FLATTEN ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Executi
518517
{
519518
auto& vm = this->vm();
520519

521-
ASSERT(m_bytecode_executable);
520+
ASSERT(bytecode_executable());
522521

523522
// 1. Let callerContext be the running execution context.
524523
// NOTE: No-op, kept by the VM in its execution context stack.
@@ -563,7 +562,7 @@ FLATTEN ThrowCompletionOr<GC::Ref<Object>> ECMAScriptFunctionObject::internal_co
563562
{
564563
auto& vm = this->vm();
565564

566-
ASSERT(m_bytecode_executable);
565+
ASSERT(bytecode_executable());
567566

568567
// 1. Let callerContext be the running execution context.
569568
// NOTE: No-op, kept by the VM in its execution context stack.
@@ -652,7 +651,6 @@ void ECMAScriptFunctionObject::visit_edges(Visitor& visitor)
652651
visitor.visit(m_home_object);
653652
visitor.visit(m_name_string);
654653
visitor.visit(m_shared_data);
655-
visitor.visit(m_bytecode_executable);
656654

657655
if (m_class_data) {
658656
for (auto& field : m_class_data->fields) {
@@ -892,7 +890,7 @@ template void async_function_start(VM&, PromiseCapability const&, GC::Function<C
892890
// 15.8.4 Runtime Semantics: EvaluateAsyncFunctionBody, https://tc39.es/ecma262/#sec-runtime-semantics-evaluatefunctionbody
893891
ThrowCompletionOr<Value> ECMAScriptFunctionObject::ordinary_call_evaluate_body(VM& vm)
894892
{
895-
auto result_and_frame = vm.bytecode_interpreter().run_executable(*m_bytecode_executable, {});
893+
auto result_and_frame = vm.bytecode_interpreter().run_executable(*bytecode_executable(), {});
896894

897895
if (result_and_frame.value.is_error()) [[unlikely]] {
898896
return result_and_frame.value.release_error();

Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class SharedFunctionInstanceData final : public GC::Cell {
5454
FunctionParsingInsights const&,
5555
Vector<LocalVariable> local_variables_names);
5656

57+
mutable GC::Ptr<Bytecode::Executable> m_executable;
58+
5759
RefPtr<FunctionParameters const> m_formal_parameters; // [[FormalParameters]]
5860
RefPtr<Statement const> m_ecmascript_code; // [[ECMAScriptCode]]
5961

@@ -142,7 +144,7 @@ class JS_API ECMAScriptFunctionObject final : public FunctionObject {
142144

143145
void set_is_class_constructor() { const_cast<SharedFunctionInstanceData&>(shared_data()).m_is_class_constructor = true; }
144146

145-
auto& bytecode_executable() const { return m_bytecode_executable; }
147+
auto& bytecode_executable() const { return shared_data().m_executable; }
146148

147149
Environment* environment() { return m_environment; }
148150
virtual Realm* realm() const override { return &shape().realm(); }
@@ -214,8 +216,6 @@ class JS_API ECMAScriptFunctionObject final : public FunctionObject {
214216

215217
GC::Ptr<PrimitiveString> m_name_string;
216218

217-
GC::Ptr<Bytecode::Executable> m_bytecode_executable;
218-
219219
// Internal Slots of ECMAScript Function Objects, https://tc39.es/ecma262/#table-internal-slots-of-ecmascript-function-objects
220220
GC::Ptr<Environment> m_environment; // [[Environment]]
221221
GC::Ptr<PrivateEnvironment> m_private_environment; // [[PrivateEnvironment]]

0 commit comments

Comments
 (0)