Make a simple gc root actually work

This commit is contained in:
Konstantin Nazarov 2024-07-20 22:56:45 +01:00
parent baa10bb56b
commit 5ca7630c8c
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
2 changed files with 16 additions and 11 deletions

View file

@ -11,6 +11,7 @@ class GcRootList;
class GcRootBase { class GcRootBase {
public: public:
GcRootBase() : _ptr(0), _node(0){};
GcRootBase(PodObject* ptr, GcRootList* node); GcRootBase(PodObject* ptr, GcRootList* node);
~GcRootBase(); ~GcRootBase();
@ -55,8 +56,8 @@ class GcRootList {
void remove() { void remove() {
_prev = 0; _prev = 0;
_next = 0; _next = 0;
_prev->_next = _next; if (_prev) _prev->_next = _next;
_next->_prev = _prev; if (_next) _next->_prev = _prev;
} }
void update(GcRootBase* root) { _root = root; } void update(GcRootBase* root) { _root = root; }
@ -114,26 +115,22 @@ class Arena {
}; };
template <uint64_t size> template <uint64_t size>
class StaticArenaHeap { class StaticArenaHeap : public ArenaHeap {
public: public:
StaticArenaHeap() : _heap(_buf, heapsize) {} StaticArenaHeap() : ArenaHeap(_buf, heapsize) {}
ArenaHeap* get() { return &_heap; }
private: private:
static const uint64_t heapsize = size - sizeof(ArenaHeap); static const uint64_t heapsize = size - sizeof(ArenaHeap);
ArenaHeap _heap;
uint8_t _buf[heapsize]{0}; uint8_t _buf[heapsize]{0};
}; };
template <uint64_t size> template <uint64_t size>
class StaticArena { class StaticArena : public Arena {
public: public:
StaticArena() : _arena(_heaps[0].get(), _heaps[1].get()) {} StaticArena() : Arena(&_heaps[0], &_heaps[1]) {}
private: private:
StaticArenaHeap<(size - sizeof(Arena)) / 2> _heaps[2]; StaticArenaHeap<(size - sizeof(Arena)) / 2> _heaps[2];
Arena _arena;
}; };
template <class T> template <class T>
@ -141,11 +138,13 @@ template <class T>
Result<GcRoot<T>> GcRoot<T>::create(T* ptr, Arena& arena) { Result<GcRoot<T>> GcRoot<T>::create(T* ptr, Arena& arena) {
auto lst = TRY(arena.alloc<GcRootList>()); auto lst = TRY(arena.alloc<GcRootList>());
arena.add_root(lst); arena.add_root(lst);
return GcRoot<T>(ptr, lst); return std::move(GcRoot<T>(ptr, lst));
} }
template <class T> template <class T>
requires std::derived_from<T, PodObject> requires std::derived_from<T, PodObject>
GcRoot<T>::GcRoot(GcRoot<T>&& rhs) { GcRoot<T>::GcRoot(GcRoot<T>&& rhs) {
rhs._node->update(this); rhs._node->update(this);
_ptr = rhs._ptr;
_node = rhs._node;
} }

View file

@ -1,10 +1,12 @@
#include <iostream> #include <iostream>
#include "arena.hpp"
#include "common.hpp" #include "common.hpp"
StaticArena<64 * 1024 * 1024> arena; StaticArena<64 * 1024 * 1024> arena;
int main() { int main() {
/*
Value val; Value val;
std::cout << sizeof(val) << "\n"; std::cout << sizeof(val) << "\n";
std::cout << int(val->tag()) << "\n"; std::cout << int(val->tag()) << "\n";
@ -14,6 +16,10 @@ int main() {
std::cout << sizeof(val) << "\n"; std::cout << sizeof(val) << "\n";
std::cout << int(val->tag()) << "\n"; std::cout << int(val->tag()) << "\n";
std::cout << int(((Int64&)*val).value()) << "\n"; std::cout << int(((Int64&)*val).value()) << "\n";
*/
auto lst = DIEIF(arena.alloc<PodPair>());
auto root = DIEIF(MkGcRoot(lst, arena));
return 0; return 0;
} }