diff options
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r-- | Userland/Libraries/LibJS/Heap/Cell.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Heap/Heap.cpp | 14 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Heap/Heap.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/WeakMap.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/WeakRef.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/WeakSet.h | 2 |
7 files changed, 25 insertions, 1 deletions
diff --git a/Userland/Libraries/LibJS/Heap/Cell.h b/Userland/Libraries/LibJS/Heap/Cell.h index f2229c9e6e..6e3e107988 100644 --- a/Userland/Libraries/LibJS/Heap/Cell.h +++ b/Userland/Libraries/LibJS/Heap/Cell.h @@ -24,9 +24,12 @@ public: bool is_marked() const { return m_mark; } void set_marked(bool b) { m_mark = b; } + virtual void did_become_zombie() { } + enum class State { Live, Dead, + Zombie, }; State state() const { return m_state; } diff --git a/Userland/Libraries/LibJS/Heap/Heap.cpp b/Userland/Libraries/LibJS/Heap/Heap.cpp index 4c5b9292d0..4e7ccdf6fb 100644 --- a/Userland/Libraries/LibJS/Heap/Heap.cpp +++ b/Userland/Libraries/LibJS/Heap/Heap.cpp @@ -183,6 +183,13 @@ public: if (cell.is_marked()) return; dbgln_if(HEAP_DEBUG, " ! {}", &cell); + + if (cell.state() == Cell::State::Zombie) { + dbgln("BUG! Marking a zombie cell, {} @ {:p}", cell.class_name(), &cell); + cell.vm().dump_backtrace(); + VERIFY_NOT_REACHED(); + } + cell.set_marked(true); cell.visit_edges(*this); } @@ -223,7 +230,12 @@ void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measure dbgln_if(HEAP_DEBUG, " ~ {}", cell); if (should_store_swept_cells) swept_cells.append(cell); - block.deallocate(cell); + if (m_zombify_dead_cells) { + cell->set_state(Cell::State::Zombie); + cell->did_become_zombie(); + } else { + block.deallocate(cell); + } ++collected_cells; collected_cell_bytes += block.cell_size(); } else { diff --git a/Userland/Libraries/LibJS/Heap/Heap.h b/Userland/Libraries/LibJS/Heap/Heap.h index 8f7ac0d39e..99cb29743c 100644 --- a/Userland/Libraries/LibJS/Heap/Heap.h +++ b/Userland/Libraries/LibJS/Heap/Heap.h @@ -69,6 +69,8 @@ public: bool should_collect_on_every_allocation() const { return m_should_collect_on_every_allocation; } void set_should_collect_on_every_allocation(bool b) { m_should_collect_on_every_allocation = b; } + void set_zombify_dead_cells(bool b) { m_zombify_dead_cells = b; } + void did_create_handle(Badge<HandleImpl>, HandleImpl&); void did_destroy_handle(Badge<HandleImpl>, HandleImpl&); @@ -127,6 +129,7 @@ private: bool m_should_gc_when_deferral_ends { false }; bool m_collecting_garbage { false }; + bool m_zombify_dead_cells { false }; }; } diff --git a/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h b/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h index 27ef6e1695..6affdcd6a3 100644 --- a/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h +++ b/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h @@ -34,6 +34,7 @@ public: private: virtual void visit_edges(Visitor& visitor) override; + virtual void did_become_zombie() override { deregister(); } FunctionObject* m_cleanup_callback { nullptr }; diff --git a/Userland/Libraries/LibJS/Runtime/WeakMap.h b/Userland/Libraries/LibJS/Runtime/WeakMap.h index 18a6b74305..2f7c01b2d1 100644 --- a/Userland/Libraries/LibJS/Runtime/WeakMap.h +++ b/Userland/Libraries/LibJS/Runtime/WeakMap.h @@ -30,6 +30,8 @@ public: virtual void remove_swept_cells(Badge<Heap>, Span<Cell*>) override; private: + virtual void did_become_zombie() override { deregister(); } + HashMap<Cell*, Value> m_values; // This stores Cell pointers instead of Object pointers to aide with sweeping }; diff --git a/Userland/Libraries/LibJS/Runtime/WeakRef.h b/Userland/Libraries/LibJS/Runtime/WeakRef.h index d93202ed55..40a370105e 100644 --- a/Userland/Libraries/LibJS/Runtime/WeakRef.h +++ b/Userland/Libraries/LibJS/Runtime/WeakRef.h @@ -31,6 +31,7 @@ public: private: virtual void visit_edges(Visitor&) override; + virtual void did_become_zombie() override { deregister(); } Object* m_value { nullptr }; u32 m_last_execution_generation { 0 }; diff --git a/Userland/Libraries/LibJS/Runtime/WeakSet.h b/Userland/Libraries/LibJS/Runtime/WeakSet.h index 36433f86c5..2206037c70 100644 --- a/Userland/Libraries/LibJS/Runtime/WeakSet.h +++ b/Userland/Libraries/LibJS/Runtime/WeakSet.h @@ -30,6 +30,8 @@ public: virtual void remove_swept_cells(Badge<Heap>, Span<Cell*>) override; private: + virtual void did_become_zombie() override { deregister(); } + HashTable<Cell*> m_values; // This stores Cell pointers instead of Object pointers to aide with sweeping }; |