summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2016-02-24 22:41:19 -0800
committerJan Kotas <jkotas@microsoft.com>2016-02-24 22:44:20 -0800
commite1fd6dc6d5adf7c4107e60fdb8a6bcb5fc57069f (patch)
tree5e135f8dcb1907cf4fe1103c79fafbae929d1a78 /src
parent81e977ce7be76c4bda86aeb952d13dc136998341 (diff)
downloadcoreclr-e1fd6dc6d5adf7c4107e60fdb8a6bcb5fc57069f.tar.gz
coreclr-e1fd6dc6d5adf7c4107e60fdb8a6bcb5fc57069f.tar.bz2
coreclr-e1fd6dc6d5adf7c4107e60fdb8a6bcb5fc57069f.zip
Update GC from CoreRT
https://github.com/dotnet/corert/tree/master/src/Native/gc d18f7e5d9fea784b4531aa8988fdad9f3a9cffc3
Diffstat (limited to 'src')
-rw-r--r--src/gc/env/gcenv.base.h1
-rw-r--r--src/gc/gc.cpp66
-rw-r--r--src/gc/gc.h6
-rw-r--r--src/gc/gccommon.cpp2
-rwxr-xr-xsrc/gc/gcee.cpp28
-rw-r--r--src/gc/gcscan.h7
-rw-r--r--src/gc/handletablecore.cpp4
-rw-r--r--src/gc/sample/gcenv.unix.cpp6
8 files changed, 57 insertions, 63 deletions
diff --git a/src/gc/env/gcenv.base.h b/src/gc/env/gcenv.base.h
index 0a277501d7..f3317fc79e 100644
--- a/src/gc/env/gcenv.base.h
+++ b/src/gc/env/gcenv.base.h
@@ -35,7 +35,6 @@
typedef uint32_t BOOL;
typedef uint32_t DWORD;
-typedef void* LPVOID;
// -----------------------------------------------------------------------------------------------------------
// HRESULT subset.
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index ca2cc9440b..5cbdfd7409 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -397,9 +397,8 @@ void log_va_msg(const char *fmt, va_list args)
static char rgchBuffer[BUFFERSIZE];
char * pBuffer = &rgchBuffer[0];
- pBuffer[0] = '\r';
- pBuffer[1] = '\n';
- int buffer_start = 2;
+ pBuffer[0] = '\n';
+ int buffer_start = 1;
int pid_len = sprintf_s (&pBuffer[buffer_start], BUFFERSIZE - buffer_start, "[%5d]", GCToOSInterface::GetCurrentThreadIdForLogging());
buffer_start += pid_len;
memset(&pBuffer[buffer_start], '-', BUFFERSIZE - buffer_start);
@@ -416,9 +415,8 @@ void log_va_msg(const char *fmt, va_list args)
char index_str[8];
memset (index_str, '-', 8);
sprintf_s (index_str, _countof(index_str), "%d", (int)gc_buffer_index);
- gc_log_buffer[gc_log_buffer_offset] = '\r';
- gc_log_buffer[gc_log_buffer_offset + 1] = '\n';
- memcpy (gc_log_buffer + (gc_log_buffer_offset + 2), index_str, 8);
+ gc_log_buffer[gc_log_buffer_offset] = '\n';
+ memcpy (gc_log_buffer + (gc_log_buffer_offset + 1), index_str, 8);
gc_buffer_index++;
if (gc_buffer_index > max_gc_buffers)
@@ -468,9 +466,8 @@ void log_va_msg_config(const char *fmt, va_list args)
static char rgchBuffer[BUFFERSIZE];
char * pBuffer = &rgchBuffer[0];
- pBuffer[0] = '\r';
- pBuffer[1] = '\n';
- int buffer_start = 2;
+ pBuffer[0] = '\n';
+ int buffer_start = 1;
int msg_len = _vsnprintf_s (&pBuffer[buffer_start], BUFFERSIZE - buffer_start, _TRUNCATE, fmt, args );
assert (msg_len != -1);
msg_len += buffer_start;
@@ -1509,6 +1506,18 @@ void WaitLongerNoInstru (int i)
{
if (bToggleGC || g_TrapReturningThreads)
{
+#ifdef _DEBUG
+ // In debug builds, all enter_spin_lock operations go through this code. If a GC has
+ // started, it is important to block until the GC thread calls set_gc_done (since it is
+ // guaranteed to have cleared g_TrapReturningThreads by this point). This avoids livelock
+ // conditions which can otherwise occur if threads are allowed to spin in this function
+ // (and therefore starve the GC thread) between the point when the GC thread sets the
+ // WaitForGC event and the point when the GC thread clears g_TrapReturningThreads.
+ if (gc_heap::gc_started)
+ {
+ gc_heap::wait_for_gc_done();
+ }
+#endif // _DEBUG
GCToEEInterface::DisablePreemptiveGC(pCurThread);
if (!bToggleGC)
{
@@ -5672,7 +5681,7 @@ void gc_heap::fix_large_allocation_area (BOOL for_gc_p)
#ifdef _DEBUG
alloc_context* acontext =
-#endif // DEBUG
+#endif // _DEBUG
generation_alloc_context (large_object_generation);
assert (acontext->alloc_ptr == 0);
assert (acontext->alloc_limit == 0);
@@ -6566,11 +6575,11 @@ uint32_t*& card_table_mark_array (uint32_t* c_table)
return ((card_table_info*)((uint8_t*)c_table - sizeof (card_table_info)))->mark_array;
}
-#if defined (_TARGET_AMD64_)
+#ifdef BIT64
#define mark_bit_pitch ((size_t)16)
#else
#define mark_bit_pitch ((size_t)8)
-#endif //AMD64
+#endif // BIT64
#define mark_word_width ((size_t)32)
#define mark_word_size (mark_word_width * mark_bit_pitch)
@@ -33342,35 +33351,6 @@ HRESULT GCHeap::Shutdown ()
return S_OK;
}
-//used by static variable implementation
-void CGCDescGcScan(LPVOID pvCGCDesc, promote_func* fn, ScanContext* sc)
-{
- CGCDesc* map = (CGCDesc*)pvCGCDesc;
-
- CGCDescSeries *last = map->GetLowestSeries();
- CGCDescSeries *cur = map->GetHighestSeries();
-
- assert (cur >= last);
- do
- {
- uint8_t** ppslot = (uint8_t**)((uint8_t*)pvCGCDesc + cur->GetSeriesOffset());
- uint8_t**ppstop = (uint8_t**)((uint8_t*)ppslot + cur->GetSeriesSize());
-
- while (ppslot < ppstop)
- {
- if (*ppslot)
- {
- (fn) ((Object**)ppslot, sc, 0);
- }
-
- ppslot++;
- }
-
- cur--;
- }
- while (cur >= last);
-}
-
// Wait until a garbage collection is complete
// returns NOERROR if wait was OK, other error code if failure.
// WARNING: This will not undo the must complete state. If you are
@@ -36629,7 +36609,7 @@ void GCHeap::WalkObject (Object* obj, walk_fn fn, void* context)
#endif //defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
// Go through and touch (read) each page straddled by a memory block.
-void TouchPages(LPVOID pStart, uint32_t cb)
+void TouchPages(void * pStart, size_t cb)
{
const uint32_t pagesize = OS_PAGE_SIZE;
_ASSERTE(0 == (pagesize & (pagesize-1))); // Must be a power of 2.
@@ -36728,7 +36708,7 @@ void initGCShadow()
}
}
-#define INVALIDGCVALUE (LPVOID)((size_t)0xcccccccd)
+#define INVALIDGCVALUE (void*)((size_t)0xcccccccd)
// test to see if 'ptr' was only updated via the write barrier.
inline void testGCShadow(Object** ptr)
diff --git a/src/gc/gc.h b/src/gc/gc.h
index 1b26b7378a..51c067718a 100644
--- a/src/gc/gc.h
+++ b/src/gc/gc.h
@@ -36,7 +36,7 @@ typedef gc_heap_segment_stub *segment_handle;
struct segment_info
{
- LPVOID pvMem; // base of the allocation, not the first object (must add ibFirstObject)
+ void * pvMem; // base of the allocation, not the first object (must add ibFirstObject)
size_t ibFirstObject; // offset to the base of the first object in the segment
size_t ibAllocated; // limit of allocated memory in the segment (>= firstobject)
size_t ibCommit; // limit of committed memory in the segment (>= alllocated)
@@ -244,7 +244,7 @@ typedef void (* gen_walk_fn)(void *context, int generation, uint8_t *range_start
struct ProfilingScanContext : ScanContext
{
BOOL fProfilerPinned;
- LPVOID pvEtwContext;
+ void * pvEtwContext;
void *pHeapId;
ProfilingScanContext(BOOL fProfilerPinnedParam) : ScanContext()
@@ -674,7 +674,7 @@ public:
extern VOLATILE(int32_t) m_GCLock;
// Go through and touch (read) each page straddled by a memory block.
-void TouchPages(LPVOID pStart, uint32_t cb);
+void TouchPages(void * pStart, size_t cb);
// For low memory notification from host
extern int32_t g_bLowMemoryFromHost;
diff --git a/src/gc/gccommon.cpp b/src/gc/gccommon.cpp
index 29bd468de6..779aac7296 100644
--- a/src/gc/gccommon.cpp
+++ b/src/gc/gccommon.cpp
@@ -55,7 +55,7 @@ int32_t g_bLowMemoryFromHost = 0;
#ifdef WRITE_BARRIER_CHECK
-#define INVALIDGCVALUE (LPVOID)((size_t)0xcccccccd)
+#define INVALIDGCVALUE (void *)((size_t)0xcccccccd)
// called by the write barrier to update the shadow heap
void updateGCShadow(Object** ptr, Object* val)
diff --git a/src/gc/gcee.cpp b/src/gc/gcee.cpp
index 54e7a056b2..60ff60aa90 100755
--- a/src/gc/gcee.cpp
+++ b/src/gc/gcee.cpp
@@ -402,8 +402,8 @@ void ProfScanRootsHelper(Object** ppObject, ScanContext *pSC, uint32_t dwFlags)
pObj = (Object*) hp->find_object(o, hp->gc_low);
}
#endif //INTERIOR_POINTERS
- ScanRootsHelper(&pObj, pSC, dwFlags);
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ ScanRootsHelper(&pObj, ppObject, pSC, dwFlags);
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
}
// TODO - at some point we would like to completely decouple profiling
@@ -416,7 +416,8 @@ void ProfScanRootsHelper(Object** ppObject, ScanContext *pSC, uint32_t dwFlags)
// Returns TRUE if GC profiling is enabled and the profiler
// should scan dependent handles, FALSE otherwise.
-BOOL ProfilerShouldTrackConditionalWeakTableElements() {
+BOOL ProfilerShouldTrackConditionalWeakTableElements()
+{
#if defined(GC_PROFILING)
return CORProfilerTrackConditionalWeakTableElements();
#else
@@ -426,17 +427,23 @@ BOOL ProfilerShouldTrackConditionalWeakTableElements() {
// If GC profiling is enabled, informs the profiler that we are done
// tracing dependent handles.
-void ProfilerEndConditionalWeakTableElementReferences(void* heapId) {
+void ProfilerEndConditionalWeakTableElementReferences(void* heapId)
+{
#if defined (GC_PROFILING)
g_profControlBlock.pProfInterface->EndConditionalWeakTableElementReferences(heapId);
+#else
+ UNREFERENCED_PARAMETER(heapId);
#endif // defined (GC_PROFILING)
}
// If GC profiling is enabled, informs the profiler that we are done
// tracing root references.
-void ProfilerEndRootReferences2(void* heapId) {
+void ProfilerEndRootReferences2(void* heapId)
+{
#if defined (GC_PROFILING)
g_profControlBlock.pProfInterface->EndRootReferences2(heapId);
+#else
+ UNREFERENCED_PARAMETER(heapId);
#endif // defined (GC_PROFILING)
}
@@ -449,6 +456,7 @@ void ProfilerEndRootReferences2(void* heapId) {
// This can also be called to do a single walk for BOTH a) and b) simultaneously. Since
// ETW can ask for roots, but not objects
#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+
void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForEtw, BOOL fShouldWalkHeapObjectsForEtw)
{
{
@@ -472,7 +480,7 @@ void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForE
// The finalizer queue is also a source of roots
SC.dwEtwRootKind = kEtwGCRootKindFinalizer;
- hp->finalize_queue->GcScanRoots(&ScanRootsHelper, hn, &SC);
+ hp->finalize_queue->GcScanRoots(&ProfScanRootsHelper, hn, &SC);
}
#else
// Ask the vm to go over all of the roots
@@ -480,7 +488,7 @@ void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForE
// The finalizer queue is also a source of roots
SC.dwEtwRootKind = kEtwGCRootKindFinalizer;
- pGenGCHeap->finalize_queue->GcScanRoots(&ScanRootsHelper, 0, &SC);
+ pGenGCHeap->finalize_queue->GcScanRoots(&ProfScanRootsHelper, 0, &SC);
#endif // MULTIPLE_HEAPS
// Handles are kept independent of wks/svr/concurrent builds
@@ -543,7 +551,7 @@ void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForE
#endif // FEATURE_EVENT_TRACE
}
}
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
void GCProfileWalkHeap()
{
@@ -572,12 +580,12 @@ void GCProfileWalkHeap()
#if defined (GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
// we need to walk the heap if one of GC_PROFILING or FEATURE_EVENT_TRACE
// is defined, since both of them make use of the walk heap worker.
- if (!fWalkedHeapForProfiler &&
+ if (!fWalkedHeapForProfiler &&
(fShouldWalkHeapRootsForEtw || fShouldWalkHeapObjectsForEtw))
{
GCProfileWalkHeapWorker(FALSE /* fProfilerPinned */, fShouldWalkHeapRootsForEtw, fShouldWalkHeapObjectsForEtw);
}
-#endif // defined (GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
}
BOOL GCHeap::IsGCInProgressHelper (BOOL bConsiderGCStart)
diff --git a/src/gc/gcscan.h b/src/gc/gcscan.h
index 25a28f0d63..1088ee5340 100644
--- a/src/gc/gcscan.h
+++ b/src/gc/gcscan.h
@@ -99,4 +99,11 @@ private:
#endif //DACCESS_COMPILE
};
+// These two functions are utilized to scan the heap if requested by ETW
+// or a profiler. The implementations of these two functions are in profheapwalkhelper.cpp.
+#if defined(FEATURE_EVENT_TRACE) | defined(GC_PROFILING)
+void ScanRootsHelper(Object** ppObject, Object** ppObjectRef, ScanContext * pSC, DWORD dwFlags);
+BOOL HeapWalkHelper(Object * pBO, void * pvContext);
+#endif
+
#endif // _GCSCAN_H_
diff --git a/src/gc/handletablecore.cpp b/src/gc/handletablecore.cpp
index 27e04c4e35..5e077de8a2 100644
--- a/src/gc/handletablecore.cpp
+++ b/src/gc/handletablecore.cpp
@@ -1433,7 +1433,7 @@ uint32_t SegmentInsertBlockFromFreeListWorker(TableSegment *pSegment, uint32_t u
if (uBlock >= uCommitLine)
{
// figure out where to commit next
- LPVOID pvCommit = pSegment->rgValue + (uCommitLine * HANDLE_HANDLES_PER_BLOCK);
+ void * pvCommit = pSegment->rgValue + (uCommitLine * HANDLE_HANDLES_PER_BLOCK);
// we should commit one more page of handles
uint32_t dwCommit = g_SystemInfo.dwPageSize;
@@ -1843,7 +1843,7 @@ void SegmentTrimExcessPages(TableSegment *pSegment)
if (dwHi > dwLo)
{
// decommit the memory
- GCToOSInterface::VirtualDecommit((LPVOID)dwLo, dwHi - dwLo);
+ GCToOSInterface::VirtualDecommit((void *)dwLo, dwHi - dwLo);
// update the commit line
pSegment->bCommitLine = (uint8_t)((dwLo - (size_t)pSegment->rgValue) / HANDLE_BYTES_PER_BLOCK);
diff --git a/src/gc/sample/gcenv.unix.cpp b/src/gc/sample/gcenv.unix.cpp
index 37a7a69111..515820650b 100644
--- a/src/gc/sample/gcenv.unix.cpp
+++ b/src/gc/sample/gcenv.unix.cpp
@@ -387,14 +387,14 @@ WINBASEAPI
DWORD
WINAPI
GetCurrentThreadId(
- VOID)
+ void)
{
// TODO: Implement
return 1;
}
WINBASEAPI
-VOID
+void
WINAPI
YieldProcessor()
{
@@ -410,7 +410,7 @@ DebugBreak()
}
WINBASEAPI
-VOID
+void
WINAPI
MemoryBarrier()
{