1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:08:10 +00:00

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.
This commit is contained in:
Andreas Kling 2020-04-19 17:24:56 +02:00
parent cb3cf589ed
commit f7a1696087
13 changed files with 178 additions and 16 deletions

View file

@ -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;