Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 40 additions & 76 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3988,8 +3988,6 @@ bool region_allocator::allocate_large_region (int gen_num, uint8_t** start, uint
return allocate_region (gen_num, size, start, end, direction, fn);
}

// Whenever a region is deleted, it is expected that the memory and the mark array
// of the region is decommitted already.
void region_allocator::delete_region (uint8_t* region_start)
{
enter_spin_lock();
Expand Down Expand Up @@ -20327,22 +20325,22 @@ bool gc_heap::try_get_new_free_region()
bool gc_heap::init_table_for_region (int gen_number, heap_segment* region)
{
#ifdef BACKGROUND_GC
dprintf (GC_TABLE_LOG, ("new seg %Ix, mark_array is %Ix",
heap_segment_mem (region), mark_array));
if (((region->flags & heap_segment_flags_ma_committed) == 0) &&
!commit_mark_array_new_seg (__this, region))
{
dprintf (GC_TABLE_LOG, ("failed to commit mark array for the new region %Ix-%Ix",
get_region_start (region), heap_segment_reserved (region)));
dprintf (GC_TABLE_LOG, ("new seg %Ix, mark_array is %Ix",
heap_segment_mem (region), mark_array));
if (((region->flags & heap_segment_flags_ma_committed) == 0) &&
!commit_mark_array_new_seg (__this, region))
{
dprintf (GC_TABLE_LOG, ("failed to commit mark array for the new region %Ix-%Ix",
get_region_start (region), heap_segment_reserved (region)));

// We don't have memory to commit the mark array so we cannot use the new region.
decommit_region (region, gen_to_oh (gen_number), heap_number);
return false;
}
if ((region->flags & heap_segment_flags_ma_committed) != 0)
{
bgc_verify_mark_array_cleared (region, true);
}
// We don't have memory to commit the mark array so we cannot use the new region.
global_region_allocator.delete_region (get_region_start (region));
return false;
}
if ((region->flags & heap_segment_flags_ma_committed) != 0)
{
bgc_verify_mark_array_cleared (region, true);
}
#endif //BACKGROUND_GC

if (gen_number <= max_generation)
Expand Down Expand Up @@ -41066,7 +41064,31 @@ bool gc_heap::decommit_step (uint64_t step_milliseconds)
while (global_regions_to_decommit[kind].get_num_free_regions() > 0)
{
heap_segment* region = global_regions_to_decommit[kind].unlink_region_front();
size_t size = decommit_region (region, recorded_committed_free_bucket, -1);

uint8_t* page_start = align_lower_page(get_region_start(region));
uint8_t* end = use_large_pages_p ? heap_segment_used(region) : heap_segment_committed(region);
size_t size = end - page_start;
bool decommit_succeeded_p = false;
if (!use_large_pages_p)
{
decommit_succeeded_p = virtual_decommit(page_start, size, recorded_committed_free_bucket);
dprintf(REGIONS_LOG, ("decommitted region %p(%p-%p) (%zu bytes) - success: %d",
region,
page_start,
end,
size,
decommit_succeeded_p));
}
if (!decommit_succeeded_p)
{
memclr(page_start, size);
dprintf(REGIONS_LOG, ("cleared region %p(%p-%p) (%zu bytes)",
region,
page_start,
end,
size));
}
global_region_allocator.delete_region(get_region_start(region));
decommit_size += size;
if (decommit_size >= max_decommit_step_size)
{
Expand All @@ -41093,64 +41115,6 @@ bool gc_heap::decommit_step (uint64_t step_milliseconds)
return (decommit_size != 0);
}

#ifdef USE_REGIONS
size_t gc_heap::decommit_region (heap_segment* region, int bucket, int h_number)
{
uint8_t* page_start = align_lower_page (get_region_start (region));
uint8_t* end = use_large_pages_p ? heap_segment_used (region) : heap_segment_committed (region);
size_t size = end - page_start;
bool decommit_succeeded_p = false;
if (!use_large_pages_p)
{
decommit_succeeded_p = virtual_decommit (page_start, size, bucket, h_number);
}
dprintf (REGIONS_LOG, ("decommitted region %p(%p-%p) (%zu bytes) - success: %d",
region,
page_start,
end,
size,
decommit_succeeded_p));
if (decommit_succeeded_p)
{
heap_segment_committed (region) = heap_segment_mem (region);
}
else
{
memclr (page_start, size);
heap_segment_used (region) = heap_segment_mem (region);
dprintf(REGIONS_LOG, ("cleared region %p(%p-%p) (%zu bytes)",
region,
page_start,
end,
size));
}

if ((region->flags & heap_segment_flags_ma_committed) != 0)
{
#ifdef MULTIPLE_HEAPS
gc_heap* hp = heap_segment_heap (region);
#else
gc_heap* hp = pGenGCHeap;
#endif
hp->decommit_mark_array_by_seg (region);
region->flags &= ~(heap_segment_flags_ma_committed);
}

if (use_large_pages_p)
{
assert (heap_segment_used (region) == heap_segment_mem (region));
}
else
{
assert (heap_segment_committed (region) == heap_segment_mem (region));
}
assert ((region->flags & heap_segment_flags_ma_committed) == 0);
global_region_allocator.delete_region (get_region_start (region));

return size;
}
#endif //USE_REGIONS

#ifdef MULTIPLE_HEAPS
// return the decommitted size
size_t gc_heap::decommit_ephemeral_segment_pages_step ()
Expand Down
4 changes: 0 additions & 4 deletions src/coreclr/gc/gcpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2079,10 +2079,6 @@ class gc_heap
size_t decommit_heap_segment_pages_worker (heap_segment* seg, uint8_t *new_committed);
PER_HEAP_ISOLATED
bool decommit_step (uint64_t step_milliseconds);
#ifdef USE_REGIONS
PER_HEAP_ISOLATED
size_t decommit_region (heap_segment* region, int bucket, int h_number);
#endif //USE_REGIONS
PER_HEAP
void decommit_heap_segment (heap_segment* seg);
PER_HEAP_ISOLATED
Expand Down