diff options
author | Sean Gillespie <sean@swgillespie.me> | 2017-04-09 13:58:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-09 13:58:29 -0700 |
commit | 2dfc74df1f9fe238eb2ec25c4764b8b65432b010 (patch) | |
tree | e04a2ddc84bf73067292cb9648d36ff3a0b92575 /src/gc | |
parent | 1a9781b68b8ec66c223bb96f44ae1d2704ce6fdf (diff) | |
download | coreclr-2dfc74df1f9fe238eb2ec25c4764b8b65432b010.tar.gz coreclr-2dfc74df1f9fe238eb2ec25c4764b8b65432b010.tar.bz2 coreclr-2dfc74df1f9fe238eb2ec25c4764b8b65432b010.zip |
[Local GC] Move knowledge of the free object method table outside of the GC (#10755)
* [Local GC] Move knowledge of the free object method table outside of the GC
* Revert "[Local GC] Move knowledge of the free object method table outside of the GC"
This reverts commit 02979e5eb12dd44edb2603e16411dd7d7ffc377d.
* Address code review feedback: leave ArrayBase alone, as it should be part of the binary contract between the EE and the GC
* Correct a bad merge
Diffstat (limited to 'src/gc')
-rw-r--r-- | src/gc/env/gcenv.ee.h | 1 | ||||
-rw-r--r-- | src/gc/gc.cpp | 24 | ||||
-rw-r--r-- | src/gc/gc.h | 1 | ||||
-rw-r--r-- | src/gc/gccommon.cpp | 1 | ||||
-rw-r--r-- | src/gc/gcenv.ee.standalone.inl | 5 | ||||
-rw-r--r-- | src/gc/gcinterface.ee.h | 10 | ||||
-rw-r--r-- | src/gc/sample/gcenv.ee.cpp | 5 |
7 files changed, 36 insertions, 11 deletions
diff --git a/src/gc/env/gcenv.ee.h b/src/gc/env/gcenv.ee.h index 5914f333ac..aa00d19780 100644 --- a/src/gc/env/gcenv.ee.h +++ b/src/gc/env/gcenv.ee.h @@ -73,6 +73,7 @@ public: static bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj); static bool ForceFullGCToBeBlocking(); static bool EagerFinalized(Object* obj); + static MethodTable* GetFreeObjectMethodTable(); }; #endif // __GCENV_EE_H__ diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp index ca03aaf3c2..ecc13e38fd 100644 --- a/src/gc/gc.cpp +++ b/src/gc/gc.cpp @@ -3891,10 +3891,10 @@ public: { assert (size >= free_object_base_size); - assert (g_pFreeObjectMethodTable->GetBaseSize() == free_object_base_size); - assert (g_pFreeObjectMethodTable->RawGetComponentSize() == 1); + assert (g_gc_pFreeObjectMethodTable->GetBaseSize() == free_object_base_size); + assert (g_gc_pFreeObjectMethodTable->RawGetComponentSize() == 1); - RawSetMethodTable( g_pFreeObjectMethodTable ); + RawSetMethodTable( g_gc_pFreeObjectMethodTable ); size_t* numComponentsPtr = (size_t*) &((uint8_t*) this)[ArrayBase::GetOffsetOfNumComponents()]; *numComponentsPtr = size - free_object_base_size; @@ -3919,7 +3919,7 @@ public: BOOL IsFree () const { - return (GetMethodTable() == g_pFreeObjectMethodTable); + return (GetMethodTable() == g_gc_pFreeObjectMethodTable); } #ifdef FEATURE_STRUCTALIGN @@ -21090,7 +21090,7 @@ BOOL gc_heap::plan_loh() { while (o < heap_segment_allocated (seg) && !marked (o)) { - dprintf (1235, ("%Ix(%Id) F (%d)", o, AlignQword (size (o)), ((method_table (o) == g_pFreeObjectMethodTable) ? 1 : 0))); + dprintf (1235, ("%Ix(%Id) F (%d)", o, AlignQword (size (o)), ((method_table (o) == g_gc_pFreeObjectMethodTable) ? 1 : 0))); o = o + AlignQword (size (o)); } } @@ -24346,7 +24346,7 @@ void gc_heap::walk_survivors_for_bgc (void* profiling_context, record_surv_fn fn while (o < end) { - if (method_table(o) == g_pFreeObjectMethodTable) + if (method_table(o) == g_gc_pFreeObjectMethodTable) { o += Align (size (o), align_const); continue; @@ -24357,7 +24357,7 @@ void gc_heap::walk_survivors_for_bgc (void* profiling_context, record_surv_fn fn uint8_t* plug_start = o; - while (method_table(o) != g_pFreeObjectMethodTable) + while (method_table(o) != g_gc_pFreeObjectMethodTable) { o += Align (size (o), align_const); if (o >= end) @@ -31543,7 +31543,7 @@ void gc_heap::background_sweep() seg = start_seg; prev_seg = 0; o = generation_allocation_start (gen); - assert (method_table (o) == g_pFreeObjectMethodTable); + assert (method_table (o) == g_gc_pFreeObjectMethodTable); align_const = get_alignment_constant (FALSE); o = o + Align(size (o), align_const); plug_end = o; @@ -32885,7 +32885,7 @@ void gc_heap::verify_partial () //dprintf (3, ("VOM: verifying member %Ix in obj %Ix", (size_t)*oo, o)); MethodTable *pMT = method_table (*oo); - if (pMT == g_pFreeObjectMethodTable) + if (pMT == g_gc_pFreeObjectMethodTable) { free_ref_p = TRUE; FATAL_GC_ERROR(); @@ -33319,12 +33319,12 @@ gc_heap::verify_heap (BOOL begin_gc_p) } } - if (*((uint8_t**)curr_object) != (uint8_t *) g_pFreeObjectMethodTable) + if (*((uint8_t**)curr_object) != (uint8_t *) g_gc_pFreeObjectMethodTable) { #ifdef FEATURE_LOH_COMPACTION if ((curr_gen_num == (max_generation+1)) && (prev_object != 0)) { - assert (method_table (prev_object) == g_pFreeObjectMethodTable); + assert (method_table (prev_object) == g_gc_pFreeObjectMethodTable); } #endif //FEATURE_LOH_COMPACTION @@ -33630,6 +33630,8 @@ HRESULT GCHeap::Initialize () return E_FAIL; } + g_gc_pFreeObjectMethodTable = GCToEEInterface::GetFreeObjectMethodTable(); + //Initialize the static members. #ifdef TRACE_GC GcDuration = 0; diff --git a/src/gc/gc.h b/src/gc/gc.h index 8cd92fd1c7..a661c311ab 100644 --- a/src/gc/gc.h +++ b/src/gc/gc.h @@ -113,6 +113,7 @@ extern "C" uint8_t* g_gc_lowest_address; extern "C" uint8_t* g_gc_highest_address; extern "C" GCHeapType g_gc_heap_type; extern "C" uint32_t g_max_generation; +extern "C" MethodTable* g_gc_pFreeObjectMethodTable; ::IGCHandleTable* CreateGCHandleTable(); diff --git a/src/gc/gccommon.cpp b/src/gc/gccommon.cpp index 1cd3c824ac..f931597667 100644 --- a/src/gc/gccommon.cpp +++ b/src/gc/gccommon.cpp @@ -43,6 +43,7 @@ uint8_t* g_gc_lowest_address = 0; uint8_t* g_gc_highest_address = 0; GCHeapType g_gc_heap_type = GC_HEAP_INVALID; uint32_t g_max_generation = max_generation; +MethodTable* g_gc_pFreeObjectMethodTable = nullptr; #ifdef GC_CONFIG_DRIVEN void record_global_mechanism (int mech_index) diff --git a/src/gc/gcenv.ee.standalone.inl b/src/gc/gcenv.ee.standalone.inl index f26a7768d5..f6954fc476 100644 --- a/src/gc/gcenv.ee.standalone.inl +++ b/src/gc/gcenv.ee.standalone.inl @@ -231,6 +231,11 @@ ALWAYS_INLINE bool GCToEEInterface::EagerFinalized(Object* obj) return g_theGCToCLR->EagerFinalized(obj); } +ALWAYS_INLINE MethodTable* GCToEEInterface::GetFreeObjectMethodTable() +{ + assert(g_theGCToCLR != nullptr); + return g_theGCToCLR->GetFreeObjectMethodTable(); +} #undef ALWAYS_INLINE #endif // __GCTOENV_EE_STANDALONE_INL__ diff --git a/src/gc/gcinterface.ee.h b/src/gc/gcinterface.ee.h index 3723dabe43..7b868e780e 100644 --- a/src/gc/gcinterface.ee.h +++ b/src/gc/gcinterface.ee.h @@ -156,6 +156,16 @@ public: // the EE can opt to elevate that collection to be a blocking GC and not a background one. virtual bool ForceFullGCToBeBlocking() = 0; + + // Retrieves the method table for the free object, a special kind of object used by the GC + // to keep the heap traversable. Conceptually, the free object is similar to a managed array + // of bytes: it consists of an object header (like all objects) and a "numComponents" field, + // followed by some number of bytes of space that's free on the heap. + // + // The free object allows the GC to traverse the heap because it can inspect the numComponents + // field to see how many bytes to skip before the next object on a heap segment begins. + virtual + MethodTable* GetFreeObjectMethodTable() = 0; }; #endif // _GCINTERFACE_EE_H_ diff --git a/src/gc/sample/gcenv.ee.cpp b/src/gc/sample/gcenv.ee.cpp index 0f7dca1d98..fa6efbf2d6 100644 --- a/src/gc/sample/gcenv.ee.cpp +++ b/src/gc/sample/gcenv.ee.cpp @@ -286,6 +286,11 @@ bool GCToEEInterface::EagerFinalized(Object* obj) return false; } +MethodTable* GCToEEInterface::GetFreeObjectMethodTable() +{ + return g_pFreeObjectMethodTable; +} + bool IsGCSpecialThread() { // TODO: Implement for background GC |