mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 23:37:43 +00:00
LibJS: Add caching of this value in ResolveThisBinding instruction
Because "this" value cannot be changed during function execution it is safe to compute it once and then use for future access. This optimization makes ai-astar.js run 8% faster.
This commit is contained in:
parent
bbd80d2e4d
commit
2bdc69c42c
3 changed files with 12 additions and 2 deletions
|
@ -208,6 +208,8 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Realm& realm, Execu
|
||||||
else
|
else
|
||||||
push_call_frame(make<CallFrame>(), executable.number_of_registers);
|
push_call_frame(make<CallFrame>(), executable.number_of_registers);
|
||||||
|
|
||||||
|
TemporaryChange restore_this_value { m_this_value, {} };
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Bytecode::InstructionStreamIterator pc(m_current_block->instruction_stream());
|
Bytecode::InstructionStreamIterator pc(m_current_block->instruction_stream());
|
||||||
TemporaryChange temp_change { m_pc, &pc };
|
TemporaryChange temp_change { m_pc, &pc };
|
||||||
|
|
|
@ -95,6 +95,8 @@ public:
|
||||||
|
|
||||||
VM::InterpreterExecutionScope ast_interpreter_scope(Realm&);
|
VM::InterpreterExecutionScope ast_interpreter_scope(Realm&);
|
||||||
|
|
||||||
|
Optional<Value>& this_value() { return m_this_value; }
|
||||||
|
|
||||||
void visit_edges(Cell::Visitor&);
|
void visit_edges(Cell::Visitor&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -119,6 +121,7 @@ private:
|
||||||
Span<Value> m_current_call_frame;
|
Span<Value> m_current_call_frame;
|
||||||
Optional<BasicBlock const*> m_pending_jump;
|
Optional<BasicBlock const*> m_pending_jump;
|
||||||
BasicBlock const* m_scheduled_jump { nullptr };
|
BasicBlock const* m_scheduled_jump { nullptr };
|
||||||
|
Optional<Value> m_this_value;
|
||||||
Optional<Value> m_return_value;
|
Optional<Value> m_return_value;
|
||||||
Optional<Value> m_saved_exception;
|
Optional<Value> m_saved_exception;
|
||||||
Executable* m_current_executable { nullptr };
|
Executable* m_current_executable { nullptr };
|
||||||
|
|
|
@ -732,8 +732,13 @@ ThrowCompletionOr<void> Jump::execute_impl(Bytecode::Interpreter& interpreter) c
|
||||||
|
|
||||||
ThrowCompletionOr<void> ResolveThisBinding::execute_impl(Bytecode::Interpreter& interpreter) const
|
ThrowCompletionOr<void> ResolveThisBinding::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
auto& vm = interpreter.vm();
|
if (!interpreter.this_value().has_value()) {
|
||||||
interpreter.accumulator() = TRY(vm.resolve_this_binding());
|
// OPTIMIZATION: Because the value of 'this' cannot be reassigned during a function execution, it's
|
||||||
|
// resolved once and then saved for subsequent use.
|
||||||
|
auto& vm = interpreter.vm();
|
||||||
|
interpreter.this_value() = TRY(vm.resolve_this_binding());
|
||||||
|
}
|
||||||
|
interpreter.accumulator() = interpreter.this_value().value();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue