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
85 changes: 64 additions & 21 deletions src/coreclr/gc/allocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5473,6 +5473,55 @@ heap_segment* gc_heap::get_next_alloc_seg (generation* gen)
#endif //USE_REGIONS
}

bool gc_heap::decide_on_gen1_pin_promotion (float pin_frag_ratio, float pin_surv_ratio)
{
return ((pin_frag_ratio > 0.15) && (pin_surv_ratio > 0.30));
}

// Add the size of the pinned plug to the higher generation's pinned allocations.
void gc_heap::attribute_pin_higher_gen_alloc (
#ifdef USE_REGIONS
heap_segment* seg, int to_gen_number,
#endif
uint8_t* plug, size_t len)
{
//find out which gen this pinned plug came from
int frgn = object_gennum (plug);
if ((frgn != (int)max_generation) && settings.promotion)
{
generation_pinned_allocation_sweep_size (generation_of (frgn + 1)) += len;

#ifdef USE_REGIONS
// With regions it's a bit more complicated since we only set the plan_gen_num
// of a region after we've planned it. This means if the pinning plug is in
// the same seg we are planning, we haven't set its plan_gen_num yet. So we
Comment thread
janvorli marked this conversation as resolved.
// need to check for that first.
int togn = (in_range_for_segment (plug, seg) ? to_gen_number : object_gennum_plan (plug));
#else
int togn = object_gennum_plan (plug);
#endif //USE_REGIONS
if (frgn < togn)
{
generation_pinned_allocation_compact_size (generation_of (togn)) += len;
}
}
}

#ifdef USE_REGIONS
void gc_heap::attribute_pin_higher_gen_alloc (int frgn, int togn, size_t len)
{
if ((frgn != (int)max_generation) && settings.promotion)
{
generation_pinned_allocation_sweep_size (generation_of (frgn + 1)) += len;

if (frgn < togn)
{
generation_pinned_allocation_compact_size (generation_of (togn)) += len;
}
}
}
#endif //USE_REGIONS

uint8_t* gc_heap::allocate_in_condemned_generations (generation* gen,
size_t size,
int from_gen_number,
Expand Down Expand Up @@ -5505,6 +5554,16 @@ uint8_t* gc_heap::allocate_in_condemned_generations (generation* gen,

#ifdef SHORT_PLUGS
int pad_in_front = ((old_loc != 0) && (to_gen_number != max_generation)) ? USE_PADDING_FRONT : 0;

// A near-region-sized plug can't fit with front padding even in an empty region, so skip the padding.
// This is safe because front padding only exists to protect short plugs (shorter than sizeof(plug_and_gap))
// from being overwritten by the plug_and_gap header during compaction — a plug this large is in no such danger.
if ((pad_in_front & USE_PADDING_FRONT) &&
(size + Align (min_obj_size) >
((size_t)1 << min_segment_size_shr) - sizeof (aligned_plug_and_gap)))
{
pad_in_front = 0;
}
Comment thread
janvorli marked this conversation as resolved.
#else //SHORT_PLUGS
int pad_in_front = 0;
#endif //SHORT_PLUGS
Expand Down Expand Up @@ -5560,28 +5619,12 @@ uint8_t* gc_heap::allocate_in_condemned_generations (generation* gen,
generation_allocation_context_start_region (gen) = generation_allocation_pointer (gen);
generation_allocation_limit (gen) = heap_segment_plan_allocated (seg);
set_allocator_next_pin (gen);

//Add the size of the pinned plug to the right pinned allocations
//find out which gen this pinned plug came from
int frgn = object_gennum (plug);
if ((frgn != (int)max_generation) && settings.promotion)
{
generation_pinned_allocation_sweep_size (generation_of (frgn + 1)) += len;

attribute_pin_higher_gen_alloc (
#ifdef USE_REGIONS
// With regions it's a bit more complicated since we only set the plan_gen_num
// of a region after we've planned it. This means if the pinning plug is in the
// the same seg we are planning, we haven't set its plan_gen_num yet. So we
// need to check for that first.
int togn = (in_range_for_segment (plug, seg) ? to_gen_number : object_gennum_plan (plug));
#else
int togn = object_gennum_plan (plug);
#endif //USE_REGIONS
if (frgn < togn)
{
generation_pinned_allocation_compact_size (generation_of (togn)) += len;
}
}
seg, to_gen_number,
#endif
plug, len);

goto retry;
}

Expand Down
10 changes: 4 additions & 6 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,14 @@ BOOL bgc_heap_walk_for_etw_p = FALSE;
#define num_partial_refs 32
#endif //SERVER_GC

#define demotion_plug_len_th (6*1024*1024)

#ifdef USE_REGIONS
// If the pinned survived is 1+% of the region size, we don't demote.
#define demotion_pinned_ratio_th (1)
// If the survived / region_size is 90+%, we don't compact this region.
#define sip_surv_ratio_th (90)
// If the survived due to cards from old generations / region_size is 90+%,
// we don't compact this region, also we immediately promote it to gen2.
#define sip_old_card_surv_ratio_th (90)
#else
#define demotion_plug_len_th (6*1024*1024)
#endif //USE_REGIONS

#ifdef HOST_64BIT
Expand Down Expand Up @@ -2316,6 +2314,8 @@ BOOL gc_heap::last_gc_before_oom = FALSE;

BOOL gc_heap::sufficient_gen0_space_p = FALSE;

BOOL gc_heap::decide_promote_gen1_pins_p = TRUE;

#ifdef BACKGROUND_GC
uint8_t* gc_heap::background_saved_lowest_address = 0;
uint8_t* gc_heap::background_saved_highest_address = 0;
Expand Down Expand Up @@ -2367,8 +2367,6 @@ uint8_t* gc_heap::demotion_low;

uint8_t* gc_heap::demotion_high;

BOOL gc_heap::demote_gen1_p = TRUE;

uint8_t* gc_heap::last_gen1_pin_end;
#endif //!USE_REGIONS

Expand Down
19 changes: 17 additions & 2 deletions src/coreclr/gc/gcpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1694,7 +1694,10 @@ class gc_heap
PER_HEAP_METHOD void set_region_sweep_in_plan (heap_segment* region);
PER_HEAP_METHOD void clear_region_sweep_in_plan (heap_segment* region);
PER_HEAP_METHOD void clear_region_demoted (heap_segment* region);
PER_HEAP_METHOD void decide_on_demotion_pin_surv (heap_segment* region, int* no_pinned_surv_region_count);
PER_HEAP_METHOD void decide_on_demotion_pin_surv (heap_segment* region,
int* no_pinned_surv_region_count,
bool promote_gen1_pins_p,
bool large_pins_p);
PER_HEAP_METHOD void skip_pins_in_alloc_region (generation* consing_gen, int plan_gen_num);
PER_HEAP_METHOD void process_last_np_surv_region (generation* consing_gen,
int current_plan_gen_num,
Expand Down Expand Up @@ -2625,6 +2628,15 @@ class gc_heap
#ifndef USE_REGIONS
PER_HEAP_METHOD generation* ensure_ephemeral_heap_segment (generation* consing_gen);
#endif //!USE_REGIONS

PER_HEAP_ISOLATED_METHOD bool decide_on_gen1_pin_promotion (float pin_frag_ratio, float pin_surv_ratio);

PER_HEAP_METHOD void attribute_pin_higher_gen_alloc (
#ifdef USE_REGIONS
heap_segment* seg, int to_gen_number,
#endif
uint8_t* plug, size_t len);

PER_HEAP_METHOD uint8_t* allocate_in_condemned_generations (generation* gen,
size_t size,
int from_gen_number,
Expand All @@ -2646,6 +2658,8 @@ class gc_heap
PER_HEAP_METHOD size_t get_promoted_bytes();

#ifdef USE_REGIONS
PER_HEAP_METHOD void attribute_pin_higher_gen_alloc (int frgn, int togn, size_t len);

PER_HEAP_ISOLATED_METHOD void sync_promoted_bytes();

PER_HEAP_ISOLATED_METHOD void set_heap_for_contained_basic_regions (heap_segment* region, gc_heap* hp);
Expand Down Expand Up @@ -3529,6 +3543,8 @@ class gc_heap
// Set during a GC and checked by allocator after that GC
PER_HEAP_FIELD_SINGLE_GC BOOL sufficient_gen0_space_p;

PER_HEAP_FIELD_SINGLE_GC BOOL decide_promote_gen1_pins_p;

PER_HEAP_FIELD_SINGLE_GC bool no_gc_oom_p;
PER_HEAP_FIELD_SINGLE_GC heap_segment* saved_loh_segment_no_gc;

Expand Down Expand Up @@ -3668,7 +3684,6 @@ class gc_heap

PER_HEAP_FIELD_SINGLE_GC uint8_t* demotion_low;
PER_HEAP_FIELD_SINGLE_GC uint8_t* demotion_high;
PER_HEAP_FIELD_SINGLE_GC BOOL demote_gen1_p;
PER_HEAP_FIELD_SINGLE_GC uint8_t* last_gen1_pin_end;

PER_HEAP_FIELD_SINGLE_GC BOOL ephemeral_promotion;
Expand Down
Loading
Loading