Skip to content

Commit e128033

Browse files
committed
Avoid circular allocations.
1 parent 702b32d commit e128033

File tree

1 file changed

+12
-13
lines changed

1 file changed

+12
-13
lines changed

src/mini_heap.h

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -143,19 +143,17 @@ class MiniHeap {
143143

144144
public:
145145
MiniHeap(void *arenaBegin, Span span, size_t objectCount, size_t objectSize)
146-
: _bitmap(nullptr),
147-
_span(span),
146+
: _span(span),
148147
_flags(objectCount, objectCount > 1 ? SizeMap::SizeClass(objectSize) : 1, 0, list::Attached),
149148
_objectSizeReciprocal(1.0 / (float)objectSize) {
150-
// Allocate bitmap separately to support larger sizes
151-
_bitmap = new internal::Bitmap(objectCount);
149+
// Allocate bitmap using internal heap (same pattern as bitmap's own allocations)
150+
// This avoids any circular dependencies with Mesh's allocator
151+
void *bitmapMem = internal::Heap().malloc(sizeof(internal::Bitmap));
152+
d_assert(bitmapMem != nullptr);
153+
_bitmap = new (bitmapMem) internal::Bitmap(objectCount);
152154
d_assert(_bitmap != nullptr);
153155
d_assert(_bitmap->inUseCount() == 0);
154156

155-
// Memory fence to ensure bitmap initialization is visible to other threads
156-
// before this MiniHeap is published via trackMiniHeap
157-
std::atomic_thread_fence(std::memory_order_release);
158-
159157
const auto expectedSpanSize = _span.byteLength();
160158
d_assert_msg(expectedSpanSize == spanSize(), "span size %zu == %zu (%u, %u)", expectedSpanSize, spanSize(),
161159
maxCount(), this->objectSize());
@@ -165,7 +163,10 @@ class MiniHeap {
165163

166164
~MiniHeap() {
167165
if (_bitmap != nullptr) {
168-
delete _bitmap;
166+
// Manually call destructor and free memory (since we used placement new)
167+
typedef internal::Bitmap BitmapType;
168+
_bitmap->~BitmapType();
169+
internal::Heap().free(_bitmap);
169170
_bitmap = nullptr;
170171
}
171172
}
@@ -355,14 +356,12 @@ class MiniHeap {
355356
}
356357

357358
const internal::Bitmap &bitmap() const {
358-
// Acquire fence to synchronize with release fence in constructor
359-
std::atomic_thread_fence(std::memory_order_acquire);
359+
d_assert(_bitmap != nullptr);
360360
return *_bitmap;
361361
}
362362

363363
internal::Bitmap &writableBitmap() {
364-
// Acquire fence to synchronize with release fence in constructor
365-
std::atomic_thread_fence(std::memory_order_acquire);
364+
d_assert(_bitmap != nullptr);
366365
return *_bitmap;
367366
}
368367

0 commit comments

Comments
 (0)