Files
ladybird/Libraries/LibJS/Heap/MarkedVector.h
Shannon Booth c2988a7dd5 LibJS: Don't directly teach the heap about the javascript VM or Realm
Instead, smuggle it in as a `void*` private data and let Javascript
aware code cast out that pointer to a VM&.

In order to make this split, rename JS::Cell to JS::CellImpl. Once we
have a LibGC, this will become GC::Cell. CellImpl then has no specific
knowledge of the VM& and Realm&. That knowledge is instead put into
JS::Cell, which inherits from CellImpl. JS::Cell is responsible for
JavaScript's realm initialization, as well as converting of the void*
private data to what it knows should be the VM&.
2024-11-14 15:38:45 +01:00

82 lines
2.0 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 <LibJS/Forward.h>
#include <LibJS/Heap/CellImpl.h>
#include <LibJS/Heap/HeapRoot.h>
namespace JS {
class MarkedVectorBase {
public:
virtual void gather_roots(HashMap<CellImpl*, JS::HeapRoot>&) const = 0;
protected:
explicit MarkedVectorBase(Heap&);
~MarkedVectorBase();
MarkedVectorBase& operator=(MarkedVectorBase const&);
Heap* m_heap { nullptr };
IntrusiveListNode<MarkedVectorBase> m_list_node;
public:
using List = IntrusiveList<&MarkedVectorBase::m_list_node>;
};
template<typename T, size_t inline_capacity>
class MarkedVector final
: public MarkedVectorBase
, public Vector<T, inline_capacity> {
public:
explicit MarkedVector(Heap& heap)
: MarkedVectorBase(heap)
{
}
virtual ~MarkedVector() = default;
MarkedVector(MarkedVector const& other)
: MarkedVectorBase(*other.m_heap)
, Vector<T, inline_capacity>(other)
{
}
MarkedVector(MarkedVector&& other)
: MarkedVectorBase(*other.m_heap)
, Vector<T, inline_capacity>(move(static_cast<Vector<T, inline_capacity>&>(other)))
{
}
MarkedVector& operator=(MarkedVector const& other)
{
Vector<T, inline_capacity>::operator=(other);
MarkedVectorBase::operator=(other);
return *this;
}
virtual void gather_roots(HashMap<CellImpl*, JS::HeapRoot>& roots) const override
{
for (auto& value : *this) {
if constexpr (IsSame<Value, T>) {
if (value.is_cell())
roots.set(&const_cast<T&>(value).as_cell(), HeapRoot { .type = HeapRoot::Type::MarkedVector });
} else {
roots.set(value, HeapRoot { .type = HeapRoot::Type::MarkedVector });
}
}
}
};
}