update gc

This commit is contained in:
blueloveTH 2023-03-29 10:52:58 +08:00
parent 16ef631bfd
commit 8764a23302
5 changed files with 28 additions and 26 deletions

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "common.h" #include "common.h"
#include <type_traits>
namespace pkpy{ namespace pkpy{
@ -68,25 +69,30 @@ shared_ptr<T> make_sp(Args&&... args) {
return shared_ptr<T>(p); return shared_ptr<T>(p);
} }
template<typename T, int __Bucket, int __BucketSize=32, bool __ZeroCheck=true> template<typename T, int __Bucket, bool __ZeroInit>
struct FreeListA { struct FreeListA {
std::vector<T*> buckets[__Bucket+1]; std::vector<T*> buckets[__Bucket+1];
T* alloc(int n){ T* alloc(int n){
if constexpr(__ZeroCheck) if(n == 0) return nullptr; static_assert(std::is_standard_layout_v<T>);
T* p;
if(n > __Bucket || buckets[n].empty()){ if(n > __Bucket || buckets[n].empty()){
return new T[n]; p = (T*)malloc(sizeof(T) * n);
}else{ }else{
T* p = buckets[n].back(); p = buckets[n].back();
buckets[n].pop_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){ void dealloc(T* p, int n){
if constexpr(__ZeroCheck) if(n == 0) return; if(p == nullptr) return;
if(n > __Bucket || buckets[n].size() >= __BucketSize){ if(n > __Bucket || buckets[n].size() >= 80){
delete[] p; free(p);
}else{ }else{
buckets[n].push_back(p); buckets[n].push_back(p);
} }
@ -94,7 +100,7 @@ struct FreeListA {
~FreeListA(){ ~FreeListA(){
for(int i=0; i<=__Bucket; i++){ for(int i=0; i<=__Bucket; i++){
for(T* p : buckets[i]) delete[] p; for(T* p : buckets[i]) free(p);
} }
} }
}; };

View File

@ -34,7 +34,7 @@ inline static uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vect
struct NameDict { struct NameDict {
using Item = std::pair<StrName, PyObject*>; using Item = std::pair<StrName, PyObject*>;
inline static FreeListA<Item, 32, 32, false> _pool; inline static THREAD_LOCAL FreeListA<Item, 32, true> _pool;
uint16_t _capacity; uint16_t _capacity;
uint16_t _size; uint16_t _size;
@ -88,8 +88,7 @@ while(!_items[i].first.empty()) { \
return _items[i].second; return _items[i].second;
} }
template<typename T> void set(StrName key, PyObject* val){
void set(StrName key, T&& val){
bool ok; uint16_t i; bool ok; uint16_t i;
HASH_PROBE(key, ok, i); HASH_PROBE(key, ok, i);
if(!ok) { if(!ok) {
@ -100,7 +99,7 @@ while(!_items[i].first.empty()) { \
} }
_items[i].first = key; _items[i].first = key;
} }
_items[i].second = std::forward<T>(val); _items[i].second = val;
} }
void _rehash(bool resize){ void _rehash(bool resize){

View File

@ -105,12 +105,7 @@ struct PyObject {
NameDict& attr() noexcept { return *_attr; } NameDict& attr() noexcept { return *_attr; }
PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; } PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; }
virtual void* value() = 0; virtual void* value() = 0;
virtual void mark() = 0;
virtual void mark() {
if(!gc.enabled || gc.marked) return;
gc.marked = true;
if(is_attr_valid()) attr().apply_v([](PyObject* v){ v->mark(); });
}
PyObject(Type type) : type(type) {} PyObject(Type type) : type(type) {}
virtual ~PyObject() { delete _attr; } virtual ~PyObject() { delete _attr; }
@ -137,7 +132,9 @@ struct Py_ : PyObject {
void* value() override { return &_value; } void* value() override { return &_value; }
void mark() override { 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<T>::value) _value._mark(); if constexpr (is_container_gc<T>::value) _value._mark();
} }
}; };

View File

@ -68,7 +68,7 @@ inline void init_builtins(VM* _vm) {
if(!vm->isinstance(args[1], type)){ if(!vm->isinstance(args[1], type)){
vm->TypeError("super(type, obj): obj must be an instance or subtype of 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)); 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 // 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_object)->attr().set(__class__, property(CPP_LAMBDA(vm->_t(args[0]))));
_t(tp_type)->attr().set(__base__, property([](VM* vm, Args& args){ _t(tp_type)->attr().set(__base__, 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 info.base.index == -1 ? vm->None : vm->_all_types[info.base.index].obj; return info.base.index == -1 ? vm->None : vm->_all_types[info.base].obj;
})); }));
_t(tp_type)->attr().set(__name__, property([](VM* vm, Args& args){ _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); return VAR(info.name);
})); }));
} }

View File

@ -9,13 +9,13 @@ namespace pkpy {
using List = std::vector<PyObject*>; using List = std::vector<PyObject*>;
class Args { class Args {
inline static THREAD_LOCAL FreeListA<PyObject*, 10> _pool; inline static THREAD_LOCAL FreeListA<PyObject*, 10, false> _pool;
PyObject** _args; PyObject** _args;
int _size; int _size;
void _alloc(int n){ void _alloc(int n){
this->_args = _pool.alloc(n); this->_args = (n==0) ? nullptr : _pool.alloc(n);
this->_size = n; this->_size = n;
} }