diff options
author | Andreas Kling <kling@serenityos.org> | 2020-04-19 17:24:56 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-19 17:34:33 +0200 |
commit | f7a1696087d3b2f03e11f07cb28ef4f6cbd9fdb0 (patch) | |
tree | 0dfdd8c0b6cfa0e8a2534da52b3f997943bd62cf /Libraries/LibJS/Heap | |
parent | cb3cf589ed8a5df38a801bbc34a21951924e9195 (diff) | |
download | serenity-f7a1696087d3b2f03e11f07cb28ef4f6cbd9fdb0.zip |
LibJS: Add MarkedValueList and use it for argument passing
A MarkedValueList is basically a Vector<JS::Value> that registers with
the Heap and makes sure that the stored values don't get GC'd.
Before this change, we were unsafely keeping Vector<JS::Value> in some
places, which is out-of-reach for the live reference finding logic
since Vector puts its elements on the heap by default.
We now pass all the JavaScript tests even when running with "js -g",
which does a GC on every heap allocation.
Diffstat (limited to 'Libraries/LibJS/Heap')
-rw-r--r-- | Libraries/LibJS/Heap/Heap.cpp | 20 | ||||
-rw-r--r-- | Libraries/LibJS/Heap/Heap.h | 5 |
2 files changed, 25 insertions, 0 deletions
diff --git a/Libraries/LibJS/Heap/Heap.cpp b/Libraries/LibJS/Heap/Heap.cpp index 0bb47f0d6b..c36a43e7cf 100644 --- a/Libraries/LibJS/Heap/Heap.cpp +++ b/Libraries/LibJS/Heap/Heap.cpp @@ -30,6 +30,7 @@ #include <LibJS/Heap/Heap.h> #include <LibJS/Heap/HeapBlock.h> #include <LibJS/Interpreter.h> +#include <LibJS/Runtime/MarkedValueList.h> #include <LibJS/Runtime/Object.h> #include <setjmp.h> #include <stdio.h> @@ -104,6 +105,13 @@ void Heap::gather_roots(HashTable<Cell*>& roots) for (auto* handle : m_handles) roots.set(handle->cell()); + for (auto* list : m_marked_value_lists) { + for (auto& value : list->values()) { + if (value.is_cell()) + roots.set(value.as_cell()); + } + } + #ifdef HEAP_DEBUG dbg() << "gather_roots:"; for (auto* root : roots) { @@ -266,6 +274,18 @@ void Heap::did_destroy_handle(Badge<HandleImpl>, HandleImpl& impl) m_handles.remove(&impl); } +void Heap::did_create_marked_value_list(Badge<MarkedValueList>, MarkedValueList& list) +{ + ASSERT(!m_marked_value_lists.contains(&list)); + m_marked_value_lists.set(&list); +} + +void Heap::did_destroy_marked_value_list(Badge<MarkedValueList>, MarkedValueList& list) +{ + ASSERT(m_marked_value_lists.contains(&list)); + m_marked_value_lists.remove(&list); +} + void Heap::defer_gc(Badge<DeferGC>) { ++m_gc_deferrals; diff --git a/Libraries/LibJS/Heap/Heap.h b/Libraries/LibJS/Heap/Heap.h index 5504472107..6544021b5a 100644 --- a/Libraries/LibJS/Heap/Heap.h +++ b/Libraries/LibJS/Heap/Heap.h @@ -68,6 +68,9 @@ public: void did_create_handle(Badge<HandleImpl>, HandleImpl&); void did_destroy_handle(Badge<HandleImpl>, HandleImpl&); + void did_create_marked_value_list(Badge<MarkedValueList>, MarkedValueList&); + void did_destroy_marked_value_list(Badge<MarkedValueList>, MarkedValueList&); + void defer_gc(Badge<DeferGC>); void undefer_gc(Badge<DeferGC>); @@ -90,6 +93,8 @@ private: Vector<NonnullOwnPtr<HeapBlock>> m_blocks; HashTable<HandleImpl*> m_handles; + HashTable<MarkedValueList*> m_marked_value_lists; + size_t m_gc_deferrals { 0 }; bool m_should_gc_when_deferral_ends { false }; }; |