@@ -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();
@@ -20334,16 +20336,8 @@ bool gc_heap::init_table_for_region (int gen_number, heap_segment* region)
2033420336 get_region_start (region), heap_segment_reserved (region)));
2033520337
2033620338 // We don't have memory to commit the mark array so we cannot use the new region.
20337- int h_number =
20338- #ifdef MULTIPLE_HEAPS
20339- heap_number;
20340- #else
20341- 0;
20342- #endif
20343- gc_oh_num oh = gen_to_oh (gen_number);
20344- size_t size = heap_segment_committed(region) - heap_segment_mem (region);
20345- virtual_decommit(heap_segment_mem (region), size, oh, h_number);
20346- global_region_allocator.delete_region (get_region_start (region));
20339+ decommit_region (region, gen_to_oh (gen_number), heap_number);
20340+ delete_region (region);
2034720341 return false;
2034820342 }
2034920343 if ((region->flags & heap_segment_flags_ma_committed) != 0)
@@ -41073,37 +41067,15 @@ bool gc_heap::decommit_step (uint64_t step_milliseconds)
4107341067 while (global_regions_to_decommit[kind].get_num_free_regions() > 0)
4107441068 {
4107541069 heap_segment* region = global_regions_to_decommit[kind].unlink_region_front();
41076-
41077- uint8_t* page_start = align_lower_page(get_region_start(region));
41078- uint8_t* end = use_large_pages_p ? heap_segment_used(region) : heap_segment_committed(region);
41079- size_t size = end - page_start;
41080- bool decommit_succeeded_p = false;
41081- if (!use_large_pages_p)
41082- {
41083- decommit_succeeded_p = virtual_decommit(page_start, size, recorded_committed_free_bucket);
41070+ size_t size = decommit_region (region, recorded_committed_free_bucket, -1);
4108441071#ifdef MULTIPLE_HEAPS
41085- gc_heap* hp = heap_segment_heap (region);
41072+ gc_heap* hp = heap_segment_heap (region);
4108641073#else
41087- gc_heap* hp = __this ;
41074+ gc_heap* hp = pGenGCHeap ;
4108841075#endif
41089- hp->decommit_mark_array_by_seg (region);
41090- dprintf(REGIONS_LOG, ("decommitted region %p(%p-%p) (%zu bytes) - success: %d",
41091- region,
41092- page_start,
41093- end,
41094- size,
41095- decommit_succeeded_p));
41096- }
41097- if (!decommit_succeeded_p)
41098- {
41099- memclr(page_start, size);
41100- dprintf(REGIONS_LOG, ("cleared region %p(%p-%p) (%zu bytes)",
41101- region,
41102- page_start,
41103- end,
41104- size));
41105- }
41106- global_region_allocator.delete_region(get_region_start(region));
41076+ hp->decommit_mark_array_by_seg (region);
41077+ region->flags &= ~(heap_segment_flags_ma_committed);
41078+ delete_region (region);
4110741079 decommit_size += size;
4110841080 if (decommit_size >= max_decommit_step_size)
4110941081 {
@@ -41130,6 +41102,55 @@ bool gc_heap::decommit_step (uint64_t step_milliseconds)
4113041102 return (decommit_size != 0);
4113141103}
4113241104
41105+ #ifdef USE_REGIONS
41106+ size_t gc_heap::decommit_region (heap_segment* region, int bucket, int h_number)
41107+ {
41108+ uint8_t* page_start = align_lower_page (get_region_start (region));
41109+ uint8_t* end = use_large_pages_p ? heap_segment_used (region) : heap_segment_committed (region);
41110+ size_t size = end - page_start;
41111+ bool decommit_succeeded_p = false;
41112+ if (!use_large_pages_p)
41113+ {
41114+ decommit_succeeded_p = virtual_decommit (page_start, size, bucket, h_number);
41115+ }
41116+ dprintf (REGIONS_LOG, ("decommitted region %p(%p-%p) (%zu bytes) - success: %d",
41117+ region,
41118+ page_start,
41119+ end,
41120+ size,
41121+ decommit_succeeded_p));
41122+ if (decommit_succeeded_p)
41123+ {
41124+ heap_segment_committed (region) = heap_segment_mem (region);
41125+ }
41126+ else
41127+ {
41128+ memclr (page_start, size);
41129+ heap_segment_used (region) = heap_segment_mem (region);
41130+ dprintf(REGIONS_LOG, ("cleared region %p(%p-%p) (%zu bytes)",
41131+ region,
41132+ page_start,
41133+ end,
41134+ size));
41135+ }
41136+ return size;
41137+ }
41138+
41139+ void gc_heap::delete_region (heap_segment* region)
41140+ {
41141+ if (use_large_pages_p)
41142+ {
41143+ assert (heap_segment_used (region) == heap_segment_mem (region));
41144+ }
41145+ else
41146+ {
41147+ assert (heap_segment_committed (region) == heap_segment_mem (region));
41148+ }
41149+ assert ((region->flags & heap_segment_flags_ma_committed) == 0);
41150+ global_region_allocator.delete_region (get_region_start (region));
41151+ }
41152+ #endif //USE_REGIONS
41153+
4113341154#ifdef MULTIPLE_HEAPS
4113441155// return the decommitted size
4113541156size_t gc_heap::decommit_ephemeral_segment_pages_step ()
0 commit comments