mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40:18 +00:00
improve gc
This commit is contained in:
parent
f3c98934dd
commit
9e82b52a05
@ -68,5 +68,5 @@ int Frame__prepare_jump_exception_handler(py_Frame* self, ValueStack*);
|
|||||||
UnwindTarget* Frame__find_unwind_target(py_Frame* self, int iblock);
|
UnwindTarget* Frame__find_unwind_target(py_Frame* self, int iblock);
|
||||||
void Frame__set_unwind_target(py_Frame* self, py_TValue* sp);
|
void Frame__set_unwind_target(py_Frame* self, py_TValue* sp);
|
||||||
|
|
||||||
void Frame__gc_mark(py_Frame* self);
|
void Frame__gc_mark(py_Frame* self, c11_vector* p_stack);
|
||||||
SourceLocation Frame__source_location(py_Frame* self);
|
SourceLocation Frame__source_location(py_Frame* self);
|
@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
typedef struct ManagedHeap {
|
typedef struct ManagedHeap {
|
||||||
MultiPool small_objects;
|
MultiPool small_objects;
|
||||||
c11_vector /* PyObject* */ large_objects;
|
c11_vector /* PyObject_p */ large_objects;
|
||||||
|
c11_vector /* PyObject_p */ gc_roots;
|
||||||
|
|
||||||
int freed_ma[3];
|
int freed_ma[3];
|
||||||
int gc_threshold; // threshold for gc_counter
|
int gc_threshold; // threshold for gc_counter
|
||||||
|
@ -24,5 +24,5 @@ typedef struct {
|
|||||||
|
|
||||||
typedef c11_vector List;
|
typedef c11_vector List;
|
||||||
|
|
||||||
void c11_chunked_array2d__mark(void* ud);
|
void c11_chunked_array2d__mark(void* ud, c11_vector* p_stack);
|
||||||
void function__gc_mark(void* ud);
|
void function__gc_mark(void* ud, c11_vector* p_stack);
|
@ -34,7 +34,7 @@ typedef struct VM {
|
|||||||
|
|
||||||
py_Callbacks callbacks;
|
py_Callbacks callbacks;
|
||||||
|
|
||||||
py_TValue ascii_literals[128+1];
|
py_TValue ascii_literals[128 + 1];
|
||||||
|
|
||||||
py_TValue last_retval;
|
py_TValue last_retval;
|
||||||
py_TValue curr_exception;
|
py_TValue curr_exception;
|
||||||
@ -64,10 +64,19 @@ void VM__dtor(VM* self);
|
|||||||
void VM__push_frame(VM* self, py_Frame* frame);
|
void VM__push_frame(VM* self, py_Frame* frame);
|
||||||
void VM__pop_frame(VM* self);
|
void VM__pop_frame(VM* self);
|
||||||
|
|
||||||
bool pk__parse_int_slice(py_Ref slice, int length, int* restrict start, int* restrict stop, int* restrict step);
|
bool pk__parse_int_slice(py_Ref slice,
|
||||||
|
int length,
|
||||||
|
int* restrict start,
|
||||||
|
int* restrict stop,
|
||||||
|
int* restrict step);
|
||||||
bool pk__normalize_index(int* index, int length);
|
bool pk__normalize_index(int* index, int length);
|
||||||
|
|
||||||
#define pk__mark_value(val) if((val)->is_ptr && !(val)->_obj->gc_marked) PyObject__mark((val)->_obj)
|
#define pk__mark_value(val) \
|
||||||
|
if((val)->is_ptr && !(val)->_obj->gc_marked) { \
|
||||||
|
PyObject* obj = (val)->_obj; \
|
||||||
|
obj->gc_marked = true; \
|
||||||
|
c11_vector__push(PyObject*, p_stack, obj); \
|
||||||
|
}
|
||||||
|
|
||||||
bool pk__object_new(int argc, py_Ref argv);
|
bool pk__object_new(int argc, py_Ref argv);
|
||||||
py_TypeInfo* pk__type_info(py_Type type);
|
py_TypeInfo* pk__type_info(py_Type type);
|
||||||
|
@ -89,7 +89,7 @@ typedef struct CodeObject {
|
|||||||
void CodeObject__ctor(CodeObject* self, SourceData_ src, c11_sv name);
|
void CodeObject__ctor(CodeObject* self, SourceData_ src, c11_sv name);
|
||||||
void CodeObject__dtor(CodeObject* self);
|
void CodeObject__dtor(CodeObject* self);
|
||||||
int CodeObject__add_varname(CodeObject* self, py_Name name);
|
int CodeObject__add_varname(CodeObject* self, py_Name name);
|
||||||
void CodeObject__gc_mark(const CodeObject* self);
|
void CodeObject__gc_mark(const CodeObject* self, c11_vector* p_stack);
|
||||||
|
|
||||||
typedef struct FuncDeclKwArg {
|
typedef struct FuncDeclKwArg {
|
||||||
int index; // index in co->varnames
|
int index; // index in co->varnames
|
||||||
@ -122,7 +122,7 @@ void FuncDecl__add_arg(FuncDecl* self, py_Name name);
|
|||||||
void FuncDecl__add_kwarg(FuncDecl* self, py_Name name, const py_TValue* value);
|
void FuncDecl__add_kwarg(FuncDecl* self, py_Name name, const py_TValue* value);
|
||||||
void FuncDecl__add_starred_arg(FuncDecl* self, py_Name name);
|
void FuncDecl__add_starred_arg(FuncDecl* self, py_Name name);
|
||||||
void FuncDecl__add_starred_kwarg(FuncDecl* self, py_Name name);
|
void FuncDecl__add_starred_kwarg(FuncDecl* self, py_Name name);
|
||||||
void FuncDecl__gc_mark(const FuncDecl* self);
|
void FuncDecl__gc_mark(const FuncDecl* self, c11_vector* p_stack);
|
||||||
|
|
||||||
// runtime function
|
// runtime function
|
||||||
typedef struct Function {
|
typedef struct Function {
|
||||||
|
@ -25,4 +25,4 @@ void ModuleDict__dtor(ModuleDict* self);
|
|||||||
void ModuleDict__set(ModuleDict* self, const char* key, py_TValue val);
|
void ModuleDict__set(ModuleDict* self, const char* key, py_TValue val);
|
||||||
py_TValue* ModuleDict__try_get(ModuleDict* self, const char* path);
|
py_TValue* ModuleDict__try_get(ModuleDict* self, const char* path);
|
||||||
bool ModuleDict__contains(ModuleDict* self, const char* path);
|
bool ModuleDict__contains(ModuleDict* self, const char* path);
|
||||||
void ModuleDict__apply_mark(ModuleDict* self);
|
void ModuleDict__apply_mark(ModuleDict* self, c11_vector* p_stack);
|
||||||
|
@ -24,4 +24,4 @@ void* PyObject__userdata(PyObject* self);
|
|||||||
#define PK_OBJ_SLOTS_SIZE(slots) ((slots) >= 0 ? sizeof(py_TValue) * (slots) : sizeof(NameDict))
|
#define PK_OBJ_SLOTS_SIZE(slots) ((slots) >= 0 ? sizeof(py_TValue) * (slots) : sizeof(NameDict))
|
||||||
|
|
||||||
void PyObject__dtor(PyObject* self);
|
void PyObject__dtor(PyObject* self);
|
||||||
void PyObject__mark(PyObject* self);
|
|
||||||
|
@ -114,10 +114,10 @@ void Frame__set_unwind_target(py_Frame* self, py_TValue* sp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame__gc_mark(py_Frame* self) {
|
void Frame__gc_mark(py_Frame* self, c11_vector* p_stack) {
|
||||||
pk__mark_value(self->globals);
|
pk__mark_value(self->globals);
|
||||||
if(self->is_locals_special) pk__mark_value(self->locals);
|
if(self->is_locals_special) pk__mark_value(self->locals);
|
||||||
CodeObject__gc_mark(self->co);
|
CodeObject__gc_mark(self->co, p_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Frame__lineno(const py_Frame* self) {
|
int Frame__lineno(const py_Frame* self) {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
void ManagedHeap__ctor(ManagedHeap* self) {
|
void ManagedHeap__ctor(ManagedHeap* self) {
|
||||||
MultiPool__ctor(&self->small_objects);
|
MultiPool__ctor(&self->small_objects);
|
||||||
c11_vector__ctor(&self->large_objects, sizeof(PyObject*));
|
c11_vector__ctor(&self->large_objects, sizeof(PyObject*));
|
||||||
|
c11_vector__ctor(&self->gc_roots, sizeof(PyObject*));
|
||||||
|
|
||||||
for(int i = 0; i < c11__count_array(self->freed_ma); i++) {
|
for(int i = 0; i < c11__count_array(self->freed_ma); i++) {
|
||||||
self->freed_ma[i] = PK_GC_MIN_THRESHOLD;
|
self->freed_ma[i] = PK_GC_MIN_THRESHOLD;
|
||||||
@ -26,6 +27,7 @@ void ManagedHeap__dtor(ManagedHeap* self) {
|
|||||||
PK_FREE(obj);
|
PK_FREE(obj);
|
||||||
}
|
}
|
||||||
c11_vector__dtor(&self->large_objects);
|
c11_vector__dtor(&self->large_objects);
|
||||||
|
c11_vector__dtor(&self->gc_roots);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagedHeap__collect_if_needed(ManagedHeap* self) {
|
void ManagedHeap__collect_if_needed(ManagedHeap* self) {
|
||||||
|
@ -606,84 +606,30 @@ void PyObject__dtor(PyObject* self) {
|
|||||||
if(self->slots == -1) NameDict__dtor(PyObject__dict(self));
|
if(self->slots == -1) NameDict__dtor(PyObject__dict(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PyObject__mark(PyObject* obj) {
|
void FuncDecl__gc_mark(const FuncDecl* self, c11_vector* p_stack) {
|
||||||
assert(!obj->gc_marked);
|
CodeObject__gc_mark(&self->code, p_stack);
|
||||||
|
|
||||||
obj->gc_marked = true;
|
|
||||||
|
|
||||||
if(obj->slots > 0) {
|
|
||||||
py_TValue* p = PyObject__slots(obj);
|
|
||||||
for(int i = 0; i < obj->slots; i++)
|
|
||||||
pk__mark_value(p + i);
|
|
||||||
} else if(obj->slots == -1) {
|
|
||||||
NameDict* namedict = PyObject__dict(obj);
|
|
||||||
for(int i = 0; i < namedict->length; i++) {
|
|
||||||
NameDict_KV* kv = c11__at(NameDict_KV, namedict, i);
|
|
||||||
pk__mark_value(&kv->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void* ud = PyObject__userdata(obj);
|
|
||||||
switch(obj->type) {
|
|
||||||
case tp_list: {
|
|
||||||
List* self = ud;
|
|
||||||
for(int i = 0; i < self->length; i++) {
|
|
||||||
pk__mark_value(c11__at(py_TValue, self, i));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case tp_dict: {
|
|
||||||
Dict* self = ud;
|
|
||||||
for(int i = 0; i < self->entries.length; i++) {
|
|
||||||
DictEntry* entry = c11__at(DictEntry, &self->entries, i);
|
|
||||||
if(py_isnil(&entry->key)) continue;
|
|
||||||
pk__mark_value(&entry->key);
|
|
||||||
pk__mark_value(&entry->val);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case tp_generator: {
|
|
||||||
Generator* self = ud;
|
|
||||||
if(self->frame) Frame__gc_mark(self->frame);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case tp_function: {
|
|
||||||
function__gc_mark(ud);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case tp_code: {
|
|
||||||
CodeObject* self = ud;
|
|
||||||
CodeObject__gc_mark(self);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case tp_chunked_array2d: {
|
|
||||||
c11_chunked_array2d__mark(ud);
|
|
||||||
}
|
|
||||||
default: return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FuncDecl__gc_mark(const FuncDecl* self) {
|
|
||||||
CodeObject__gc_mark(&self->code);
|
|
||||||
for(int j = 0; j < self->kwargs.length; j++) {
|
for(int j = 0; j < self->kwargs.length; j++) {
|
||||||
FuncDeclKwArg* kw = c11__at(FuncDeclKwArg, &self->kwargs, j);
|
FuncDeclKwArg* kw = c11__at(FuncDeclKwArg, &self->kwargs, j);
|
||||||
pk__mark_value(&kw->value);
|
pk__mark_value(&kw->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeObject__gc_mark(const CodeObject* self) {
|
void CodeObject__gc_mark(const CodeObject* self, c11_vector* p_stack) {
|
||||||
for(int i = 0; i < self->consts.length; i++) {
|
for(int i = 0; i < self->consts.length; i++) {
|
||||||
py_TValue* p = c11__at(py_TValue, &self->consts, i);
|
py_TValue* p = c11__at(py_TValue, &self->consts, i);
|
||||||
pk__mark_value(p);
|
pk__mark_value(p);
|
||||||
}
|
}
|
||||||
for(int i = 0; i < self->func_decls.length; i++) {
|
for(int i = 0; i < self->func_decls.length; i++) {
|
||||||
FuncDecl_ decl = c11__getitem(FuncDecl_, &self->func_decls, i);
|
FuncDecl_ decl = c11__getitem(FuncDecl_, &self->func_decls, i);
|
||||||
FuncDecl__gc_mark(decl);
|
FuncDecl__gc_mark(decl, p_stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagedHeap__mark(ManagedHeap* self) {
|
void ManagedHeap__mark(ManagedHeap* self) {
|
||||||
VM* vm = pk_current_vm;
|
VM* vm = pk_current_vm;
|
||||||
|
c11_vector* p_stack = &self->gc_roots;
|
||||||
|
assert(p_stack->length == 0);
|
||||||
|
|
||||||
// mark value stack
|
// mark value stack
|
||||||
for(py_TValue* p = vm->stack.begin; p != vm->stack.end; p++) {
|
for(py_TValue* p = vm->stack.begin; p != vm->stack.end; p++) {
|
||||||
pk__mark_value(p);
|
pk__mark_value(p);
|
||||||
@ -693,7 +639,7 @@ void ManagedHeap__mark(ManagedHeap* self) {
|
|||||||
pk__mark_value(&vm->ascii_literals[i]);
|
pk__mark_value(&vm->ascii_literals[i]);
|
||||||
}
|
}
|
||||||
// mark modules
|
// mark modules
|
||||||
ModuleDict__apply_mark(&vm->modules);
|
ModuleDict__apply_mark(&vm->modules, p_stack);
|
||||||
// mark types
|
// mark types
|
||||||
int types_length = vm->types.length;
|
int types_length = vm->types.length;
|
||||||
// 0-th type is placeholder
|
// 0-th type is placeholder
|
||||||
@ -720,7 +666,7 @@ void ManagedHeap__mark(ManagedHeap* self) {
|
|||||||
}
|
}
|
||||||
// mark frame
|
// mark frame
|
||||||
for(py_Frame* frame = vm->top_frame; frame; frame = frame->f_back) {
|
for(py_Frame* frame = vm->top_frame; frame; frame = frame->f_back) {
|
||||||
Frame__gc_mark(frame);
|
Frame__gc_mark(frame, p_stack);
|
||||||
}
|
}
|
||||||
// mark vm's registers
|
// mark vm's registers
|
||||||
pk__mark_value(&vm->last_retval);
|
pk__mark_value(&vm->last_retval);
|
||||||
@ -733,6 +679,66 @@ void ManagedHeap__mark(ManagedHeap* self) {
|
|||||||
RInternedEntry* entry = c11__at(RInternedEntry, &vm->names.r_interned, i);
|
RInternedEntry* entry = c11__at(RInternedEntry, &vm->names.r_interned, i);
|
||||||
pk__mark_value(&entry->obj);
|
pk__mark_value(&entry->obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************/
|
||||||
|
while(p_stack->length > 0) {
|
||||||
|
PyObject* obj = c11_vector__back(PyObject*, p_stack);
|
||||||
|
c11_vector__pop(p_stack);
|
||||||
|
|
||||||
|
assert(obj->gc_marked);
|
||||||
|
|
||||||
|
if(obj->slots > 0) {
|
||||||
|
py_TValue* p = PyObject__slots(obj);
|
||||||
|
for(int i = 0; i < obj->slots; i++)
|
||||||
|
pk__mark_value(p + i);
|
||||||
|
} else if(obj->slots == -1) {
|
||||||
|
NameDict* namedict = PyObject__dict(obj);
|
||||||
|
for(int i = 0; i < namedict->length; i++) {
|
||||||
|
NameDict_KV* kv = c11__at(NameDict_KV, namedict, i);
|
||||||
|
pk__mark_value(&kv->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ud = PyObject__userdata(obj);
|
||||||
|
switch(obj->type) {
|
||||||
|
case tp_list: {
|
||||||
|
List* self = ud;
|
||||||
|
for(int i = 0; i < self->length; i++) {
|
||||||
|
py_TValue* val = c11__at(py_TValue, self, i);
|
||||||
|
pk__mark_value(val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case tp_dict: {
|
||||||
|
Dict* self = ud;
|
||||||
|
for(int i = 0; i < self->entries.length; i++) {
|
||||||
|
DictEntry* entry = c11__at(DictEntry, &self->entries, i);
|
||||||
|
if(py_isnil(&entry->key)) continue;
|
||||||
|
pk__mark_value(&entry->key);
|
||||||
|
pk__mark_value(&entry->val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case tp_generator: {
|
||||||
|
Generator* self = ud;
|
||||||
|
if(self->frame) Frame__gc_mark(self->frame, p_stack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case tp_function: {
|
||||||
|
function__gc_mark(ud, p_stack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case tp_code: {
|
||||||
|
CodeObject* self = ud;
|
||||||
|
CodeObject__gc_mark(self, p_stack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case tp_chunked_array2d: {
|
||||||
|
c11_chunked_array2d__mark(ud, p_stack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pk_print_stack(VM* self, py_Frame* frame, Bytecode byte) {
|
void pk_print_stack(VM* self, py_Frame* frame, Bytecode byte) {
|
||||||
|
@ -1222,7 +1222,7 @@ void c11_chunked_array2d__dtor(c11_chunked_array2d* self) {
|
|||||||
c11_chunked_array2d_chunks__dtor(&self->chunks);
|
c11_chunked_array2d_chunks__dtor(&self->chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void c11_chunked_array2d__mark(void* ud) {
|
void c11_chunked_array2d__mark(void* ud, c11_vector* p_stack) {
|
||||||
c11_chunked_array2d* self = ud;
|
c11_chunked_array2d* self = ud;
|
||||||
pk__mark_value(&self->default_T);
|
pk__mark_value(&self->default_T);
|
||||||
pk__mark_value(&self->context_builder);
|
pk__mark_value(&self->context_builder);
|
||||||
|
@ -75,8 +75,12 @@ bool ModuleDict__contains(ModuleDict* self, const char* path) {
|
|||||||
return ModuleDict__try_get(self, path) != NULL;
|
return ModuleDict__try_get(self, path) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleDict__apply_mark(ModuleDict *self) {
|
void ModuleDict__apply_mark(ModuleDict* self, c11_vector* p_stack) {
|
||||||
if(!self->module._obj->gc_marked) PyObject__mark(self->module._obj);
|
PyObject* obj = self->module._obj;
|
||||||
if(self->left) ModuleDict__apply_mark(self->left);
|
if(!obj->gc_marked) {
|
||||||
if(self->right) ModuleDict__apply_mark(self->right);
|
obj->gc_marked = true;
|
||||||
|
c11_vector__push(PyObject*, p_stack, obj);
|
||||||
|
}
|
||||||
|
if(self->left) ModuleDict__apply_mark(self->left, p_stack);
|
||||||
|
if(self->right) ModuleDict__apply_mark(self->right, p_stack);
|
||||||
}
|
}
|
||||||
|
@ -759,7 +759,7 @@ py_TValue pk_builtins__register() {
|
|||||||
return *builtins;
|
return *builtins;
|
||||||
}
|
}
|
||||||
|
|
||||||
void function__gc_mark(void* ud) {
|
void function__gc_mark(void* ud, c11_vector* p_stack) {
|
||||||
Function* func = ud;
|
Function* func = ud;
|
||||||
if(func->globals) pk__mark_value(func->globals);
|
if(func->globals) pk__mark_value(func->globals);
|
||||||
if(func->closure) {
|
if(func->closure) {
|
||||||
@ -769,7 +769,7 @@ void function__gc_mark(void* ud) {
|
|||||||
pk__mark_value(&kv->value);
|
pk__mark_value(&kv->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FuncDecl__gc_mark(func->decl);
|
FuncDecl__gc_mark(func->decl, p_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool function__doc__(int argc, py_Ref argv) {
|
static bool function__doc__(int argc, py_Ref argv) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user