Skip to content

Commit

Permalink
regions BGC work (#46972)
Browse files Browse the repository at this point in the history
Regions work (mostly for BGC) -

+  updated the regions list for newly allocated UOH segs, when we delete segs during sweep/compact UOH
    and deleting segs that were marked eligible for deletion during BGC.
+  updated the region list for SOH segs deleted during BGC.
+  commit mark array for new segs if needed for BGC.
+  need to have BGC's ephemeral sweep look at background_allocated of gen0 regions because we could have
    alloc contexts on some gen0 regions that haven't been fixed up yet so we can't go beyond
    background_allocated. and it needs to set it to 0 when it's done with a region so BGC sweep doesn't
    try to look at it.
+  fixed a bug in GCHeap::IsPromoted where we should return true if it's not in condemned.
+  added the necessarily handle table methods to make STRESS_REGIONS work with embedded GC
+  made some dprintfs that only printed region print heap_segment_mem (region) so it's easier to correlate
+  fixed a bug in process_last_np_surv_region that Peter hit when he wasn't using STRESS_REGIONS where we
    ran out gen0 regions for the new consing_gen alloc context. I'm just getting a new region here and assuming
    we can but we need to make sure we actually can (I've put TODOs for this in the code).

Other work -

+  define VERIFY_HEAP for standalone GC and sample.
+  fixed a bug that also exists for doubly linked FL where we didn't update current_sweep_pos when a GC is
    triggered when we are waiting to acquire the UOH alloc lock which caused us to erroneously set BGC mark
    bit during BGC planning.

=================================================================

I've been running this GCPerfSim cmdline for 15 hours with no problems in the following condition -

gcperfsim.dll -tc 2 -tagb 128 -tlgb 0.05 -lohar 100 -sohsi 10 -lohsi 100 -pohsi 0 -sohpi 0 -lohpi 0 -sohfi 0 -lohfi 0 -pohfi 0 -allocType reference -testKind time -printEveryNthIter 300000

with the following env vars -

complus_GCRegionsRange=20000000
complus_GCName=clrgc.dll
(and env vars for logging)

So standalone GC with WKS GC + BGC + STRESS_REGIONS. I actually did do heap verification but a light weight version.

I also tried with embedded GC but just a little to verify the handle table changes.
  • Loading branch information
Maoni0 committed Jan 15, 2021
1 parent e3247ad commit 0fb9c00
Show file tree
Hide file tree
Showing 8 changed files with 442 additions and 137 deletions.
1 change: 1 addition & 0 deletions src/coreclr/gc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ if(CLR_CMAKE_HOST_UNIX)
endif(CLR_CMAKE_HOST_UNIX)

add_definitions(-DBUILD_AS_STANDALONE)
add_definitions(-DVERIFY_HEAP)
if(CLR_CMAKE_HOST_OSX)
# The implementation of GCToOSInterface on MacOS makes use of non-POSIX
# pthreads APIs, which by default are not included in the pthreads header
Expand Down
496 changes: 369 additions & 127 deletions src/coreclr/gc/gc.cpp

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions src/coreclr/gc/gcpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,8 @@ class gc_heap
PER_HEAP
void verify_free_lists();
PER_HEAP
void verify_regions();
PER_HEAP
void verify_heap (BOOL begin_gc_p);
PER_HEAP
BOOL check_need_card (uint8_t* child_obj, int gen_num_for_cards,
Expand Down Expand Up @@ -1307,6 +1309,16 @@ class gc_heap
void thread_rest_of_generation (generation* gen, heap_segment* region);
PER_HEAP
heap_segment* get_new_region (int gen_number);
// This allocates one from region allocator and commit the mark array if needed.
PER_HEAP_ISOLATED
heap_segment* allocate_new_region (gc_heap* hp, int gen_num, bool uoh_p);
// When we delete a region we need to update start and tail region
// if needed.
PER_HEAP
void update_start_tail_regions (generation* gen,
heap_segment* region_to_delete,
heap_segment* prev_region,
heap_segment* next_region);
#endif //USE_REGIONS

static
Expand Down Expand Up @@ -3364,6 +3376,12 @@ class gc_heap
PER_HEAP
int num_free_large_regions;

PER_HEAP
int num_free_large_regions_added;

PER_HEAP
int num_free_large_regions_removed;

PER_HEAP
size_t committed_in_free;

Expand Down
13 changes: 3 additions & 10 deletions src/coreclr/gc/handletable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,21 +540,14 @@ void HndLogSetEvent(OBJECTHANDLE handle, _UNCHECKED_OBJECTREF value)

#ifndef DACCESS_COMPILE
/*
* HndWriteBarrier
* HndWriteBarrierWorker
*
* Resets the generation number for the handle's clump to zero.
*
*/
void HndWriteBarrier(OBJECTHANDLE handle, OBJECTREF objref)
void HndWriteBarrierWorker(OBJECTHANDLE handle, _UNCHECKED_OBJECTREF value)
{
STATIC_CONTRACT_NOTHROW;
STATIC_CONTRACT_GC_NOTRIGGER;
STATIC_CONTRACT_MODE_COOPERATIVE;

// unwrap the objectref we were given
_UNCHECKED_OBJECTREF value = OBJECTREF_TO_UNCHECKED_OBJECTREF(objref);

_ASSERTE (objref != NULL);
_ASSERTE (value != NULL);

// find the write barrier for this handle
uint8_t *barrier = (uint8_t *)((uintptr_t)handle & HANDLE_SEGMENT_ALIGN_MASK);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/gc/handletable.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ HHANDLETABLE HndGetHandleTable(OBJECTHANDLE handle);
/*
* write barrier
*/
void HndWriteBarrierWorker(OBJECTHANDLE handle, _UNCHECKED_OBJECTREF value);
void HndWriteBarrier(OBJECTHANDLE handle, OBJECTREF value);

/*
Expand Down
40 changes: 40 additions & 0 deletions src/coreclr/gc/handletable.inl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@
#ifndef _HANDLETABLE_INL
#define _HANDLETABLE_INL

inline void HndWriteBarrier(OBJECTHANDLE handle, OBJECTREF objref)
{
STATIC_CONTRACT_NOTHROW;
STATIC_CONTRACT_GC_NOTRIGGER;
STATIC_CONTRACT_MODE_COOPERATIVE;

// unwrap the objectref we were given
_UNCHECKED_OBJECTREF value = OBJECTREF_TO_UNCHECKED_OBJECTREF(objref);

_ASSERTE (objref != NULL);

HndWriteBarrierWorker(handle, value);
}

inline void HndAssignHandle(OBJECTHANDLE handle, OBJECTREF objref)
{
CONTRACTL
Expand All @@ -33,6 +47,32 @@ inline void HndAssignHandle(OBJECTHANDLE handle, OBJECTREF objref)
*(_UNCHECKED_OBJECTREF *)handle = value;
}

// This is used by the GC before we actually construct the object so we cannot
// do the normal object verification.
inline void HndAssignHandleGC(OBJECTHANDLE handle, uint8_t* objref)
{
CONTRACTL
{
NOTHROW;
GC_NOTRIGGER;
MODE_COOPERATIVE;
}
CONTRACTL_END;

// sanity
_ASSERTE(handle);

// unwrap the objectref we were given
_UNCHECKED_OBJECTREF value = (_UNCHECKED_OBJECTREF)(Object*)objref;

// if we are doing a non-NULL pointer store then invoke the write-barrier
if (value)
HndWriteBarrierWorker(handle, value);

// store the pointer
*(_UNCHECKED_OBJECTREF *)handle = value;
}

inline void* HndInterlockedCompareExchangeHandle(OBJECTHANDLE handle, OBJECTREF objref, OBJECTREF oldObjref)
{
WRAPPER_NO_CONTRACT;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/gc/sample/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ if(CLR_CMAKE_TARGET_WIN32)
advapi32.lib)
endif(CLR_CMAKE_TARGET_WIN32)

add_definitions(-DVERIFY_HEAP)

if(CLR_CMAKE_TARGET_WIN32)
list(APPEND SOURCES
../windows/gcenv.windows.cpp)
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/gc/sample/gcenv.ee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,11 @@ inline void GCToEEInterface::AnalyzeSurvivorsFinished(size_t gcIndex, int condem
{

}

void GCToEEInterface::VerifySyncTableEntry()
{
}

void GCToEEInterface::UpdateGCEventStatus(int currentPublicLevel, int currentPublicKeywords, int currentPrivateLevel, int currentPrivateKeywords)
{
}

0 comments on commit 0fb9c00

Please sign in to comment.