diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 40cb8694fd4d52..d8faaf545e4e81 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -2322,7 +2322,9 @@ uint64_t gc_heap::gc_last_ephemeral_decommit_time = 0; CLRCriticalSection gc_heap::check_commit_cs; +#ifdef COMMITTED_BYTES_SHADOW CLRCriticalSection gc_heap::decommit_lock; +#endif //COMMITTED_BYTES_SHADOW size_t gc_heap::current_total_committed = 0; @@ -7000,9 +7002,13 @@ void gc_heap::gc_thread_function () if (gradual_decommit_in_progress_p) { +#ifdef COMMITTED_BYTES_SHADOW decommit_lock.Enter (); +#endif //COMMITTED_BYTES_SHADOW gradual_decommit_in_progress_p = decommit_step (DECOMMIT_TIME_STEP_MILLISECONDS); +#ifdef COMMITTED_BYTES_SHADOW decommit_lock.Leave (); +#endif //COMMITTED_BYTES_SHADOW } continue; } @@ -7208,7 +7214,13 @@ void gc_heap::gc_thread_function () // check if we should do some decommitting if (gradual_decommit_in_progress_p) { +#ifdef COMMITTED_BYTES_SHADOW + decommit_lock.Enter (); +#endif //COMMITTED_BYTES_SHADOW gradual_decommit_in_progress_p = decommit_step (DECOMMIT_TIME_STEP_MILLISECONDS); +#ifdef COMMITTED_BYTES_SHADOW + decommit_lock.Leave (); +#endif //COMMITTED_BYTES_SHADOW } } else @@ -7274,9 +7286,6 @@ bool gc_heap::virtual_commit (void* address, size_t size, int bucket, int h_numb dprintf(3, ("commit-accounting: commit in %d [%p, %p) for heap %d", bucket, address, ((uint8_t*)address + size), h_number)); -#ifndef COMMITTED_BYTES_SHADOW - if (heap_hard_limit) -#endif //!COMMITTED_BYTES_SHADOW { check_commit_cs.Enter(); bool exceeded_p = false; @@ -7299,20 +7308,19 @@ bool gc_heap::virtual_commit (void* address, size_t size, int bucket, int h_numb exceeded_p = true; } } -#ifdef COMMITTED_BYTES_SHADOW + if (!heap_hard_limit) { exceeded_p = false; } -#endif //COMMITTED_BYTES_SHADOW if (!exceeded_p) { -#if defined(_DEBUG) && defined(MULTIPLE_HEAPS) +#ifdef MULTIPLE_HEAPS if ((h_number != -1) && (bucket < total_oh_count)) { g_heaps[h_number]->committed_by_oh_per_heap[bucket] += size; } -#endif // _DEBUG && MULTIPLE_HEAPS +#endif // MULTIPLE_HEAPS committed_by_oh[bucket] += size; current_total_committed += size; if (h_number < 0) @@ -7341,13 +7349,13 @@ bool gc_heap::virtual_commit (void* address, size_t size, int bucket, int h_numb { check_commit_cs.Enter(); committed_by_oh[bucket] -= size; -#if defined(_DEBUG) && defined(MULTIPLE_HEAPS) +#ifdef MULTIPLE_HEAPS if ((h_number != -1) && (bucket < total_oh_count)) { assert (g_heaps[h_number]->committed_by_oh_per_heap[bucket] >= size); g_heaps[h_number]->committed_by_oh_per_heap[bucket] -= size; } -#endif // _DEBUG && MULTIPLE_HEAPS +#endif //MULTIPLE_HEAPS dprintf (1, ("commit failed, updating %zd to %zd", current_total_committed, (current_total_committed - size))); current_total_committed -= size; @@ -7383,20 +7391,17 @@ bool gc_heap::virtual_decommit (void* address, size_t size, int bucket, int h_nu dprintf(3, ("commit-accounting: decommit in %d [%p, %p) for heap %d", bucket, address, ((uint8_t*)address + size), h_number)); if (decommit_succeeded_p) -#ifndef COMMITTED_BYTES_SHADOW - if (heap_hard_limit) -#endif //!COMMITTED_BYTES_SHADOW { check_commit_cs.Enter(); assert (committed_by_oh[bucket] >= size); committed_by_oh[bucket] -= size; -#if defined(_DEBUG) && defined(MULTIPLE_HEAPS) +#ifdef MULTIPLE_HEAPS if ((h_number != -1) && (bucket < total_oh_count)) { assert (g_heaps[h_number]->committed_by_oh_per_heap[bucket] >= size); g_heaps[h_number]->committed_by_oh_per_heap[bucket] -= size; } -#endif // _DEBUG && MULTIPLE_HEAPS +#endif //MULTIPLE_HEAPS assert (current_total_committed >= size); current_total_committed -= size; if (bucket == recorded_committed_bookkeeping_bucket) @@ -11756,9 +11761,6 @@ void gc_heap::return_free_region (heap_segment* region) { gc_oh_num oh = heap_segment_oh (region); dprintf(3, ("commit-accounting: from %d to free [%p, %p) for heap %d", oh, get_region_start (region), heap_segment_committed (region), heap_number)); -#ifndef COMMITTED_BYTES_SHADOW - if (heap_hard_limit) -#endif //!COMMITTED_BYTES_SHADOW { size_t committed = heap_segment_committed (region) - get_region_start (region); if (committed > 0) @@ -11767,10 +11769,10 @@ void gc_heap::return_free_region (heap_segment* region) assert (committed_by_oh[oh] >= committed); committed_by_oh[oh] -= committed; committed_by_oh[recorded_committed_free_bucket] += committed; -#if defined(_DEBUG) && defined(MULTIPLE_HEAPS) +#ifdef MULTIPLE_HEAPS assert (committed_by_oh_per_heap[oh] >= committed); committed_by_oh_per_heap[oh] -= committed; -#endif // _DEBUG && MULTIPLE_HEAPS +#endif //MULTIPLE_HEAPS check_commit_cs.Leave(); } } @@ -11853,9 +11855,6 @@ heap_segment* gc_heap::get_free_region (int gen_number, size_t size) gc_oh_num oh = gen_to_oh (gen_number); dprintf(3, ("commit-accounting: from free to %d [%p, %p) for heap %d", oh, get_region_start (region), heap_segment_committed (region), heap_number)); -#ifndef COMMITTED_BYTES_SHADOW - if (heap_hard_limit) -#endif //!COMMITTED_BYTES_SHADOW { size_t committed = heap_segment_committed (region) - get_region_start (region); if (committed > 0) @@ -11864,9 +11863,9 @@ heap_segment* gc_heap::get_free_region (int gen_number, size_t size) committed_by_oh[oh] += committed; assert (committed_by_oh[recorded_committed_free_bucket] >= committed); committed_by_oh[recorded_committed_free_bucket] -= committed; -#if defined(_DEBUG) && defined(MULTIPLE_HEAPS) +#ifdef MULTIPLE_HEAPS committed_by_oh_per_heap[oh] += committed; -#endif // _DEBUG && MULTIPLE_HEAPS +#endif //MULTIPLE_HEAPS check_commit_cs.Leave(); } } @@ -14107,13 +14106,10 @@ HRESULT gc_heap::initialize_gc (size_t soh_segment_size, int number_of_heaps = 1; #endif //MULTIPLE_HEAPS -#ifndef COMMITTED_BYTES_SHADOW - if (heap_hard_limit) -#endif //!COMMITTED_BYTES_SHADOW - { - check_commit_cs.Initialize(); - } + check_commit_cs.Initialize(); +#ifdef COMMITTED_BYTES_SHADOW decommit_lock.Initialize(); +#endif //COMMITTED_BYTES_SHADOW #ifdef USE_REGIONS if (regions_range) @@ -14727,9 +14723,7 @@ int gc_heap::init_gc_heap (int h_number) { #ifdef MULTIPLE_HEAPS -#ifdef _DEBUG memset (committed_by_oh_per_heap, 0, sizeof (committed_by_oh_per_heap)); -#endif g_heaps [h_number] = this; @@ -24364,22 +24358,18 @@ heap_segment* gc_heap::unlink_first_rw_region (int gen_idx) assert (!heap_segment_read_only_p (region)); dprintf (REGIONS_LOG, ("unlink_first_rw_region on heap: %d gen: %d region: %p", heap_number, gen_idx, heap_segment_mem (region))); -#if defined(_DEBUG) && defined(HOST_64BIT) -#ifndef COMMITTED_BYTES_SHADOW - if (heap_hard_limit) -#endif //!COMMITTED_BYTES_SHADOW +#ifdef HOST_64BIT + int oh = heap_segment_oh (region); + dprintf(3, ("commit-accounting: from %d to temp [%p, %p) for heap %d", oh, get_region_start (region), heap_segment_committed (region), this->heap_number)); + size_t committed = heap_segment_committed (region) - get_region_start (region); + if (committed > 0) { - int old_oh = heap_segment_oh (region); - int old_heap = heap_segment_heap (region)->heap_number; - dprintf(3, ("commit-accounting: from %d to temp [%p, %p) for heap %d", old_oh, get_region_start (region), heap_segment_committed (region), old_heap)); - - size_t committed = heap_segment_committed (region) - get_region_start (region); check_commit_cs.Enter(); - assert (g_heaps[old_heap]->committed_by_oh_per_heap[old_oh] >= committed); - g_heaps[old_heap]->committed_by_oh_per_heap[old_oh] -= committed; + assert (this->committed_by_oh_per_heap[oh] >= committed); + this->committed_by_oh_per_heap[oh] -= committed; check_commit_cs.Leave(); } -#endif // _DEBUG && HOST_64BIT +#endif //HOST_64BIT set_heap_for_contained_basic_regions (region, nullptr); @@ -24407,22 +24397,15 @@ void gc_heap::thread_rw_region_front (int gen_idx, heap_segment* region) } dprintf (REGIONS_LOG, ("thread_rw_region_front on heap: %d gen: %d region: %p", heap_number, gen_idx, heap_segment_mem (region))); -#if defined(_DEBUG) && defined(HOST_64BIT) -#ifndef COMMITTED_BYTES_SHADOW - if (heap_hard_limit) -#endif //!COMMITTED_BYTES_SHADOW - { - int new_oh = gen_to_oh (gen_idx); - int new_heap = this->heap_number; - dprintf(3, ("commit-accounting: from temp to %d [%p, %p) for heap %d", new_oh, get_region_start (region), heap_segment_committed (region), new_heap)); - - size_t committed = heap_segment_committed (region) - get_region_start (region); - check_commit_cs.Enter(); - assert (heap_segment_heap (region) == nullptr); - g_heaps[new_heap]->committed_by_oh_per_heap[new_oh] += committed; - check_commit_cs.Leave(); - } -#endif // _DEBUG && HOST_64BIT +#ifdef HOST_64BIT + int oh = heap_segment_oh (region); + dprintf(3, ("commit-accounting: from temp to %d [%p, %p) for heap %d", oh, get_region_start (region), heap_segment_committed (region), this->heap_number)); + size_t committed = heap_segment_committed (region) - get_region_start (region); + check_commit_cs.Enter(); + assert (heap_segment_heap (region) == nullptr); + this->committed_by_oh_per_heap[oh] += committed; + check_commit_cs.Leave(); +#endif //HOST_64BIT set_heap_for_contained_basic_regions (region, this); } @@ -24555,6 +24538,15 @@ void gc_heap::equalize_promoted_bytes(int condemned_gen_number) assert (start_region); dprintf (3, ("making sure heap %d gen %d has at least one region by adding region %zx", start_region)); heap_segment_next (start_region) = nullptr; + + assert (heap_segment_heap (start_region) == nullptr && hp != nullptr); + int oh = heap_segment_oh (start_region); + size_t committed = heap_segment_committed (start_region) - get_region_start (start_region); + dprintf(3, ("commit-accounting: from temp to %d [%p, %p) for heap %d", oh, get_region_start (start_region), heap_segment_committed (start_region), hp->heap_number)); + check_commit_cs.Enter(); + g_heaps[hp->heap_number]->committed_by_oh_per_heap[oh] += committed; + check_commit_cs.Leave(); + set_heap_for_contained_basic_regions (start_region, hp); max_survived = max (max_survived, heap_segment_survived (start_region)); hp->thread_start_region (gen, start_region); @@ -24681,8 +24673,9 @@ void gc_heap::equalize_promoted_bytes(int condemned_gen_number) for (int i = 0; i < n_heaps; i++) { gc_heap* hp = g_heaps[i]; - +#ifdef _DEBUG hp->verify_regions (gen_idx, true, true); +#endif //_DEBUG } #ifdef TRACE_GC max_surv_per_heap = 0; @@ -26088,6 +26081,20 @@ bool gc_heap::change_heap_count (int new_n_heaps) for (heap_segment* region = start_region; region != nullptr; region = heap_segment_next(region)) { + assert (hp != nullptr && hpd != nullptr && hp != hpd); + + int oh = heap_segment_oh (region); + size_t committed = heap_segment_committed (region) - get_region_start (region); + if (committed > 0) + { + dprintf(3, ("commit-accounting: from %d to %d [%p, %p) for heap %d to heap %d", oh, oh, get_region_start (region), heap_segment_committed (region), i, dest_heap_number)); + check_commit_cs.Enter(); + assert (hp->committed_by_oh_per_heap[oh] >= committed); + hp->committed_by_oh_per_heap[oh] -= committed; + hpd->committed_by_oh_per_heap[oh] += committed; + check_commit_cs.Leave(); + } + set_heap_for_contained_basic_regions (region, hpd); } if (tail_ro_region != nullptr) @@ -33971,60 +33978,7 @@ void gc_heap::plan_phase (int condemned_gen_number) #endif //FEATURE_EVENT_TRACE #if defined(_DEBUG) && defined(USE_REGIONS) - if (heap_hard_limit) - { - size_t committed = 0; - for (int i = 0; i < total_generation_count; i++) - { - int oh = i - max_generation; -#ifdef MULTIPLE_HEAPS - for (int hn = 0; hn < gc_heap::n_heaps; hn++) - { - gc_heap* hp = gc_heap::g_heaps[hn]; -#else - { - gc_heap* hp = pGenGCHeap; -#endif // MULTIPLE_HEAPS - heap_segment* region = generation_start_segment (hp->generation_of (i)); - while (region) - { - if (!heap_segment_read_only_p (region)) - { - committed += heap_segment_committed (region) - get_region_start (region); - } - region = heap_segment_next (region); - } -#ifdef BACKGROUND_GC - if (oh == soh) - { - heap_segment* freeable = hp->freeable_soh_segment; - while (freeable) - { - committed += (heap_segment_committed (freeable) - get_region_start (freeable)); - freeable = heap_segment_next (freeable); - } - } - else - { - heap_segment* freeable = hp->freeable_uoh_segment; - while (freeable) - { - if (heap_segment_oh (freeable) == oh) - { - committed += (heap_segment_committed (freeable) - get_region_start (freeable)); - } - freeable = heap_segment_next (freeable); - } - } -#endif //BACKGROUND_GC - } - if (i >= max_generation) - { - assert (committed_by_oh[oh] == committed); - committed = 0; - } - } - } + verify_committed_bytes (); #endif // _DEBUG && USE_REGIONS #ifdef MULTIPLE_HEAPS @@ -34730,8 +34684,9 @@ void gc_heap::thread_final_regions (bool compact_p) assert (!"we shouldn't be getting new regions in TFR!"); } - +#ifdef _DEBUG verify_regions (true, false); +#endif //_DEBUG } void gc_heap::thread_start_region (generation* gen, heap_segment* region) @@ -34781,8 +34736,9 @@ heap_segment* gc_heap::get_new_region (int gen_number, size_t size) generation* gen = generation_of (gen_number); heap_segment_next (generation_tail_region (gen)) = new_region; generation_tail_region (gen) = new_region; - +#ifdef _DEBUG verify_regions (gen_number, false, settings.concurrent); +#endif //_DEBUG } return new_region; @@ -34850,8 +34806,9 @@ void gc_heap::update_start_tail_regions (generation* gen, dprintf (REGIONS_LOG, ("tail region of gen%d updated to %zx(%p)", gen->gen_num, (size_t)prev_region, heap_segment_mem (prev_region))); } - +#ifdef _DEBUG verify_regions (false, settings.concurrent); +#endif //_DEBUG } // There's one complication with deciding whether we can make a region SIP or not - if the plan_gen_num of @@ -47560,9 +47517,53 @@ gc_heap::verify_free_lists () } } -void gc_heap::verify_regions (int gen_number, bool can_verify_gen_num, bool can_verify_tail, size_t* p_total_committed) -{ #ifdef USE_REGIONS + +void gc_heap::verify_committed_bytes_per_heap() +{ + size_t committed_bookkeeping = 0; // unused + for (int oh = soh; oh < total_oh_count; oh++) + { +#ifdef MULTIPLE_HEAPS + assert (committed_by_oh_per_heap[oh] == compute_committed_bytes_per_heap (oh, committed_bookkeeping)); +#else + assert (committed_by_oh[oh] == compute_committed_bytes_per_heap (oh, committed_bookkeeping)); +#endif //MULTIPLE_HEAPS + } +} + +void gc_heap::verify_committed_bytes() +{ + size_t total_committed = 0; + size_t committed_decommit; // unused + size_t committed_free; // unused + size_t committed_bookkeeping = 0; + size_t new_current_total_committed; + size_t new_current_total_committed_bookkeeping; + size_t new_committed_by_oh[recorded_committed_bucket_counts]; + compute_committed_bytes(total_committed, committed_decommit, committed_free, + committed_bookkeeping, new_current_total_committed, new_current_total_committed_bookkeeping, + new_committed_by_oh); +#ifdef MULTIPLE_HEAPS + for (int h = 0; h < n_heaps; h++) + { + for (int oh = soh; oh < total_oh_count; oh++) + { + assert (g_heaps[h]->committed_by_oh_per_heap[oh] == g_heaps[h]->committed_by_oh_per_heap_refresh[oh]); + } + } + for (int i = 0; i < recorded_committed_bucket_counts; i++) + { + assert (new_committed_by_oh[i] == committed_by_oh[i]); + } +#endif //MULTIPLE_HEAPS + assert (new_current_total_committed == current_total_committed); + assert (new_current_total_committed_bookkeeping == current_total_committed_bookkeeping); +} + +#ifdef _DEBUG +void gc_heap::verify_regions (int gen_number, bool can_verify_gen_num, bool can_verify_tail) +{ // For the given generation, verify that // // 1) it has at least one region. @@ -47579,13 +47580,6 @@ void gc_heap::verify_regions (int gen_number, bool can_verify_gen_num, bool can_ while (seg_in_gen) { - if (p_total_committed) - { - if (!heap_segment_read_only_p (seg_in_gen)) - { - *p_total_committed += (heap_segment_committed (seg_in_gen) - get_region_start (seg_in_gen)); - } - } if (can_verify_gen_num) { if (heap_segment_gen_num (seg_in_gen) != min (gen_number, max_generation)) @@ -47638,7 +47632,6 @@ void gc_heap::verify_regions (int gen_number, bool can_verify_gen_num, bool can_ prev_region_in_gen, heap_segment_mem (prev_region_in_gen))); FATAL_GC_ERROR(); } -#endif //USE_REGIONS } inline bool is_user_alloc_gen (int gen_number) @@ -47648,61 +47641,21 @@ inline bool is_user_alloc_gen (int gen_number) void gc_heap::verify_regions (bool can_verify_gen_num, bool concurrent_p) { -#ifdef USE_REGIONS - size_t total_committed = 0; for (int i = 0; i < total_generation_count; i++) { bool can_verify_tail = (concurrent_p ? !is_user_alloc_gen (i) : true); - verify_regions (i, can_verify_gen_num, can_verify_tail, &total_committed); + verify_regions (i, can_verify_gen_num, can_verify_tail); if (can_verify_gen_num && can_verify_tail && - (i >= max_generation) && - heap_hard_limit) + (i >= max_generation)) { - int oh = i - max_generation; -#ifdef BACKGROUND_GC - if (oh == soh) - { - heap_segment* freeable = freeable_soh_segment; - while (freeable) - { - total_committed += (heap_segment_committed (freeable) - get_region_start (freeable)); - freeable = heap_segment_next (freeable); - } - } - else - { - heap_segment* freeable = freeable_uoh_segment; - while (freeable) - { - if (heap_segment_oh (freeable) == oh) - { - total_committed += (heap_segment_committed (freeable) - get_region_start (freeable)); - } - freeable = heap_segment_next (freeable); - } - } -#endif //BACKGROUND_GC -#ifdef MULTIPLE_HEAPS -#ifdef _DEBUG - size_t total_accounted = committed_by_oh_per_heap[i - max_generation]; -#else // _DEBUG - size_t total_accounted = total_committed; -#endif // _DEBUG -#else // MULTIPLE_HEAPS - size_t total_accounted = committed_by_oh[i - max_generation]; -#endif // MULTIPLE_HEAPS - if (total_committed != total_accounted) - { - FATAL_GC_ERROR(); - } - dprintf(3, ("commit-accounting: checkpoint for %d for heap %d", oh, heap_number)); - total_committed = 0; + verify_committed_bytes_per_heap (); } } -#endif //USE_REGIONS } +#endif //_DEBUG +#endif //USE_REGIONS BOOL gc_heap::check_need_card (uint8_t* child_obj, int gen_num_for_cards, uint8_t* low, uint8_t* high) @@ -47823,6 +47776,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p) //verify that the generation structures makes sense { +#ifdef _DEBUG #ifdef USE_REGIONS verify_regions (true, settings.concurrent); #else //USE_REGIONS @@ -47849,6 +47803,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p) gen_num--; } #endif //USE_REGIONS +#endif //_DEBUG } size_t total_objects_verified = 0; @@ -52853,6 +52808,31 @@ bool gc_heap::compute_memory_settings(bool is_initialization, uint32_t& nhp, uin } #ifdef USE_REGIONS +size_t gc_heap::compute_committed_bytes_per_heap(int oh, size_t& committed_bookkeeping) +{ + int start_generation = (oh == 0) ? 0 : oh + max_generation; + int end_generation = oh + max_generation; + + size_t total_committed_per_heap = 0; + for (int gen = start_generation; gen <= end_generation; gen++) + { + accumulate_committed_bytes (generation_start_segment (generation_of (gen)), total_committed_per_heap, committed_bookkeeping); + } + +#ifdef BACKGROUND_GC + if (oh == soh) + { + accumulate_committed_bytes (freeable_soh_segment, total_committed_per_heap, committed_bookkeeping); + } + else +#endif //BACKGROUND_GC + { + accumulate_committed_bytes (freeable_uoh_segment, total_committed_per_heap, committed_bookkeeping, (gc_oh_num)oh); + } + + return total_committed_per_heap; +} + void gc_heap::compute_committed_bytes(size_t& total_committed, size_t& committed_decommit, size_t& committed_free, size_t& committed_bookkeeping, size_t& new_current_total_committed, size_t& new_current_total_committed_bookkeeping, size_t* new_committed_by_oh) @@ -52860,8 +52840,6 @@ void gc_heap::compute_committed_bytes(size_t& total_committed, size_t& committed // Accounting for the bytes committed for the regions for (int oh = soh; oh < total_oh_count; oh++) { - int start_generation = (oh == 0) ? 0 : oh + max_generation; - int end_generation = oh + max_generation; size_t total_committed_per_oh = 0; #ifdef MULTIPLE_HEAPS for (int h = 0; h < n_heaps; h++) @@ -52871,25 +52849,10 @@ void gc_heap::compute_committed_bytes(size_t& total_committed, size_t& committed { gc_heap* heap = pGenGCHeap; #endif //MULTIPLE_HEAPS - size_t total_committed_per_heap = 0; - for (int gen = start_generation; gen <= end_generation; gen++) - { - heap->accumulate_committed_bytes ( generation_start_segment (heap->generation_of (gen)), total_committed_per_heap, committed_bookkeeping); - } - -#ifdef BACKGROUND_GC - if (oh == soh) - { - heap->accumulate_committed_bytes (heap->freeable_soh_segment, total_committed_per_heap, committed_bookkeeping); - } - else -#endif //BACKGROUND_GC - { - heap->accumulate_committed_bytes (heap->freeable_uoh_segment, total_committed_per_heap, committed_bookkeeping, (gc_oh_num)oh); - } -#if defined(MULTIPLE_HEAPS) && defined(_DEBUG) + size_t total_committed_per_heap = heap->compute_committed_bytes_per_heap (oh, committed_bookkeeping); +#ifdef MULTIPLE_HEAPS heap->committed_by_oh_per_heap_refresh[oh] = total_committed_per_heap; -#endif //MULTIPLE_HEAPS && _DEBUG +#endif //MULTIPLE_HEAPS total_committed_per_oh += total_committed_per_heap; } new_committed_by_oh[oh] = total_committed_per_oh; @@ -52972,19 +52935,10 @@ int gc_heap::refresh_memory_limit() GCToEEInterface::SuspendEE(SUSPEND_FOR_GC); -#ifdef USE_REGIONS + +#ifdef COMMITTED_BYTES_SHADOW decommit_lock.Enter(); - size_t total_committed = 0; - size_t committed_decommit; // unused - size_t committed_free; // unused - size_t committed_bookkeeping = 0; - size_t new_current_total_committed; - size_t new_current_total_committed_bookkeeping; - size_t new_committed_by_oh[recorded_committed_bucket_counts]; - compute_committed_bytes(total_committed, committed_decommit, committed_free, - committed_bookkeeping, new_current_total_committed, new_current_total_committed_bookkeeping, - new_committed_by_oh); -#endif //USE_REGIONS +#endif //COMMITTED_BYTES_SHADOW uint32_t nhp_from_config = static_cast(GCConfig::GetHeapCount()); #ifdef MULTIPLE_HEAPS @@ -53019,7 +52973,7 @@ int gc_heap::refresh_memory_limit() size_t new_current_total_committed = 0; #endif //USE_REGIONS - if (succeed && !compute_memory_settings(false, nhp, nhp_from_config, seg_size_from_config, new_current_total_committed)) + if (succeed && !compute_memory_settings(false, nhp, nhp_from_config, seg_size_from_config, current_total_committed)) { succeed = false; status = refresh_hard_limit_too_low; @@ -53035,53 +52989,17 @@ int gc_heap::refresh_memory_limit() heap_hard_limit_oh[poh] = old_heap_hard_limit_poh; hard_limit_config_p = old_hard_limit_config_p; } +#ifdef COMMITTED_BYTES_SHADOW else -#ifndef COMMITTED_BYTES_SHADOW - if (!old_heap_hard_limit && heap_hard_limit) -#endif //COMMITTED_BYTES_SHADOW { -#ifdef USE_REGIONS - check_commit_cs.Initialize(); -#ifdef COMMITTED_BYTES_SHADOW - assert (new_current_total_committed == current_total_committed); - assert (new_current_total_committed_bookkeeping == current_total_committed_bookkeeping); -#else - current_total_committed = new_current_total_committed; - current_total_committed_bookkeeping = new_current_total_committed_bookkeeping; -#endif - for (int i = 0; i < recorded_committed_bucket_counts; i++) - { -#ifdef COMMITTED_BYTES_SHADOW - assert (new_committed_by_oh[i] == committed_by_oh[i]); -#else - committed_by_oh[i] = new_committed_by_oh[i]; -#endif - } -#ifdef MULTIPLE_HEAPS -#ifdef _DEBUG - for (int h = 0; h < n_heaps; h++) - { - for (int oh = soh; oh < total_oh_count; oh++) - { -#ifdef COMMITTED_BYTES_SHADOW - assert (g_heaps[h]->committed_by_oh_per_heap[oh] == g_heaps[h]->committed_by_oh_per_heap_refresh[oh]); -#else - g_heaps[h]->committed_by_oh_per_heap[oh] = g_heaps[h]->committed_by_oh_per_heap_refresh[oh]; -#endif - } - } -#endif //_DEBUG -#endif //MULTIPLE_HEAPS -#else - assert (!"NYI - Segments"); -#endif //USE_REGIONS + verify_committed_bytes (); } +#endif //COMMITTED_BYTES_SHADOW - -#ifdef USE_REGIONS + GCToEEInterface::RestartEE(TRUE); +#ifdef COMMITTED_BYTES_SHADOW decommit_lock.Leave(); #endif - GCToEEInterface::RestartEE(TRUE); return (int)status; } diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index 788cbff9f5e507..2471d50ad91a81 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -1563,8 +1563,10 @@ class gc_heap #ifdef VERIFY_HEAP PER_HEAP_METHOD void verify_free_lists(); - PER_HEAP_METHOD void verify_regions (int gen_number, bool can_verify_gen_num, bool can_verify_tail, size_t* p_total_committed = nullptr); +#if defined (USE_REGIONS) && defined (_DEBUG) + PER_HEAP_METHOD void verify_regions (int gen_number, bool can_verify_gen_num, bool can_verify_tail); PER_HEAP_METHOD void verify_regions (bool can_verify_gen_num, bool concurrent_p); +#endif //USE_REGIONS && _DEBUG PER_HEAP_ISOLATED_METHOD void enter_gc_lock_for_verify_heap(); PER_HEAP_ISOLATED_METHOD void leave_gc_lock_for_verify_heap(); PER_HEAP_METHOD void verify_heap (BOOL begin_gc_p); @@ -1572,6 +1574,11 @@ class gc_heap uint8_t* low, uint8_t* high); #endif //VERIFY_HEAP +#ifdef USE_REGIONS + PER_HEAP_METHOD void verify_committed_bytes_per_heap(); + PER_HEAP_ISOLATED_METHOD void verify_committed_bytes(); +#endif //USE_REGIONS + PER_HEAP_ISOLATED_METHOD void fire_per_heap_hist_event (gc_history_per_heap* current_gc_data_per_heap, int heap_num); PER_HEAP_ISOLATED_METHOD void fire_pevents(); @@ -3345,6 +3352,7 @@ class gc_heap size_t new_current_total_committed); #ifdef USE_REGIONS + PER_HEAP_METHOD size_t gc_heap::compute_committed_bytes_per_heap(int oh, size_t& committed_bookkeeping); PER_HEAP_ISOLATED_METHOD void compute_committed_bytes(size_t& total_committed, size_t& committed_decommit, size_t& committed_free, size_t& committed_bookkeeping, size_t& new_current_total_committed, size_t& new_current_total_committed_bookkeeping, size_t* new_committed_by_oh); @@ -3886,10 +3894,8 @@ class gc_heap PER_HEAP_FIELD_DIAG_ONLY gc_history gchist_per_heap[max_history_count]; #ifdef MULTIPLE_HEAPS -#ifdef _DEBUG PER_HEAP_FIELD_DIAG_ONLY size_t committed_by_oh_per_heap[total_oh_count]; PER_HEAP_FIELD_DIAG_ONLY size_t committed_by_oh_per_heap_refresh[total_oh_count]; -#endif //_DEBUG #else //MULTIPLE_HEAPS #endif //MULTIPLE_HEAPS @@ -4522,7 +4528,9 @@ class gc_heap // Used both in a GC and on the allocator code paths when heap_hard_limit is non zero PER_HEAP_ISOLATED_FIELD_INIT_ONLY CLRCriticalSection check_commit_cs; +#ifdef COMMITTED_BYTES_SHADOW PER_HEAP_ISOLATED_FIELD_INIT_ONLY CLRCriticalSection decommit_lock; +#endif // Indicate to use large pages. This only works if hardlimit is also enabled. PER_HEAP_ISOLATED_FIELD_INIT_ONLY bool use_large_pages_p;