aboutsummaryrefslogtreecommitdiff
path: root/vm
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2023-11-02 23:25:37 +0000
committerAryadev Chavali <aryadev@aryadevchavali.com>2023-11-02 23:25:37 +0000
commitf433febb2215dc343ab1fb40edca6380581554a3 (patch)
tree40340b9aa9f8e2cdff6d92797b30228c088838a8 /vm
parent4eee6e1a0a17465756f1b4156727c55bc17214f1 (diff)
downloadovm-f433febb2215dc343ab1fb40edca6380581554a3.tar.gz
ovm-f433febb2215dc343ab1fb40edca6380581554a3.tar.bz2
ovm-f433febb2215dc343ab1fb40edca6380581554a3.zip
Added memory leak dialog in vm_stop
Stack, call stack and heap are evaluated to check for leaks.
Diffstat (limited to 'vm')
-rw-r--r--vm/runtime.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/vm/runtime.c b/vm/runtime.c
index 996eb58..c5f82c5 100644
--- a/vm/runtime.c
+++ b/vm/runtime.c
@@ -380,10 +380,60 @@ void vm_load_call_stack(vm_t *vm, word *buffer, size_t size)
void vm_stop(vm_t *vm)
{
+#if VERBOSE >= 1
+ bool leaks = false;
+ printf("[" TERM_YELLOW "DATA" TERM_RESET "]: Checking for leaks...\n");
+ if (vm->call_stack.ptr > 0)
+ {
+ leaks = true;
+ printf("\t[" TERM_RED "DATA" TERM_RESET "]: Call stack at %lu\n\t[" TERM_RED
+ "DATA" TERM_RESET "]\n\t[" TERM_RED "DATA" TERM_RESET "]: Call "
+ "stack trace:",
+ vm->call_stack.ptr);
+ for (size_t i = vm->call_stack.ptr; i > 0; --i)
+ {
+ word w = vm->call_stack.address_pointers[i - 1];
+ printf("\t\t%lu: %lX", vm->call_stack.ptr - i, w);
+ if (i != 1)
+ printf(", ");
+ printf("\n");
+ }
+ }
+ if (vm->heap.pages > 0)
+ {
+ leaks = true;
+ page_t *cur = vm->heap.beg;
+ size_t capacities[vm->heap.pages], total_capacity = 0;
+ for (size_t i = 0; i < vm->heap.pages; ++i)
+ {
+ capacities[i] = cur->available;
+ total_capacity += capacities[i];
+ }
+ printf("\t[" TERM_RED "DATA" TERM_RESET
+ "]: Heap: %luB (over %lu %s) not reclaimed\n",
+ total_capacity, vm->heap.pages,
+ vm->heap.pages == 1 ? "page" : "pages");
+ printf("\t[" TERM_RED "DATA" TERM_RESET "]: Complete breakdown:\n");
+ for (size_t i = 0; i < vm->heap.pages; i++)
+ printf("\t\t[%lu]: %luB bytes lost\n", i, capacities[i]);
+ }
+ if (vm->stack.ptr > 0)
+ {
+ leaks = true;
+ printf("\t[" TERM_RED "DATA" TERM_RESET "]: Stack: %luB not reclaimed\n",
+ vm->stack.ptr);
+ }
+ if (leaks)
+ printf("[" TERM_RED "DATA" TERM_RESET "]: Leaks found\n");
+ else
+ printf("[" TERM_GREEN "DATA" TERM_RESET "]: No leaks found\n");
+#endif
+
free(vm->registers.data);
free(vm->program.instructions);
free(vm->stack.data);
heap_stop(&vm->heap);
+ free(vm->call_stack.address_pointers);
vm->registers = (registers_t){0};
vm->program = (struct Program){0};