artifact_cache: fix leak of old-generation artifacts, when those artifacts are replaced by newer generation computations. artifacts can opaquely hold things like arena pointers, and so when we replace them in the cache, we need to respect the lookup api's provision of create/destroy hooks for the cache, such that the artifacts can be released correctly (using the destroy hook) before being replaced. this is separate from regular eviction.

This commit is contained in:
Ryan Fleury committed 2026-05-11 11:49:15 -07:00
1 parent 6a95da35e0
commit 52da228efe
8 files changed
+157 -24

No files matched your search

+79 -1
View File
@@ -1,6 +1,25 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Global Arena Table
#if ARENA_TABLE_DEBUG
typedef struct ArenaTableNode ArenaTableNode;
struct ArenaTableNode
{
ArenaTableNode *next;
Arena *arena;
};
global U64 arena_table_take_init = 0;
global U64 arena_table_inited = 0;
global U64 arena_table_lock = 0;
global ArenaTableNode *arena_table = 0;
global U64 arena_table_count = 0;
global U64 arena_table_cap = 0;
global ArenaTableNode *free_arena_table_node = 0;
#endif
////////////////////////////////
//~ rjf: Arena Functions
@@ -8,7 +27,7 @@
internal Arena *
arena_alloc_(ArenaParams *params)
{
{
U64 reserve_size = params->reserve_size;
U64 commit_size = params->commit_size;
@@ -73,6 +92,47 @@ arena_alloc_(ArenaParams *params)
#if ARENA_FREE_LIST
arena->free_last = 0;
#endif
// rjf: store in global arena table
#if ARENA_TABLE_DEBUG
if(ins_atomic_u64_eval_cond_assign(&arena_table_take_init, 1, 0) == 0)
{
arena_table = reserve_memory(GB(256));
arena_table_cap = 4096;
commit_memory(arena_table, arena_table_cap * sizeof(arena_table[0]));
ins_atomic_u64_inc_eval(&arena_table_inited);
}
for(;!ins_atomic_u64_eval(&arena_table_inited);) {}
for(;;)
{
B32 got_lock = (ins_atomic_u64_eval_cond_assign(&arena_table_lock, 1, 0) == 0);
if(got_lock)
{
ArenaTableNode *node = free_arena_table_node;
if(node != 0)
{
SLLStackPop(free_arena_table_node);
}
else
{
node = &arena_table[arena_table_count];
if(arena_table_count >= arena_table_cap)
{
U64 arena_table_cap__pre_grow = arena_table_cap;
arena_table_cap *= 2;
U64 arena_table_cap__post_grow = arena_table_cap;
commit_memory(arena_table + arena_table_cap__pre_grow, sizeof(arena_table[0]) * (arena_table_cap__post_grow - arena_table_cap__pre_grow));
}
arena_table_count += 1;
}
node->arena = arena;
arena->table_node = node;
ins_atomic_u64_eval_assign(&arena_table_lock, 0);
break;
}
}
#endif
return arena;
}
@@ -87,6 +147,24 @@ arena_release(Arena *arena)
}
#endif
#if ARENA_TABLE_DEBUG
for(Arena *n = arena->current; n != 0; n = n->prev)
{
for(;;)
{
B32 got_lock = (ins_atomic_u64_eval_cond_assign(&arena_table_lock, 1, 0) == 0);
if(got_lock)
{
ArenaTableNode *table_node = n->table_node;
MemoryZeroStruct(table_node);
SLLStackPush(free_arena_table_node, table_node);
ins_atomic_u64_eval_assign(&arena_table_lock, 0);
break;
}
}
}
#endif
for(Arena *n = arena->current, *prev = 0; n != 0; n = prev)
{
prev = n->prev;