diff options
author | Jan Kotas <jkotas@microsoft.com> | 2016-02-24 22:41:19 -0800 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2016-02-24 22:44:20 -0800 |
commit | e1fd6dc6d5adf7c4107e60fdb8a6bcb5fc57069f (patch) | |
tree | 5e135f8dcb1907cf4fe1103c79fafbae929d1a78 | |
parent | 81e977ce7be76c4bda86aeb952d13dc136998341 (diff) | |
download | coreclr-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
-rw-r--r-- | src/gc/env/gcenv.base.h | 1 | ||||
-rw-r--r-- | src/gc/gc.cpp | 66 | ||||
-rw-r--r-- | src/gc/gc.h | 6 | ||||
-rw-r--r-- | src/gc/gccommon.cpp | 2 | ||||
-rwxr-xr-x | src/gc/gcee.cpp | 28 | ||||
-rw-r--r-- | src/gc/gcscan.h | 7 | ||||
-rw-r--r-- | src/gc/handletablecore.cpp | 4 | ||||
-rw-r--r-- | src/gc/sample/gcenv.unix.cpp | 6 |
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() { |