mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-08 05:27:14 +09:00
LibGC: Add GC::RootHashMap<...> template container
This is a GC-aware wrapper around AK::HashMap. Entry values are treated as GC roots, much like the GC::RootVector we already had. We also provide GC::OrderedRootHashMap as a convenience.
This commit is contained in:
parent
a453da2906
commit
11ece7de10
Notes:
github-actions[bot]
2025-05-03 15:34:58 +00:00
Author: https://github.com/awesomekling
Commit: 11ece7de10
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4573
6 changed files with 122 additions and 0 deletions
|
@ -5,6 +5,7 @@ set(SOURCES
|
|||
ConservativeVector.cpp
|
||||
ForeignCell.cpp
|
||||
Root.cpp
|
||||
RootHashMap.cpp
|
||||
RootVector.cpp
|
||||
Heap.cpp
|
||||
HeapBlock.cpp
|
||||
|
|
|
@ -282,6 +282,9 @@ void Heap::gather_roots(HashMap<Cell*, HeapRoot>& roots)
|
|||
for (auto& vector : m_root_vectors)
|
||||
vector.gather_roots(roots);
|
||||
|
||||
for (auto& hash_map : m_root_hash_maps)
|
||||
hash_map.gather_roots(roots);
|
||||
|
||||
if constexpr (HEAP_DEBUG) {
|
||||
dbgln("gather_roots:");
|
||||
for (auto* root : roots.keys())
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <LibGC/HeapRoot.h>
|
||||
#include <LibGC/Internals.h>
|
||||
#include <LibGC/Root.h>
|
||||
#include <LibGC/RootHashMap.h>
|
||||
#include <LibGC/RootVector.h>
|
||||
#include <LibGC/WeakContainer.h>
|
||||
|
||||
|
@ -64,6 +65,9 @@ public:
|
|||
void did_create_root_vector(Badge<RootVectorBase>, RootVectorBase&);
|
||||
void did_destroy_root_vector(Badge<RootVectorBase>, RootVectorBase&);
|
||||
|
||||
void did_create_root_hash_map(Badge<RootHashMapBase>, RootHashMapBase&);
|
||||
void did_destroy_root_hash_map(Badge<RootHashMapBase>, RootHashMapBase&);
|
||||
|
||||
void did_create_conservative_vector(Badge<ConservativeVectorBase>, ConservativeVectorBase&);
|
||||
void did_destroy_conservative_vector(Badge<ConservativeVectorBase>, ConservativeVectorBase&);
|
||||
|
||||
|
@ -142,6 +146,7 @@ private:
|
|||
|
||||
RootImpl::List m_roots;
|
||||
RootVectorBase::List m_root_vectors;
|
||||
RootHashMapBase::List m_root_hash_maps;
|
||||
ConservativeVectorBase::List m_conservative_vectors;
|
||||
WeakContainer::List m_weak_containers;
|
||||
|
||||
|
@ -181,6 +186,18 @@ inline void Heap::did_destroy_root_vector(Badge<RootVectorBase>, RootVectorBase&
|
|||
m_root_vectors.remove(vector);
|
||||
}
|
||||
|
||||
inline void Heap::did_create_root_hash_map(Badge<RootHashMapBase>, RootHashMapBase& hash_map)
|
||||
{
|
||||
VERIFY(!m_root_hash_maps.contains(hash_map));
|
||||
m_root_hash_maps.append(hash_map);
|
||||
}
|
||||
|
||||
inline void Heap::did_destroy_root_hash_map(Badge<RootHashMapBase>, RootHashMapBase& hash_map)
|
||||
{
|
||||
VERIFY(m_root_hash_maps.contains(hash_map));
|
||||
m_root_hash_maps.remove(hash_map);
|
||||
}
|
||||
|
||||
inline void Heap::did_create_conservative_vector(Badge<ConservativeVectorBase>, ConservativeVectorBase& vector)
|
||||
{
|
||||
VERIFY(!m_conservative_vectors.contains(vector));
|
||||
|
|
|
@ -15,6 +15,7 @@ struct HeapRoot {
|
|||
HeapFunctionCapturedPointer,
|
||||
Root,
|
||||
RootVector,
|
||||
RootHashMap,
|
||||
ConservativeVector,
|
||||
RegisterPointer,
|
||||
StackPointer,
|
||||
|
|
34
Libraries/LibGC/RootHashMap.cpp
Normal file
34
Libraries/LibGC/RootHashMap.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Andreas Kling <andreas@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibGC/Heap.h>
|
||||
#include <LibGC/RootHashMap.h>
|
||||
|
||||
namespace GC {
|
||||
|
||||
RootHashMapBase::RootHashMapBase(Heap& heap)
|
||||
: m_heap(&heap)
|
||||
{
|
||||
m_heap->did_create_root_hash_map({}, *this);
|
||||
}
|
||||
|
||||
RootHashMapBase::~RootHashMapBase()
|
||||
{
|
||||
m_heap->did_destroy_root_hash_map({}, *this);
|
||||
}
|
||||
|
||||
void RootHashMapBase::assign_heap(Heap* heap)
|
||||
{
|
||||
if (m_heap == heap)
|
||||
return;
|
||||
|
||||
m_heap = heap;
|
||||
|
||||
// NOTE: IntrusiveList will remove this RootHashMap from the old heap it was part of.
|
||||
m_heap->did_create_root_hash_map({}, *this);
|
||||
}
|
||||
|
||||
}
|
66
Libraries/LibGC/RootHashMap.h
Normal file
66
Libraries/LibGC/RootHashMap.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Andreas Kling <andreas@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/IntrusiveList.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGC/Cell.h>
|
||||
#include <LibGC/Forward.h>
|
||||
#include <LibGC/HeapRoot.h>
|
||||
|
||||
namespace GC {
|
||||
|
||||
class RootHashMapBase {
|
||||
public:
|
||||
virtual void gather_roots(HashMap<Cell*, GC::HeapRoot>&) const = 0;
|
||||
|
||||
protected:
|
||||
explicit RootHashMapBase(Heap&);
|
||||
~RootHashMapBase();
|
||||
|
||||
void assign_heap(Heap*);
|
||||
|
||||
Heap* m_heap { nullptr };
|
||||
IntrusiveListNode<RootHashMapBase> m_list_node;
|
||||
|
||||
public:
|
||||
using List = IntrusiveList<&RootHashMapBase::m_list_node>;
|
||||
};
|
||||
|
||||
template<typename K, typename V, typename KeyTraits = Traits<K>, typename ValueTraits = Traits<V>, bool IsOrdered = false>
|
||||
class RootHashMap final
|
||||
: public RootHashMapBase
|
||||
, public HashMap<K, V, KeyTraits, ValueTraits, IsOrdered> {
|
||||
|
||||
using HashMapBase = HashMap<K, V, KeyTraits, ValueTraits, IsOrdered>;
|
||||
|
||||
public:
|
||||
explicit RootHashMap(Heap& heap)
|
||||
: RootHashMapBase(heap)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~RootHashMap() = default;
|
||||
|
||||
virtual void gather_roots(HashMap<Cell*, GC::HeapRoot>& roots) const override
|
||||
{
|
||||
for (auto& [key, value] : *this) {
|
||||
if constexpr (IsBaseOf<NanBoxedValue, V>) {
|
||||
if (value.is_cell())
|
||||
roots.set(&const_cast<V&>(value).as_cell(), HeapRoot { .type = HeapRoot::Type::RootHashMap });
|
||||
} else {
|
||||
roots.set(value, HeapRoot { .type = HeapRoot::Type::RootHashMap });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename K, typename V, typename KeyTraits = Traits<K>, typename ValueTraits = Traits<V>>
|
||||
using OrderedRootHashMap = RootHashMap<K, V, KeyTraits, ValueTraits, true>;
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue