mirror of
https://github.com/RGBCube/serenity
synced 2025-10-24 00:22:30 +00:00
This change introduces a very basic GC graph dumper. The `dump_graph()`
function outputs JSON data that contains information about all nodes in
the graph, including their class types and edges.
Root nodes will have a property indicating their root type or source
location if the root is captured by a SafeFunction. It would be useful
to add source location for other types of roots in the future.
Output JSON dump have following format:
```json
"4908721208": {
"class_name": "Accessor",
"edges": [
"4909298232",
"4909297976"
]
},
"4907520440": {
"root": "SafeFunction Optional Optional.h:137",
"class_name": "Realm",
"edges": [
"4908269624",
"4924821560",
"4908409240",
"4908483960",
"4924527672"
]
},
"4908251320": {
"class_name": "CSSStyleRule",
"edges": [
"4908302648",
"4925101656",
"4908251192"
]
},
```
81 lines
2 KiB
C++
81 lines
2 KiB
C++
/*
|
|
* Copyright (c) 2021, Andreas Kling <kling@serenityos.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/Cell.h>
|
|
#include <LibJS/Heap/HeapRootTypeOrLocation.h>
|
|
|
|
namespace JS {
|
|
|
|
class MarkedVectorBase {
|
|
public:
|
|
virtual void gather_roots(HashMap<Cell*, JS::HeapRootTypeOrLocation>&) 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<Cell*, JS::HeapRootTypeOrLocation>& roots) const override
|
|
{
|
|
for (auto& value : *this) {
|
|
if constexpr (IsSame<Value, T>) {
|
|
if (value.is_cell())
|
|
roots.set(&const_cast<T&>(value).as_cell(), HeapRootType::MarkedVector);
|
|
} else {
|
|
roots.set(value, HeapRootType::MarkedVector);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
}
|