Fix a few bugs with GC roots

This commit is contained in:
Konstantin Nazarov 2024-07-27 01:01:38 +01:00
parent db91d830af
commit ded19f7962
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
4 changed files with 35 additions and 6 deletions

View file

@ -1,6 +1,7 @@
#pragma once
#include <concepts>
#include <iostream>
#include "error.hpp"
#include "pod.hpp"
@ -58,10 +59,10 @@ class GcRootList {
}
void remove() {
_prev = 0;
_next = 0;
if (_prev) _prev->_next = _next;
if (_next) _next->_prev = _prev;
_prev = 0;
_next = 0;
}
GcRootList* next() { return _next; }
@ -161,4 +162,5 @@ GcRoot<T>::GcRoot(GcRoot<T>&& rhs) {
rhs._node->update(this);
_ptr = rhs._ptr;
_node = rhs._node;
rhs._node = 0;
}

View file

@ -96,10 +96,28 @@ class String : public Object {
auto pod_string = TRY(arena.alloc<PodString>(size * sizeof(char32_t)));
memcpy(pod_string->data, chars, size * sizeof(char32_t));
pod_string->size = size;
return String(TRY(MkGcRoot(pod_string, arena)));
}
static Result<String> create(Arena& arena, const char* str) {
uint64_t size = strlen(str);
auto pod_string = TRY(arena.alloc<PodString>(size * sizeof(char32_t)));
for (uint64_t i = 0; i < size; i++) pod_string->data[i] = str[i];
pod_string->size = size;
return String(TRY(MkGcRoot(pod_string, arena)));
}
uint64_t size() { return _value->size; }
Result<char32_t> operator[](uint64_t idx) {
if (idx >= _value->size) return ErrorCode::IndexOutOfRange;
return _value->data[idx];
}
virtual Result<Value> copy(Arena& arena) final;
private:
@ -204,7 +222,10 @@ class Value {
public:
Value() { new (buf) Nil(); }
~Value() { ((Object*)buf)->~Object(); }
Value(Value&& val) { memcpy(buf, val.buf, 24); }
Value(Value&& val) {
memcpy(buf, val.buf, 24);
new (val.buf) Nil();
}
Value(const Value&) = delete;
template <class T>

View file

@ -2,6 +2,7 @@
enum class ErrorCode {
Success,
OutOfMemory
OutOfMemory,
IndexOutOfRange
};

View file

@ -18,8 +18,13 @@ int main() {
std::cout << int(((Int64&)*val).value()) << "\n";
*/
auto lst = DIEIF(arena.alloc<PodPair>());
auto root = DIEIF(MkGcRoot(lst, arena));
{
auto s = DIEIF(String::create(arena, "foo"));
std::cout << "roout count: " << arena.root_count() << "\n";
std::cout << "char: " << (char)DIEIF(s[2]) << "\n";
}
std::cout << "roout count: " << arena.root_count() << "\n";
return 0;
}