From 8764a23302d93ef0208491dbddca150f87a00d51 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Wed, 29 Mar 2023 10:52:58 +0800 Subject: [PATCH] update gc --- src/memory.h | 24 +++++++++++++++--------- src/namedict.h | 7 +++---- src/obj.h | 11 ++++------- src/pocketpy.h | 8 ++++---- src/tuplelist.h | 4 ++-- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/memory.h b/src/memory.h index 16e2321c..61f6246d 100644 --- a/src/memory.h +++ b/src/memory.h @@ -1,6 +1,7 @@ #pragma once #include "common.h" +#include namespace pkpy{ @@ -68,25 +69,30 @@ shared_ptr make_sp(Args&&... args) { return shared_ptr(p); } -template +template struct FreeListA { std::vector buckets[__Bucket+1]; T* alloc(int n){ - if constexpr(__ZeroCheck) if(n == 0) return nullptr; + static_assert(std::is_standard_layout_v); + T* p; if(n > __Bucket || buckets[n].empty()){ - return new T[n]; + p = (T*)malloc(sizeof(T) * n); }else{ - T* p = buckets[n].back(); + p = buckets[n].back(); buckets[n].pop_back(); - return p; } + if constexpr(__ZeroInit){ + // the constructor of T should be equivalent to zero initialization + memset((void*)p, 0, sizeof(T) * n); + } + return p; } void dealloc(T* p, int n){ - if constexpr(__ZeroCheck) if(n == 0) return; - if(n > __Bucket || buckets[n].size() >= __BucketSize){ - delete[] p; + if(p == nullptr) return; + if(n > __Bucket || buckets[n].size() >= 80){ + free(p); }else{ buckets[n].push_back(p); } @@ -94,7 +100,7 @@ struct FreeListA { ~FreeListA(){ for(int i=0; i<=__Bucket; i++){ - for(T* p : buckets[i]) delete[] p; + for(T* p : buckets[i]) free(p); } } }; diff --git a/src/namedict.h b/src/namedict.h index 888980c3..0cd24e36 100644 --- a/src/namedict.h +++ b/src/namedict.h @@ -34,7 +34,7 @@ inline static uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vect struct NameDict { using Item = std::pair; - inline static FreeListA _pool; + inline static THREAD_LOCAL FreeListA _pool; uint16_t _capacity; uint16_t _size; @@ -88,8 +88,7 @@ while(!_items[i].first.empty()) { \ return _items[i].second; } - template - void set(StrName key, T&& val){ + void set(StrName key, PyObject* val){ bool ok; uint16_t i; HASH_PROBE(key, ok, i); if(!ok) { @@ -100,7 +99,7 @@ while(!_items[i].first.empty()) { \ } _items[i].first = key; } - _items[i].second = std::forward(val); + _items[i].second = val; } void _rehash(bool resize){ diff --git a/src/obj.h b/src/obj.h index 3a776cf6..3593b366 100644 --- a/src/obj.h +++ b/src/obj.h @@ -105,12 +105,7 @@ struct PyObject { NameDict& attr() noexcept { return *_attr; } PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; } virtual void* value() = 0; - - virtual void mark() { - if(!gc.enabled || gc.marked) return; - gc.marked = true; - if(is_attr_valid()) attr().apply_v([](PyObject* v){ v->mark(); }); - } + virtual void mark() = 0; PyObject(Type type) : type(type) {} virtual ~PyObject() { delete _attr; } @@ -137,7 +132,9 @@ struct Py_ : PyObject { void* value() override { return &_value; } void mark() override { - PyObject::mark(); + if(!gc.enabled || gc.marked) return; + gc.marked = true; + if(is_attr_valid()) attr().apply_v([](PyObject* v){ v->mark(); }); if constexpr (is_container_gc::value) _value._mark(); } }; diff --git a/src/pocketpy.h b/src/pocketpy.h index 3f92734e..13502ec0 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -68,7 +68,7 @@ inline void init_builtins(VM* _vm) { if(!vm->isinstance(args[1], type)){ vm->TypeError("super(type, obj): obj must be an instance or subtype of type"); } - Type base = vm->_all_types[type.index].base; + Type base = vm->_all_types[type].base; return vm->gcnew(vm->tp_super, Super(args[1], base)); }); @@ -788,11 +788,11 @@ inline void VM::post_init(){ // property is defined in builtins.py so we need to add it after builtins is loaded _t(tp_object)->attr().set(__class__, property(CPP_LAMBDA(vm->_t(args[0])))); _t(tp_type)->attr().set(__base__, property([](VM* vm, Args& args){ - const PyTypeInfo& info = vm->_all_types[OBJ_GET(Type, args[0]).index]; - return info.base.index == -1 ? vm->None : vm->_all_types[info.base.index].obj; + const PyTypeInfo& info = vm->_all_types[OBJ_GET(Type, args[0])]; + return info.base.index == -1 ? vm->None : vm->_all_types[info.base].obj; })); _t(tp_type)->attr().set(__name__, property([](VM* vm, Args& args){ - const PyTypeInfo& info = vm->_all_types[OBJ_GET(Type, args[0]).index]; + const PyTypeInfo& info = vm->_all_types[OBJ_GET(Type, args[0])]; return VAR(info.name); })); } diff --git a/src/tuplelist.h b/src/tuplelist.h index 8143dda8..4c9cda33 100644 --- a/src/tuplelist.h +++ b/src/tuplelist.h @@ -9,13 +9,13 @@ namespace pkpy { using List = std::vector; class Args { - inline static THREAD_LOCAL FreeListA _pool; + inline static THREAD_LOCAL FreeListA _pool; PyObject** _args; int _size; void _alloc(int n){ - this->_args = _pool.alloc(n); + this->_args = (n==0) ? nullptr : _pool.alloc(n); this->_size = n; }