Handmade Hero»Episode Guide
Adding Memory Usage Visualization
?
?

Keyboard Navigation

Global Keys

[, < / ], > Jump to previous / next episode
W, K, P / S, J, N Jump to previous / next marker
t / T Toggle theatre / SUPERtheatre mode
V Revert filter to original state Y Select link (requires manual Ctrl-c)

Menu toggling

q Quotes r References f Filter y Link c Credits

In-Menu Movement

a
w
s
d
h j k l


Quotes and References Menus

Enter Jump to timecode

Quotes, References and Credits Menus

o Open URL (in new tab)

Filter Menu

x, Space Toggle category and focus next
X, ShiftSpace Toggle category and focus previous
v Invert topics / media as per focus

Filter and Link Menus

z Toggle filter / linking mode

Credits Menu

Enter Open URL (in new tab)
0:03Welcome to the stream
🗩
0:03Welcome to the stream
🗩
0:03Welcome to the stream
🗩
0:55kim_jorgensen Q: There is a small compile error with Clang: "extra tokens at end of #endif" in handmade_import.cpp (#endif HANDMADE_INTERNAL). Could you fix this?
🗪
0:55kim_jorgensen Q: There is a small compile error with Clang: "extra tokens at end of #endif" in handmade_import.cpp (#endif HANDMADE_INTERNAL). Could you fix this?
🗪
0:55kim_jorgensen Q: There is a small compile error with Clang: "extra tokens at end of #endif" in handmade_import.cpp (#endif HANDMADE_INTERNAL). Could you fix this?
🗪
1:49Remove HANDMADE_INTERNAL from the #endif
1:49Remove HANDMADE_INTERNAL from the #endif
1:49Remove HANDMADE_INTERNAL from the #endif
2:11kim_jorgensen Q. Yes
🗪
2:11kim_jorgensen Q. Yes
🗪
2:11kim_jorgensen Q. Yes
🗪
2:37Recap our new debug-ready Push*() functions and set the stage for the day using their file and line number information and tracking memory
🗩
2:37Recap our new debug-ready Push*() functions and set the stage for the day using their file and line number information and tracking memory
🗩
2:37Recap our new debug-ready Push*() functions and set the stage for the day using their file and line number information and tracking memory
🗩
8:28Embark on memory tracking, introducing DEBUG_RECORD_ALLOCATION(), DEBUG_RECORD_BLOCK_FREE(), DEBUG_RECORD_BLOCK_TRUNCATE() and DEBUG_ARENA_NAME()
8:28Embark on memory tracking, introducing DEBUG_RECORD_ALLOCATION(), DEBUG_RECORD_BLOCK_FREE(), DEBUG_RECORD_BLOCK_TRUNCATE() and DEBUG_ARENA_NAME()
8:28Embark on memory tracking, introducing DEBUG_RECORD_ALLOCATION(), DEBUG_RECORD_BLOCK_FREE(), DEBUG_RECORD_BLOCK_TRUNCATE() and DEBUG_ARENA_NAME()
16:40Introduce debug_arena_allocation, debug_arena_block and debug_arena as a mirror of the real memory arenas
16:40Introduce debug_arena_allocation, debug_arena_block and debug_arena as a mirror of the real memory arenas
16:40Introduce debug_arena_allocation, debug_arena_block and debug_arena as a mirror of the real memory arenas
20:55Consider cleaning up our debug system in a more purpose-built way
🗩
20:55Consider cleaning up our debug system in a more purpose-built way
🗩
20:55Consider cleaning up our debug system in a more purpose-built way
🗩
21:24The importance of thread-awareness in a debug system
🗩
21:24The importance of thread-awareness in a debug system
🗩
21:24The importance of thread-awareness in a debug system
🗩
23:21#define internal and non-internal versions of DEBUG_RECORD_ALLOCATION(), DEBUG_RECORD_BLOCK_FREE(), DEBUG_RECORD_BLOCK_TRUNCATE() and DEBUG_ARENA_NAME()
23:21#define internal and non-internal versions of DEBUG_RECORD_ALLOCATION(), DEBUG_RECORD_BLOCK_FREE(), DEBUG_RECORD_BLOCK_TRUNCATE() and DEBUG_ARENA_NAME()
23:21#define internal and non-internal versions of DEBUG_RECORD_ALLOCATION(), DEBUG_RECORD_BLOCK_FREE(), DEBUG_RECORD_BLOCK_TRUNCATE() and DEBUG_ARENA_NAME()
26:45Implement our memory DEBUG*() macros, recording operations into the debug events stream, from which the debug system may pull them
26:45Implement our memory DEBUG*() macros, recording operations into the debug events stream, from which the debug system may pull them
26:45Implement our memory DEBUG*() macros, recording operations into the debug events stream, from which the debug system may pull them
41:53Change the Push*() functions to get their __FILE__ and __LINE__ from a DEBUG_NAME(), noting the differing treatment of string concatenation by GCC and Visual Studio1
41:53Change the Push*() functions to get their __FILE__ and __LINE__ from a DEBUG_NAME(), noting the differing treatment of string concatenation by GCC and Visual Studio1
41:53Change the Push*() functions to get their __FILE__ and __LINE__ from a DEBUG_NAME(), noting the differing treatment of string concatenation by GCC and Visual Studio1
44:56Fix up macro-related compile errors, and remove DebugType_memory_arena_p
44:56Fix up macro-related compile errors, and remove DebugType_memory_arena_p
44:56Fix up macro-related compile errors, and remove DebugType_memory_arena_p
53:31Set up CollateDebugRecords() to handle our new memory debug types
53:31Set up CollateDebugRecords() to handle our new memory debug types
53:31Set up CollateDebugRecords() to handle our new memory debug types
54:56Find that the game continues to play fine
🏃
54:56Find that the game continues to play fine
🏃
54:56Find that the game continues to play fine
🏃
55:17Introduce DEBUGArenaSetName(), DEBUGArenaBlockFree(), DEBUGArenaBlockTruncate() and DEBUGArenaAllocate() for CollateDebugRecords() to call
55:17Introduce DEBUGArenaSetName(), DEBUGArenaBlockFree(), DEBUGArenaBlockTruncate() and DEBUGArenaAllocate() for CollateDebugRecords() to call
55:17Introduce DEBUGArenaSetName(), DEBUGArenaBlockFree(), DEBUGArenaBlockTruncate() and DEBUGArenaAllocate() for CollateDebugRecords() to call
1:09:25Implement DEBUGArenaBlockTruncate(), introducing DEBUGMoveToFreeList()
1:09:25Implement DEBUGArenaBlockTruncate(), introducing DEBUGMoveToFreeList()
1:09:25Implement DEBUGArenaBlockTruncate(), introducing DEBUGMoveToFreeList()
1:20:30Implement DEBUGArenaAllocate() and introduce DEBUG_RECORD_BLOCK_ALLOCATION()
1:20:30Implement DEBUGArenaAllocate() and introduce DEBUG_RECORD_BLOCK_ALLOCATION()
1:20:30Implement DEBUGArenaAllocate() and introduce DEBUG_RECORD_BLOCK_ALLOCATION()
1:35:11Fix up compile errors
1:35:11Fix up compile errors
1:35:11Fix up compile errors
1:39:54Implement DEBUGGetArenaByPointer()
1:39:54Implement DEBUGGetArenaByPointer()
1:39:54Implement DEBUGGetArenaByPointer()
1:42:58Hit our Block->MemoryAddress == UMMFromPointer(Op->Block) assertion in DEBUGArenaAllocate() and investigate why
🏃
1:42:58Hit our Block->MemoryAddress == UMMFromPointer(Op->Block) assertion in DEBUGArenaAllocate() and investigate why
🏃
1:42:58Hit our Block->MemoryAddress == UMMFromPointer(Op->Block) assertion in DEBUGArenaAllocate() and investigate why
🏃
1:45:45Try out remedybg's value locking functionality
🗹
1:45:45Try out remedybg's value locking functionality
🗹
1:45:45Try out remedybg's value locking functionality
🗹
1:47:49remedybg feature request: Savable variable values
🗹
1:47:49remedybg feature request: Savable variable values
🗹
1:47:49remedybg feature request: Savable variable values
🗹
1:49:28Continue to investigate our debug memory arena assertion hit
🏃
1:49:28Continue to investigate our debug memory arena assertion hit
🏃
1:49:28Continue to investigate our debug memory arena assertion hit
🏃
1:58:20Realise that memory arenas move around upon growing, and consider how to handle such moves
🗩
1:58:20Realise that memory arenas move around upon growing, and consider how to handle such moves
🗩
1:58:20Realise that memory arenas move around upon growing, and consider how to handle such moves
🗩
2:01:48Tentatively introduce MoveArena() and DEBUG_MEMORY_MOVE_ARENA()
2:01:48Tentatively introduce MoveArena() and DEBUG_MEMORY_MOVE_ARENA()
2:01:48Tentatively introduce MoveArena() and DEBUG_MEMORY_MOVE_ARENA()
2:03:56Enable the debug system to handle memory reallocations by respecifying DEBUGGetArenaByPointer() as DEBUGGetArenaByLookupBlock(), and augmenting the debug_memory_op with an ArenaLookupBlock
2:03:56Enable the debug system to handle memory reallocations by respecifying DEBUGGetArenaByPointer() as DEBUGGetArenaByLookupBlock(), and augmenting the debug_memory_op with an ArenaLookupBlock
2:03:56Enable the debug system to handle memory reallocations by respecifying DEBUGGetArenaByPointer() as DEBUGGetArenaByLookupBlock(), and augmenting the debug_memory_op with an ArenaLookupBlock
2:18:48Fix compile errors
2:18:48Fix compile errors
2:18:48Fix compile errors
2:22:29Introduce DEBUGRemoveArena()
2:22:29Introduce DEBUGRemoveArena()
2:22:29Introduce DEBUGRemoveArena()
2:26:05Hit our assertion in DEBUGMoveToFreeList() and investigate why
🏃
2:26:05Hit our assertion in DEBUGMoveToFreeList() and investigate why
🏃
2:26:05Hit our assertion in DEBUGMoveToFreeList() and investigate why
🏃
2:27:37Fix typo in DEBUGArenaAllocate()
2:27:37Fix typo in DEBUGArenaAllocate()
2:27:37Fix typo in DEBUGArenaAllocate()
2:27:54Hit our Block->MemoryAddress == UMMFromPointer(Op->Block) assertion in DEBUGArenaAllocate() due to the arena containing no blocks
🏃
2:27:54Hit our Block->MemoryAddress == UMMFromPointer(Op->Block) assertion in DEBUGArenaAllocate() due to the arena containing no blocks
🏃
2:27:54Hit our Block->MemoryAddress == UMMFromPointer(Op->Block) assertion in DEBUGArenaAllocate() due to the arena containing no blocks
🏃
2:28:47Disallow creation of memory blocks by all functions except DEBUGArenaBlockAllocate()
2:28:47Disallow creation of memory blocks by all functions except DEBUGArenaBlockAllocate()
2:28:47Disallow creation of memory blocks by all functions except DEBUGArenaBlockAllocate()
2:29:55Hit our new AllowCreation assertion in DEBUGGetArenaByLookupBlock() and investigate why
🏃
2:29:55Hit our new AllowCreation assertion in DEBUGGetArenaByLookupBlock() and investigate why
🏃
2:29:55Hit our new AllowCreation assertion in DEBUGGetArenaByLookupBlock() and investigate why
🏃
2:41:27Fix DEBUGGetArenaByLookupBlock() to correctly set the state of a reused arena
2:41:27Fix DEBUGGetArenaByLookupBlock() to correctly set the state of a reused arena
2:41:27Fix DEBUGGetArenaByLookupBlock() to correctly set the state of a reused arena
2:41:48Find that the game may be leaking memory
🏃
2:41:48Find that the game may be leaking memory
🏃
2:41:48Find that the game may be leaking memory
🏃
2:42:56Scour the code for our apparent memory leak
📖
2:42:56Scour the code for our apparent memory leak
📖
2:42:56Scour the code for our apparent memory leak
📖
2:51:59Realise that, since the debug system uses memory arenas, it's just recording its own arena allocations
📖
2:51:59Realise that, since the debug system uses memory arenas, it's just recording its own arena allocations
📖
2:51:59Realise that, since the debug system uses memory arenas, it's just recording its own arena allocations
📖
2:53:40Prevent the debug system from recording its own allocations, introducing DEBUG_ARENA_SUPPRESS()
2:53:40Prevent the debug system from recording its own allocations, introducing DEBUG_ARENA_SUPPRESS()
2:53:40Prevent the debug system from recording its own allocations, introducing DEBUG_ARENA_SUPPRESS()
3:01:57Hit our AllowCreation assertion in DEBUGGetArenaByLookupBlock() and investigate why
🏃
3:01:57Hit our AllowCreation assertion in DEBUGGetArenaByLookupBlock() and investigate why
🏃
3:01:57Hit our AllowCreation assertion in DEBUGGetArenaByLookupBlock() and investigate why
🏃
3:03:07Let the debug system only track memory blocks, just not its own suppressed allocations
3:03:07Let the debug system only track memory blocks, just not its own suppressed allocations
3:03:07Let the debug system only track memory blocks, just not its own suppressed allocations
3:04:31Find that the game now has more stable memory usage
🏃
3:04:31Find that the game now has more stable memory usage
🏃
3:04:31Find that the game now has more stable memory usage
🏃
3:06:18Add a memory group in DEBUGInit()
3:06:18Add a memory group in DEBUGInit()
3:06:18Add a memory group in DEBUGInit()
3:11:32Check out our blank memory viewer
🏃
3:11:32Check out our blank memory viewer
🏃
3:11:32Check out our blank memory viewer
🏃
3:13:05Set up the UI to display our memory arenas, frames and sizes
3:13:05Set up the UI to display our memory arenas, frames and sizes
3:13:05Set up the UI to display our memory arenas, frames and sizes
3:22:32Add a "Top Memory" list to the UI, introducing DrawTopMemList()
3:22:32Add a "Top Memory" list to the UI, introducing DrawTopMemList()
3:22:32Add a "Top Memory" list to the UI, introducing DrawTopMemList()
3:36:05Find that we display nothing
🏃
3:36:05Find that we display nothing
🏃
3:36:05Find that we display nothing
🏃
3:36:21Make DEBUGDrawElement() call DrawTopMemList()
3:36:21Make DEBUGDrawElement() call DrawTopMemList()
3:36:21Make DEBUGDrawElement() call DrawTopMemList()
3:37:36Hit our "Unrecognized format specifier" assertion from DrawTopMemList()
🏃
3:37:36Hit our "Unrecognized format specifier" assertion from DrawTopMemList()
🏃
3:37:36Hit our "Unrecognized format specifier" assertion from DrawTopMemList()
🏃
3:38:09Fix format string in DrawTopMemList()
3:38:09Fix format string in DrawTopMemList()
3:38:09Fix format string in DrawTopMemList()
3:38:20Check out our memory sizes viewer
🏃
3:38:20Check out our memory sizes viewer
🏃
3:38:20Check out our memory sizes viewer
🏃
3:40:32Change DEBUG_ARENA_SUPPRESS() to take a Name
3:40:32Change DEBUG_ARENA_SUPPRESS() to take a Name
3:40:32Change DEBUG_ARENA_SUPPRESS() to take a Name
3:41:47Check out our named debug system arena in the UI
🏃
3:41:47Check out our named debug system arena in the UI
🏃
3:41:47Check out our named debug system arena in the UI
🏃
3:42:14Add a memory occupancy viewer to the UI, introducing DrawArenaInterval()
3:42:14Add a memory occupancy viewer to the UI, introducing DrawArenaInterval()
3:42:14Add a memory occupancy viewer to the UI, introducing DrawArenaInterval()
4:00:43Crash 4coder after switching to the left-hand pane and typing something
🗹
4:00:43Crash 4coder after switching to the left-hand pane and typing something
🗹
4:00:43Crash 4coder after switching to the left-hand pane and typing something
🗹
4:01:45Retype and continue to implement DrawArenaInterval()
4:01:45Retype and continue to implement DrawArenaInterval()
4:01:45Retype and continue to implement DrawArenaInterval()
4:12:15Fail to see our memory arena visualisation
🏃
4:12:15Fail to see our memory arena visualisation
🏃
4:12:15Fail to see our memory arena visualisation
🏃
4:13:45Fix DrawArenaInterval() to increment the BlockIndex and draw the block rectangles
4:13:45Fix DrawArenaInterval() to increment the BlockIndex and draw the block rectangles
4:13:45Fix DrawArenaInterval() to increment the BlockIndex and draw the block rectangles
4:14:59See our block rectangle
🏃
4:14:59See our block rectangle
🏃
4:14:59See our block rectangle
🏃
4:15:10Briefly scour DrawArenaInterval() for bugs
📖
4:15:10Briefly scour DrawArenaInterval() for bugs
📖
4:15:10Briefly scour DrawArenaInterval() for bugs
📖
4:16:32Step in to DrawArenaInterval() and inspect its values
🏃
4:16:32Step in to DrawArenaInterval() and inspect its values
🏃
4:16:32Step in to DrawArenaInterval() and inspect its values
🏃
4:19:24Prevent DrawArenaInterval() from drawing suppressed blocks, and make it offset the BlockRect by the ProfileRect
4:19:24Prevent DrawArenaInterval() from drawing suppressed blocks, and make it offset the BlockRect by the ProfileRect
4:19:24Prevent DrawArenaInterval() from drawing suppressed blocks, and make it offset the BlockRect by the ProfileRect
4:20:10Find that we're properly sizing the block rectangle, but not moving it along
🏃
4:20:10Find that we're properly sizing the block rectangle, but not moving it along
🏃
4:20:10Find that we're properly sizing the block rectangle, but not moving it along
🏃
4:21:01Make DrawArenaInterval() apply an outline to the BlockRect
4:21:01Make DrawArenaInterval() apply an outline to the BlockRect
4:21:01Make DrawArenaInterval() apply an outline to the BlockRect
4:22:39Check out our two, outlined block rects, and step through DrawArenaInterval()
🏃
4:22:39Check out our two, outlined block rects, and step through DrawArenaInterval()
🏃
4:22:39Check out our two, outlined block rects, and step through DrawArenaInterval()
🏃
4:24:08Make DrawArenaInterval() compute the correct dimensions of the RegionRect
4:24:08Make DrawArenaInterval() compute the correct dimensions of the RegionRect
4:24:08Make DrawArenaInterval() compute the correct dimensions of the RegionRect
4:26:19Continue to step through DrawArenaInterval() to see that we Suppress memory allocations for the Game Mode
🏃
4:26:19Continue to step through DrawArenaInterval() to see that we Suppress memory allocations for the Game Mode
🏃
4:26:19Continue to step through DrawArenaInterval() to see that we Suppress memory allocations for the Game Mode
🏃
4:27:48Make DEBUG_ARENA_NAME() set the AllocatedSize to 0
4:27:48Make DEBUG_ARENA_NAME() set the AllocatedSize to 0
4:27:48Make DEBUG_ARENA_NAME() set the AllocatedSize to 0
4:28:02Check out our memory Arenas viewer
🏃
4:28:02Check out our memory Arenas viewer
🏃
4:28:02Check out our memory Arenas viewer
🏃
4:29:52Comment out the ground_cover from the entity struct
4:29:52Comment out the ground_cover from the entity struct
4:29:52Comment out the ground_cover from the entity struct
4:30:33Check out our memory Arenas viewer, absent the ground_cover
🏃
4:30:33Check out our memory Arenas viewer, absent the ground_cover
🏃
4:30:33Check out our memory Arenas viewer, absent the ground_cover
🏃
4:31:00Uncomment the ground_cover in the entity struct
4:31:00Uncomment the ground_cover in the entity struct
4:31:00Uncomment the ground_cover in the entity struct
4:31:06Check out our memory Arenas viewer, including the ground_cover
🏃
4:31:06Check out our memory Arenas viewer, including the ground_cover
🏃
4:31:06Check out our memory Arenas viewer, including the ground_cover
🏃
4:32:15Q&A
🗩
4:32:15Q&A
🗩
4:32:15Q&A
🗩
4:32:58thepr1ms Q: Not on-topic at all but could you just say hi to my friend Thomas Grim who is a fervent follower of yours?
🗪
4:32:58thepr1ms Q: Not on-topic at all but could you just say hi to my friend Thomas Grim who is a fervent follower of yours?
🗪
4:32:58thepr1ms Q: Not on-topic at all but could you just say hi to my friend Thomas Grim who is a fervent follower of yours?
🗪
4:33:54Close it down
🗩
4:33:54Close it down
🗩
4:33:54Close it down
🗩