@@ -77,15 +77,35 @@ private:
7777 ThreadBinState[ThreadBinCount] binStates;
7878
7979public :
80+ bool isInitialized () {
81+ return nextAllocationEvent > 0 ;
82+ }
83+
84+ bool ensureThreadCacheIsInitialized () {
85+ if (likely(isInitialized())) {
86+ return false ;
87+ }
88+
89+ initialize(&gExtentMap, &gBase);
90+ return true ;
91+ }
92+
8093 void initialize (shared (ExtentMap)* emap, shared (Base)* base) {
94+ this .emap = CachedExtentMap(emap, base);
95+
96+ // Make sure initialize can be called multiple
97+ // times on the same thread cache.
98+ if (isInitialized()) {
99+ assert (self == pthread_self(), " Invalid pthread_self!" );
100+ return ;
101+ }
102+
81103 self = pthread_self();
82104
83105 nextAllocationEvent = DefaultEventWait;
84106 nextDeallocationEvent = DefaultEventWait;
85107 nextGCRun = DefaultEventWait;
86108
87- this .emap = CachedExtentMap(emap, base);
88-
89109 uint sp = 0 ;
90110 uint i = 0 ;
91111
@@ -340,6 +360,8 @@ private:
340360 void * allocSmallBin (ubyte sizeClass, uint slotSize, bool containsPointers) {
341361 assert (slotSize == binInfos[sizeClass].slotSize, " Invalid slot size!" );
342362
363+ ensureThreadCacheIsInitialized();
364+
343365 auto index = getBinIndex(sizeClass, containsPointers);
344366 auto bin = &bins[index];
345367
@@ -397,6 +419,8 @@ private:
397419 * Large allocations.
398420 */
399421 void * allocLarge (uint pages, bool containsPointers, bool zero) {
422+ ensureThreadCacheIsInitialized();
423+
400424 void * ptr;
401425
402426 {
@@ -682,6 +706,7 @@ private:
682706 }
683707
684708 auto chooseArena (bool containsPointers) {
709+ assert (state.busy, " Must be busy!" );
685710 auto group = selectArenaGroup();
686711
687712 import d.gc.arena;
0 commit comments