This commit is contained in:
blueloveTH 2024-05-20 00:35:37 +08:00
parent 7de1d4d55a
commit 87453c80a7
6 changed files with 30 additions and 28 deletions

View File

@ -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;

View File

@ -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)

View File

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

View File

@ -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

View File

@ -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();

View File

@ -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{