mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
update gc
This commit is contained in:
parent
16ef631bfd
commit
8764a23302
24
src/memory.h
24
src/memory.h
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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){
|
||||
|
11
src/obj.h
11
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<T>::value) _value._mark();
|
||||
}
|
||||
};
|
||||
|
@ -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);
|
||||
}));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user