@@ -3988,6 +3988,8 @@ bool region_allocator::allocate_large_region (int gen_num, uint8_t** start, uint
39883988 return allocate_region (gen_num, size, start, end, direction, fn);
39893989}
39903990
3991+ // Whenever a region is deleted, it is expected that the memory and the mark array
3992+ // of the region is decommitted already.
39913993void region_allocator::delete_region (uint8_t* region_start)
39923994{
39933995 enter_spin_lock();
@@ -20325,22 +20327,22 @@ bool gc_heap::try_get_new_free_region()
2032520327bool gc_heap::init_table_for_region (int gen_number, heap_segment* region)
2032620328{
2032720329#ifdef BACKGROUND_GC
20328- dprintf (GC_TABLE_LOG, ("new seg %Ix, mark_array is %Ix",
20329- heap_segment_mem (region), mark_array));
20330- if (((region->flags & heap_segment_flags_ma_committed) == 0) &&
20331- !commit_mark_array_new_seg (__this, region))
20332- {
20333- dprintf (GC_TABLE_LOG, ("failed to commit mark array for the new region %Ix-%Ix",
20334- get_region_start (region), heap_segment_reserved (region)));
20330+ dprintf (GC_TABLE_LOG, ("new seg %Ix, mark_array is %Ix",
20331+ heap_segment_mem (region), mark_array));
20332+ if (((region->flags & heap_segment_flags_ma_committed) == 0) &&
20333+ !commit_mark_array_new_seg (__this, region))
20334+ {
20335+ dprintf (GC_TABLE_LOG, ("failed to commit mark array for the new region %Ix-%Ix",
20336+ get_region_start (region), heap_segment_reserved (region)));
2033520337
20336- // We don't have memory to commit the mark array so we cannot use the new region.
20337- global_region_allocator.delete_region (get_region_start (region) );
20338- return false;
20339- }
20340- if ((region->flags & heap_segment_flags_ma_committed) != 0)
20341- {
20342- bgc_verify_mark_array_cleared (region, true);
20343- }
20338+ // We don't have memory to commit the mark array so we cannot use the new region.
20339+ decommit_region (region, gen_to_oh (gen_number), heap_number );
20340+ return false;
20341+ }
20342+ if ((region->flags & heap_segment_flags_ma_committed) != 0)
20343+ {
20344+ bgc_verify_mark_array_cleared (region, true);
20345+ }
2034420346#endif //BACKGROUND_GC
2034520347
2034620348 if (gen_number <= max_generation)
@@ -41064,31 +41066,7 @@ bool gc_heap::decommit_step (uint64_t step_milliseconds)
4106441066 while (global_regions_to_decommit[kind].get_num_free_regions() > 0)
4106541067 {
4106641068 heap_segment* region = global_regions_to_decommit[kind].unlink_region_front();
41067-
41068- uint8_t* page_start = align_lower_page(get_region_start(region));
41069- uint8_t* end = use_large_pages_p ? heap_segment_used(region) : heap_segment_committed(region);
41070- size_t size = end - page_start;
41071- bool decommit_succeeded_p = false;
41072- if (!use_large_pages_p)
41073- {
41074- decommit_succeeded_p = virtual_decommit(page_start, size, recorded_committed_free_bucket);
41075- dprintf(REGIONS_LOG, ("decommitted region %p(%p-%p) (%zu bytes) - success: %d",
41076- region,
41077- page_start,
41078- end,
41079- size,
41080- decommit_succeeded_p));
41081- }
41082- if (!decommit_succeeded_p)
41083- {
41084- memclr(page_start, size);
41085- dprintf(REGIONS_LOG, ("cleared region %p(%p-%p) (%zu bytes)",
41086- region,
41087- page_start,
41088- end,
41089- size));
41090- }
41091- global_region_allocator.delete_region(get_region_start(region));
41069+ size_t size = decommit_region (region, recorded_committed_free_bucket, -1);
4109241070 decommit_size += size;
4109341071 if (decommit_size >= max_decommit_step_size)
4109441072 {
@@ -41115,6 +41093,64 @@ bool gc_heap::decommit_step (uint64_t step_milliseconds)
4111541093 return (decommit_size != 0);
4111641094}
4111741095
41096+ #ifdef USE_REGIONS
41097+ size_t gc_heap::decommit_region (heap_segment* region, int bucket, int h_number)
41098+ {
41099+ uint8_t* page_start = align_lower_page (get_region_start (region));
41100+ uint8_t* end = use_large_pages_p ? heap_segment_used (region) : heap_segment_committed (region);
41101+ size_t size = end - page_start;
41102+ bool decommit_succeeded_p = false;
41103+ if (!use_large_pages_p)
41104+ {
41105+ decommit_succeeded_p = virtual_decommit (page_start, size, bucket, h_number);
41106+ }
41107+ dprintf (REGIONS_LOG, ("decommitted region %p(%p-%p) (%zu bytes) - success: %d",
41108+ region,
41109+ page_start,
41110+ end,
41111+ size,
41112+ decommit_succeeded_p));
41113+ if (decommit_succeeded_p)
41114+ {
41115+ heap_segment_committed (region) = heap_segment_mem (region);
41116+ }
41117+ else
41118+ {
41119+ memclr (page_start, size);
41120+ heap_segment_used (region) = heap_segment_mem (region);
41121+ dprintf(REGIONS_LOG, ("cleared region %p(%p-%p) (%zu bytes)",
41122+ region,
41123+ page_start,
41124+ end,
41125+ size));
41126+ }
41127+
41128+ if ((region->flags & heap_segment_flags_ma_committed) != 0)
41129+ {
41130+ #ifdef MULTIPLE_HEAPS
41131+ gc_heap* hp = heap_segment_heap (region);
41132+ #else
41133+ gc_heap* hp = pGenGCHeap;
41134+ #endif
41135+ hp->decommit_mark_array_by_seg (region);
41136+ region->flags &= ~(heap_segment_flags_ma_committed);
41137+ }
41138+
41139+ if (use_large_pages_p)
41140+ {
41141+ assert (heap_segment_used (region) == heap_segment_mem (region));
41142+ }
41143+ else
41144+ {
41145+ assert (heap_segment_committed (region) == heap_segment_mem (region));
41146+ }
41147+ assert ((region->flags & heap_segment_flags_ma_committed) == 0);
41148+ global_region_allocator.delete_region (get_region_start (region));
41149+
41150+ return size;
41151+ }
41152+ #endif //USE_REGIONS
41153+
4111841154#ifdef MULTIPLE_HEAPS
4111941155// return the decommitted size
4112041156size_t gc_heap::decommit_ephemeral_segment_pages_step ()
0 commit comments