summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2015-12-08 20:46:46 -0800
committerJan Kotas <jkotas@microsoft.com>2015-12-08 20:46:46 -0800
commit58060b21799c81515f42872bafd5acd21e09311b (patch)
tree24bdfe3cae5f7b2a6fc1a7dc0cf1c76e26cceef1
parent9e874596ae7858591bbc6ce14c5a94e503e95151 (diff)
parent8058b6ab287d6b93b975d951384209b5fd0173eb (diff)
downloadcoreclr-58060b21799c81515f42872bafd5acd21e09311b.tar.gz
coreclr-58060b21799c81515f42872bafd5acd21e09311b.tar.bz2
coreclr-58060b21799c81515f42872bafd5acd21e09311b.zip
Merge pull request #2272 from jkotas/gc-update
Update GC from CoreRT
-rw-r--r--src/gc/env/gcenv.base.h11
-rw-r--r--src/gc/gc.cpp40
-rw-r--r--src/gc/gcscan.cpp71
-rw-r--r--src/gc/gcscan.h9
-rw-r--r--src/gc/sample/GCSample.cpp8
-rw-r--r--src/gc/sample/gcenv.cpp15
-rw-r--r--src/gc/sample/gcenv.h4
-rw-r--r--src/vm/gcenv.cpp64
-rw-r--r--src/vm/gcenv.h9
9 files changed, 111 insertions, 120 deletions
diff --git a/src/gc/env/gcenv.base.h b/src/gc/env/gcenv.base.h
index 57fbb0460b..5b8f5f7dd3 100644
--- a/src/gc/env/gcenv.base.h
+++ b/src/gc/env/gcenv.base.h
@@ -602,6 +602,8 @@ typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t);
typedef void (CALLBACK *HANDLESCANPROC)(PTR_UNCHECKED_OBJECTREF pref, uintptr_t *pExtraInfo, uintptr_t param1, uintptr_t param2);
+typedef void enum_alloc_context_func(alloc_context*, void*);
+
class GCToEEInterface
{
public:
@@ -620,10 +622,7 @@ public:
//
// The stack roots enumeration callback
//
- static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc);
-
- // Optional static GC refs scanning for better parallelization of server GC marking
- static void ScanStaticGCRefsOpportunistically(promote_func* fn, ScanContext* sc);
+ static void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
//
// Callbacks issues during GC that the execution engine can do its own bookeeping
@@ -655,12 +654,12 @@ public:
static void EnablePreemptiveGC(Thread * pThread);
static void DisablePreemptiveGC(Thread * pThread);
static void SetGCSpecial(Thread * pThread);
- static alloc_context * GetAllocContext(Thread * pThread);
static bool CatchAtSafePoint(Thread * pThread);
+ static alloc_context * GetAllocContext(Thread * pThread);
// ThreadStore functions
static void AttachCurrentThread(); // does not acquire thread store lock
- static Thread * GetThreadList(Thread * pThread);
+ static void GcEnumAllocContexts (enum_alloc_context_func* fn, void* param);
};
class FinalizerThread
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index 44450c0b1b..db878fbd8e 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -5767,7 +5767,7 @@ void gc_heap::fix_allocation_context (alloc_context* acontext, BOOL for_gc_p,
//used by the heap verification for concurrent gc.
//it nulls out the words set by fix_allocation_context for heap_verification
-void repair_allocation (alloc_context* acontext)
+void repair_allocation (alloc_context* acontext, void*)
{
uint8_t* point = acontext->alloc_ptr;
@@ -5780,7 +5780,7 @@ void repair_allocation (alloc_context* acontext)
}
}
-void void_allocation (alloc_context* acontext)
+void void_allocation (alloc_context* acontext, void*)
{
uint8_t* point = acontext->alloc_ptr;
@@ -5793,22 +5793,38 @@ void void_allocation (alloc_context* acontext)
}
}
-void gc_heap::fix_allocation_contexts (BOOL for_gc_p)
-{
- CNameSpace::GcFixAllocContexts ((void*)(size_t)for_gc_p, __this);
- fix_youngest_allocation_area (for_gc_p);
- fix_large_allocation_area (for_gc_p);
-}
-
void gc_heap::repair_allocation_contexts (BOOL repair_p)
{
- CNameSpace::GcEnumAllocContexts (repair_p ? repair_allocation : void_allocation);
+ GCToEEInterface::GcEnumAllocContexts (repair_p ? repair_allocation : void_allocation, NULL);
alloc_context* acontext = generation_alloc_context (youngest_generation);
if (repair_p)
- repair_allocation (acontext);
+ repair_allocation (acontext, NULL);
else
- void_allocation (acontext);
+ void_allocation (acontext, NULL);
+}
+
+struct fix_alloc_context_args
+{
+ BOOL for_gc_p;
+ void* heap;
+};
+
+void fix_alloc_context(alloc_context* acontext, void* param)
+{
+ fix_alloc_context_args* args = (fix_alloc_context_args*)param;
+ GCHeap::GetGCHeap()->FixAllocContext(acontext, FALSE, (void*)(size_t)(args->for_gc_p), args->heap);
+}
+
+void gc_heap::fix_allocation_contexts(BOOL for_gc_p)
+{
+ fix_alloc_context_args args;
+ args.for_gc_p = for_gc_p;
+ args.heap = __this;
+ GCToEEInterface::GcEnumAllocContexts(fix_alloc_context, &args);
+
+ fix_youngest_allocation_area(for_gc_p);
+ fix_large_allocation_area(for_gc_p);
}
void gc_heap::fix_older_allocation_area (generation* older_gen)
diff --git a/src/gc/gcscan.cpp b/src/gc/gcscan.cpp
index 50b76f54cd..dd7b4c1be6 100644
--- a/src/gc/gcscan.cpp
+++ b/src/gc/gcscan.cpp
@@ -36,11 +36,16 @@ bool CNameSpace::GetGcRuntimeStructuresValid ()
}
#ifdef DACCESS_COMPILE
+
+#ifndef FEATURE_REDHAWK
void
CNameSpace::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
{
+ UNREFERENCED_PARAMETER(flags);
m_GcStructuresInvalidCnt.EnumMem();
}
+#endif
+
#else
//
@@ -119,7 +124,7 @@ void CNameSpace::GcWeakPtrScan( promote_func* fn, int condemned, int max_gen, Sc
Ref_ScanDependentHandlesForClearing(condemned, max_gen, sc, fn);
}
-static void CALLBACK CheckPromoted(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pExtraInfo, uintptr_t lp1, uintptr_t lp2)
+static void CALLBACK CheckPromoted(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t * /*pExtraInfo*/, uintptr_t /*lp1*/, uintptr_t /*lp2*/)
{
LIMITED_METHOD_CONTRACT;
@@ -140,6 +145,8 @@ static void CALLBACK CheckPromoted(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pEx
void CNameSpace::GcWeakPtrScanBySingleThread( int condemned, int max_gen, ScanContext* sc )
{
+ UNREFERENCED_PARAMETER(condemned);
+ UNREFERENCED_PARAMETER(max_gen);
GCToEEInterface::SyncBlockCacheWeakPtrScan(&CheckPromoted, (uintptr_t)sc, 0);
}
@@ -151,6 +158,7 @@ void CNameSpace::GcScanSizedRefs(promote_func* fn, int condemned, int max_gen, S
void CNameSpace::GcShortWeakPtrScan(promote_func* fn, int condemned, int max_gen,
ScanContext* sc)
{
+ UNREFERENCED_PARAMETER(fn);
Ref_CheckAlive(condemned, max_gen, (uintptr_t)sc);
}
@@ -166,37 +174,7 @@ void CNameSpace::GcScanRoots(promote_func* fn, int condemned, int max_gen,
PAL_TRY
#endif // _DEBUG && CATCH_GC
{
- STRESS_LOG1(LF_GCROOTS, LL_INFO10, "GCScan: Promotion Phase = %d\n", sc->promotion);
- {
- // In server GC, we should be competing for marking the statics
- if (GCHeap::MarkShouldCompeteForStatics())
- {
- if (condemned == max_gen && sc->promotion)
- {
- GCToEEInterface::ScanStaticGCRefsOpportunistically(fn, sc);
- }
- }
-
- Thread* pThread = NULL;
- while ((pThread = GCToEEInterface::GetThreadList(pThread)) != NULL)
- {
- STRESS_LOG2(LF_GC|LF_GCROOTS, LL_INFO100, "{ Starting scan of Thread %p ID = %x\n", pThread, pThread->GetThreadId());
-
- if (GCHeap::GetGCHeap()->IsThreadUsingAllocationContextHeap(
- GCToEEInterface::GetAllocContext(pThread), sc->thread_number))
- {
- sc->thread_under_crawl = pThread;
-#ifdef FEATURE_EVENT_TRACE
- sc->dwEtwRootKind = kEtwGCRootKindStack;
-#endif // FEATURE_EVENT_TRACE
- GCToEEInterface::ScanStackRoots(pThread, fn, sc);
-#ifdef FEATURE_EVENT_TRACE
- sc->dwEtwRootKind = kEtwGCRootKindOther;
-#endif // FEATURE_EVENT_TRACE
- }
- STRESS_LOG2(LF_GC|LF_GCROOTS, LL_INFO100, "Ending scan of Thread %p ID = 0x%x }\n", pThread, pThread->GetThreadId());
- }
- }
+ GCToEEInterface::GcScanRoots(fn, condemned, max_gen, sc);
}
#if defined ( _DEBUG) && defined (CATCH_GC)
PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -318,35 +296,6 @@ void CNameSpace::GcPromotionsGranted (int condemned, int max_gen, ScanContext* s
}
-void CNameSpace::GcFixAllocContexts (void* arg, void *heap)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (GCHeap::UseAllocationContexts())
- {
- Thread *thread = NULL;
- while ((thread = GCToEEInterface::GetThreadList(thread)) != NULL)
- {
- GCHeap::GetGCHeap()->FixAllocContext(GCToEEInterface::GetAllocContext(thread), FALSE, arg, heap);
- }
- }
-}
-
-void CNameSpace::GcEnumAllocContexts (enum_alloc_context_func* fn)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (GCHeap::UseAllocationContexts())
- {
- Thread *thread = NULL;
- while ((thread = GCToEEInterface::GetThreadList(thread)) != NULL)
- {
- (*fn) (GCToEEInterface::GetAllocContext(thread));
- }
- }
-}
-
-
size_t CNameSpace::AskForMoreReservedMemory (size_t old_size, size_t need_size)
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/gc/gcscan.h b/src/gc/gcscan.h
index 956622abb4..0fddf3540e 100644
--- a/src/gc/gcscan.h
+++ b/src/gc/gcscan.h
@@ -39,17 +39,12 @@ struct DhContext
// something like GCDomain....
// </TODO>
-typedef void enum_alloc_context_func(alloc_context*);
-
class CNameSpace
{
friend struct ::_DacGlobals;
public:
- // Called on gc start
- static void GcStartDoWork();
-
static void GcScanSizedRefs(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
// Regular stack Roots
@@ -99,10 +94,6 @@ class CNameSpace
// post-promotions callback some roots were demoted
static void GcDemote (int condemned, int max_gen, ScanContext* sc);
-
- static void GcEnumAllocContexts (enum_alloc_context_func* fn);
-
- static void GcFixAllocContexts (void* arg, void *heap);
static size_t AskForMoreReservedMemory (size_t old_size, size_t need_size);
diff --git a/src/gc/sample/GCSample.cpp b/src/gc/sample/GCSample.cpp
index 7ae6c2d115..446956110a 100644
--- a/src/gc/sample/GCSample.cpp
+++ b/src/gc/sample/GCSample.cpp
@@ -26,11 +26,11 @@
// static void SuspendEE(SUSPEND_REASON reason);
// static void RestartEE(bool bFinishedGC); //resume threads.
//
-// * Enumeration of threads that are running managed code:
-// static Thread * GetThreadList(Thread * pThread);
+// * Enumeration of thread-local allocators:
+// static void GcEnumAllocContexts (enum_alloc_context_func* fn, void* param);
//
-// * Scanning of stack roots of given thread:
-// static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc);
+// * Scanning of stack roots:
+// static void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
//
// The sample has trivial implementation for these methods. It is single threaded, and there are no stack roots to
// be reported. There are number of other callbacks that GC calls to optionally allow the execution engine to do its
diff --git a/src/gc/sample/gcenv.cpp b/src/gc/sample/gcenv.cpp
index f1d6cfad0f..2164fb0c5e 100644
--- a/src/gc/sample/gcenv.cpp
+++ b/src/gc/sample/gcenv.cpp
@@ -60,15 +60,11 @@ void GCToEEInterface::RestartEE(bool bFinishedGC)
GCHeap::GetGCHeap()->SetGCInProgress(FALSE);
}
-void GCToEEInterface::ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
+void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc)
{
// TODO: Implement - Scan stack roots on given thread
}
-void GCToEEInterface::ScanStaticGCRefsOpportunistically(promote_func* fn, ScanContext* sc)
-{
-}
-
void GCToEEInterface::GcStartWork(int condemned, int max_gen)
{
}
@@ -126,11 +122,16 @@ void GCToEEInterface::AttachCurrentThread()
ThreadStore::AttachCurrentThread();
}
-Thread * GCToEEInterface::GetThreadList(Thread * pThread)
+void GCToEEInterface::GcEnumAllocContexts (enum_alloc_context_func* fn, void* param)
{
- return ThreadStore::GetThreadList(pThread);
+ Thread * pThread = NULL;
+ while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL)
+ {
+ fn(pThread->GetAllocContext(), param);
+ }
}
+
void FinalizerThread::EnableFinalization()
{
// Signal to finalizer thread that there are objects to finalize
diff --git a/src/gc/sample/gcenv.h b/src/gc/sample/gcenv.h
index 1a9fac5717..1e391ab80c 100644
--- a/src/gc/sample/gcenv.h
+++ b/src/gc/sample/gcenv.h
@@ -16,6 +16,7 @@
#define _ASSERTE(_expr) ASSERT(_expr)
#endif
+#include "gcenv.structs.h"
#include "gcenv.base.h"
#include "gcenv.object.h"
#include "gcenv.sync.h"
@@ -139,3 +140,6 @@ public:
};
extern EEConfig * g_pConfig;
+
+#include "etmdummy.h"
+#define ETW_EVENT_ENABLED(e,f) false
diff --git a/src/vm/gcenv.cpp b/src/vm/gcenv.cpp
index 5188e424e8..99880b54a1 100644
--- a/src/vm/gcenv.cpp
+++ b/src/vm/gcenv.cpp
@@ -466,23 +466,11 @@ VOID GCToEEInterface::AfterGcScanRoots (int condemned, int max_gen,
#endif // FEATURE_COMINTEROP
}
-void GCToEEInterface::ScanStaticGCRefsOpportunistically(promote_func* fn, ScanContext* sc)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- SystemDomain::EnumAllStaticGCRefs(fn, sc);
-}
-
/*
* Scan all stack roots
*/
-VOID GCToEEInterface::ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
+static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
{
GCCONTEXT gcctx;
@@ -557,6 +545,40 @@ VOID GCToEEInterface::ScanStackRoots(Thread * pThread, promote_func* fn, ScanCon
}
}
+void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc)
+{
+ STRESS_LOG1(LF_GCROOTS, LL_INFO10, "GCScan: Promotion Phase = %d\n", sc->promotion);
+
+ // In server GC, we should be competing for marking the statics
+ if (GCHeap::MarkShouldCompeteForStatics())
+ {
+ if (condemned == max_gen && sc->promotion)
+ {
+ SystemDomain::EnumAllStaticGCRefs(fn, sc);
+ }
+ }
+
+ Thread* pThread = NULL;
+ while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL)
+ {
+ STRESS_LOG2(LF_GC | LF_GCROOTS, LL_INFO100, "{ Starting scan of Thread %p ID = %x\n", pThread, pThread->GetThreadId());
+
+ if (GCHeap::GetGCHeap()->IsThreadUsingAllocationContextHeap(
+ GCToEEInterface::GetAllocContext(pThread), sc->thread_number))
+ {
+ sc->thread_under_crawl = pThread;
+#ifdef FEATURE_EVENT_TRACE
+ sc->dwEtwRootKind = kEtwGCRootKindStack;
+#endif // FEATURE_EVENT_TRACE
+ ScanStackRoots(pThread, fn, sc);
+#ifdef FEATURE_EVENT_TRACE
+ sc->dwEtwRootKind = kEtwGCRootKindOther;
+#endif // FEATURE_EVENT_TRACE
+ }
+ STRESS_LOG2(LF_GC | LF_GCROOTS, LL_INFO100, "Ending scan of Thread %p ID = 0x%x }\n", pThread, pThread->GetThreadId());
+ }
+}
+
void GCToEEInterface::GcStartWork (int condemned, int max_gen)
{
CONTRACTL
@@ -689,8 +711,18 @@ bool GCToEEInterface::CatchAtSafePoint(Thread * pThread)
return !!pThread->CatchAtSafePoint();
}
-Thread * GCToEEInterface::GetThreadList(Thread * pThread)
+void GCToEEInterface::GcEnumAllocContexts(enum_alloc_context_func* fn, void* param)
{
- WRAPPER_NO_CONTRACT;
- return ThreadStore::GetThreadList(pThread);
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ Thread * pThread = NULL;
+ while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL)
+ {
+ fn(pThread->GetAllocContext(), param);
+ }
}
diff --git a/src/vm/gcenv.h b/src/vm/gcenv.h
index 93d41850a7..73e65852a7 100644
--- a/src/vm/gcenv.h
+++ b/src/vm/gcenv.h
@@ -51,6 +51,8 @@ class CrawlFrame;
typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t);
+typedef void enum_alloc_context_func(alloc_context*, void*);
+
typedef struct
{
promote_func* f;
@@ -77,10 +79,7 @@ public:
//
// The GC roots enumeration callback
//
- static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc);
-
- // Optional static GC refs scanning for better parallelization of server GC marking
- static void ScanStaticGCRefsOpportunistically(promote_func* fn, ScanContext* sc);
+ static void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
//
// Callbacks issues during GC that the execution engine can do its own bookeeping
@@ -130,7 +129,7 @@ public:
static alloc_context * GetAllocContext(Thread * pThread);
static bool CatchAtSafePoint(Thread * pThread);
- static Thread * GetThreadList(Thread * pThread);
+ static void GcEnumAllocContexts(enum_alloc_context_func* fn, void* param);
};
#define GCMemoryStatus MEMORYSTATUSEX