[no ci] backup

This commit is contained in:
blueloveTH 2025-11-23 13:58:02 +08:00
parent a6d0d9b04f
commit 6e2e9706dd
5 changed files with 74 additions and 23 deletions

View File

@ -2,6 +2,7 @@
#include "pocketpy/objects/object.h" #include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/objectpool.h" #include "pocketpy/interpreter/objectpool.h"
#include <time.h>
typedef struct ManagedHeap { typedef struct ManagedHeap {
MultiPool small_objects; MultiPool small_objects;
@ -14,12 +15,35 @@ typedef struct ManagedHeap {
bool gc_enabled; bool gc_enabled;
} ManagedHeap; } ManagedHeap;
typedef struct {
clock_t start;
clock_t end;
int* small_types;
int* large_types;
int small_freed;
int large_freed;
struct {
bool valid;
int before;
int after;
int upper;
int lower;
int avg_freed;
float free_ratio;
} auto_thres;
} ManagedHeapSwpetInfo;
void ManagedHeap__ctor(ManagedHeap* self); void ManagedHeap__ctor(ManagedHeap* self);
void ManagedHeap__dtor(ManagedHeap* self); void ManagedHeap__dtor(ManagedHeap* self);
void ManagedHeap__collect_if_needed(ManagedHeap* self); void ManagedHeapSwpetInfo__ctor(ManagedHeapSwpetInfo* self);
int ManagedHeap__collect(ManagedHeap* self); void ManagedHeapSwpetInfo__dtor(ManagedHeapSwpetInfo* self);
int ManagedHeap__sweep(ManagedHeap* self);
void ManagedHeap__collect_if_needed(ManagedHeap* self, ManagedHeapSwpetInfo* out_info);
int ManagedHeap__collect(ManagedHeap* self, ManagedHeapSwpetInfo* out_info);
int ManagedHeap__sweep(ManagedHeap* self, ManagedHeapSwpetInfo* out_info);
#define ManagedHeap__new(self, type, slots, udsize) \ #define ManagedHeap__new(self, type, slots, udsize) \
ManagedHeap__gcnew((self), (type), (slots), (udsize)) ManagedHeap__gcnew((self), (type), (slots), (udsize))

View File

@ -31,7 +31,7 @@ typedef struct MultiPool {
} MultiPool; } MultiPool;
void* MultiPool__alloc(MultiPool* self, int size); void* MultiPool__alloc(MultiPool* self, int size);
int MultiPool__sweep_dealloc(MultiPool* self); int MultiPool__sweep_dealloc(MultiPool* self, int* out_types);
void MultiPool__ctor(MultiPool* self); void MultiPool__ctor(MultiPool* self);
void MultiPool__dtor(MultiPool* self); void MultiPool__dtor(MultiPool* self);
c11_string* MultiPool__summary(MultiPool* self); c11_string* MultiPool__summary(MultiPool* self);

View File

