summaryrefslogtreecommitdiff
path: root/src/gc
diff options
context:
space:
mode:
authorSean Gillespie <sean@swgillespie.me>2017-04-09 13:58:29 -0700
committerGitHub <noreply@github.com>2017-04-09 13:58:29 -0700
commit2dfc74df1f9fe238eb2ec25c4764b8b65432b010 (patch)
treee04a2ddc84bf73067292cb9648d36ff3a0b92575 /src/gc
parent1a9781b68b8ec66c223bb96f44ae1d2704ce6fdf (diff)
downloadcoreclr-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.h1
-rw-r--r--src/gc/gc.cpp24
-rw-r--r--src/gc/gc.h1
-rw-r--r--src/gc/gccommon.cpp1
-rw-r--r--src/gc/gcenv.ee.standalone.inl5
-rw-r--r--src/gc/gcinterface.ee.h10
-rw-r--r--src/gc/sample/gcenv.ee.cpp5
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