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 {
PoolAllocator :: struct (Elem: type_expr) {
buffer : [] Elem;
first_free : ^Elem;
+
+ alloc :: pool_alloc
+ free :: pool_free
}
#local
__output_string("\n");
- __exit(1);
+ // __exit(1);
+ *(cast(^i32) 0xffffffff);
}
// This procedure should only be called once at the very begining
raw_free(alloc.heap_allocator, __tls_base);
thread.__exited(id);
}
-}
\ No newline at end of file
+}
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) {
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