fix a bug

This commit is contained in:
blueloveTH 2023-04-06 15:25:13 +08:00
parent 352688e9ae
commit 6b9b5945a3
8 changed files with 43 additions and 41 deletions

View File

@ -68,14 +68,10 @@ struct CodeObject {
void optimize(VM* vm);
void _mark() const {
void _gc_mark() const {
for(PyObject* v : consts) OBJ_MARK(v);
for(auto& decl: func_decls){
decl->kwargs._mark();
decl->code->_mark();
}
for(auto& decl: func_decls) decl->_gc_mark();
}
};
} // namespace pkpy

View File

@ -33,11 +33,11 @@
// debug macros
#define DEBUG_NO_BUILTIN_MODULES 0
#define DEBUG_EXTRA_CHECK 0
#define DEBUG_DIS_EXEC_REPL 0
#define DEBUG_DIS_EXEC_REPL_MIN 1
#define DEBUG_DIS_EXEC 0
#define DEBUG_DIS_EXEC_MIN 1
#define DEBUG_CEVAL_STEP 0
#define DEBUG_FULL_EXCEPTION 0
#define DEBUG_NO_GC 1
#define DEBUG_NO_GC 0
#if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
#define PK_ENABLE_FILEIO 0

View File

@ -154,15 +154,15 @@ struct Frame {
_data.pop_back_n(n);
}
void _mark() const {
void _gc_mark() const {
for(PyObject* obj : _data) OBJ_MARK(obj);
OBJ_MARK(_module);
_locals->_mark();
_closure->_mark();
if(_locals != nullptr) _locals->_gc_mark();
if(_closure != nullptr) _closure->_gc_mark();
for(auto& p : s_try_block){
for(PyObject* obj : p.second) OBJ_MARK(obj);
}
co->_mark();
co->_gc_mark();
}
};

View File

