printing a stack trace on trap; best fit not first fit
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 17 Jan 2022 03:05:19 +0000 (21:05 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 17 Jan 2022 03:05:19 +0000 (21:05 -0600)
core/alloc/heap.onyx
core/alloc/pool.onyx
core/runtime/common.onyx
src/wasm_runtime.c

index 11ba6ade657a3302846cbb053861b9a85a852a90..959b5d8aaaa1171026f3f2118dbddb313b83edb0 100644 (file)
@@ -94,38 +94,52 @@ get_freed_size :: () => {
 
         prev := ^heap_state.free_list;
         hb := heap_state.free_list;
+
+        best_extra := 0xffffffff;
+        best: typeof hb = null;
+        best_prev: typeof prev = null;
+
         while hb != null {
             if hb.size >= size {
-                #if Enable_Debug {
-                    assert(hb.size & Allocated_Flag == 0, "Allocated block in free list.");
-                    assert(hb.magic_number == Free_Block_Magic_Number, "Malformed free block in free list.");
+                extra := hb.size - size;
+                if extra < best_extra {
+                    best = hb;
+                    best_prev = prev;
+                    best_extra = extra;
                 }
+            }
 
-                if hb.size - size >= Block_Split_Size {
-                    new_block := cast(^heap_freed_block) (cast(uintptr) hb + size);
-                    new_block.size = hb.size - size;
-                    new_block.next = hb.next;
-                    new_block.prev = hb.prev;
-                    new_block.magic_number = Free_Block_Magic_Number;
-                    hb.size = size;
+            prev = ^hb.next;
+            hb = hb.next;
+        }
 
-                    if hb.next != null do hb.next.prev = new_block;
-                    *prev = new_block;
+        if best != null {
+            #if Enable_Debug {
+                assert(best.size & Allocated_Flag == 0, "Allocated block in free list.");
+                assert(best.magic_number == Free_Block_Magic_Number, "Malformed free block in free list.");
+            }
 
-                } else {
-                    if hb.next != null do hb.next.prev = hb.prev;
-                    *prev = hb.next;
-                }
+            if best.size - size >= Block_Split_Size {
+                new_block := cast(^heap_freed_block) (cast(uintptr) best + size);
+                new_block.size = best.size - size;
+                new_block.next = best.next;
+                new_block.prev = best.prev;
+                new_block.magic_number = Free_Block_Magic_Number;
+                best.size = size;
+
+                if best.next != null do best.next.prev = new_block;
+                *best_prev = new_block;
 
-                hb.next = null;
-                hb.prev = null;
-                hb.magic_number = 0;
-                hb.size |= Allocated_Flag;
-                return cast(rawptr) (cast(uintptr) hb + sizeof heap_allocated_block);
+            } else {
+                if best.next != null do best.next.prev = best.prev;
+                *best_prev = best.next;
             }
 
-            prev = ^hb.next;
-            hb = hb.next;
+            best.next = null;
+            best.prev = null;
+            best.magic_number = 0;
+            best.size |= Allocated_Flag;
+            return cast(rawptr) (cast(uintptr) best + sizeof heap_allocated_block);
         }
 
         if size < heap_state.remaining_space {
index 88f8d827690f68c53fbfe13da027596e859ba217..12b003bbd7c5e40fad87b55ef93d76a0d0a259d8 100644 (file)
@@ -14,6 +14,9 @@ package core.alloc.pool
 PoolAllocator :: struct (Elem: type_expr) {
     buffer     : [] Elem;
     first_free : ^Elem;
+
+    alloc :: pool_alloc
+    free  :: pool_free
 }
 
 #local
index 0aa87931aafec8a72362ac194cd9ff818ae98e6f..f511b7afcd9e6d391fc2ad7f844e0c76864edac3 100644 (file)
@@ -16,7 +16,8 @@ __assert_handler :: (msg: str, site: CallSite) {
 
     __output_string("\n");
 
-    __exit(1);
+    // __exit(1);
+    *(cast(^i32) 0xffffffff);
 }
 
 // This procedure should only be called once at the very begining
@@ -73,4 +74,4 @@ __thread_initialize :: macro () {
         raw_free(alloc.heap_allocator, __tls_base);
         thread.__exited(id);
     }
-}
\ No newline at end of file
+}
index 7cfba39a1f64eac312a9ee53a20965cc9d247f28..979f1fc9d8646e45b8f961368a639d7c3a144a04 100644 (file)
@@ -171,8 +171,7 @@ static void onyx_print_trap(wasm_trap_t* trap) {
     wasm_trap_message(trap, &msg);
     bh_printf("TRAP: %b\n", msg.data, msg.size);
 
-    wasm_frame_t *origin = wasm_trap_origin(trap);
-    i32 index = wasm_frame_func_index(origin);
+    i32 func_name_section = 0;
 
     i32 cursor = 8; // skip the magic number and version
     while (cursor < wasm_raw_bytes.length) {
@@ -184,20 +183,27 @@ static void onyx_print_trap(wasm_trap_t* trap) {
             u64 name_len = uleb128_to_uint(wasm_raw_bytes.data, &cursor);
             if (!strncmp(wasm_raw_bytes.data + cursor, "_onyx_func_offsets", name_len)) {
                 cursor += name_len;
-                i32 section_start = cursor;
-
-                cursor += 4 * index;
-                i32 func_offset = *(i32 *) (wasm_raw_bytes.data + cursor);
-                char* func_name = wasm_raw_bytes.data + section_start + func_offset;
-
-                bh_printf("HERE: %s\n", func_name);
-                bh_printf("OFFSET: %p\n", wasm_frame_module_offset(origin));
+                func_name_section = cursor;
                 break;
             }
         }
 
         cursor = section_start + section_size;
     }
+
+    bh_printf("TRACE:\n");
+    wasm_frame_vec_t frames;
+    wasm_trap_trace(trap, &frames);
+    fori (i, 0, (i32) frames.size) {
+        i32 func_idx   = wasm_frame_func_index(frames.data[i]);
+        i32 mod_offset = wasm_frame_module_offset(frames.data[i]);
+
+        i32 cursor = func_name_section + 4 * func_idx;
+        i32 func_offset = *(i32 *) (wasm_raw_bytes.data + cursor);
+        char* func_name = wasm_raw_bytes.data + func_name_section + func_offset;
+
+        bh_printf("    func[%d]:%p at %s\n", func_idx, mod_offset, func_name);
+    }
 }
 
 // Returns 1 if successful