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 {
|
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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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*));
|
||||||
|
@ -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);
|
||||||
|
@ -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(¬_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, ¬_free_arenas);
|
freed += Pool__sweep_dealloc(item, &arenas, &no_free_arenas);
|
||||||
}
|
}
|
||||||
c11_vector__dtor(&arenas);
|
c11_vector__dtor(&arenas);
|
||||||
c11_vector__dtor(¬_free_arenas);
|
c11_vector__dtor(&no_free_arenas);
|
||||||
return freed;
|
return freed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user