فهرست منبع

LibJS: Use a Function to indirectly let Heap visit VM's GC roots

This allows the heap to mark cells that it needs to mark as roots
without needing to directly reference the VM.
Shannon Booth 7 ماه پیش
والد
کامیت
ae6d105f41
3فایلهای تغییر یافته به همراه10 افزوده شده و 5 حذف شده
  1. 4 3
      Libraries/LibJS/Heap/Heap.cpp
  2. 3 1
      Libraries/LibJS/Heap/Heap.h
  3. 3 1
      Libraries/LibJS/Runtime/VM.cpp

+ 4 - 3
Libraries/LibJS/Heap/Heap.cpp

@@ -7,6 +7,7 @@
 
 
 #include <AK/Badge.h>
 #include <AK/Badge.h>
 #include <AK/Debug.h>
 #include <AK/Debug.h>
+#include <AK/Function.h>
 #include <AK/HashTable.h>
 #include <AK/HashTable.h>
 #include <AK/JsonArray.h>
 #include <AK/JsonArray.h>
 #include <AK/JsonObject.h>
 #include <AK/JsonObject.h>
@@ -19,7 +20,6 @@
 #include <LibJS/Heap/Heap.h>
 #include <LibJS/Heap/Heap.h>
 #include <LibJS/Heap/HeapBlock.h>
 #include <LibJS/Heap/HeapBlock.h>
 #include <LibJS/Heap/NanBoxedValue.h>
 #include <LibJS/Heap/NanBoxedValue.h>
-#include <LibJS/Runtime/VM.h>
 #include <setjmp.h>
 #include <setjmp.h>
 
 
 #ifdef HAS_ADDRESS_SANITIZER
 #ifdef HAS_ADDRESS_SANITIZER
@@ -28,8 +28,9 @@
 
 
 namespace JS {
 namespace JS {
 
 
-Heap::Heap(VM& vm)
+Heap::Heap(VM& vm, Function<void(HashMap<Cell*, JS::HeapRoot>&)> gather_embedder_roots)
     : HeapBase(vm)
     : HeapBase(vm)
+    , m_gather_embedder_roots(move(gather_embedder_roots))
 {
 {
     static_assert(HeapBlock::min_possible_cell_size <= 32, "Heap Cell tracking uses too much data!");
     static_assert(HeapBlock::min_possible_cell_size <= 32, "Heap Cell tracking uses too much data!");
     m_size_based_cell_allocators.append(make<CellAllocator>(64));
     m_size_based_cell_allocators.append(make<CellAllocator>(64));
@@ -259,7 +260,7 @@ void Heap::collect_garbage(CollectionType collection_type, bool print_report)
 
 
 void Heap::gather_roots(HashMap<Cell*, HeapRoot>& roots)
 void Heap::gather_roots(HashMap<Cell*, HeapRoot>& roots)
 {
 {
-    vm().gather_roots(roots);
+    m_gather_embedder_roots(roots);
     gather_conservative_roots(roots);
     gather_conservative_roots(roots);
 
 
     for (auto& handle : m_handles)
     for (auto& handle : m_handles)

+ 3 - 1
Libraries/LibJS/Heap/Heap.h

@@ -7,6 +7,7 @@
 #pragma once
 #pragma once
 
 
 #include <AK/Badge.h>
 #include <AK/Badge.h>
+#include <AK/Function.h>
 #include <AK/HashTable.h>
 #include <AK/HashTable.h>
 #include <AK/IntrusiveList.h>
 #include <AK/IntrusiveList.h>
 #include <AK/Noncopyable.h>
 #include <AK/Noncopyable.h>
@@ -32,7 +33,7 @@ class Heap : public HeapBase {
     AK_MAKE_NONMOVABLE(Heap);
     AK_MAKE_NONMOVABLE(Heap);
 
 
 public:
 public:
-    explicit Heap(VM&);
+    explicit Heap(VM&, Function<void(HashMap<Cell*, JS::HeapRoot>&)> gather_embedder_roots);
     ~Heap();
     ~Heap();
 
 
     template<typename T, typename... Args>
     template<typename T, typename... Args>
@@ -145,6 +146,7 @@ private:
 
 
     bool m_collecting_garbage { false };
     bool m_collecting_garbage { false };
     StackInfo m_stack_info;
     StackInfo m_stack_info;
+    Function<void(HashMap<Cell*, JS::HeapRoot>&)> m_gather_embedder_roots;
 };
 };
 
 
 inline void Heap::did_create_handle(Badge<HandleImpl>, HandleImpl& impl)
 inline void Heap::did_create_handle(Badge<HandleImpl>, HandleImpl& impl)

+ 3 - 1
Libraries/LibJS/Runtime/VM.cpp

@@ -62,7 +62,9 @@ static constexpr auto make_single_ascii_character_strings(IndexSequence<code_poi
 static constexpr auto single_ascii_character_strings = make_single_ascii_character_strings(MakeIndexSequence<128>());
 static constexpr auto single_ascii_character_strings = make_single_ascii_character_strings(MakeIndexSequence<128>());
 
 
 VM::VM(OwnPtr<CustomData> custom_data, ErrorMessages error_messages)
 VM::VM(OwnPtr<CustomData> custom_data, ErrorMessages error_messages)
-    : m_heap(*this)
+    : m_heap(*this, [this](HashMap<Cell*, JS::HeapRoot>& roots) {
+        gather_roots(roots);
+    })
     , m_error_messages(move(error_messages))
     , m_error_messages(move(error_messages))
     , m_custom_data(move(custom_data))
     , m_custom_data(move(custom_data))
 {
 {