Use GC roots in primitive types
This commit is contained in:
parent
5ca7630c8c
commit
7a6bdc8aad
3 changed files with 100 additions and 25 deletions
|
@ -30,8 +30,12 @@ class GcRoot : public GcRootBase {
|
||||||
GcRoot(GcRoot&& rhs);
|
GcRoot(GcRoot&& rhs);
|
||||||
|
|
||||||
static Result<GcRoot<T>> create(T* ptr, Arena& arena);
|
static Result<GcRoot<T>> create(T* ptr, Arena& arena);
|
||||||
|
Result<GcRoot<T>> copy(Arena& arena) {
|
||||||
|
return GcRoot<T>::create((T*)_ptr, arena);
|
||||||
|
}
|
||||||
|
|
||||||
T& operator*() { return *(T*)_ptr; }
|
T& operator*() { return *(T*)_ptr; }
|
||||||
|
T* operator->() { return (T*)_ptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -60,6 +64,8 @@ class GcRootList {
|
||||||
if (_next) _next->_prev = _prev;
|
if (_next) _next->_prev = _prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GcRootList* next() { return _next; }
|
||||||
|
|
||||||
void update(GcRootBase* root) { _root = root; }
|
void update(GcRootBase* root) { _root = root; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -108,6 +114,14 @@ class Arena {
|
||||||
|
|
||||||
void add_root(GcRootList* node) { _gcroot.insert(node); }
|
void add_root(GcRootList* node) { _gcroot.insert(node); }
|
||||||
|
|
||||||
|
uint64_t root_count() {
|
||||||
|
uint64_t res = 0;
|
||||||
|
for (GcRootList* cur = &_gcroot; cur->next() != 0; cur = cur->next()) {
|
||||||
|
++res;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ArenaHeap* _heaps[2];
|
ArenaHeap* _heaps[2];
|
||||||
GcRootList _gcroot;
|
GcRootList _gcroot;
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include "arena.hpp"
|
||||||
|
|
||||||
Syntax::Syntax(String filename, String modulename, Value expression) {}
|
Syntax::Syntax(String filename, String modulename, Value expression) {}
|
||||||
|
|
||||||
Value Syntax::get_value() {
|
Value Syntax::get_value() {
|
||||||
return pod_to_value(_value->expression.get(_value));
|
return pod_to_value(_value->expression.get(&*_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
Value pod_to_value(PodObject* obj) {
|
Result<Value> pod_to_value(PodObject* obj, Arena& arena) {
|
||||||
switch (obj->header.tag) {
|
switch (obj->header.tag) {
|
||||||
case Tag::Nil:
|
case Tag::Nil:
|
||||||
return Value();
|
return Value();
|
||||||
|
@ -15,20 +17,41 @@ Value pod_to_value(PodObject* obj) {
|
||||||
case Tag::Float:
|
case Tag::Float:
|
||||||
return Value(Int64(((PodFloat*)obj)->value));
|
return Value(Int64(((PodFloat*)obj)->value));
|
||||||
case Tag::String:
|
case Tag::String:
|
||||||
return Value(String((PodString*)obj));
|
return Value(TRY(String::create(arena, (PodString*)obj)));
|
||||||
case Tag::Symbol:
|
case Tag::Symbol:
|
||||||
return Value(Symbol((PodSymbol*)obj));
|
return Value(TRY(Symbol::create(arena, (PodSymbol*)obj)));
|
||||||
case Tag::Syntax:
|
case Tag::Syntax:
|
||||||
return Value(Syntax((PodSyntax*)obj));
|
return Value(TRY(Syntax::create(arena, (PodSyntax*)obj)));
|
||||||
case Tag::Pair:
|
case Tag::Pair:
|
||||||
return Value(Pair((PodPair*)obj));
|
return Value(TRY(Pair::create(arena, (PodPair*)obj)));
|
||||||
};
|
};
|
||||||
return Value();
|
return Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
Value syntax_unwrap(Value val) {
|
Result<Value> syntax_unwrap(Arena& arena, Value& val) {
|
||||||
Syntax* syntax = val.to<Syntax>();
|
Syntax* syntax = val.to<Syntax>();
|
||||||
if (syntax == 0) return val;
|
if (syntax == 0) return val.copy(arena);
|
||||||
|
|
||||||
return syntax->get_value();
|
return syntax->get_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<Value> Nil::copy(Arena& arena) { return Value(Nil()); }
|
||||||
|
|
||||||
|
Result<Value> Int64::copy(Arena& arena) { return Value(Int64(_value)); }
|
||||||
|
Result<Value> Float::copy(Arena& arena) { return Value(Float(_value)); }
|
||||||
|
|
||||||
|
Result<Value> String::copy(Arena& arena) {
|
||||||
|
return Value(String(TRY(_value.copy(arena))));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<Value> Symbol::copy(Arena& arena) {
|
||||||
|
return Value(Symbol(TRY(_value.copy(arena))));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<Value> Syntax::copy(Arena& arena) {
|
||||||
|
return Value(Syntax(TRY(_value.copy(arena))));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<Value> Pair::copy(Arena& arena) {
|
||||||
|
return Value(Pair(TRY(_value.copy(arena))));
|
||||||
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ class PodPair : public PodObject {
|
||||||
class Object {
|
class Object {
|
||||||
public:
|
public:
|
||||||
virtual Tag tag() = 0;
|
virtual Tag tag() = 0;
|
||||||
|
virtual Result<Value> copy(Arena& arena) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Nil : public Object {
|
class Nil : public Object {
|
||||||
|
@ -79,63 +80,91 @@ class Nil : public Object {
|
||||||
Nil() {}
|
Nil() {}
|
||||||
|
|
||||||
virtual Tag tag() final { return Tag::Nil; }
|
virtual Tag tag() final { return Tag::Nil; }
|
||||||
|
virtual Result<Value> copy(Arena& arena) final;
|
||||||
};
|
};
|
||||||
|
|
||||||
class String : public Object {
|
class String : public Object {
|
||||||
public:
|
public:
|
||||||
String() : _value(0) {}
|
String() {}
|
||||||
String(PodString* val) : _value(val) {}
|
String(GcRoot<PodString>&& val) : _value(std::move(val)) {}
|
||||||
virtual Tag tag() final { return Tag::String; }
|
virtual Tag tag() final { return Tag::String; }
|
||||||
|
|
||||||
|
static Result<String> create(Arena& arena, PodString* obj) {
|
||||||
|
return String(TRY(MkGcRoot(obj, arena)));
|
||||||
|
}
|
||||||
static Result<String> create(Arena& arena, char32_t* chars, int64_t size) {
|
static Result<String> create(Arena& arena, char32_t* chars, int64_t size) {
|
||||||
auto pod_string = TRY(arena.alloc<PodString>(size * sizeof(char32_t)));
|
auto pod_string = TRY(arena.alloc<PodString>(size * sizeof(char32_t)));
|
||||||
|
|
||||||
memcpy(pod_string->data, chars, size * sizeof(char32_t));
|
memcpy(pod_string->data, chars, size * sizeof(char32_t));
|
||||||
|
|
||||||
return String(pod_string);
|
return String(TRY(MkGcRoot(pod_string, arena)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Result<Value> copy(Arena& arena) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PodString* _value;
|
GcRoot<PodString> _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Symbol : public Object {
|
class Symbol : public Object {
|
||||||
public:
|
public:
|
||||||
Symbol() : _value(0) {}
|
Symbol() {}
|
||||||
Symbol(PodSymbol* val) : _value(val) {}
|
Symbol(GcRoot<PodSymbol>&& val) : _value(std::move(val)) {}
|
||||||
virtual Tag tag() final { return Tag::Symbol; }
|
virtual Tag tag() final { return Tag::Symbol; }
|
||||||
|
|
||||||
|
static Result<Symbol> create(Arena& arena, PodSymbol* obj) {
|
||||||
|
return Symbol(TRY(MkGcRoot(obj, arena)));
|
||||||
|
}
|
||||||
|
|
||||||
static Result<Symbol> create(Arena& arena, char32_t* chars, int64_t size) {
|
static Result<Symbol> create(Arena& arena, char32_t* chars, int64_t size) {
|
||||||
auto pod_symbol = TRY(arena.alloc<PodSymbol>(size * sizeof(char32_t)));
|
auto pod_symbol = TRY(arena.alloc<PodSymbol>(size * sizeof(char32_t)));
|
||||||
|
|
||||||
memcpy(pod_symbol->data, chars, size * sizeof(char32_t));
|
memcpy(pod_symbol->data, chars, size * sizeof(char32_t));
|
||||||
|
|
||||||
return Symbol(pod_symbol);
|
return Symbol(TRY(MkGcRoot(pod_symbol, arena)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Result<Value> copy(Arena& arena) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PodSymbol* _value;
|
GcRoot<PodSymbol> _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Syntax : public Object {
|
class Syntax : public Object {
|
||||||
public:
|
public:
|
||||||
Syntax(PodSyntax* val) : _value(val) {}
|
Syntax() {}
|
||||||
|
Syntax(GcRoot<PodSyntax>&& val) : _value(std::move(val)) {}
|
||||||
Syntax(String filename, String modulename, Value expression);
|
Syntax(String filename, String modulename, Value expression);
|
||||||
virtual Tag tag() final { return Tag::Syntax; }
|
virtual Tag tag() final { return Tag::Syntax; }
|
||||||
|
|
||||||
|
static Result<Syntax> create(Arena& arena, PodSyntax* obj) {
|
||||||
|
return Syntax(TRY(MkGcRoot(obj, arena)));
|
||||||
|
}
|
||||||
|
|
||||||
Value get_value();
|
Value get_value();
|
||||||
|
|
||||||
|
virtual Result<Value> copy(Arena& arena) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PodSyntax* _value;
|
GcRoot<PodSyntax> _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Pair : public Object {
|
class Pair : public Object {
|
||||||
public:
|
public:
|
||||||
Pair(PodPair* value) : _value(value) {}
|
Pair() {}
|
||||||
|
Pair(GcRoot<PodPair>&& val) : _value(std::move(val)) {}
|
||||||
virtual Tag tag() final { return Tag::Pair; }
|
virtual Tag tag() final { return Tag::Pair; }
|
||||||
|
|
||||||
|
static Result<Pair> create(Arena& arena, PodPair* obj) {
|
||||||
|
return Pair(TRY(MkGcRoot(obj, arena)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result<Value> first(Arena& arena);
|
||||||
|
|
||||||
|
virtual Result<Value> copy(Arena& arena) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PodPair* _value;
|
GcRoot<PodPair> _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Int64 : public Object {
|
class Int64 : public Object {
|
||||||
|
@ -148,6 +177,8 @@ class Int64 : public Object {
|
||||||
|
|
||||||
int64_t value() { return _value; }
|
int64_t value() { return _value; }
|
||||||
|
|
||||||
|
virtual Result<Value> copy(Arena& arena) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int64_t _value;
|
int64_t _value;
|
||||||
};
|
};
|
||||||
|
@ -155,12 +186,15 @@ class Int64 : public Object {
|
||||||
class Float : public Object {
|
class Float : public Object {
|
||||||
public:
|
public:
|
||||||
Float() : _value(0) {}
|
Float() : _value(0) {}
|
||||||
|
Float(double val) : _value(val) {}
|
||||||
virtual ~Float() = default;
|
virtual ~Float() = default;
|
||||||
|
|
||||||
virtual Tag tag() final { return Tag::Float; }
|
virtual Tag tag() final { return Tag::Float; }
|
||||||
|
|
||||||
double value() { return _value; }
|
double value() { return _value; }
|
||||||
|
|
||||||
|
virtual Result<Value> copy(Arena& arena) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double _value;
|
double _value;
|
||||||
};
|
};
|
||||||
|
@ -170,12 +204,14 @@ class Value {
|
||||||
public:
|
public:
|
||||||
Value() { new (buf) Nil(); }
|
Value() { new (buf) Nil(); }
|
||||||
~Value() { ((Object*)buf)->~Object(); }
|
~Value() { ((Object*)buf)->~Object(); }
|
||||||
|
Value(Value&& val) { memcpy(buf, val.buf, 24); }
|
||||||
|
Value(const Value&) = delete;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Value(const T& obj)
|
Value(T&& obj)
|
||||||
requires std::derived_from<T, Object> && (sizeof(T) <= 16)
|
requires std::derived_from<T, Object>
|
||||||
{
|
{
|
||||||
new (buf) T(obj);
|
new (buf) T(std::move(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -191,10 +227,12 @@ class Value {
|
||||||
Object& operator*() { return *(Object*)(buf); }
|
Object& operator*() { return *(Object*)(buf); }
|
||||||
Object* operator->() { return (Object*)(buf); }
|
Object* operator->() { return (Object*)(buf); }
|
||||||
|
|
||||||
|
Result<Value> copy(Arena& arena) { return ((Object*)buf)->copy(arena); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t buf[16];
|
uint8_t buf[24];
|
||||||
};
|
};
|
||||||
|
|
||||||
Value pod_to_value(PodObject* obj);
|
Value pod_to_value(PodObject* obj);
|
||||||
|
|
||||||
Value syntax_unwrap(Value);
|
Result<Value> syntax_unwrap(Value& val);
|
||||||
|
|
Loading…
Reference in a new issue