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
#include "common.h"
#include <type_traits>
namespace pkpy{
@ -68,25 +69,30 @@ shared_ptr<T> make_sp(Args&&... args) {
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 {
std::vector<T*> buckets[__Bucket+1];
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()){
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);
}
}
};

View File

@ -34,7 +34,7 @@ inline static uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vect
struct NameDict {
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 _size;
@ -88,8 +88,7 @@ while(!_items[i].first.empty()) { \
return _items[i].second;
}
template<typename T>
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<T>(val);
_items[i].second = val;
}
void _rehash(bool resize){

View File

@ -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<T>::value) _value._mark();
}
};

View File

@ -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);
}));
}

View File

@ -9,13 +9,13 @@ namespace pkpy {
using List = std::vector<PyObject*>;
class Args {
inline static THREAD_LOCAL FreeListA<PyObject*, 10> _pool;
inline static THREAD_LOCAL FreeListA<PyObject*, 10, false> _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;
}