@ -133,36 +133,42 @@ struct ManagedHeap{
void mark(VM* vm);
};
inline void NameDict::_mark() const{
inline void NameDict::_gc_mark() const{
for(uint16_t i=0; i<_capacity; i++){
if(_items[i].first.empty()) continue;
OBJ_MARK(_items[i].second);
}
}
template<> inline void _mark<List>(List& t){
inline void FuncDecl::_gc_mark() const{
code->_gc_mark();
kwargs._gc_mark();
}
template<> inline void _gc_mark<List>(List& t){
for(PyObject* obj: t) OBJ_MARK(obj);
}
template<> inline void _mark<Tuple>(Tuple& t){
template<> inline void _gc_mark<Tuple>(Tuple& t){
for(int i=0; i<t.size(); i++) OBJ_MARK(t[i]);
}
template<> inline void _mark<Function>(Function& t){
template<> inline void _gc_mark<Function>(Function& t){
t.decl->_gc_mark();
if(t._module != nullptr) OBJ_MARK(t._module);
if(t._closure != nullptr) t._closure->_mark();
if(t._closure != nullptr) t._closure->_gc_mark();
}
template<> inline void _mark<BoundMethod>(BoundMethod& t){
template<> inline void _gc_mark<BoundMethod>(BoundMethod& t){
OBJ_MARK(t.obj);
OBJ_MARK(t.method);
}
template<> inline void _mark<StarWrapper>(StarWrapper& t){
template<> inline void _gc_mark<StarWrapper>(StarWrapper& t){
OBJ_MARK(t.obj);
}
template<> inline void _mark<Super>(Super& t){
template<> inline void _gc_mark<Super>(Super& t){
OBJ_MARK(t.first);
}
// NOTE: std::function may capture some PyObject*, they can not be marked

View File

@ -37,7 +37,7 @@ public:
return p->operator[](index++);
}
void _mark() override {
void _gc_mark() const override {
OBJ_MARK(ref);
}
};
@ -54,7 +54,7 @@ public:
return VAR(str->u8_getitem(index++));
}
void _mark() override {
void _gc_mark() const override {
OBJ_MARK(ref);
}
};
@ -74,14 +74,14 @@ inline PyObject* Generator::next(){
}
}
inline void Generator::_mark(){
if(frame!=nullptr) frame->_mark();
inline void Generator::_gc_mark() const{
if(frame != nullptr) frame->_gc_mark();
}
template<typename T>
void _mark(T& t){
void _gc_mark(T& t) {
if constexpr(std::is_base_of_v<BaseIter, T>){
t._mark();
t._gc_mark();
}
}

View File

@ -180,7 +180,7 @@ while(!_items[i].first.empty()) { \
return v;
}
void _mark() const;
void _gc_mark() const;
#undef HASH_PROBE
#undef _hash
};

View File

@ -38,6 +38,8 @@ struct FuncDecl {
bool _2 = kwargs.contains(val);
return _0 || _1 || _2;
}
void _gc_mark() const;
};
using FuncDecl_ = shared_ptr<FuncDecl>;
@ -87,7 +89,7 @@ protected:
VM* vm;
public:
BaseIter(VM* vm) : vm(vm) {}
virtual void _mark() {}
virtual void _gc_mark() const {}
virtual PyObject* next() = 0;
virtual ~BaseIter() = default;
};
@ -107,14 +109,14 @@ struct PyObject {
NameDict& attr() noexcept { return *_attr; }
PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; }
virtual void* value() = 0;
virtual void _mark() = 0;
virtual void _obj_gc_mark() = 0;
PyObject(Type type) : type(type) {}
virtual ~PyObject() { delete _attr; }
};
template<typename T>
void _mark(T& t);
void _gc_mark(T& t);
template <typename T>
struct Py_ : PyObject {
@ -136,16 +138,16 @@ struct Py_ : PyObject {
}
void* value() override { return &_value; }
void _mark() override {
void _obj_gc_mark() override {
if(gc.marked) return;
gc.marked = true;
if(_attr != nullptr) _attr->_mark();
pkpy::_mark<T>(_value); // handle PyObject* inside _value `T`
if(_attr != nullptr) _attr->_gc_mark();
pkpy::_gc_mark<T>(_value); // handle PyObject* inside _value `T`
}
};
#define OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
#define OBJ_MARK(obj) if(!is_tagged(obj)) obj->_mark()
#define OBJ_MARK(obj) if(!is_tagged(obj)) obj->_obj_gc_mark()
#if DEBUG_NO_BUILTIN_MODULES
#define OBJ_NAME(obj) Str("<?>")

View File

@ -36,7 +36,7 @@ public:
: BaseIter(vm), frame(std::move(frame)), state(0) {}
PyObject* next() override;
void _mark() override;
void _gc_mark() const override;
};
struct PyTypeInfo{
@ -166,7 +166,7 @@ public:
if(_module == nullptr) _module = _main;
try {
CodeObject_ code = compile(source, filename, mode);
#if DEBUG_DIS_EXEC_REPL
#if DEBUG_DIS_EXEC
if(_module == _main) std::cout << disassemble(code) << '\n';
#endif
return _exec(code, _module, builtins);
@ -615,7 +615,7 @@ inline Str VM::disassemble(CodeObject_ co){
if(i != co->codes.size() - 1) ss << '\n';
}
#if !DEBUG_DIS_EXEC_REPL_MIN
#if !DEBUG_DIS_EXEC_MIN
StrStream consts;
consts << "co_consts: ";
consts << CAST(Str, asRepr(VAR(co->consts)));
@ -909,9 +909,7 @@ inline PyObject* VM::_exec(){
inline void ManagedHeap::mark(VM *vm) {
for(PyObject* obj: _no_gc) OBJ_MARK(obj);
for(auto& frame : vm->callstack.data()){
frame->_mark();
}
for(auto& frame : vm->callstack.data()) frame->_gc_mark();
}
inline void ManagedHeap::_delete_hook(VM *vm, PyObject *obj){