mirror of
https://github.com/pocketpy/pocketpy
synced 2025-12-07 18:50:19 +00:00
some fix
This commit is contained in:
parent
7de1d4d55a
commit
87453c80a7
@ -8,10 +8,10 @@
|
|||||||
|
|
||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
struct ManagedHeap{
|
struct ManagedHeap{
|
||||||
std::vector<PyVar> _no_gc;
|
std::vector<PyObject*> _no_gc;
|
||||||
std::vector<PyVar> gen;
|
std::vector<PyObject*> gen;
|
||||||
VM* vm;
|
VM* vm;
|
||||||
void (*_gc_on_delete)(VM*, PyVar) = nullptr;
|
void (*_gc_on_delete)(VM*, PyObject*) = nullptr;
|
||||||
void (*_gc_marker_ex)(VM*) = nullptr;
|
void (*_gc_marker_ex)(VM*) = nullptr;
|
||||||
|
|
||||||
ManagedHeap(VM* vm): vm(vm) {}
|
ManagedHeap(VM* vm): vm(vm) {}
|
||||||
@ -43,24 +43,24 @@ struct ManagedHeap{
|
|||||||
using __T = std::decay_t<T>;
|
using __T = std::decay_t<T>;
|
||||||
static_assert(!is_sso_v<__T>, "gcnew cannot be used with SSO types");
|
static_assert(!is_sso_v<__T>, "gcnew cannot be used with SSO types");
|
||||||
// https://github.com/pocketpy/pocketpy/issues/94#issuecomment-1594784476
|
// https://github.com/pocketpy/pocketpy/issues/94#issuecomment-1594784476
|
||||||
PyObject* p = new(pool128_alloc(py_sizeof<__T>)) PyObject();
|
PyObject* p = new(pool128_alloc(py_sizeof<__T>)) PyObject(type);
|
||||||
p->placement_new<__T>(std::forward<Args>(args)...);
|
p->placement_new<__T>(std::forward<Args>(args)...);
|
||||||
gen.emplace_back(type, p);
|
gen.push_back(p);
|
||||||
gc_counter++;
|
gc_counter++;
|
||||||
return gen.back();
|
return PyVar(type, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
PyVar _new(Type type, Args&&... args){
|
PyVar _new(Type type, Args&&... args){
|
||||||
using __T = std::decay_t<T>;
|
using __T = std::decay_t<T>;
|
||||||
static_assert(!is_sso_v<__T>);
|
static_assert(!is_sso_v<__T>);
|
||||||
PyObject* p = new(pool128_alloc<__T>()) PyObject();
|
PyObject* p = new(pool128_alloc<__T>()) PyObject(type);
|
||||||
p->placement_new<__T>(std::forward<Args>(args)...);
|
p->placement_new<__T>(std::forward<Args>(args)...);
|
||||||
_no_gc.emplace_back(type, p);
|
_no_gc.push_back(p);
|
||||||
return _no_gc.back();
|
return PyVar(type, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _delete(PyVar);
|
void _delete(PyObject*);
|
||||||
|
|
||||||
#if PK_DEBUG_GC_STATS
|
#if PK_DEBUG_GC_STATS
|
||||||
inline static std::map<Type, int> deleted;
|
inline static std::map<Type, int> deleted;
|
||||||
|
|||||||
@ -103,6 +103,7 @@ struct Slice {
|
|||||||
|
|
||||||
struct PyObject final{
|
struct PyObject final{
|
||||||
bool gc_marked; // whether this object is marked
|
bool gc_marked; // whether this object is marked
|
||||||
|
Type type; // we have a duplicated type here for saving memory
|
||||||
NameDict* _attr;
|
NameDict* _attr;
|
||||||
|
|
||||||
bool is_attr_valid() const noexcept { return _attr != nullptr; }
|
bool is_attr_valid() const noexcept { return _attr != nullptr; }
|
||||||
@ -118,7 +119,7 @@ struct PyObject final{
|
|||||||
return (*_attr)[name];
|
return (*_attr)[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject() : gc_marked(false), _attr(nullptr) {}
|
PyObject(Type type) : gc_marked(false), type(type), _attr(nullptr) {}
|
||||||
|
|
||||||
template<typename T, typename ...Args>
|
template<typename T, typename ...Args>
|
||||||
void placement_new(Args&&... args){
|
void placement_new(Args&&... args){
|
||||||
@ -190,7 +191,7 @@ obj_get_t<T> PyVar::obj_get(){
|
|||||||
|
|
||||||
#define PK_OBJ_MARK(obj) \
|
#define PK_OBJ_MARK(obj) \
|
||||||
if(!is_tagged(obj) && !(obj)->gc_marked) { \
|
if(!is_tagged(obj) && !(obj)->gc_marked) { \
|
||||||
vm->__obj_gc_mark(obj); \
|
vm->__obj_gc_mark(obj.get()); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VAR(x) py_var(vm, x)
|
#define VAR(x) py_var(vm, x)
|
||||||
|
|||||||
@ -484,7 +484,7 @@ public:
|
|||||||
PyVar __pack_next_retval(unsigned);
|
PyVar __pack_next_retval(unsigned);
|
||||||
PyVar __minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key);
|
PyVar __minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key);
|
||||||
bool __py_bool_non_trivial(PyVar);
|
bool __py_bool_non_trivial(PyVar);
|
||||||
void __obj_gc_mark(PyVar);
|
void __obj_gc_mark(PyObject*);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ namespace pkpy{
|
|||||||
blocks.push_back(CodeBlock(CodeBlockType::NO_BLOCK, -1, 0, 0));
|
blocks.push_back(CodeBlock(CodeBlockType::NO_BLOCK, -1, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar const PY_NULL(Type(), new PyObject());
|
PyVar const PY_NULL(Type(), new PyObject(Type()));
|
||||||
PyVar const PY_OP_CALL(Type(), new PyObject());
|
PyVar const PY_OP_CALL(Type(), new PyObject(Type()));
|
||||||
PyVar const PY_OP_YIELD(Type(), new PyObject());
|
PyVar const PY_OP_YIELD(Type(), new PyObject(Type()));
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
||||||
@ -3,8 +3,8 @@
|
|||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
|
|
||||||
int ManagedHeap::sweep(){
|
int ManagedHeap::sweep(){
|
||||||
std::vector<PyVar> alive;
|
std::vector<PyObject*> alive;
|
||||||
for(PyVar obj: gen){
|
for(PyObject* obj: gen){
|
||||||
PK_DEBUG_ASSERT(!obj.is_sso)
|
PK_DEBUG_ASSERT(!obj.is_sso)
|
||||||
if(obj->gc_marked){
|
if(obj->gc_marked){
|
||||||
obj->gc_marked = false;
|
obj->gc_marked = false;
|
||||||
@ -19,7 +19,7 @@ namespace pkpy{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clear _no_gc marked flag
|
// clear _no_gc marked flag
|
||||||
for(PyVar obj: _no_gc) obj->gc_marked = false;
|
for(PyObject* obj: _no_gc) obj->gc_marked = false;
|
||||||
|
|
||||||
int freed = gen.size() - alive.size();
|
int freed = gen.size() - alive.size();
|
||||||
|
|
||||||
|
|||||||
19
src/vm.cpp
19
src/vm.cpp
@ -398,8 +398,8 @@ namespace pkpy{
|
|||||||
|
|
||||||
VM::~VM() {
|
VM::~VM() {
|
||||||
// clear managed heap
|
// clear managed heap
|
||||||
for(PyVar obj: heap.gen) heap._delete(obj);
|
for(PyObject* obj: heap.gen) heap._delete(obj);
|
||||||
for(PyVar obj: heap._no_gc) heap._delete(obj);
|
for(PyObject* obj: heap._no_gc) heap._delete(obj);
|
||||||
// clear everything
|
// clear everything
|
||||||
callstack.clear();
|
callstack.clear();
|
||||||
s_data.clear();
|
s_data.clear();
|
||||||
@ -427,9 +427,9 @@ bool VM::__py_bool_non_trivial(PyVar obj){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM::__obj_gc_mark(PyVar obj){
|
void VM::__obj_gc_mark(PyObject* obj){
|
||||||
obj->gc_marked = true;
|
obj->gc_marked = true;
|
||||||
const PyTypeInfo* ti = _tp_info(obj);
|
const PyTypeInfo* ti = _tp_info(obj->type);
|
||||||
if(ti->vt._gc_mark) ti->vt._gc_mark(obj->_value_ptr(), this);
|
if(ti->vt._gc_mark) ti->vt._gc_mark(obj->_value_ptr(), this);
|
||||||
if(obj->is_attr_valid()){
|
if(obj->is_attr_valid()){
|
||||||
obj->attr().apply([this](StrName _, PyVar obj){
|
obj->attr().apply([this](StrName _, PyVar obj){
|
||||||
@ -1821,7 +1821,9 @@ void Frame::_gc_mark(VM* vm) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ManagedHeap::mark() {
|
void ManagedHeap::mark() {
|
||||||
for(PyVar obj: _no_gc) PK_OBJ_MARK(obj);
|
for(PyObject* obj: _no_gc){
|
||||||
|
if(!obj->gc_marked) vm->__obj_gc_mark(obj);
|
||||||
|
}
|
||||||
vm->callstack.apply([this](Frame& frame){ frame._gc_mark(vm); });
|
vm->callstack.apply([this](Frame& frame){ frame._gc_mark(vm); });
|
||||||
for(PyVar obj: vm->s_data) PK_OBJ_MARK(obj);
|
for(PyVar obj: vm->s_data) PK_OBJ_MARK(obj);
|
||||||
for(auto [_, co]: vm->__cached_codes) co->_gc_mark(vm);
|
for(auto [_, co]: vm->__cached_codes) co->_gc_mark(vm);
|
||||||
@ -1831,15 +1833,14 @@ void ManagedHeap::mark() {
|
|||||||
if(_gc_marker_ex) _gc_marker_ex(vm);
|
if(_gc_marker_ex) _gc_marker_ex(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagedHeap::_delete(PyVar obj){
|
void ManagedHeap::_delete(PyObject* obj){
|
||||||
PK_DEBUG_ASSERT(!obj.is_sso)
|
const PyTypeInfo* ti = vm->_tp_info(obj->type);
|
||||||
const PyTypeInfo* ti = vm->_tp_info(obj);
|
|
||||||
if(ti->vt._dtor) ti->vt._dtor(obj->_value_ptr());
|
if(ti->vt._dtor) ti->vt._dtor(obj->_value_ptr());
|
||||||
if(obj->_attr){
|
if(obj->_attr){
|
||||||
obj->_attr->~NameDict();
|
obj->_attr->~NameDict();
|
||||||
pool128_dealloc(obj->_attr);
|
pool128_dealloc(obj->_attr);
|
||||||
}
|
}
|
||||||
pool128_dealloc(obj.get());
|
pool128_dealloc(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dict::_gc_mark(VM* vm) const{
|
void Dict::_gc_mark(VM* vm) const{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user