Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

regions BGC work #46972

Merged
merged 1 commit into from
Jan 15, 2021
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
regions BGC work
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 14, 2021
commit cb7ed0685ea2ca07f4761ff1636308119c3e1eb1
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);
Maoni0 marked this conversation as resolved.
Show resolved Hide resolved
_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)
{
}