Skip to content

Commit 2d76e21

Browse files
committed
LibJS: Don't use GC::Root unnecessarily in Error stack traces
This was causing a fair bit of root registration churn on pages that throw lots of errors. Since there's no need for these pointers to float around freely, we can just visit them during the mark phase as usual.
1 parent 6ca69d9 commit 2d76e21

File tree

5 files changed

+18
-10
lines changed

5 files changed

+18
-10
lines changed

Libraries/LibJS/Runtime/Error.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ Error::Error(Object& prototype)
5858
populate_stack();
5959
}
6060

61+
void Error::visit_edges(Visitor& visitor)
62+
{
63+
Base::visit_edges(visitor);
64+
for (auto& frame : m_traceback)
65+
visitor.visit(frame.cached_source_range);
66+
}
67+
6168
// 20.5.8.1 InstallErrorCause ( O, options ), https://tc39.es/ecma262/#sec-installerrorcause
6269
ThrowCompletionOr<void> Error::install_error_cause(Value options)
6370
{

Libraries/LibJS/Runtime/Error.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct JS_API TracebackFrame {
2121
Utf16String function_name;
2222
[[nodiscard]] SourceRange const& source_range() const;
2323

24-
GC::Root<CachedSourceRange> cached_source_range;
24+
GC::Ptr<CachedSourceRange> cached_source_range;
2525
};
2626

2727
enum CompactTraceback {
@@ -51,6 +51,8 @@ class JS_API Error : public Object {
5151
protected:
5252
explicit Error(Object& prototype);
5353

54+
virtual void visit_edges(Visitor&) override;
55+
5456
private:
5557
virtual bool is_error_object() const final { return true; }
5658

Libraries/LibJS/Runtime/ExecutionContext.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ static_assert(IsTriviallyDestructible<ExecutionContext>);
164164
} while (0)
165165

166166
struct StackTraceElement {
167-
ExecutionContext* execution_context;
168-
GC::Root<CachedSourceRange> source_range;
167+
ExecutionContext* execution_context { nullptr };
168+
GC::Ptr<CachedSourceRange> source_range;
169169
};
170170

171171
}

Libraries/LibJS/Runtime/VM.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -774,11 +774,11 @@ static GC::Ptr<CachedSourceRange> get_source_range(ExecutionContext* context)
774774
return context->rare_data()->cached_source_range;
775775
}
776776

777-
Vector<StackTraceElement> VM::stack_trace() const
777+
GC::ConservativeVector<StackTraceElement> VM::stack_trace() const
778778
{
779-
Vector<StackTraceElement> stack_trace;
780-
for (ssize_t i = m_execution_context_stack.size() - 1; i >= 0; i--) {
781-
auto* context = m_execution_context_stack[i];
779+
GC::ConservativeVector<StackTraceElement> stack_trace(heap());
780+
stack_trace.ensure_capacity(m_execution_context_stack.size());
781+
for (auto* context : m_execution_context_stack.in_reverse()) {
782782
stack_trace.append({
783783
.execution_context = context,
784784
.source_range = get_source_range(context),

Libraries/LibJS/Runtime/VM.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ class JS_API VM : public RefCounted<VM> {
5858
static NonnullRefPtr<VM> create();
5959
~VM();
6060

61-
GC::Heap& heap() { return m_heap; }
62-
GC::Heap const& heap() const { return m_heap; }
61+
GC::Heap& heap() const { return const_cast<GC::Heap&>(m_heap); }
6362

6463
Bytecode::Interpreter& bytecode_interpreter() { return *m_bytecode_interpreter; }
6564

@@ -295,7 +294,7 @@ class JS_API VM : public RefCounted<VM> {
295294
Function<ThrowCompletionOr<void>(Realm&, NonnullOwnPtr<ExecutionContext>, ShadowRealm&)> host_initialize_shadow_realm;
296295
Function<Crypto::SignedBigInteger(Object const& global)> host_system_utc_epoch_nanoseconds;
297296

298-
Vector<StackTraceElement> stack_trace() const;
297+
[[nodiscard]] GC::ConservativeVector<StackTraceElement> stack_trace() const;
299298

300299
private:
301300
using ErrorMessages = AK::Array<Utf16String, to_underlying(ErrorMessage::__Count)>;

0 commit comments

Comments
 (0)