From e11ee2633269dfbd6be3a1f521bb2d668a8c7a01 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Sat, 15 Jun 2024 20:26:34 -0700 Subject: [PATCH] Allow stack to grow in gc The previous bound was valid in each logical version of the map, but not for the physical map's structure. --- VersionedMap.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/VersionedMap.cpp b/VersionedMap.cpp index 13606d7..c4109ea 100644 --- a/VersionedMap.cpp +++ b/VersionedMap.cpp @@ -285,9 +285,11 @@ struct MemManager { void gc(const uint32_t *roots, int numRoots, int64_t oldestVersion) { // Calculate reachable set BitSet reachable{next}; - // Each node has at most 3 children and nodes along the search path aren't - // in the stack, so we need 2 * kPathLengthUpperBound - uint32_t stack[2 * kPathLengthUpperBound]; + Arena arena; + constexpr int kInitialStackCapacity = 128; + int64_t stackCapacity = kInitialStackCapacity; + uint32_t stackStack[kInitialStackCapacity]; + uint32_t *stack = stackStack; int stackIndex = 0; auto tryPush = [&]([[maybe_unused]] uint32_t parent, uint32_t child) { if (!reachable.set(child)) { @@ -296,7 +298,12 @@ struct MemManager { printf(" GC: reach: %u (parent %u)\n", child, parent); } #endif - assert(stackIndex < int(sizeof(stack) / sizeof(stack[0]))); + if (stackIndex == stackCapacity) [[unlikely]] { + auto *old = stack; + stackCapacity *= 2; + stack = new (arena) uint32_t[stackCapacity]; + memcpy(stack, old, stackIndex * sizeof(stack[0])); + } stack[stackIndex++] = child; } };