Found and fixed a memory leak in the rope strings

Also fixed a bit manipulation error in the GC.
This commit is contained in:
2026-05-10 15:39:04 +10:00
parent 3b813da1cf
commit 83fb5222a2
9 changed files with 124 additions and 6 deletions
+82
View File
@@ -0,0 +1,82 @@
#include "bucket_inspector.h"
// #include <toy_string.h>
#include <stdio.h>
int inspect_bucket(Toy_Bucket** bucketHandle) {
int depth = 0;
//for each bucket
for (Toy_Bucket* iter = (*bucketHandle); iter != NULL; iter = iter->next) {
int occupied = 0;
int released = 0;
unsigned char* ptr = iter->data;
while ((ptr - iter->data < iter->count) && *((int*)ptr) != 0) { //for each partition
if ( ( *((int*)ptr) & 1) == 0) { //is this partition still in use?
occupied++;
}
else {
released++;
}
//jump distance: ((*((int*)ptr) | 1) ^ 1) + 4
// printf(" jump %d, ", ((*((int*)ptr) | 1) ^ 1) + 4);
ptr += ((*((int*)ptr) | 1) ^ 1) + 4; //OR + XOR to remove the 'free' flag from the size
}
printf("Bucket link %d: count %u, %d occupied, %d released\n", depth, iter->count, occupied, released);
depth++;
}
printf("\n");
return depth;
}
/*
int inspect_bucket_for_strings(Toy_Bucket** bucketHandle) {
int depth = 0;
//for each bucket
for (Toy_Bucket* iter = (*bucketHandle); iter != NULL; iter = iter->next) {
int occupied = 0;
int released = 0;
unsigned char* ptr = iter->data;
while ((ptr - iter->data < iter->count) && *((int*)ptr) != 0) { //for each partition
if ( ( *((int*)ptr) & 1) == 0) { //is this partition still in use?
occupied++;
//try to print as a string if possible
Toy_String* str = (void*)(ptr + 4);
if (str->info.type == TOY_STRING_LEAF && str->info.length < 255) {
printf("String Leaf (%d bytes, %d refCount): %.*s\n", *((int*)ptr), str->info.refCount, str->info.length, str->leaf.data);
}
else if (str->info.type == TOY_STRING_NODE) {
printf("String Node (%d bytes, %d refCount): ...\n", *((int*)ptr), str->info.refCount);
}
}
else {
released++;
}
//jump distance: ((*((int*)ptr) | 1) ^ 1) + 4
// printf(" jump %d, ", ((*((int*)ptr) | 1) ^ 1) + 4);
ptr += ((*((int*)ptr) | 1) ^ 1) + 4; //OR + XOR to remove the 'free' flag from the size
}
printf("Bucket link %d: count %u, %d occupied, %d released\n", depth, iter->count, occupied, released);
depth++;
}
printf("\n");
return depth;
}
*/
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "toy_bucket.h"
int inspect_bucket(Toy_Bucket** bucketHandle);
// int inspect_bucket_for_strings(Toy_Bucket** bucketHandle);
+13
View File
@@ -1,5 +1,6 @@
#include "ast_inspector.h"
#include "bytecode_inspector.h"
#include "bucket_inspector.h"
#include "toy_console_colors.h"
@@ -380,14 +381,26 @@ int repl(const char* filepath, bool verbose) {
//run
Toy_runVM(&vm);
int depthBeforeGC = 0;
int depthAfterGC = 0;
//print the debug info
if (verbose) {
debugStackPrint(vm.stack);
debugScopePrint(vm.scope, 0);
depthBeforeGC = inspect_bucket(&vm.memoryBucket);
}
//free the memory, and leave the VM ready for the next loop
Toy_resetVM(&vm, true, true);
if (verbose) {
depthAfterGC = inspect_bucket(&vm.memoryBucket);
printf("GC Report: %d -> %d\n", depthBeforeGC, depthAfterGC);
}
free(bytecode);
printf("%s> ", prompt); //shows the terminal prompt