mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2026-04-18 09:50:27 +00:00
It's harmless if the WeakRef is asked to remove dead cells when it has no dead cells to remove. This can happen if the WeakRef lives longer due to someone referencing it. Caught by test-js with different GC frequency.
57 lines
1.5 KiB
C++
57 lines
1.5 KiB
C++
/*
|
|
* Copyright (c) 2021-2022, Idan Horowitz <idan.horowitz@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibJS/Runtime/WeakRef.h>
|
|
|
|
namespace JS {
|
|
|
|
GC_DEFINE_ALLOCATOR(WeakRef);
|
|
|
|
GC::Ref<WeakRef> WeakRef::create(Realm& realm, Object& value)
|
|
{
|
|
return realm.create<WeakRef>(value, realm.intrinsics().weak_ref_prototype());
|
|
}
|
|
|
|
GC::Ref<WeakRef> WeakRef::create(Realm& realm, Symbol& value)
|
|
{
|
|
return realm.create<WeakRef>(value, realm.intrinsics().weak_ref_prototype());
|
|
}
|
|
|
|
WeakRef::WeakRef(Object& value, Object& prototype)
|
|
: Object(ConstructWithPrototypeTag::Tag, prototype)
|
|
, WeakContainer(heap())
|
|
, m_value(&value)
|
|
, m_last_execution_generation(vm().execution_generation())
|
|
{
|
|
}
|
|
|
|
WeakRef::WeakRef(Symbol& value, Object& prototype)
|
|
: Object(ConstructWithPrototypeTag::Tag, prototype)
|
|
, WeakContainer(heap())
|
|
, m_value(&value)
|
|
, m_last_execution_generation(vm().execution_generation())
|
|
{
|
|
}
|
|
|
|
void WeakRef::remove_dead_cells(Badge<GC::Heap>)
|
|
{
|
|
if (m_value.visit([](Cell* cell) -> bool { return cell->state() == Cell::State::Live; }, [](Empty) -> bool { return true; }))
|
|
return;
|
|
|
|
m_value = Empty {};
|
|
}
|
|
|
|
void WeakRef::visit_edges(Visitor& visitor)
|
|
{
|
|
Base::visit_edges(visitor);
|
|
|
|
if (vm().execution_generation() == m_last_execution_generation) {
|
|
auto* cell = m_value.visit([](Cell* cell) -> Cell* { return cell; }, [](Empty) -> Cell* { return nullptr; });
|
|
visitor.visit(cell);
|
|
}
|
|
}
|
|
|
|
}
|