mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-11 17:37:33 +02:00
111 lines
2.8 KiB
C++
111 lines
2.8 KiB
C++
/*
|
|
* Copyright (c) 2021, Andreas Kling <andreas@ladybird.org>
|
|
* Copyright (c) 2022, Linus Groh <linusg@serenityos.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 GC_API RootVectorBase {
|
|
public:
|
|
virtual void gather_roots(HashMap<Cell*, GC::HeapRoot>&) const = 0;
|
|
|
|
protected:
|
|
explicit RootVectorBase(Heap&);
|
|
~RootVectorBase();
|
|
|
|
void assign_heap(Heap*);
|
|
|
|
Heap* m_heap { nullptr };
|
|
IntrusiveListNode<RootVectorBase> m_list_node;
|
|
|
|
public:
|
|
using List = IntrusiveList<&RootVectorBase::m_list_node>;
|
|
};
|
|
|
|
template<typename T, size_t inline_capacity>
|
|
class RootVector final
|
|
: public RootVectorBase
|
|
, public Vector<T, inline_capacity> {
|
|
|
|
using VectorBase = Vector<T, inline_capacity>;
|
|
|
|
public:
|
|
explicit RootVector(Heap& heap)
|
|
: RootVectorBase(heap)
|
|
{
|
|
}
|
|
|
|
~RootVector() = default;
|
|
|
|
RootVector(Heap& heap, ReadonlySpan<T> other)
|
|
: RootVectorBase(heap)
|
|
, Vector<T, inline_capacity>(other)
|
|
{
|
|
}
|
|
|
|
RootVector(RootVector const& other)
|
|
: RootVectorBase(*other.m_heap)
|
|
, Vector<T, inline_capacity>(other)
|
|
{
|
|
}
|
|
|
|
RootVector(RootVector&& other)
|
|
: RootVectorBase(*other.m_heap)
|
|
, VectorBase(move(static_cast<VectorBase&>(other)))
|
|
{
|
|
}
|
|
|
|
RootVector& operator=(RootVector const& other)
|
|
{
|
|
if (&other == this)
|
|
return *this;
|
|
|
|
assign_heap(other.m_heap);
|
|
VectorBase::operator=(other);
|
|
return *this;
|
|
}
|
|
|
|
RootVector& operator=(RootVector&& other)
|
|
{
|
|
assign_heap(other.m_heap);
|
|
VectorBase::operator=(move(static_cast<VectorBase&>(other)));
|
|
return *this;
|
|
}
|
|
|
|
virtual void gather_roots(HashMap<Cell*, GC::HeapRoot>& roots) const override
|
|
{
|
|
static_assert(IsBaseOf<NanBoxedValue, T> || IsConvertible<T, Cell const*>,
|
|
"RootVector element type must be convertible to Cell const* or derive from NanBoxedValue");
|
|
for (auto& value : *this) {
|
|
if constexpr (IsBaseOf<NanBoxedValue, T>) {
|
|
if (value.is_cell())
|
|
roots.set(&const_cast<T&>(value).as_cell(), HeapRoot { .type = HeapRoot::Type::RootVector });
|
|
} else if constexpr (IsConvertible<T, Cell const*>) {
|
|
roots.set(const_cast<Cell*>(static_cast<Cell const*>(value)), HeapRoot { .type = HeapRoot::Type::RootVector });
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
RootVector(Heap&, ReadonlySpan<T> const&) -> RootVector<T>;
|
|
|
|
template<typename T>
|
|
RootVector(Heap&, Span<T> const&) -> RootVector<T>;
|
|
|
|
template<typename T>
|
|
RootVector(Heap&, Vector<T> const&) -> RootVector<T>;
|
|
|
|
}
|