Browse Source

[no ci] backup

blueloveTH 3 months ago
parent
commit
6e2e9706dd

+ 27 - 3
include/pocketpy/interpreter/heap.h

@@ -2,6 +2,7 @@
 
 #include "pocketpy/objects/object.h"
 #include "pocketpy/interpreter/objectpool.h"
+#include <time.h>
 
 typedef struct ManagedHeap {
     MultiPool small_objects;
@@ -14,12 +15,35 @@ typedef struct ManagedHeap {
     bool gc_enabled;
 } 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__dtor(ManagedHeap* self);
 
-void ManagedHeap__collect_if_needed(ManagedHeap* self);
-int ManagedHeap__collect(ManagedHeap* self);
-int ManagedHeap__sweep(ManagedHeap* self);
+void ManagedHeapSwpetInfo__ctor(ManagedHeapSwpetInfo* self);
+void ManagedHeapSwpetInfo__dtor(ManagedHeapSwpetInfo* 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)                                                \
     ManagedHeap__gcnew((self), (type), (slots), (udsize))

+ 1 - 1
include/pocketpy/interpreter/objectpool.h

@@ -31,7 +31,7 @@ typedef struct MultiPool {
 } MultiPool;
 
 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__dtor(MultiPool* self);
 c11_string* MultiPool__summary(MultiPool* self);

+ 22 - 12
src/interpreter/heap.c

@@ -31,10 +31,10 @@ void ManagedHeap__dtor(ManagedHeap* self) {
     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_counter < self->gc_threshold) return;
-    int freed = ManagedHeap__collect(self);
+    int freed = ManagedHeap__collect(self, out_info);
     // adjust `gc_threshold` based on `freed_ma`
     self->freed_ma[0] = self->freed_ma[1];
     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;
     float free_ratio = (float)avg_freed / self->gc_threshold;
     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,
-    // new_threshold);
+    if(out_info) {
+        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);
 }
 
-int ManagedHeap__collect(ManagedHeap* self) {
+int ManagedHeap__collect(ManagedHeap* self, ManagedHeapSwpetInfo* out_info) {
     self->gc_counter = 0;
     ManagedHeap__mark(self);
-    int freed = ManagedHeap__sweep(self);
-    // printf("GC: collected %d objects\n", freed);
-    return freed;
+    return ManagedHeap__sweep(self, out_info);
 }
 
-int ManagedHeap__sweep(ManagedHeap* self) {
+int ManagedHeap__sweep(ManagedHeap* self, ManagedHeapSwpetInfo* out_info) {
     // 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
     int large_living_count = 0;
     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);
             large_living_count++;
         } else {
+            if(out_info) out_info->large_types[obj->type]++;
             PyObject__dtor(obj);
             PK_FREE(obj);
         }
@@ -76,8 +83,11 @@ int ManagedHeap__sweep(ManagedHeap* self) {
     // shrink `self->large_objects`
     int large_freed = self->large_objects.length - large_living_count;
     self->large_objects.length = large_living_count;
-    // printf("large_freed=%d\n", large_freed);
-    // printf("small_freed=%d\n", small_freed);
+    if(out_info) {
+        out_info->small_freed = small_freed;
+        out_info->large_freed = large_freed;
+        out_info->end = clock();
+    }
     return small_freed + large_freed;
 }
 

+ 10 - 6
src/interpreter/objectpool.c

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

+ 14 - 1
src/interpreter/vmx.c

@@ -128,4 +128,17 @@ void PyObject__dtor(PyObject* self) {
         NameDict* dict = PyObject__dict(self);
         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));
+}