blueloveTH hai 1 ano
pai
achega
87453c80a7
Modificáronse 6 ficheiros con 30 adicións e 28 borrados
  1. 10 10
      include/pocketpy/gc.h
  2. 3 2
      include/pocketpy/obj.h
  3. 1 1
      include/pocketpy/vm.h
  4. 3 3
      src/codeobject.cpp
  5. 3 3
      src/gc.cpp
  6. 10 9
      src/vm.cpp

+ 10 - 10
include/pocketpy/gc.h

@@ -8,10 +8,10 @@
 
 namespace pkpy {
 struct ManagedHeap{
-    std::vector<PyVar> _no_gc;
-    std::vector<PyVar> gen;
+    std::vector<PyObject*> _no_gc;
+    std::vector<PyObject*> 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<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>(args)...);
-        gen.emplace_back(type, p);
+        gen.push_back(p);
         gc_counter++;
-        return gen.back();
+        return PyVar(type, p);
     }
 
     template<typename T, typename... Args>
     PyVar _new(Type type, Args&&... args){
         using __T = std::decay_t<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)...);
-        _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<Type, int> deleted;

+ 3 - 2
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<typename T, typename ...Args>
     void placement_new(Args&&... args){
@@ -190,7 +191,7 @@ obj_get_t<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)

+ 1 - 1
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*);
 };
 
 

+ 3 - 3
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

+ 3 - 3
src/gc.cpp

@@ -3,8 +3,8 @@
 namespace pkpy{
 
     int ManagedHeap::sweep(){
-        std::vector<PyVar> alive;
-        for(PyVar obj: gen){
+        std::vector<PyObject*> 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();
 

+ 10 - 9
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{