LibJS: Don't track executing AST nodes in a Vector

Instead just link together the InterpreterNodeScopes in a linked list.
This was surprisingly hot on CanvasCycle.
This commit is contained in:
Andreas Kling 2021-03-21 17:38:42 +01:00
parent 46e61d208b
commit e0abfcb27d
Notes: sideshowbarker 2024-07-18 21:11:08 +09:00
4 changed files with 27 additions and 29 deletions

View file

@ -59,19 +59,20 @@ class InterpreterNodeScope {
public: public:
InterpreterNodeScope(Interpreter& interpreter, const ASTNode& node) InterpreterNodeScope(Interpreter& interpreter, const ASTNode& node)
: m_interpreter(interpreter) : m_interpreter(interpreter)
, m_node(node) , m_chain_node { nullptr, node }
{ {
m_interpreter.enter_node(m_node); m_interpreter.vm().call_frame().current_node = &node;
m_interpreter.push_ast_node(m_chain_node);
} }
~InterpreterNodeScope() ~InterpreterNodeScope()
{ {
m_interpreter.exit_node(m_node); m_interpreter.pop_ast_node();
} }
private: private:
Interpreter& m_interpreter; Interpreter& m_interpreter;
const ASTNode& m_node; ExecutingASTNodeChain m_chain_node;
}; };
String ASTNode::class_name() const String ASTNode::class_name() const
@ -2169,8 +2170,7 @@ void SequenceExpression::dump(int indent) const
Value SequenceExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const Value SequenceExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
{ {
interpreter.enter_node(*this); InterpreterNodeScope node_scope { interpreter, *this };
ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
Value last_value; Value last_value;
for (auto& expression : m_expressions) { for (auto& expression : m_expressions) {

View file

@ -143,17 +143,6 @@ void Interpreter::exit_scope(const ScopeNode& scope_node)
vm().unwind(ScopeType::None); vm().unwind(ScopeType::None);
} }
void Interpreter::enter_node(const ASTNode& node)
{
vm().call_frame().current_node = &node;
push_ast_node(node);
}
void Interpreter::exit_node(const ASTNode&)
{
pop_ast_node();
}
void Interpreter::push_scope(ScopeFrame frame) void Interpreter::push_scope(ScopeFrame frame)
{ {
m_scope_stack.append(move(frame)); m_scope_stack.append(move(frame));

View file

@ -44,6 +44,11 @@
namespace JS { namespace JS {
struct ExecutingASTNodeChain {
ExecutingASTNodeChain* previous { nullptr };
const ASTNode& node;
};
class Interpreter : public Weakable<Interpreter> { class Interpreter : public Weakable<Interpreter> {
public: public:
template<typename GlobalObjectType, typename... Args> template<typename GlobalObjectType, typename... Args>
@ -77,14 +82,21 @@ public:
void enter_scope(const ScopeNode&, ScopeType, GlobalObject&); void enter_scope(const ScopeNode&, ScopeType, GlobalObject&);
void exit_scope(const ScopeNode&); void exit_scope(const ScopeNode&);
void enter_node(const ASTNode&); void push_ast_node(ExecutingASTNodeChain& chain_node)
void exit_node(const ASTNode&); {
chain_node.previous = m_ast_node_chain;
m_ast_node_chain = &chain_node;
}
void push_ast_node(const ASTNode& node) { m_ast_nodes.append(&node); } void pop_ast_node()
void pop_ast_node() { m_ast_nodes.take_last(); } {
VERIFY(m_ast_node_chain);
m_ast_node_chain = m_ast_node_chain->previous;
}
const ASTNode* current_node() const { return !m_ast_nodes.is_empty() ? m_ast_nodes.last() : nullptr; } const ASTNode* current_node() const { return m_ast_node_chain ? &m_ast_node_chain->node : nullptr; }
const Vector<const ASTNode*>& node_stack() const { return m_ast_nodes; } ExecutingASTNodeChain* executing_ast_node_chain() { return m_ast_node_chain; }
const ExecutingASTNodeChain* executing_ast_node_chain() const { return m_ast_node_chain; }
Value execute_statement(GlobalObject&, const Statement&, ScopeType = ScopeType::Block); Value execute_statement(GlobalObject&, const Statement&, ScopeType = ScopeType::Block);
@ -94,7 +106,7 @@ private:
void push_scope(ScopeFrame frame); void push_scope(ScopeFrame frame);
Vector<ScopeFrame> m_scope_stack; Vector<ScopeFrame> m_scope_stack;
Vector<const ASTNode*> m_ast_nodes; ExecutingASTNodeChain* m_ast_node_chain { nullptr };
NonnullRefPtr<VM> m_vm; NonnullRefPtr<VM> m_vm;

View file

@ -45,11 +45,8 @@ Exception::Exception(Value value)
} }
if (auto* interpreter = vm.interpreter_if_exists()) { if (auto* interpreter = vm.interpreter_if_exists()) {
auto& node_stack = interpreter->node_stack(); for (auto* node_chain = interpreter->executing_ast_node_chain(); node_chain; node_chain = node_chain->previous) {
for (ssize_t i = node_stack.size() - 1; i >= 0; --i) { m_source_ranges.append(node_chain->node.source_range());
auto* node = node_stack[i];
VERIFY(node);
m_source_ranges.append(node->source_range());
} }
} }
} }