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
|
#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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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){
|
||||||
|
11
src/obj.h
11
src/obj.h
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user