This commit is contained in:
blueloveTH 2025-01-23 14:00:51 +08:00
parent 7233cff311
commit adceacc0f5
7 changed files with 50 additions and 41 deletions

View File

@ -9,14 +9,14 @@
typedef struct PoolArena { typedef struct PoolArena {
int block_size; int block_size;
int block_count; int block_count;
int unused_count; int unused_length;
int* unused; int* unused;
char data[kPoolArenaSize]; char data[kPoolArenaSize];
} PoolArena; } PoolArena;
typedef struct Pool { typedef struct Pool {
c11_vector /* PoolArena* */ arenas; c11_vector /* PoolArena* */ arenas;
c11_vector /* PoolArena* */ not_free_arenas; c11_vector /* PoolArena* */ no_free_arenas;
int block_size; int block_size;
} Pool; } Pool;

View File

@ -60,7 +60,6 @@ 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);
bool pk_wrapper__self(int argc, py_Ref argv); bool pk_wrapper__self(int argc, py_Ref argv);
bool pk_wrapper__NotImplementedError(int argc, py_Ref argv);
const char* pk_op2str(py_Name op); const char* pk_op2str(py_Name op);

View File

@ -25,3 +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 (*marker)(PyObject*));

View File

@ -81,6 +81,7 @@ PyObject* ManagedHeap__gcnew(ManagedHeap* self, py_Type type, int slots, int uds
int size = sizeof(PyObject) + PK_OBJ_SLOTS_SIZE(slots) + udsize; int size = sizeof(PyObject) + PK_OBJ_SLOTS_SIZE(slots) + udsize;
if(!PK_LOW_MEMORY_MODE && size <= kPoolMaxBlockSize) { if(!PK_LOW_MEMORY_MODE && size <= kPoolMaxBlockSize) {
obj = MultiPool__alloc(&self->small_objects, size); obj = MultiPool__alloc(&self->small_objects, size);
assert(obj != NULL);
} else { } else {
obj = PK_MALLOC(size); obj = PK_MALLOC(size);
c11_vector__push(PyObject*, &self->large_objects, obj); c11_vector__push(PyObject*, &self->large_objects, obj);

View File

@ -11,11 +11,10 @@
static PoolArena* PoolArena__new(int block_size) { static PoolArena* PoolArena__new(int block_size) {
assert(kPoolArenaSize % block_size == 0); assert(kPoolArenaSize % block_size == 0);
int block_count = kPoolArenaSize / block_size; int block_count = kPoolArenaSize / block_size;
int total_size = sizeof(PoolArena) + sizeof(int) * block_count; PoolArena* self = PK_MALLOC(sizeof(PoolArena) + sizeof(int) * block_count);
PoolArena* self = PK_MALLOC(total_size);
self->block_size = block_size; self->block_size = block_size;
self->block_count = block_count; self->block_count = block_count;
self->unused_count = block_count; self->unused_length = block_count;
self->unused = PK_MALLOC(sizeof(int) * block_count); self->unused = PK_MALLOC(sizeof(int) * block_count);
for(int i = 0; i < block_count; i++) { for(int i = 0; i < block_count; i++) {
self->unused[i] = i; self->unused[i] = i;
@ -34,27 +33,30 @@ static void PoolArena__delete(PoolArena* self) {
} }
static void* PoolArena__alloc(PoolArena* self) { static void* PoolArena__alloc(PoolArena* self) {
assert(self->unused_count > 0); assert(self->unused_length > 0);
int index = self->unused[self->unused_count - 1]; int index = self->unused[self->unused_length - 1];
self->unused_count--; self->unused_length--;
return self->data + index * self->block_size; return self->data + index * self->block_size;
} }
static int PoolArena__sweep_dealloc(PoolArena* self) { static int PoolArena__sweep_dealloc(PoolArena* self) {
int freed = 0; int freed = 0;
self->unused_count = 0; self->unused_length = 0;
for(int i = 0; i < self->block_count; i++) { for(int i = 0; i < self->block_count; i++) {
PyObject* obj = (PyObject*)(self->data + i * self->block_size); PyObject* obj = (PyObject*)(self->data + i * self->block_size);
if(obj->type == 0) { if(obj->type == 0) {
self->unused[self->unused_count] = i; // free slot
self->unused_count++; self->unused[self->unused_length] = i;
self->unused_length++;
} else { } else {
if(!obj->gc_marked) { if(!obj->gc_marked) {
// not marked, need to free
obj->type = 0; obj->type = 0;
freed++; freed++;
self->unused[self->unused_count] = i; self->unused[self->unused_length] = i;
self->unused_count++; self->unused_length++;
} else { } else {
// marked, clear mark
obj->gc_marked = false; obj->gc_marked = false;
} }
} }
@ -64,15 +66,15 @@ static int PoolArena__sweep_dealloc(PoolArena* self) {
static void Pool__ctor(Pool* self, int block_size) { static void Pool__ctor(Pool* self, int block_size) {
c11_vector__ctor(&self->arenas, sizeof(PoolArena*)); c11_vector__ctor(&self->arenas, sizeof(PoolArena*));
c11_vector__ctor(&self->not_free_arenas, sizeof(PoolArena*)); c11_vector__ctor(&self->no_free_arenas, sizeof(PoolArena*));
self->block_size = block_size; self->block_size = block_size;
} }
static void Pool__dtor(Pool* self) { static void Pool__dtor(Pool* self) {
c11__foreach(PoolArena*, &self->arenas, arena) { PoolArena__delete(*arena); } c11__foreach(PoolArena*, &self->arenas, arena) PoolArena__delete(*arena);
c11__foreach(PoolArena*, &self->not_free_arenas, arena) { PoolArena__delete(*arena); } c11__foreach(PoolArena*, &self->no_free_arenas, arena) PoolArena__delete(*arena);
c11_vector__dtor(&self->arenas); c11_vector__dtor(&self->arenas);
c11_vector__dtor(&self->not_free_arenas); c11_vector__dtor(&self->no_free_arenas);
} }
static void* Pool__alloc(Pool* self) { static void* Pool__alloc(Pool* self) {
@ -84,25 +86,25 @@ static void* Pool__alloc(Pool* self) {
arena = c11_vector__back(PoolArena*, &self->arenas); arena = c11_vector__back(PoolArena*, &self->arenas);
} }
void* ptr = PoolArena__alloc(arena); void* ptr = PoolArena__alloc(arena);
if(arena->unused_count == 0) { if(arena->unused_length == 0) {
c11_vector__pop(&self->arenas); c11_vector__pop(&self->arenas);
c11_vector__push(PoolArena*, &self->not_free_arenas, arena); c11_vector__push(PoolArena*, &self->no_free_arenas, arena);
} }
return ptr; return ptr;
} }
static int Pool__sweep_dealloc(Pool* self, c11_vector* arenas, c11_vector* not_free_arenas) { static int Pool__sweep_dealloc(Pool* self, c11_vector* arenas, c11_vector* no_free_arenas) {
c11_vector__clear(arenas); c11_vector__clear(arenas);
c11_vector__clear(not_free_arenas); c11_vector__clear(no_free_arenas);
int freed = 0; int freed = 0;
for(int i = 0; i < self->arenas.length; i++) { for(int i = 0; i < self->arenas.length; i++) {
PoolArena* item = c11__getitem(PoolArena*, &self->arenas, i); PoolArena* item = c11__getitem(PoolArena*, &self->arenas, i);
assert(item->unused_count > 0); assert(item->unused_length > 0);
freed += PoolArena__sweep_dealloc(item); freed += PoolArena__sweep_dealloc(item);
if(item->unused_count == item->block_count) { if(item->unused_length == item->block_count) {
// all free // all free
if(self->arenas.length > 0) { if(arenas->length > 0) {
// at least one arena // at least one arena
PoolArena__delete(item); PoolArena__delete(item);
} else { } else {
@ -114,14 +116,14 @@ static int Pool__sweep_dealloc(Pool* self, c11_vector* arenas, c11_vector* not_f
c11_vector__push(PoolArena*, arenas, item); c11_vector__push(PoolArena*, arenas, item);
} }
} }
for(int i = 0; i < self->not_free_arenas.length; i++) { for(int i = 0; i < self->no_free_arenas.length; i++) {
PoolArena* item = c11__getitem(PoolArena*, &self->not_free_arenas, i); PoolArena* item = c11__getitem(PoolArena*, &self->no_free_arenas, i);
freed += PoolArena__sweep_dealloc(item); freed += PoolArena__sweep_dealloc(item);
if(item->unused_count == 0) { if(item->unused_length == 0) {
// still not free // still no free
c11_vector__push(PoolArena*, not_free_arenas, item); c11_vector__push(PoolArena*, no_free_arenas, item);
} else { } else {
if(item->unused_count == item->block_count) { if(item->unused_length == item->block_count) {
// all free // all free
PoolArena__delete(item); PoolArena__delete(item);
} else { } else {
@ -132,7 +134,7 @@ static int Pool__sweep_dealloc(Pool* self, c11_vector* arenas, c11_vector* not_f
} }
c11_vector__swap(&self->arenas, arenas); c11_vector__swap(&self->arenas, arenas);
c11_vector__swap(&self->not_free_arenas, not_free_arenas); c11_vector__swap(&self->no_free_arenas, no_free_arenas);
return freed; return freed;
} }
@ -148,16 +150,16 @@ void* MultiPool__alloc(MultiPool* self, int size) {
int MultiPool__sweep_dealloc(MultiPool* self) { int MultiPool__sweep_dealloc(MultiPool* self) {
c11_vector arenas; c11_vector arenas;
c11_vector not_free_arenas; c11_vector no_free_arenas;
c11_vector__ctor(&arenas, sizeof(PoolArena*)); c11_vector__ctor(&arenas, sizeof(PoolArena*));
c11_vector__ctor(&not_free_arenas, sizeof(PoolArena*)); c11_vector__ctor(&no_free_arenas, sizeof(PoolArena*));
int freed = 0; int freed = 0;
for(int i = 0; i < kMultiPoolCount; i++) { for(int i = 0; i < kMultiPoolCount; i++) {
Pool* item = &self->pools[i]; Pool* item = &self->pools[i];
freed += Pool__sweep_dealloc(item, &arenas, &not_free_arenas); freed += Pool__sweep_dealloc(item, &arenas, &no_free_arenas);
} }
c11_vector__dtor(&arenas); c11_vector__dtor(&arenas);
c11_vector__dtor(&not_free_arenas); c11_vector__dtor(&no_free_arenas);
return freed; return freed;
} }

View File

@ -645,11 +645,15 @@ void ManagedHeap__mark(ManagedHeap* self) {
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);
} }
// mark modules
ModuleDict__apply_mark(&vm->modules, mark_object);
// 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
for(py_Type i = 1; i < types_length; i++) { for(py_Type i = 1; i < types_length; i++) {
py_TypeInfo* ti = TypeList__get(&vm->types, i); py_TypeInfo* ti = TypeList__get(&vm->types, i);
// mark type object
pk__mark_value(&ti->self);
// mark common magic slots // mark common magic slots
for(int j = 0; j < PK_MAGIC_SLOTS_COMMON_LENGTH; j++) { for(int j = 0; j < PK_MAGIC_SLOTS_COMMON_LENGTH; j++) {
py_TValue* slot = ti->magic_0 + j; py_TValue* slot = ti->magic_0 + j;
@ -744,10 +748,6 @@ bool pk_wrapper__self(int argc, py_Ref argv) {
return true; return true;
} }
bool pk_wrapper__NotImplementedError(int argc, py_Ref argv) {
return py_exception(tp_NotImplementedError, "");
}
py_TypeInfo* pk__type_info(py_Type type) { return TypeList__get(&pk_current_vm->types, type); } py_TypeInfo* pk__type_info(py_Type type) { return TypeList__get(&pk_current_vm->types, type); }
int py_replinput(char* buf, int max_size) { int py_replinput(char* buf, int max_size) {

View File

@ -72,4 +72,10 @@ 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) {
return ModuleDict__try_get(self, path) != NULL; return ModuleDict__try_get(self, path) != NULL;
} }
void ModuleDict__apply_mark(ModuleDict *self, void (*marker)(PyObject*)) {
if(self->left) ModuleDict__apply_mark(self->left, marker);
if(self->right) ModuleDict__apply_mark(self->right, marker);
marker(self->module._obj);
}