mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-05 15:49:11 +00: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
|
ConservativeVector.cpp
|
||||||
ForeignCell.cpp
|
ForeignCell.cpp
|
||||||
Root.cpp
|
Root.cpp
|
||||||
|
RootHashMap.cpp
|
||||||
RootVector.cpp
|
RootVector.cpp
|
||||||
Heap.cpp
|
Heap.cpp
|
||||||
HeapBlock.cpp
|
HeapBlock.cpp
|
||||||
|
|
|
@ -282,6 +282,9 @@ void Heap::gather_roots(HashMap<Cell*, HeapRoot>& roots)
|
||||||
for (auto& vector : m_root_vectors)
|
for (auto& vector : m_root_vectors)
|
||||||
vector.gather_roots(roots);
|
vector.gather_roots(roots);
|
||||||
|
|
||||||
|
for (auto& hash_map : m_root_hash_maps)
|
||||||
|
hash_map.gather_roots(roots);
|
||||||
|
|
||||||
if constexpr (HEAP_DEBUG) {
|
if constexpr (HEAP_DEBUG) {
|
||||||
dbgln("gather_roots:");
|
dbgln("gather_roots:");
|
||||||
for (auto* root : roots.keys())
|
for (auto* root : roots.keys())
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <LibGC/HeapRoot.h>
|
#include <LibGC/HeapRoot.h>
|
||||||
#include <LibGC/Internals.h>
|
#include <LibGC/Internals.h>
|
||||||
#include <LibGC/Root.h>
|
#include <LibGC/Root.h>
|
||||||
|
#include <LibGC/RootHashMap.h>
|
||||||
#include <LibGC/RootVector.h>
|
#include <LibGC/RootVector.h>
|
||||||
#include <LibGC/WeakContainer.h>
|
#include <LibGC/WeakContainer.h>
|
||||||
|
|
||||||
|
@ -64,6 +65,9 @@ public:
|
||||||
void did_create_root_vector(Badge<RootVectorBase>, RootVectorBase&);
|
void did_create_root_vector(Badge<RootVectorBase>, RootVectorBase&);
|
||||||
void did_destroy_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_create_conservative_vector(Badge<ConservativeVectorBase>, ConservativeVectorBase&);
|
||||||
void did_destroy_conservative_vector(Badge<ConservativeVectorBase>, ConservativeVectorBase&);
|
void did_destroy_conservative_vector(Badge<ConservativeVectorBase>, ConservativeVectorBase&);
|
||||||
|
|
||||||
|
@ -142,6 +146,7 @@ private:
|
||||||
|
|
||||||
RootImpl::List m_roots;
|
RootImpl::List m_roots;
|
||||||
RootVectorBase::List m_root_vectors;
|
RootVectorBase::List m_root_vectors;
|
||||||
|
RootHashMapBase::List m_root_hash_maps;
|
||||||
ConservativeVectorBase::List m_conservative_vectors;
|
ConservativeVectorBase::List m_conservative_vectors;
|
||||||
WeakContainer::List m_weak_containers;
|
WeakContainer::List m_weak_containers;
|
||||||
|
|
||||||
|
@ -181,6 +186,18 @@ inline void Heap::did_destroy_root_vector(Badge<RootVectorBase>, RootVectorBase&
|
||||||
m_root_vectors.remove(vector);
|
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)
|
inline void Heap::did_create_conservative_vector(Badge<ConservativeVectorBase>, ConservativeVectorBase& vector)
|
||||||
{
|
{
|
||||||
VERIFY(!m_conservative_vectors.contains(vector));
|
VERIFY(!m_conservative_vectors.contains(vector));
|
||||||
|
|
|
@ -15,6 +15,7 @@ struct HeapRoot {
|
||||||
HeapFunctionCapturedPointer,
|
HeapFunctionCapturedPointer,
|
||||||
Root,
|
Root,
|
||||||
RootVector,
|
RootVector,
|
||||||
|
RootHashMap,
|
||||||
ConservativeVector,
|
ConservativeVector,
|
||||||
RegisterPointer,
|
RegisterPointer,
|
||||||
StackPointer,
|
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