summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r--Userland/Libraries/LibJS/Heap/Cell.h3
-rw-r--r--Userland/Libraries/LibJS/Heap/Heap.cpp14
-rw-r--r--Userland/Libraries/LibJS/Heap/Heap.h3
-rw-r--r--Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/WeakMap.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/WeakRef.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/WeakSet.h2
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
};