mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
This commit is contained in:
parent
7233cff311
commit
adceacc0f5
@ -9,14 +9,14 @@
|
||||
typedef struct PoolArena {
|
||||
int block_size;
|
||||
int block_count;
|
||||
int unused_count;
|
||||
int unused_length;
|
||||
int* unused;
|
||||
char data[kPoolArenaSize];
|
||||
} PoolArena;
|
||||
|
||||
typedef struct Pool {
|
||||
c11_vector /* PoolArena* */ arenas;
|
||||
c11_vector /* PoolArena* */ not_free_arenas;
|
||||
c11_vector /* PoolArena* */ no_free_arenas;
|
||||
int block_size;
|
||||
} Pool;
|
||||
|
||||
|
@ -60,7 +60,6 @@ bool pk__object_new(int argc, py_Ref argv);
|
||||
py_TypeInfo* pk__type_info(py_Type type);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -25,3 +25,4 @@ void ModuleDict__dtor(ModuleDict* self);
|
||||
void ModuleDict__set(ModuleDict* self, const char* key, py_TValue val);
|
||||
py_TValue* ModuleDict__try_get(ModuleDict* self, const char* path);
|
||||
bool ModuleDict__contains(ModuleDict* self, const char* path);
|
||||
void ModuleDict__apply_mark(ModuleDict* self, void (*marker)(PyObject*));
|
||||
|
@ -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;
|
||||
if(!PK_LOW_MEMORY_MODE && size <= kPoolMaxBlockSize) {
|
||||
obj = MultiPool__alloc(&self->small_objects, size);
|
||||
assert(obj != NULL);
|
||||
} else {
|
||||
obj = PK_MALLOC(size);
|
||||
c11_vector__push(PyObject*, &self->large_objects, obj);
|
||||
|
@ -11,11 +11,10 @@
|
||||
static PoolArena* PoolArena__new(int block_size) {
|
||||
assert(kPoolArenaSize % block_size == 0);
|
||||
int block_count = kPoolArenaSize / block_size;
|
||||
int total_size = sizeof(PoolArena) + sizeof(int) * block_count;
|
||||
PoolArena* self = PK_MALLOC(total_size);
|
||||
PoolArena* self = PK_MALLOC(sizeof(PoolArena) + sizeof(int) * block_count);
|
||||
self->block_size = block_size;
|
||||
self->block_count = block_count;
|
||||
self->unused_count = block_count;
|
||||
self->unused_length = block_count;
|
||||
self->unused = PK_MALLOC(sizeof(int) * block_count);
|
||||
for(int i = 0; i < block_count; i++) {
|
||||
self->unused[i] = i;
|
||||
@ -34,27 +33,30 @@ static void PoolArena__delete(PoolArena* self) {
|
||||
}
|
||||
|
||||
static void* PoolArena__alloc(PoolArena* self) {
|
||||
assert(self->unused_count > 0);
|
||||
int index = self->unused[self->unused_count - 1];
|
||||
self->unused_count--;
|
||||
assert(self->unused_length > 0);
|
||||
int index = self->unused[self->unused_length - 1];
|
||||
self->unused_length--;
|
||||
return self->data + index * self->block_size;
|
||||
}
|
||||
|
||||
static int PoolArena__sweep_dealloc(PoolArena* self) {
|
||||
int freed = 0;
|
||||
self->unused_count = 0;
|
||||
self->unused_length = 0;
|
||||
for(int i = 0; i < self->block_count; i++) {
|
||||
PyObject* obj = (PyObject*)(self->data + i * self->block_size);
|
||||
if(obj->type == 0) {
|
||||
self->unused[self->unused_count] = i;
|
||||
self->unused_count++;
|
||||
// free slot
|
||||
self->unused[self->unused_length] = i;
|
||||
self->unused_length++;
|
||||
} else {
|
||||
if(!obj->gc_marked) {
|
||||
// not marked, need to free
|
||||
obj->type = 0;
|
||||
freed++;
|
||||
self->unused[self->unused_count] = i;
|
||||
self->unused_count++;
|
||||
self->unused[self->unused_length] = i;
|
||||
self->unused_length++;
|
||||
} else {
|
||||
// marked, clear mark
|
||||
obj->gc_marked = false;
|
||||
}
|
||||
}
|
||||
@ -64,15 +66,15 @@ static int PoolArena__sweep_dealloc(PoolArena* self) {
|
||||
|
||||
static void Pool__ctor(Pool* self, int block_size) {
|
||||
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;
|
||||
}
|
||||
|
||||
static void Pool__dtor(Pool* self) {
|
||||
c11__foreach(PoolArena*, &self->arenas, arena) { PoolArena__delete(*arena); }
|
||||
c11__foreach(PoolArena*, &self->not_free_arenas, arena) { PoolArena__delete(*arena); }
|
||||
c11__foreach(PoolArena*, &self->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->not_free_arenas);
|
||||
c11_vector__dtor(&self->no_free_arenas);
|
||||
}
|
||||
|
||||
static void* Pool__alloc(Pool* self) {
|
||||
@ -84,25 +86,25 @@ static void* Pool__alloc(Pool* self) {
|
||||
arena = c11_vector__back(PoolArena*, &self->arenas);
|
||||
}
|
||||
void* ptr = PoolArena__alloc(arena);
|
||||
if(arena->unused_count == 0) {
|
||||
if(arena->unused_length == 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
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(not_free_arenas);
|
||||
c11_vector__clear(no_free_arenas);
|
||||
|
||||
int freed = 0;
|
||||
for(int i = 0; i < self->arenas.length; i++) {
|
||||
PoolArena* item = c11__getitem(PoolArena*, &self->arenas, i);
|
||||
assert(item->unused_count > 0);
|
||||
assert(item->unused_length > 0);
|
||||
freed += PoolArena__sweep_dealloc(item);
|
||||
if(item->unused_count == item->block_count) {
|
||||
if(item->unused_length == item->block_count) {
|
||||
// all free
|
||||
if(self->arenas.length > 0) {
|
||||
if(arenas->length > 0) {
|
||||
// at least one arena
|
||||
PoolArena__delete(item);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < self->not_free_arenas.length; i++) {
|
||||
PoolArena* item = c11__getitem(PoolArena*, &self->not_free_arenas, i);
|
||||
for(int i = 0; i < self->no_free_arenas.length; i++) {
|
||||
PoolArena* item = c11__getitem(PoolArena*, &self->no_free_arenas, i);
|
||||
freed += PoolArena__sweep_dealloc(item);
|
||||
if(item->unused_count == 0) {
|
||||
// still not free
|
||||
c11_vector__push(PoolArena*, not_free_arenas, item);
|
||||
if(item->unused_length == 0) {
|
||||
// still no free
|
||||
c11_vector__push(PoolArena*, no_free_arenas, item);
|
||||
} else {
|
||||
if(item->unused_count == item->block_count) {
|
||||
if(item->unused_length == item->block_count) {
|
||||
// all free
|
||||
PoolArena__delete(item);
|
||||
} 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->not_free_arenas, not_free_arenas);
|
||||
c11_vector__swap(&self->no_free_arenas, no_free_arenas);
|
||||
return freed;
|
||||
}
|
||||
|
||||
@ -148,16 +150,16 @@ void* MultiPool__alloc(MultiPool* self, int size) {
|
||||
|
||||
int MultiPool__sweep_dealloc(MultiPool* self) {
|
||||
c11_vector arenas;
|
||||
c11_vector not_free_arenas;
|
||||
c11_vector no_free_arenas;
|
||||
c11_vector__ctor(&arenas, sizeof(PoolArena*));
|
||||
c11_vector__ctor(¬_free_arenas, sizeof(PoolArena*));
|
||||
c11_vector__ctor(&no_free_arenas, sizeof(PoolArena*));
|
||||
int freed = 0;
|
||||
for(int i = 0; i < kMultiPoolCount; i++) {
|
||||
Pool* item = &self->pools[i];
|
||||
freed += Pool__sweep_dealloc(item, &arenas, ¬_free_arenas);
|
||||
freed += Pool__sweep_dealloc(item, &arenas, &no_free_arenas);
|
||||
}
|
||||
c11_vector__dtor(&arenas);
|
||||
c11_vector__dtor(¬_free_arenas);
|
||||
c11_vector__dtor(&no_free_arenas);
|
||||
return freed;
|
||||
}
|
||||
|
||||
|
@ -645,11 +645,15 @@ void ManagedHeap__mark(ManagedHeap* self) {
|
||||
for(py_TValue* p = vm->stack.begin; p != vm->stack.end; p++) {
|
||||
pk__mark_value(p);
|
||||
}
|
||||
// mark modules
|
||||
ModuleDict__apply_mark(&vm->modules, mark_object);
|
||||
// mark types
|
||||
int types_length = vm->types.length;
|
||||
// 0-th type is placeholder
|
||||
for(py_Type i = 1; i < types_length; i++) {
|
||||
py_TypeInfo* ti = TypeList__get(&vm->types, i);
|
||||
// mark type object
|
||||
pk__mark_value(&ti->self);
|
||||
// mark common magic slots
|
||||
for(int j = 0; j < PK_MAGIC_SLOTS_COMMON_LENGTH; j++) {
|
||||
py_TValue* slot = ti->magic_0 + j;
|
||||
@ -744,10 +748,6 @@ bool pk_wrapper__self(int argc, py_Ref argv) {
|
||||
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); }
|
||||
|
||||
int py_replinput(char* buf, int max_size) {
|
||||
|
@ -73,3 +73,9 @@ py_TValue* ModuleDict__try_get(ModuleDict* self, const char* path) {
|
||||
bool ModuleDict__contains(ModuleDict* self, const char* path) {
|
||||
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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user