diff options
-rw-r--r-- | rts/Capability.c | 4 | ||||
-rw-r--r-- | rts/Capability.h | 3 | ||||
-rw-r--r-- | rts/Schedule.c | 2 | ||||
-rw-r--r-- | rts/sm/NonMoving.c | 118 | ||||
-rw-r--r-- | rts/sm/NonMoving.h | 11 | ||||
-rw-r--r-- | rts/sm/NonMovingCensus.c | 24 | ||||
-rw-r--r-- | rts/sm/NonMovingCensus.h | 4 | ||||
-rw-r--r-- | rts/sm/NonMovingMark.c | 4 | ||||
-rw-r--r-- | rts/sm/NonMovingMark.h | 2 | ||||
-rw-r--r-- | rts/sm/Sanity.c | 31 | ||||
-rw-r--r-- | rts/sm/Storage.c | 23 |
11 files changed, 89 insertions, 137 deletions
diff --git a/rts/Capability.c b/rts/Capability.c index 7d5def832d..05f4794bef 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -293,6 +293,7 @@ initCapability (Capability *cap, uint32_t i) cap->saved_mut_lists = stgMallocBytes(sizeof(bdescr *) * RtsFlags.GcFlags.generations, "initCapability"); + cap->current_segments = NULL; // At this point storage manager is not initialized yet, so this will be @@ -1258,6 +1259,9 @@ freeCapability (Capability *cap) { stgFree(cap->mut_lists); stgFree(cap->saved_mut_lists); + if (cap->current_segments) { + stgFree(cap->current_segments); + } #if defined(THREADED_RTS) freeSparkPool(cap->sparks); #endif diff --git a/rts/Capability.h b/rts/Capability.h index 4f9593c8b2..a039aae235 100644 --- a/rts/Capability.h +++ b/rts/Capability.h @@ -97,6 +97,9 @@ struct Capability_ { // The update remembered set for the non-moving collector UpdRemSet upd_rem_set; + // Array of current segments for the non-moving collector. + // Of length NONMOVING_ALLOCA_CNT. + struct NonmovingSegment **current_segments; // block for allocating pinned objects into bdescr *pinned_object_block; diff --git a/rts/Schedule.c b/rts/Schedule.c index 94f756c5e4..5b5e765231 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -2331,7 +2331,9 @@ setNumCapabilities (uint32_t new_n_capabilities USED_IF_THREADS) moreCapabilities(n_capabilities, new_n_capabilities); // Resize and update storage manager data structures + ACQUIRE_SM_LOCK; storageAddCapabilities(n_capabilities, new_n_capabilities); + RELEASE_SM_LOCK; } } diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c index 320898f0b3..798e09545c 100644 --- a/rts/sm/NonMoving.c +++ b/rts/sm/NonMoving.c @@ -715,10 +715,11 @@ void *nonmovingAllocate(Capability *cap, StgWord sz) // object and not moved) which is covered by allocator 9. ASSERT(log_block_size < NONMOVING_ALLOCA0 + NONMOVING_ALLOCA_CNT); - struct NonmovingAllocator *alloca = nonmovingHeap.allocators[log_block_size - NONMOVING_ALLOCA0]; + unsigned int alloca_idx = log_block_size - NONMOVING_ALLOCA0; + struct NonmovingAllocator *alloca = &nonmovingHeap.allocators[alloca_idx]; // Allocate into current segment - struct NonmovingSegment *current = alloca->current[cap->no]; + struct NonmovingSegment *current = cap->current_segments[alloca_idx]; ASSERT(current); // current is never NULL void *ret = nonmovingSegmentGetBlock_(current, log_block_size, current->next_free); ASSERT(GET_CLOSURE_TAG(ret) == 0); // check alignment @@ -751,29 +752,12 @@ void *nonmovingAllocate(Capability *cap, StgWord sz) // make it current new_current->link = NULL; SET_SEGMENT_STATE(new_current, CURRENT); - alloca->current[cap->no] = new_current; + cap->current_segments[alloca_idx] = new_current; } return ret; } -/* Allocate a nonmovingAllocator */ -static struct NonmovingAllocator *alloc_nonmoving_allocator(uint32_t n_caps) -{ - size_t allocator_sz = - sizeof(struct NonmovingAllocator) + - sizeof(void*) * n_caps; // current segment pointer for each capability - struct NonmovingAllocator *alloc = - stgMallocBytes(allocator_sz, "nonmovingInit"); - memset(alloc, 0, allocator_sz); - return alloc; -} - -static void free_nonmoving_allocator(struct NonmovingAllocator *alloc) -{ - stgFree(alloc); -} - void nonmovingInit(void) { if (! RtsFlags.GcFlags.useNonmoving) return; @@ -782,10 +766,7 @@ void nonmovingInit(void) initCondition(&concurrent_coll_finished); initMutex(&concurrent_coll_finished_lock); #endif - for (unsigned int i = 0; i < NONMOVING_ALLOCA_CNT; i++) { - nonmovingHeap.allocators[i] = alloc_nonmoving_allocator(getNumCapabilities()); - } - nonmovingMarkInitUpdRemSet(); + nonmovingMarkInit(); } // Stop any nonmoving collection in preparation for RTS shutdown. @@ -818,44 +799,24 @@ void nonmovingExit(void) closeCondition(&concurrent_coll_finished); closeMutex(&nonmoving_collection_mutex); #endif - - for (unsigned int i = 0; i < NONMOVING_ALLOCA_CNT; i++) { - free_nonmoving_allocator(nonmovingHeap.allocators[i]); - } } -/* - * Assumes that no garbage collector or mutator threads are running to safely - * resize the nonmoving_allocators. - * - * Must hold sm_mutex. - */ -void nonmovingAddCapabilities(uint32_t new_n_caps) +/* Initialize a new capability. Caller must hold SM_LOCK */ +void nonmovingInitCapability(Capability *cap) { - unsigned int old_n_caps = nonmovingHeap.n_caps; - struct NonmovingAllocator **allocs = nonmovingHeap.allocators; - + // Initialize current segment array + struct NonmovingSegment **segs = + stgMallocBytes(sizeof(struct NonmovingSegment*) * NONMOVING_ALLOCA_CNT, "current segment array"); for (unsigned int i = 0; i < NONMOVING_ALLOCA_CNT; i++) { - struct NonmovingAllocator *old = allocs[i]; - allocs[i] = alloc_nonmoving_allocator(new_n_caps); - - // Copy the old state - allocs[i]->filled = old->filled; - allocs[i]->active = old->active; - for (unsigned int j = 0; j < old_n_caps; j++) { - allocs[i]->current[j] = old->current[j]; - } - stgFree(old); - - // Initialize current segments for the new capabilities - for (unsigned int j = old_n_caps; j < new_n_caps; j++) { - allocs[i]->current[j] = nonmovingAllocSegment(getCapability(j)->node); - nonmovingInitSegment(allocs[i]->current[j], NONMOVING_ALLOCA0 + i); - SET_SEGMENT_STATE(allocs[i]->current[j], CURRENT); - allocs[i]->current[j]->link = NULL; - } + segs[i] = nonmovingAllocSegment(cap->node); + nonmovingInitSegment(segs[i], NONMOVING_ALLOCA0 + i); + SET_SEGMENT_STATE(segs[i], CURRENT); } - nonmovingHeap.n_caps = new_n_caps; + cap->current_segments = segs; + + // Initialize update remembered set + cap->upd_rem_set.queue.blocks = NULL; + nonmovingInitUpdRemSet(&cap->upd_rem_set); } void nonmovingClearBitmap(struct NonmovingSegment *seg) @@ -875,13 +836,15 @@ static void nonmovingPrepareMark(void) // Should have been cleared by the last sweep ASSERT(nonmovingHeap.sweep_list == NULL); + nonmovingHeap.n_caps = n_capabilities; nonmovingBumpEpoch(); for (int alloca_idx = 0; alloca_idx < NONMOVING_ALLOCA_CNT; ++alloca_idx) { - struct NonmovingAllocator *alloca = nonmovingHeap.allocators[alloca_idx]; + struct NonmovingAllocator *alloca = &nonmovingHeap.allocators[alloca_idx]; // Update current segments' snapshot pointers for (uint32_t cap_n = 0; cap_n < nonmovingHeap.n_caps; ++cap_n) { - struct NonmovingSegment *seg = alloca->current[cap_n]; + Capability *cap = getCapability(cap_n); + struct NonmovingSegment *seg = cap->current_segments[alloca_idx]; nonmovingSegmentInfo(seg)->next_free_snap = seg->next_free; } @@ -1114,7 +1077,7 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * // Walk the list of filled segments that we collected during preparation, // updated their snapshot pointers and move them to the sweep list. for (int alloca_idx = 0; alloca_idx < NONMOVING_ALLOCA_CNT; ++alloca_idx) { - struct NonmovingSegment *filled = nonmovingHeap.allocators[alloca_idx]->saved_filled; + struct NonmovingSegment *filled = nonmovingHeap.allocators[alloca_idx].saved_filled; uint32_t n_filled = 0; if (filled) { struct NonmovingSegment *seg = filled; @@ -1133,7 +1096,7 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * seg->link = nonmovingHeap.sweep_list; nonmovingHeap.sweep_list = filled; } - nonmovingHeap.allocators[alloca_idx]->saved_filled = NULL; + nonmovingHeap.allocators[alloca_idx].saved_filled = NULL; } // Mark Weak#s @@ -1350,10 +1313,12 @@ void assert_in_nonmoving_heap(StgPtr p) } for (int alloca_idx = 0; alloca_idx < NONMOVING_ALLOCA_CNT; ++alloca_idx) { - struct NonmovingAllocator *alloca = nonmovingHeap.allocators[alloca_idx]; + struct NonmovingAllocator *alloca = &nonmovingHeap.allocators[alloca_idx]; + // Search current segments for (uint32_t cap_idx = 0; cap_idx < nonmovingHeap.n_caps; ++cap_idx) { - struct NonmovingSegment *seg = alloca->current[cap_idx]; + Capability *cap = getCapability(cap_idx); + struct NonmovingSegment *seg = cap->current_segments[alloca_idx]; if (p >= (P_)seg && p < (((P_)seg) + NONMOVING_SEGMENT_SIZE_W)) { return; } @@ -1412,33 +1377,16 @@ void nonmovingPrintSegment(struct NonmovingSegment *seg) debugBelch("End of segment\n\n"); } -void nonmovingPrintAllocator(struct NonmovingAllocator *alloc) -{ - debugBelch("Allocator at %p\n", (void*)alloc); - debugBelch("Filled segments:\n"); - for (struct NonmovingSegment *seg = alloc->filled; seg != NULL; seg = seg->link) { - debugBelch("%p ", (void*)seg); - } - debugBelch("\nActive segments:\n"); - for (struct NonmovingSegment *seg = alloc->active; seg != NULL; seg = seg->link) { - debugBelch("%p ", (void*)seg); - } - debugBelch("\nCurrent segments:\n"); - for (uint32_t i = 0; i < nonmovingHeap.n_caps; ++i) { - debugBelch("%p ", alloc->current[i]); - } - debugBelch("\n"); -} - void locate_object(P_ obj) { // Search allocators for (int alloca_idx = 0; alloca_idx < NONMOVING_ALLOCA_CNT; ++alloca_idx) { - struct NonmovingAllocator *alloca = nonmovingHeap.allocators[alloca_idx]; - for (uint32_t cap = 0; cap < nonmovingHeap.n_caps; ++cap) { - struct NonmovingSegment *seg = alloca->current[cap]; + struct NonmovingAllocator *alloca = &nonmovingHeap.allocators[alloca_idx]; + for (uint32_t cap_n = 0; cap_n < getNumCapabilities(); ++cap_n) { + Capability *cap = getCapability(cap_n); + struct NonmovingSegment *seg = cap->current_segments[alloca_idx]; if (obj >= (P_)seg && obj < (((P_)seg) + NONMOVING_SEGMENT_SIZE_W)) { - debugBelch("%p is in current segment of capability %d of allocator %d at %p\n", obj, cap, alloca_idx, (void*)seg); + debugBelch("%p is in current segment of capability %d of allocator %d at %p\n", obj, cap_n, alloca_idx, (void*)seg); return; } } diff --git a/rts/sm/NonMoving.h b/rts/sm/NonMoving.h index 91144f6f9b..26031626a9 100644 --- a/rts/sm/NonMoving.h +++ b/rts/sm/NonMoving.h @@ -87,8 +87,7 @@ struct NonmovingAllocator { struct NonmovingSegment *filled; struct NonmovingSegment *saved_filled; struct NonmovingSegment *active; - // indexed by capability number - struct NonmovingSegment *current[]; + // N.B. Per-capabilty "current" segment lives in Capability }; // first allocator is of size 2^NONMOVING_ALLOCA0 (in bytes) @@ -102,7 +101,7 @@ struct NonmovingAllocator { #define NONMOVING_MAX_FREE 16 struct NonmovingHeap { - struct NonmovingAllocator *allocators[NONMOVING_ALLOCA_CNT]; + struct NonmovingAllocator allocators[NONMOVING_ALLOCA_CNT]; // free segment list. This is a cache where we keep up to // NONMOVING_MAX_FREE segments to avoid thrashing the block allocator. // Note that segments in this list are still counted towards @@ -153,7 +152,7 @@ void nonmovingCollect(StgWeak **dead_weaks, StgTSO **resurrected_threads); void *nonmovingAllocate(Capability *cap, StgWord sz); -void nonmovingAddCapabilities(uint32_t new_n_caps); +void nonmovingInitCapability(Capability *cap); void nonmovingPushFreeSegment(struct NonmovingSegment *seg); void nonmovingClearBitmap(struct NonmovingSegment *seg); @@ -170,7 +169,7 @@ INLINE_HEADER uint8_t nonmovingSegmentLogBlockSize(struct NonmovingSegment *seg) INLINE_HEADER void nonmovingPushActiveSegment(struct NonmovingSegment *seg) { struct NonmovingAllocator *alloc = - nonmovingHeap.allocators[nonmovingSegmentLogBlockSize(seg) - NONMOVING_ALLOCA0]; + &nonmovingHeap.allocators[nonmovingSegmentLogBlockSize(seg) - NONMOVING_ALLOCA0]; SET_SEGMENT_STATE(seg, ACTIVE); while (true) { struct NonmovingSegment *current_active = RELAXED_LOAD(&alloc->active); @@ -185,7 +184,7 @@ INLINE_HEADER void nonmovingPushActiveSegment(struct NonmovingSegment *seg) INLINE_HEADER void nonmovingPushFilledSegment(struct NonmovingSegment *seg) { struct NonmovingAllocator *alloc = - nonmovingHeap.allocators[nonmovingSegmentLogBlockSize(seg) - NONMOVING_ALLOCA0]; + &nonmovingHeap.allocators[nonmovingSegmentLogBlockSize(seg) - NONMOVING_ALLOCA0]; SET_SEGMENT_STATE(seg, FILLED); while (true) { struct NonmovingSegment *current_filled = (struct NonmovingSegment*) RELAXED_LOAD(&alloc->filled); diff --git a/rts/sm/NonMovingCensus.c b/rts/sm/NonMovingCensus.c index 426179928b..27494284fe 100644 --- a/rts/sm/NonMovingCensus.c +++ b/rts/sm/NonMovingCensus.c @@ -21,10 +21,12 @@ // stopped. In this case is safe to look at active and current segments so we can // also collect statistics on live words. static struct NonmovingAllocCensus -nonmovingAllocatorCensus_(struct NonmovingAllocator *alloc, bool collect_live_words) +nonmovingAllocatorCensus_(uint32_t alloc_idx, bool collect_live_words) { struct NonmovingAllocCensus census = {collect_live_words, 0, 0, 0, 0}; + struct NonmovingAllocator *alloc = &nonmovingHeap.allocators[alloc_idx]; + // filled segments for (struct NonmovingSegment *seg = alloc->filled; seg != NULL; seg = seg->link) @@ -40,6 +42,7 @@ nonmovingAllocatorCensus_(struct NonmovingAllocator *alloc, bool collect_live_wo } } + // active segments for (struct NonmovingSegment *seg = alloc->active; seg != NULL; seg = seg->link) @@ -56,9 +59,11 @@ nonmovingAllocatorCensus_(struct NonmovingAllocator *alloc, bool collect_live_wo } } - for (unsigned int cap=0; cap < getNumCapabilities(); cap++) + // current segments + for (unsigned int cap_n=0; cap_n < getNumCapabilities(); cap_n++) { - struct NonmovingSegment *seg = alloc->current[cap]; + Capability *cap = getCapability(cap_n); + struct NonmovingSegment *seg = cap->current_segments[alloc_idx]; unsigned int n = nonmovingSegmentBlockCount(seg); for (unsigned int i=0; i < n; i++) { if (nonmovingGetMark(seg, i)) { @@ -76,15 +81,15 @@ nonmovingAllocatorCensus_(struct NonmovingAllocator *alloc, bool collect_live_wo * all blocks in nonmoving heap are valid closures. */ struct NonmovingAllocCensus -nonmovingAllocatorCensusWithWords(struct NonmovingAllocator *alloc) +nonmovingAllocatorCensusWithWords(uint32_t alloc_idx) { - return nonmovingAllocatorCensus_(alloc, true); + return nonmovingAllocatorCensus_(alloc_idx, true); } struct NonmovingAllocCensus -nonmovingAllocatorCensus(struct NonmovingAllocator *alloc) +nonmovingAllocatorCensus(uint32_t alloc_idx) { - return nonmovingAllocatorCensus_(alloc, false); + return nonmovingAllocatorCensus_(alloc_idx, false); } @@ -130,7 +135,7 @@ void nonmovingPrintAllocatorCensus(bool collect_live_words) for (int i=0; i < NONMOVING_ALLOCA_CNT; i++) { struct NonmovingAllocCensus census = - nonmovingAllocatorCensus_(nonmovingHeap.allocators[i], collect_live_words); + nonmovingAllocatorCensus_(i, collect_live_words); print_alloc_census(i, census); } @@ -143,8 +148,7 @@ void nonmovingTraceAllocatorCensus() return; for (int i=0; i < NONMOVING_ALLOCA_CNT; i++) { - const struct NonmovingAllocCensus census = - nonmovingAllocatorCensus(nonmovingHeap.allocators[i]); + const struct NonmovingAllocCensus census = nonmovingAllocatorCensus(i); const uint32_t log_blk_size = i + NONMOVING_ALLOCA0; traceNonmovingHeapCensus(log_blk_size, &census); } diff --git a/rts/sm/NonMovingCensus.h b/rts/sm/NonMovingCensus.h index 988df290ea..164017eccc 100644 --- a/rts/sm/NonMovingCensus.h +++ b/rts/sm/NonMovingCensus.h @@ -20,10 +20,10 @@ struct NonmovingAllocCensus { struct NonmovingAllocCensus -nonmovingAllocatorCensusWithWords(struct NonmovingAllocator *alloc); +nonmovingAllocatorCensusWithWords(uint32_t alloc_idx); struct NonmovingAllocCensus -nonmovingAllocatorCensus(struct NonmovingAllocator *alloc); +nonmovingAllocatorCensus(uint32_t alloc_idx); void nonmovingPrintAllocatorCensus(bool collect_live_words); void nonmovingTraceAllocatorCensus(void); diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c index d46ace2849..3ec1baee20 100644 --- a/rts/sm/NonMovingMark.c +++ b/rts/sm/NonMovingMark.c @@ -251,7 +251,7 @@ StgWord nonmoving_write_barrier_enabled = false; MarkQueue *current_mark_queue = NULL; /* Initialise update remembered set data structures */ -void nonmovingMarkInitUpdRemSet() { +void nonmovingMarkInit() { #if defined(THREADED_RTS) initMutex(&upd_rem_set_lock); initCondition(&upd_rem_set_flushed_cond); @@ -295,8 +295,8 @@ static void nonmovingAddUpdRemSetBlocks_lock(MarkQueue *rset) // Reset the state of the remembered set. ACQUIRE_SM_LOCK; init_mark_queue_(rset); - rset->is_upd_rem_set = true; RELEASE_SM_LOCK; + rset->is_upd_rem_set = true; } /* diff --git a/rts/sm/NonMovingMark.h b/rts/sm/NonMovingMark.h index 1b56083113..763192ff4b 100644 --- a/rts/sm/NonMovingMark.h +++ b/rts/sm/NonMovingMark.h @@ -140,7 +140,7 @@ extern MarkQueue *current_mark_queue; extern bdescr *upd_rem_set_block_list; -void nonmovingMarkInitUpdRemSet(void); +void nonmovingMarkInit(void); void nonmovingInitUpdRemSet(UpdRemSet *rset); void updateRemembSetPushClosure(Capability *cap, StgClosure *p); diff --git a/rts/sm/Sanity.c b/rts/sm/Sanity.c index e360586222..74260955bc 100644 --- a/rts/sm/Sanity.c +++ b/rts/sm/Sanity.c @@ -637,12 +637,13 @@ void checkNonmovingHeap (const struct NonmovingHeap *heap) checkLargeObjects(nonmoving_marked_large_objects); checkCompactObjects(nonmoving_compact_objects); for (unsigned int i=0; i < NONMOVING_ALLOCA_CNT; i++) { - const struct NonmovingAllocator *alloc = heap->allocators[i]; + const struct NonmovingAllocator *alloc = &heap->allocators[i]; checkNonmovingSegments(alloc->filled); checkNonmovingSegments(alloc->saved_filled); checkNonmovingSegments(alloc->active); - for (unsigned int cap=0; cap < getNumCapabilities(); cap++) { - checkNonmovingSegments(alloc->current[cap]); + for (unsigned int cap_n=0; cap_n < getNumCapabilities(); cap_n++) { + Capability *cap = getCapability(cap_n); + checkNonmovingSegments(cap->current_segments[i]); } } } @@ -1070,12 +1071,13 @@ findMemoryLeak (void) markBlocks(nonmoving_compact_objects); markBlocks(nonmoving_marked_compact_objects); for (i = 0; i < NONMOVING_ALLOCA_CNT; i++) { - struct NonmovingAllocator *alloc = nonmovingHeap.allocators[i]; + struct NonmovingAllocator *alloc = &nonmovingHeap.allocators[i]; markNonMovingSegments(alloc->filled); markNonMovingSegments(alloc->saved_filled); markNonMovingSegments(alloc->active); for (j = 0; j < getNumCapabilities(); j++) { - markNonMovingSegments(alloc->current[j]); + Capability *cap = getCapability(j); + markNonMovingSegments(cap->current_segments[i]); } } markNonMovingSegments(nonmovingHeap.sweep_list); @@ -1181,22 +1183,17 @@ countNonMovingSegments(struct NonmovingSegment *segs) } static W_ -countNonMovingAllocator(struct NonmovingAllocator *alloc) -{ - W_ ret = countNonMovingSegments(alloc->filled) - + countNonMovingSegments(alloc->active); - for (uint32_t i = 0; i < getNumCapabilities(); ++i) { - ret += countNonMovingSegments(alloc->current[i]); - } - return ret; -} - -static W_ countNonMovingHeap(struct NonmovingHeap *heap) { W_ ret = 0; for (int alloc_idx = 0; alloc_idx < NONMOVING_ALLOCA_CNT; alloc_idx++) { - ret += countNonMovingAllocator(heap->allocators[alloc_idx]); + struct NonmovingAllocator *alloc = &heap->allocators[alloc_idx]; + ret += countNonMovingSegments(alloc->filled); + ret += countNonMovingSegments(alloc->active); + for (uint32_t c = 0; c < getNumCapabilities(); ++c) { + Capability *cap = getCapability(c); + ret += countNonMovingSegments(cap->current_segments[alloc_idx]); + } } ret += countNonMovingSegments(heap->sweep_list); ret += countNonMovingSegments(heap->free); diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index 0309d3a565..9605d0a764 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -193,14 +193,13 @@ initStorage (void) initMutex(&sm_mutex); #endif - ACQUIRE_SM_LOCK; - /* allocate generation info array */ generations = (generation *)stgMallocBytes(RtsFlags.GcFlags.generations * sizeof(struct generation_), "initStorage: gens"); /* Initialise all generations */ + ACQUIRE_SM_LOCK; for(g = 0; g < RtsFlags.GcFlags.generations; g++) { initGeneration(&generations[g], g); } @@ -215,17 +214,14 @@ initStorage (void) } oldest_gen->to = oldest_gen; - // Nonmoving heap uses oldest_gen so initialize it after initializing oldest_gen - nonmovingInit(); - #if defined(THREADED_RTS) // nonmovingAddCapabilities allocates segments, which requires taking the gc // sync lock, so initialize it before nonmovingAddCapabilities initSpinLock(&gc_alloc_block_sync); #endif - if (RtsFlags.GcFlags.useNonmoving) - nonmovingAddCapabilities(getNumCapabilities()); + // Nonmoving heap uses oldest_gen so initialize it after initializing oldest_gen + nonmovingInit(); /* The oldest generation has one step. */ if (RtsFlags.GcFlags.compact || RtsFlags.GcFlags.sweep) { @@ -264,9 +260,9 @@ initStorage (void) RELEASE_SM_LOCK; traceInitEvent(traceHeapInfo); - } +// Caller must hold SM_LOCK. void storageAddCapabilities (uint32_t from, uint32_t to) { uint32_t n, g, i, new_n_nurseries; @@ -321,12 +317,10 @@ void storageAddCapabilities (uint32_t from, uint32_t to) } } - // Initialize NonmovingAllocators and UpdRemSets + // Initialize non-moving collector if (RtsFlags.GcFlags.useNonmoving) { - nonmovingAddCapabilities(to); for (i = from; i < to; i++) { - getCapability(i)->upd_rem_set.queue.blocks = NULL; - nonmovingInitUpdRemSet(&getCapability(i)->upd_rem_set); + nonmovingInitCapability(getCapability(i)); } } @@ -1954,14 +1948,15 @@ void rts_clearMemory(void) { } for (int i = 0; i < NONMOVING_ALLOCA_CNT; ++i) { - struct NonmovingAllocator *alloc = nonmovingHeap.allocators[i]; + struct NonmovingAllocator *alloc = &nonmovingHeap.allocators[i]; for (struct NonmovingSegment *seg = alloc->active; seg; seg = seg->link) { clear_segment_free_blocks(seg); } for (unsigned int j = 0; j < getNumCapabilities(); ++j) { - clear_segment_free_blocks(alloc->current[j]); + Capability *cap = getCapability(j); + clear_segment_free_blocks(cap->current_segments[i]); } } } |