|
|
@@ -1,6 +1,10 @@
|
|
|
#include "memory.h"
|
|
|
#include "vm.h"
|
|
|
+
|
|
|
+#ifdef DEBUG_LOG_GC
|
|
|
+#include "debug.h"
|
|
|
#include <stdlib.h>
|
|
|
+#endif
|
|
|
|
|
|
// oldSize newSize Operation
|
|
|
// 0 Non‑zero Allocate new block.
|
|
|
@@ -8,6 +12,12 @@
|
|
|
// Non‑zero Smaller than oldSize Shrink existing allocation.
|
|
|
// Non‑zero Larger than oldSize Grow existing allocation.
|
|
|
void *reallocate(void *pointer, size_t oldSize, size_t newSize) {
|
|
|
+ if (newSize > oldSize) {
|
|
|
+#ifdef DEBUG_STRESS_GC
|
|
|
+ collectGarbage();
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
if (newSize == 0) {
|
|
|
free(pointer);
|
|
|
return NULL;
|
|
|
@@ -30,6 +40,10 @@ void *reallocate(void *pointer, size_t oldSize, size_t newSize) {
|
|
|
return result;
|
|
|
}
|
|
|
static void freeObject(Obj *object) {
|
|
|
+#ifdef DEBUG_LOG_GC
|
|
|
+ printf("%p free type %d\n", (void *) object, object->type);
|
|
|
+#endif
|
|
|
+
|
|
|
switch (object->type) {
|
|
|
case OBJ_NATIVE:
|
|
|
FREE(ObjNative, object);
|
|
|
@@ -63,3 +77,43 @@ void freeObjects() {
|
|
|
object = next;
|
|
|
}
|
|
|
}
|
|
|
+static void markRoots() {
|
|
|
+ for (Value *slot = vm.stack; slot < vm.stackTop; slot++) {
|
|
|
+ markValue(*slot);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < vm.frameCount; i++) {
|
|
|
+ markObject((Obj *) vm.frames[i].closure);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (ObjUpvalue *upvalue = vm.openUpvalues; upvalue != NULL; upvalue = upvalue->next) {
|
|
|
+ markObject((Obj *) upvalue);
|
|
|
+ }
|
|
|
+
|
|
|
+ markTable(&vm.globals);
|
|
|
+ markCompilerRoots();
|
|
|
+}
|
|
|
+void collectGarbage() {
|
|
|
+#ifdef DEBUG_LOG_GC
|
|
|
+ printf("-- gc begin\n");
|
|
|
+#endif
|
|
|
+
|
|
|
+ markRoots();
|
|
|
+
|
|
|
+#ifdef DEBUG_LOG_GC
|
|
|
+ printf("-- gc end\n");
|
|
|
+#endif
|
|
|
+}
|
|
|
+void markValue(Value value) {
|
|
|
+ if (IS_OBJ(value)) markObject(AS_OBJ(value));
|
|
|
+}
|
|
|
+void markObject(Obj *object) {
|
|
|
+ if (object == NULL) return;
|
|
|
+#ifdef DEBUG_LOG_GC
|
|
|
+ printf("%p mark ", (void *) object);
|
|
|
+ printValue(OBJ_VAL(object));
|
|
|
+ printf("\n");
|
|
|
+#endif
|
|
|
+
|
|
|
+ object->isMarked = true;
|
|
|
+}
|