@ -31,10 +31,10 @@ void ManagedHeap__dtor(ManagedHeap* self) {
c11_vector__dtor(&self->gc_roots); c11_vector__dtor(&self->gc_roots);
} }
void ManagedHeap__collect_if_needed(ManagedHeap* self) { void ManagedHeap__collect_if_needed(ManagedHeap* self, ManagedHeapSwpetInfo* out_info) {
if(!self->gc_enabled) return; if(!self->gc_enabled) return;
if(self->gc_counter < self->gc_threshold) return; if(self->gc_counter < self->gc_threshold) return;
int freed = ManagedHeap__collect(self); int freed = ManagedHeap__collect(self, out_info);
// adjust `gc_threshold` based on `freed_ma` // adjust `gc_threshold` based on `freed_ma`
self->freed_ma[0] = self->freed_ma[1]; self->freed_ma[0] = self->freed_ma[1];
self->freed_ma[1] = self->freed_ma[2]; self->freed_ma[1] = self->freed_ma[2];
@ -44,22 +44,28 @@ void ManagedHeap__collect_if_needed(ManagedHeap* self) {
const int lower = PK_GC_MIN_THRESHOLD / 2; const int lower = PK_GC_MIN_THRESHOLD / 2;
float free_ratio = (float)avg_freed / self->gc_threshold; float free_ratio = (float)avg_freed / self->gc_threshold;
int new_threshold = self->gc_threshold * (1.5f / free_ratio); int new_threshold = self->gc_threshold * (1.5f / free_ratio);
// printf("gc_threshold=%d, avg_freed=%d, new_threshold=%d\n", self->gc_threshold, avg_freed, if(out_info) {
// new_threshold); out_info->auto_thres.valid = true;
out_info->auto_thres.before = self->gc_threshold;
out_info->auto_thres.after = new_threshold;
out_info->auto_thres.upper = upper;
out_info->auto_thres.lower = lower;
out_info->auto_thres.avg_freed = avg_freed;
out_info->auto_thres.free_ratio = free_ratio;
}
self->gc_threshold = c11__min(c11__max(new_threshold, lower), upper); self->gc_threshold = c11__min(c11__max(new_threshold, lower), upper);
} }
int ManagedHeap__collect(ManagedHeap* self) { int ManagedHeap__collect(ManagedHeap* self, ManagedHeapSwpetInfo* out_info) {
self->gc_counter = 0; self->gc_counter = 0;
ManagedHeap__mark(self); ManagedHeap__mark(self);
int freed = ManagedHeap__sweep(self); return ManagedHeap__sweep(self, out_info);
// printf("GC: collected %d objects\n", freed);
return freed;
} }
int ManagedHeap__sweep(ManagedHeap* self) { int ManagedHeap__sweep(ManagedHeap* self, ManagedHeapSwpetInfo* out_info) {
// small_objects // small_objects
int small_freed = MultiPool__sweep_dealloc(&self->small_objects); int small_freed =
MultiPool__sweep_dealloc(&self->small_objects, out_info ? out_info->small_types : NULL);
// large_objects // large_objects
int large_living_count = 0; int large_living_count = 0;
for(int i = 0; i < self->large_objects.length; i++) { for(int i = 0; i < self->large_objects.length; i++) {
@ -69,6 +75,7 @@ int ManagedHeap__sweep(ManagedHeap* self) {
c11__setitem(PyObject*, &self->large_objects, large_living_count, obj); c11__setitem(PyObject*, &self->large_objects, large_living_count, obj);
large_living_count++; large_living_count++;
} else { } else {
if(out_info) out_info->large_types[obj->type]++;
PyObject__dtor(obj); PyObject__dtor(obj);
PK_FREE(obj); PK_FREE(obj);
} }
@ -76,8 +83,11 @@ int ManagedHeap__sweep(ManagedHeap* self) {
// shrink `self->large_objects` // shrink `self->large_objects`
int large_freed = self->large_objects.length - large_living_count; int large_freed = self->large_objects.length - large_living_count;
self->large_objects.length = large_living_count; self->large_objects.length = large_living_count;
// printf("large_freed=%d\n", large_freed); if(out_info) {
// printf("small_freed=%d\n", small_freed); out_info->small_freed = small_freed;
out_info->large_freed = large_freed;
out_info->end = clock();
}
return small_freed + large_freed; return small_freed + large_freed;
} }

View File

@ -36,7 +36,7 @@ static void* PoolArena__alloc(PoolArena* self) {
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* out_types) {
int freed = 0; int freed = 0;
self->unused_length = 0; self->unused_length = 0;
for(int i = 0; i < self->block_count; i++) { for(int i = 0; i < self->block_count; i++) {
@ -48,6 +48,7 @@ static int PoolArena__sweep_dealloc(PoolArena* self) {
} else { } else {
if(!obj->gc_marked) { if(!obj->gc_marked) {
// not marked, need to free // not marked, need to free
if(out_types) out_types[obj->type]++;
PyObject__dtor(obj); PyObject__dtor(obj);
obj->type = 0; obj->type = 0;
freed++; freed++;
@ -91,7 +92,10 @@ static void* Pool__alloc(Pool* self) {
return ptr; return ptr;
} }
static int Pool__sweep_dealloc(Pool* self, c11_vector* arenas, c11_vector* no_free_arenas) { static int Pool__sweep_dealloc(Pool* self,
c11_vector* arenas,
c11_vector* no_free_arenas,
int* out_types) {
c11_vector__clear(arenas); c11_vector__clear(arenas);
c11_vector__clear(no_free_arenas); c11_vector__clear(no_free_arenas);
@ -99,7 +103,7 @@ static int Pool__sweep_dealloc(Pool* self, c11_vector* arenas, c11_vector* no_fr
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_length > 0); assert(item->unused_length > 0);
freed += PoolArena__sweep_dealloc(item); freed += PoolArena__sweep_dealloc(item, out_types);
if(item->unused_length == item->block_count) { if(item->unused_length == item->block_count) {
// all free // all free
if(arenas->length > 0) { if(arenas->length > 0) {
@ -116,7 +120,7 @@ static int Pool__sweep_dealloc(Pool* self, c11_vector* arenas, c11_vector* no_fr
} }
for(int i = 0; i < self->no_free_arenas.length; i++) { for(int i = 0; i < self->no_free_arenas.length; i++) {
PoolArena* item = c11__getitem(PoolArena*, &self->no_free_arenas, i); PoolArena* item = c11__getitem(PoolArena*, &self->no_free_arenas, i);
freed += PoolArena__sweep_dealloc(item); freed += PoolArena__sweep_dealloc(item, out_types);
if(item->unused_length == 0) { if(item->unused_length == 0) {
// still no free // still no free
c11_vector__push(PoolArena*, no_free_arenas, item); c11_vector__push(PoolArena*, no_free_arenas, item);
@ -146,7 +150,7 @@ void* MultiPool__alloc(MultiPool* self, int size) {
return NULL; return NULL;
} }
int MultiPool__sweep_dealloc(MultiPool* self) { int MultiPool__sweep_dealloc(MultiPool* self, int* out_types) {
c11_vector arenas; c11_vector arenas;
c11_vector no_free_arenas; c11_vector no_free_arenas;
c11_vector__ctor(&arenas, sizeof(PoolArena*)); c11_vector__ctor(&arenas, sizeof(PoolArena*));
@ -154,7 +158,7 @@ int MultiPool__sweep_dealloc(MultiPool* self) {
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, &no_free_arenas); freed += Pool__sweep_dealloc(item, &arenas, &no_free_arenas, out_types);
} }
c11_vector__dtor(&arenas); c11_vector__dtor(&arenas);
c11_vector__dtor(&no_free_arenas); c11_vector__dtor(&no_free_arenas);

View File

@ -128,4 +128,17 @@ void PyObject__dtor(PyObject* self) {
NameDict* dict = PyObject__dict(self); NameDict* dict = PyObject__dict(self);
NameDict__dtor(dict); NameDict__dtor(dict);
} }
} }
void ManagedHeapSwpetInfo__ctor(ManagedHeapSwpetInfo* self) {
memset(self, 0, sizeof(ManagedHeapSwpetInfo));
self->start = clock();
self->small_types = py_malloc(sizeof(int) * pk_current_vm->types.length);
self->large_types = py_malloc(sizeof(int) * pk_current_vm->types.length);
}
void ManagedHeapSwpetInfo__dtor(ManagedHeapSwpetInfo* self) {
py_free(self->small_types);
py_free(self->large_types);
memset(self, 0, sizeof(ManagedHeapSwpetInfo));
}