diff --git a/code/grime_memory_tracker.odin b/code/grime_memory_tracker.odin index 4de4ecc..ff9e9b9 100644 --- a/code/grime_memory_tracker.odin +++ b/code/grime_memory_tracker.odin @@ -10,14 +10,30 @@ MemoryTracker :: struct { entries : Array(MemoryTrackerEntry), } +Track_Memory :: true + +tracker_msg_buffer : [Kilobyte * 64]u8 + memtracker_clear :: proc ( tracker : MemoryTracker ) { - // logf("Clearing tracker: %v", tracker.name) + when ! Track_Memory { + return + } + temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:]) + context.temp_allocator = arena_allocator(& temp_arena) + + logf("Clearing tracker: %v", tracker.name) memtracker_dump_entries(tracker); array_clear(tracker.entries) } memtracker_init :: proc ( tracker : ^MemoryTracker, allocator : Allocator, num_entries : u64, name : string ) { + when ! Track_Memory { + return + } + temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:]) + context.temp_allocator = arena_allocator(& temp_arena) + tracker.name = name error : AllocatorError @@ -29,6 +45,13 @@ memtracker_init :: proc ( tracker : ^MemoryTracker, allocator : Allocator, num_e memtracker_register :: proc( tracker : ^MemoryTracker, new_entry : MemoryTrackerEntry ) { + when ! Track_Memory { + return + } + profile(#procedure) + temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:]) + context.temp_allocator = arena_allocator(& temp_arena) + if tracker.entries.num == tracker.entries.capacity { ensure(false, "Memory tracker entries array full, can no longer register any more allocations") return @@ -48,21 +71,27 @@ memtracker_register :: proc( tracker : ^MemoryTracker, new_entry : MemoryTracker memtracker_dump_entries(tracker ^) } array_append_at( & tracker.entries, new_entry, idx ) - // log(str_fmt_tmp("%v : Registered: %v", tracker.name, new_entry) ) + log(str_fmt_tmp("%v : Registered: %v", tracker.name, new_entry) ) return } array_append( & tracker.entries, new_entry ) - // log(str_fmt_tmp("%v : Registered: %v", tracker.name, new_entry) ) + log(str_fmt_tmp("%v : Registered: %v", tracker.name, new_entry) ) } memtracker_register_auto_name :: proc( tracker : ^MemoryTracker, start, end : rawptr ) { + when ! Track_Memory { + return + } memtracker_register( tracker, {start, end}) } memtracker_register_auto_name_slice :: proc( tracker : ^MemoryTracker, slice : []byte ) { + when ! Track_Memory { + return + } start := raw_data(slice) end := & slice[ len(slice) - 1 ] memtracker_register( tracker, {start, end}) @@ -70,13 +99,20 @@ memtracker_register_auto_name_slice :: proc( tracker : ^MemoryTracker, slice : [ memtracker_unregister :: proc( tracker : MemoryTracker, to_remove : MemoryTrackerEntry ) { + when ! Track_Memory { + return + } + profile(#procedure) + temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:]) + context.temp_allocator = arena_allocator(& temp_arena) + entries := array_to_slice_num(tracker.entries) for idx in 0..< tracker.entries.num { entry := & entries[idx] if entry.start == to_remove.start { if (entry.end == to_remove.end || to_remove.end == nil) { - // log(str_fmt_tmp("%v: Unregistered: %v", tracker.name, to_remove)); + log(str_fmt_tmp("%v: Unregistered: %v", tracker.name, to_remove)); array_remove_at(tracker.entries, idx) return } @@ -92,8 +128,14 @@ memtracker_unregister :: proc( tracker : MemoryTracker, to_remove : MemoryTracke memtracker_check_for_collisions :: proc ( tracker : MemoryTracker ) { - entries := array_to_slice_num(tracker.entries) + when ! Track_Memory { + return + } + profile(#procedure) + temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:]) + context.temp_allocator = arena_allocator(& temp_arena) + entries := array_to_slice_num(tracker.entries) for idx in 1 ..< tracker.entries.num { // Check to make sure each allocations adjacent entries do not intersect left := & entries[idx - 1] @@ -109,6 +151,12 @@ memtracker_check_for_collisions :: proc ( tracker : MemoryTracker ) memtracker_dump_entries :: proc( tracker : MemoryTracker ) { + when ! Track_Memory { + return + } + temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:]) + context.temp_allocator = arena_allocator(& temp_arena) + log( "Dumping Memory Tracker:") for idx in 0 ..< tracker.entries.num { entry := & tracker.entries.data[idx] diff --git a/code/grime_pool_allocator.odin b/code/grime_pool_allocator.odin index 715cf29..d7ba31d 100644 --- a/code/grime_pool_allocator.odin +++ b/code/grime_pool_allocator.odin @@ -73,7 +73,9 @@ pool_init :: proc ( pool.bucket_capacity = bucket_capacity pool.alignment = alignment - memtracker_init( & pool.tracker, allocator, Kilobyte * 96, dbg_name ) + when ODIN_DEBUG { + memtracker_init( & pool.tracker, allocator, Kilobyte * 96, dbg_name ) + } if bucket_reserve_num > 0 { alloc_error = pool_allocate_buckets( pool, bucket_reserve_num ) @@ -99,7 +101,9 @@ pool_destroy :: proc ( using self : Pool ) free( self.header, backing ) - memtracker_clear( self.tracker ) + when ODIN_DEBUG { + memtracker_clear( self.tracker ) + } } pool_allocate_buckets :: proc( pool : Pool, num_buckets : uint ) -> AllocatorError @@ -164,7 +168,10 @@ pool_grab :: proc( pool : Pool, zero_memory := false ) -> ( block : []byte, allo { pool := pool if pool.current_bucket != nil { - verify( pool.current_bucket.blocks != nil, str_fmt_tmp("(corruption) current_bucket was wiped %p", pool.current_bucket) ) + if ( pool.current_bucket.blocks == nil ) { + ensure( false, str_fmt_tmp("(corruption) current_bucket was wiped %p", pool.current_bucket) ) + } + // verify( pool.current_bucket.blocks != nil, str_fmt_tmp("(corruption) current_bucket was wiped %p", pool.current_bucket) ) } // profile(#procedure) alloc_error = .None @@ -185,7 +192,9 @@ pool_grab :: proc( pool : Pool, zero_memory := false ) -> ( block : []byte, allo slice.zero(block) } - memtracker_register_auto_name_slice( & pool.tracker, block) + when ODIN_DEBUG { + memtracker_register_auto_name_slice( & pool.tracker, block) + } return } @@ -246,7 +255,9 @@ pool_grab :: proc( pool : Pool, zero_memory := false ) -> ( block : []byte, allo // log( str_fmt_tmp("Zeroed memory - Range(%p to %p)", block_ptr, cast(rawptr) (uintptr(block_ptr) + uintptr(pool.block_size)))) } - memtracker_register_auto_name_slice( & pool.tracker, block) + when ODIN_DEBUG { + memtracker_register_auto_name_slice( & pool.tracker, block) + } return } @@ -275,7 +286,9 @@ pool_release :: proc( self : Pool, block : []byte, loc := #caller_location ) start := new_free_block end := transmute(rawptr) (uintptr(new_free_block) + uintptr(self.block_size) - 1) - memtracker_unregister( self.tracker, { start, end } ) + when ODIN_DEBUG { + memtracker_unregister( self.tracker, { start, end } ) + } } pool_reset :: proc( using pool : Pool ) @@ -297,7 +310,9 @@ pool_validate :: proc( pool : Pool ) // Compiler bug ^^ same as pool_reset for ; bucket != nil; bucket = bucket.next { - verify( bucket.blocks != nil, str_fmt_tmp("Found corrupted bucket %p", bucket) ) + if ( bucket.blocks == nil ) { + ensure(false, str_fmt_tmp("Found a corrupted bucket %p", bucket )) + } } } @@ -314,7 +329,8 @@ pool_validate_ownership :: proc( using self : Pool, block : [] byte ) -> b32 end := start + uintptr(bucket_capacity) block_address := uintptr(raw_data(block)) - if start <= block_address && block_address < end { + if start <= block_address && block_address < end + { misalignment := (block_address - start) % uintptr(block_size) if misalignment != 0 { ensure(false, "pool_validate_ownership: This data is within this pool's buckets, however its not aligned to the start of a block") diff --git a/code/grime_slab_allocator.odin b/code/grime_slab_allocator.odin index 07f09f4..e567dce 100644 --- a/code/grime_slab_allocator.odin +++ b/code/grime_slab_allocator.odin @@ -70,7 +70,9 @@ slab_init :: proc( policy : ^SlabPolicy, bucket_reserve_num : uint = 0, allocato slab.header = cast( ^SlabHeader) raw_mem slab.backing = allocator slab.dbg_name = dbg_name - memtracker_init( & slab.tracker, allocator, Kilobyte * 256, dbg_name ) + when ODIN_DEBUG { + memtracker_init( & slab.tracker, allocator, Kilobyte * 256, dbg_name ) + } alloc_error = slab_init_pools( slab, policy, bucket_reserve_num, should_zero_buckets ) return } @@ -109,7 +111,9 @@ slab_destroy :: proc( using self : Slab ) } free( self.header, backing ) - memtracker_clear(tracker) + when ODIN_DEBUG { + memtracker_clear(tracker) + } } slab_alloc :: proc( self : Slab, @@ -148,7 +152,9 @@ slab_alloc :: proc( self : Slab, slice.zero(data) } - memtracker_register_auto_name( & self.tracker, raw_data(block), & block[ len(block) - 1 ] ) + when ODIN_DEBUG { + memtracker_register_auto_name( & self.tracker, raw_data(block), & block[ len(block) - 1 ] ) + } return } @@ -162,7 +168,11 @@ slab_free :: proc( using self : Slab, data : []byte, loc := #caller_location ) if pool_validate_ownership( pool, data ) { start := raw_data(data) end := ptr_offset(start, pool.block_size - 1) - memtracker_unregister( self.tracker, { start, end } ) + + when ODIN_DEBUG { + memtracker_unregister( self.tracker, { start, end } ) + } + pool_release( pool, data, loc ) return } @@ -248,11 +258,16 @@ slab_resize :: proc( using self : Slab, start := raw_data( data ) end := rawptr(uintptr(start) + uintptr(pool_old.block_size) - 1) - memtracker_unregister( self.tracker, { start, end } ) + + when ODIN_DEBUG { + memtracker_unregister( self.tracker, { start, end } ) + } } new_data = new_block[ :new_size] - memtracker_register_auto_name( & self.tracker, raw_data(new_block), & new_block[ len(new_block) - 1 ] ) + when ODIN_DEBUG { + memtracker_register_auto_name( & self.tracker, raw_data(new_block), & new_block[ len(new_block) - 1 ] ) + } return } @@ -262,7 +277,9 @@ slab_reset :: proc( slab : Slab ) pool := slab.pools.items[id] pool_reset( pool ) } - memtracker_clear(slab.tracker) + when ODIN_DEBUG { + memtracker_clear(slab.tracker) + } } slab_validate_pools :: proc( slab : Slab ) diff --git a/code/grime_string_interning.odin b/code/grime_string_interning.odin index 9cc757d..07317f2 100644 --- a/code/grime_string_interning.odin +++ b/code/grime_string_interning.odin @@ -61,7 +61,7 @@ str_cache_init :: proc( /*allocator : Allocator*/ ) -> ( cache : StringCache ) { cache.slab, alloc_error = slab_init( & policy, allocator = persistent_allocator(), dbg_name = dbg_name ) verify(alloc_error == .None, "Failed to initialize the string cache" ) - // cache.table, alloc_error = zpl_hmap_init_reserve( StringCached, persistent_slab_allocator(), 4 * Kilobyte ) + // cache.table, alloc_error = zpl_hmap_init_reserve( StringCached, persistent_slab_allocator(), 4 * Kilobyte, dbg_name ) cache.table, alloc_error = zpl_hmap_init_reserve( StringCached, persistent_slab_allocator(), 8, dbg_name ) return } diff --git a/code/grime_virtual_arena.odin b/code/grime_virtual_arena.odin index 9830611..d942480 100644 --- a/code/grime_virtual_arena.odin +++ b/code/grime_virtual_arena.odin @@ -88,8 +88,9 @@ varena_init :: proc( base_address : uintptr, to_reserve, to_commit : uint, } arena.allow_any_reize = allow_any_reize - // Setup the tracker - memtracker_init( & arena.tracker, runtime.heap_allocator(), Kilobyte * 128, dbg_name ) + when ODIN_DEBUG { + memtracker_init( & arena.tracker, runtime.heap_allocator(), Kilobyte * 128, dbg_name ) + } return } @@ -175,7 +176,7 @@ varena_free_all :: proc( using self : ^VArena ) sync.mutex_guard( & mutex ) commit_used = 0 - when ODIN_DEBUG { + when ODIN_DEBUG && Track_Memory { array_clear(tracker.entries) } } diff --git a/code/parser_whitespace.odin b/code/parser_whitespace.odin index 2e03583..df8ee13 100644 --- a/code/parser_whitespace.odin +++ b/code/parser_whitespace.odin @@ -165,7 +165,8 @@ pws_parser_lex :: proc ( text : string, allocator : Allocator ) -> ( PWS_LexResu } alloc_error : AllocatorError - tokens, alloc_error = array_init_reserve( PWS_Token, allocator, Kilobyte * 4 ) + // tokens, alloc_error = array_init_reserve( PWS_Token, allocator, Kilobyte * 4 ) + tokens, alloc_error = array_init_reserve( PWS_Token, allocator, PWS_TokenArray_ReserveSize ) if alloc_error != AllocatorError.None { ensure(false, "Failed to allocate token's array") return result, alloc_error