From 87453c80a79b76e62285452419c93d4452f4c7a0 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 20 May 2024 00:35:37 +0800 Subject: [PATCH] some fix --- include/pocketpy/gc.h | 20 ++++++++++---------- include/pocketpy/obj.h | 5 +++-- include/pocketpy/vm.h | 2 +- src/codeobject.cpp | 6 +++--- src/gc.cpp | 6 +++--- src/vm.cpp | 19 ++++++++++--------- 6 files changed, 30 insertions(+), 28 deletions(-) diff --git a/include/pocketpy/gc.h b/include/pocketpy/gc.h index e9ab0435..cd2541b8 100644 --- a/include/pocketpy/gc.h +++ b/include/pocketpy/gc.h @@ -8,10 +8,10 @@ namespace pkpy { struct ManagedHeap{ - std::vector _no_gc; - std::vector gen; + std::vector _no_gc; + std::vector gen; VM* vm; - void (*_gc_on_delete)(VM*, PyVar) = nullptr; + void (*_gc_on_delete)(VM*, PyObject*) = nullptr; void (*_gc_marker_ex)(VM*) = nullptr; ManagedHeap(VM* vm): vm(vm) {} @@ -43,24 +43,24 @@ struct ManagedHeap{ using __T = std::decay_t; static_assert(!is_sso_v<__T>, "gcnew cannot be used with SSO types"); // 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)...); - gen.emplace_back(type, p); + gen.push_back(p); gc_counter++; - return gen.back(); + return PyVar(type, p); } template PyVar _new(Type type, Args&&... args){ using __T = std::decay_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)...); - _no_gc.emplace_back(type, p); - return _no_gc.back(); + _no_gc.push_back(p); + return PyVar(type, p); } - void _delete(PyVar); + void _delete(PyObject*); #if PK_DEBUG_GC_STATS inline static std::map deleted; diff --git a/include/pocketpy/obj.h b/include/pocketpy/obj.h index e386c522..256d8fe7 100644 --- a/include/pocketpy/obj.h +++ b/include/pocketpy/obj.h @@ -103,6 +103,7 @@ struct Slice { struct PyObject final{ bool gc_marked; // whether this object is marked + Type type; // we have a duplicated type here for saving memory NameDict* _attr; bool is_attr_valid() const noexcept { return _attr != nullptr; } @@ -118,7 +119,7 @@ struct PyObject final{ return (*_attr)[name]; } - PyObject() : gc_marked(false), _attr(nullptr) {} + PyObject(Type type) : gc_marked(false), type(type), _attr(nullptr) {} template void placement_new(Args&&... args){ @@ -190,7 +191,7 @@ obj_get_t PyVar::obj_get(){ #define PK_OBJ_MARK(obj) \ 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) diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index f788ef8f..4a146d32 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -484,7 +484,7 @@ public: PyVar __pack_next_retval(unsigned); PyVar __minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key); bool __py_bool_non_trivial(PyVar); - void __obj_gc_mark(PyVar); + void __obj_gc_mark(PyObject*); }; diff --git a/src/codeobject.cpp b/src/codeobject.cpp index 358b19a8..7749086b 100644 --- a/src/codeobject.cpp +++ b/src/codeobject.cpp @@ -7,7 +7,7 @@ namespace pkpy{ blocks.push_back(CodeBlock(CodeBlockType::NO_BLOCK, -1, 0, 0)); } - PyVar const PY_NULL(Type(), new PyObject()); - PyVar const PY_OP_CALL(Type(), new PyObject()); - PyVar const PY_OP_YIELD(Type(), new PyObject()); + PyVar const PY_NULL(Type(), new PyObject(Type())); + PyVar const PY_OP_CALL(Type(), new PyObject(Type())); + PyVar const PY_OP_YIELD(Type(), new PyObject(Type())); } // namespace pkpy \ No newline at end of file diff --git a/src/gc.cpp b/src/gc.cpp index f58d7a0d..6882d3f2 100644 --- a/src/gc.cpp +++ b/src/gc.cpp @@ -3,8 +3,8 @@ namespace pkpy{ int ManagedHeap::sweep(){ - std::vector alive; - for(PyVar obj: gen){ + std::vector alive; + for(PyObject* obj: gen){ PK_DEBUG_ASSERT(!obj.is_sso) if(obj->gc_marked){ obj->gc_marked = false; @@ -19,7 +19,7 @@ namespace pkpy{ } // 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(); diff --git a/src/vm.cpp b/src/vm.cpp index 68568049..d55ee676 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -398,8 +398,8 @@ namespace pkpy{ VM::~VM() { // clear managed heap - for(PyVar obj: heap.gen) heap._delete(obj); - for(PyVar obj: heap._no_gc) heap._delete(obj); + for(PyObject* obj: heap.gen) heap._delete(obj); + for(PyObject* obj: heap._no_gc) heap._delete(obj); // clear everything callstack.clear(); s_data.clear(); @@ -427,9 +427,9 @@ bool VM::__py_bool_non_trivial(PyVar obj){ return true; } -void VM::__obj_gc_mark(PyVar obj){ +void VM::__obj_gc_mark(PyObject* obj){ 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(obj->is_attr_valid()){ obj->attr().apply([this](StrName _, PyVar obj){ @@ -1821,7 +1821,9 @@ void Frame::_gc_mark(VM* vm) const { } 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); }); for(PyVar obj: vm->s_data) PK_OBJ_MARK(obj); 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); } -void ManagedHeap::_delete(PyVar obj){ - PK_DEBUG_ASSERT(!obj.is_sso) - const PyTypeInfo* ti = vm->_tp_info(obj); +void ManagedHeap::_delete(PyObject* obj){ + const PyTypeInfo* ti = vm->_tp_info(obj->type); if(ti->vt._dtor) ti->vt._dtor(obj->_value_ptr()); if(obj->_attr){ obj->_attr->~NameDict(); pool128_dealloc(obj->_attr); } - pool128_dealloc(obj.get()); + pool128_dealloc(obj); } void Dict::_gc_mark(VM* vm) const{