GC update from CoreRT (dotnet/coreclr#6429)
authorJan Kotas <jkotas@microsoft.com>
Sat, 23 Jul 2016 14:23:21 +0000 (07:23 -0700)
committerGitHub <noreply@github.com>
Sat, 23 Jul 2016 14:23:21 +0000 (07:23 -0700)
https://github.com/dotnet/corert/tree/master/src/Native/gc dotnet/coreclr@91d7a9c8e2b393314422b6106adedec683c0ae51

Commit migrated from https://github.com/dotnet/coreclr/commit/087e750df2a13801d0f144cdcfa6c1c3e16067c2

src/coreclr/src/gc/env/gcenv.base.h
src/coreclr/src/gc/gc.cpp
src/coreclr/src/gc/sample/gcenv.unix.cpp

index 83726f4..97f1661 100644 (file)
@@ -176,6 +176,12 @@ typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(void* lpThreadParameter);
 
 #endif // _MSC_VER
 
+typedef struct _PROCESSOR_NUMBER {
+    uint16_t Group;
+    uint8_t Number;
+    uint8_t Reserved;
+} PROCESSOR_NUMBER, *PPROCESSOR_NUMBER;
+
 #endif // _INC_WINDOWS
 
 // -----------------------------------------------------------------------------------------------------------
@@ -600,4 +606,21 @@ public:
 };
 #endif // STRESS_HEAP
 
+class NumaNodeInfo
+{
+public:
+    static bool CanEnableGCNumaAware();
+    static void GetGroupForProcessor(uint16_t processor_number, uint16_t * group_number, uint16_t * group_processor_number);
+    static bool GetNumaProcessorNodeEx(PPROCESSOR_NUMBER proc_no, uint16_t * node_no);
+};
+
+class CPUGroupInfo
+{
+public:
+    static bool CanEnableGCCPUGroups();
+    static uint32_t GetNumActiveProcessors();
+    static void GetGroupForProcessor(uint16_t processor_number, uint16_t * group_number, uint16_t * group_processor_number);
+};
+
+
 #endif // __GCENV_BASE_INCLUDED__
index af2d1e7..3300421 100644 (file)
@@ -2271,7 +2271,7 @@ SPTR_IMPL_NS(PTR_gc_heap, SVR, gc_heap, g_heaps);
 size_t*     gc_heap::g_promoted;
 
 #ifdef MH_SC_MARK
-BOOL*       gc_heap::g_mark_stack_busy;
+int*        gc_heap::g_mark_stack_busy;
 #endif //MH_SC_MARK
 
 
@@ -4921,7 +4921,7 @@ public:
         return TRUE;
     }
 
-    static void init_cpu_mapping(gc_heap *heap, int heap_number)
+    static void init_cpu_mapping(gc_heap * /*heap*/, int heap_number)
     {
         if (GCToOSInterface::CanGetCurrentProcessorNumber())
         {
@@ -4942,8 +4942,10 @@ public:
             sniff_buffer[(1 + heap_number*n_sniff_buffers + sniff_index)*HS_CACHE_LINE_SIZE] &= 1;
     }
 
-    static int select_heap(alloc_context* acontext, int hint)
+    static int select_heap(alloc_context* acontext, int /*hint*/)
     {
+        UNREFERENCED_PARAMETER(acontext); // only referenced by dprintf
+
         if (GCToOSInterface::CanGetCurrentProcessorNumber())
             return proc_no_to_heap_no[GCToOSInterface::GetCurrentProcessorNumber() % gc_heap::n_heaps];
 
@@ -5103,7 +5105,7 @@ void gc_heap::destroy_thread_support ()
     }
 }
 
-#if !defined(FEATURE_REDHAWK) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
 void set_thread_group_affinity_for_heap(int heap_number, GCThreadAffinity* affinity)
 {
     affinity->Group = GCThreadAffinity::None;
@@ -5183,7 +5185,7 @@ void set_thread_affinity_mask_for_heap(int heap_number, GCThreadAffinity* affini
         }
     }
 }
-#endif // !FEATURE_REDHAWK && !FEATURE_CORECLR
+#endif // !FEATURE_PAL
 
 bool gc_heap::create_gc_thread ()
 {
@@ -5193,7 +5195,7 @@ bool gc_heap::create_gc_thread ()
     affinity.Group = GCThreadAffinity::None;
     affinity.Processor = GCThreadAffinity::None;
 
-#if !defined(FEATURE_REDHAWK) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
     if (!gc_thread_no_affinitize_p)
     {
         //We are about to set affinity for GC threads, it is a good place to setup NUMA and
@@ -5204,7 +5206,7 @@ bool gc_heap::create_gc_thread ()
         else
             set_thread_affinity_mask_for_heap(heap_number, &affinity);
     }
-#endif // !FEATURE_REDHAWK && !FEATURE_PAL
+#endif // !FEATURE_PAL
 
     return GCToOSInterface::CreateThread(gc_thread_stub, this, &affinity);
 }
@@ -13179,7 +13181,7 @@ try_again:
                     org_hp->alloc_context_count--;
                     max_hp->alloc_context_count++;
                     acontext->alloc_heap = GCHeap::GetHeap(max_hp->heap_number);
-#if !defined(FEATURE_REDHAWK) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
                     if (CPUGroupInfo::CanEnableGCCPUGroups())
                     {   //only set ideal processor when max_hp and org_hp are in the same cpu
                         //group. DO NOT MOVE THREADS ACROSS CPU GROUPS
@@ -13213,7 +13215,7 @@ try_again:
                                         org_hp->heap_number));
                         }
                     }
-#endif // !FEATURE_REDHAWK && !FEATURE_PAL
+#endif // !FEATURE_PAL
                     dprintf (3, ("Switching context %p (home heap %d) ", 
                                  acontext,
                         acontext->home_heap->pGenGCHeap->heap_number));
@@ -13232,7 +13234,7 @@ try_again:
     acontext->alloc_count++;
 }
 
-gc_heap* gc_heap::balance_heaps_loh (alloc_context* acontext, size_t size)
+gc_heap* gc_heap::balance_heaps_loh (alloc_context* acontext, size_t /*size*/)
 {
     gc_heap* org_hp = acontext->alloc_heap->pGenGCHeap;
     //dprintf (1, ("LA: %Id", size));
@@ -17762,8 +17764,8 @@ gc_heap::mark_steal()
                     if (((size_t)o > 4) && !partial_object_p (o))
                     {
                         //this is a normal object, not a partial mark tuple
-                        //success = (FastInterlockCompareExchangePointer (&ref_mark_stack (hp, level), 0, o)==o);
-                        success = (FastInterlockCompareExchangePointer (&ref_mark_stack (hp, level), 4, o)==o);
+                        //success = (Interlocked::CompareExchangePointer (&ref_mark_stack (hp, level), 0, o)==o);
+                        success = (Interlocked::CompareExchangePointer (&ref_mark_stack (hp, level), (uint8_t*)4, o)==o);
 #ifdef SNOOP_STATS
                         snoop_stat.interlocked_count++;
                         if (success)
@@ -17798,7 +17800,7 @@ gc_heap::mark_steal()
                     if (o && start)
                     {
                         //steal the object
-                        success = (FastInterlockCompareExchangePointer (&ref_mark_stack (hp, level+1), stolen, next)==next);
+                        success = (Interlocked::CompareExchangePointer (&ref_mark_stack (hp, level+1), (uint8_t*)stolen, next)==next);
 #ifdef SNOOP_STATS
                         snoop_stat.interlocked_count++;
                         if (success)
@@ -23303,13 +23305,8 @@ uint8_t* tree_search (uint8_t* tree, uint8_t* old_address)
 #ifdef FEATURE_BASICFREEZE
 bool gc_heap::frozen_object_p (Object* obj)
 {
-#ifdef MULTIPLE_HEAPS
-    ptrdiff_t delta = 0;
-    heap_segment* pSegment = segment_of ((uint8_t*)obj, delta);
-#else //MULTIPLE_HEAPS
     heap_segment* pSegment = gc_heap::find_segment ((uint8_t*)obj, FALSE);
     _ASSERTE(pSegment);
-#endif //MULTIPLE_HEAPS
 
     return heap_segment_read_only_p(pSegment);
 }
@@ -23326,6 +23323,7 @@ void gc_heap::relocate_address (uint8_t** pold_address THREAD_NUMBER_DCL)
     if (!((old_address >= gc_low) && (old_address < gc_high)))
 #ifdef MULTIPLE_HEAPS
     {
+        UNREFERENCED_PARAMETER(thread);
         if (old_address == 0)
             return;
         gc_heap* hp = heap_of (old_address);
@@ -35426,7 +35424,7 @@ int GCHeap::GetHomeHeapNumber ()
     {
         if (pThread)
         {
-            GCHeap *hp = pThread->GetAllocContext()->home_heap;
+            GCHeap *hp = GCToEEInterface::GetAllocContext(pThread)->home_heap;
             if (hp == gc_heap::g_heaps[i]->vm_heap) return i;
         }
     }
index c8663fb..a5e9e83 100644 (file)
 #include "gcenv.h"
 #include "gc.h"
 
-#include <sys/mman.h>
-#include <sys/time.h>
-
-int32_t FastInterlockIncrement(int32_t volatile *lpAddend)
-{
-    return __sync_add_and_fetch(lpAddend, 1);
-}
-
-int32_t FastInterlockDecrement(int32_t volatile *lpAddend)
-{
-    return __sync_sub_and_fetch(lpAddend, 1);
-}
-
-int32_t FastInterlockExchange(int32_t volatile *Target, int32_t Value)
-{
-    return __sync_swap(Target, Value);
-}
-
-int32_t FastInterlockCompareExchange(int32_t volatile *Destination, int32_t Exchange, int32_t Comparand)
-{
-    return __sync_val_compare_and_swap(Destination, Comparand, Exchange);
-}
-
-int32_t FastInterlockExchangeAdd(int32_t volatile *Addend, int32_t Value)
-{
-    return __sync_fetch_and_add(Addend, Value);
-}
-
-void * _FastInterlockExchangePointer(void * volatile *Target, void * Value)
-{
-    return __sync_swap(Target, Value);
-}
-
-void * _FastInterlockCompareExchangePointer(void * volatile *Destination, void * Exchange, void * Comparand)
-{
-    return __sync_val_compare_and_swap(Destination, Comparand, Exchange);
-}
-
-void FastInterlockOr(uint32_t volatile *p, uint32_t msk)
-{
-    __sync_fetch_and_or(p, msk);
-}
-
-void FastInterlockAnd(uint32_t volatile *p, uint32_t msk)
-{
-    __sync_fetch_and_and(p, msk);
-}
-
-
-void UnsafeInitializeCriticalSection(CRITICAL_SECTION * lpCriticalSection)
-{
-    pthread_mutex_init(&lpCriticalSection->mutex, NULL);
-}
-
-void UnsafeEEEnterCriticalSection(CRITICAL_SECTION *lpCriticalSection)
-{
-    pthread_mutex_lock(&lpCriticalSection->mutex);
-}
-
-void UnsafeEELeaveCriticalSection(CRITICAL_SECTION * lpCriticalSection)
-{
-    pthread_mutex_unlock(&lpCriticalSection->mutex);
-}
-
-void UnsafeDeleteCriticalSection(CRITICAL_SECTION *lpCriticalSection)
-{
-    pthread_mutex_destroy(&lpCriticalSection->mutex);
-}
-
-#if 0
-void CLREventStatic::CreateManualEvent(bool bInitialState)
-{
-    // TODO: Implement
-    m_fInitialized = true;
-}
-
-void CLREventStatic::CreateAutoEvent(bool bInitialState)
-{
-    // TODO: Implement
-    m_fInitialized = true;
-}
-
-void CLREventStatic::CreateOSManualEvent(bool bInitialState)
-{
-    CreateManualEvent(bInitialState);
-}
-
-void CLREventStatic::CreateOSAutoEvent (bool bInitialState)
-{
-    CreateAutoEvent(bInitialState);
-}
-
-void CLREventStatic::CloseEvent()
-{
-    if (m_fInitialized)
-    {
-        // TODO: Implement
-        m_fInitialized = false;
-    }
-}
-
-bool CLREventStatic::IsValid() const
-{
-    return m_fInitialized; 
-}
-
-bool CLREventStatic::Set()
-{
-    if (!m_fInitialized)
-        return false;
-    // TODO: Implement
-    return true; 
-}
-
-bool CLREventStatic::Reset()
-{
-    if (!m_fInitialized)
-        return false;
-    // TODO: Implement
-    return true;
-}
-
-uint32_t CLREventStatic::Wait(uint32_t dwMilliseconds, bool bAlertable)
-{
-    DWORD result = WAIT_FAILED;
-
-    if (m_fInitialized)
-    {
-        bool        disablePreemptive = false;
-        Thread *    pCurThread  = GetThread();
-
-        if (NULL != pCurThread)
-        {
-            if (pCurThread->PreemptiveGCDisabled())
-            {
-                pCurThread->EnablePreemptiveGC();
-                disablePreemptive = true;
-            }
-        }
-
-        // TODO: Implement
-        result = WAIT_OBJECT_0;
-
-        if (disablePreemptive)
-        {
-            pCurThread->DisablePreemptiveGC();
-        }
-    }
-
-    return result;
-}
-#endif // 0
-
-bool __SwitchToThread(uint32_t dwSleepMSec, uint32_t dwSwitchCount)
-{
-    return sched_yield() == 0;
-}
-
-static int W32toUnixAccessControl(uint32_t flProtect)
-{
-    int prot = 0;
-
-    switch (flProtect & 0xff)
-    {
-    case PAGE_NOACCESS:
-        prot = PROT_NONE;
-        break;
-    case PAGE_READWRITE:
-        prot = PROT_READ | PROT_WRITE;
-        break;
-    default:
-        _ASSERTE(false);
-        break;
-    }
-    return prot;
-}
-
-MethodTable * g_pFreeObjectMethodTable;
-
-GCSystemInfo g_SystemInfo;
-
-void InitializeSystemInfo()
-{
-    // TODO: Implement
-    g_SystemInfo.dwNumberOfProcessors = 4;
-
-    g_SystemInfo.dwPageSize = OS_PAGE_SIZE;
-    g_SystemInfo.dwAllocationGranularity = OS_PAGE_SIZE;
-}
-
-int32_t g_TrapReturningThreads;
-
-bool g_fFinalizerRunOnShutDown;
-
-#if 0
-#ifdef _MSC_VER
-__declspec(thread)
-#else
-__thread
-#endif
-Thread * pCurrentThread;
-
-Thread * GetThread()
-{
-    return pCurrentThread;
-}
-
-Thread * g_pThreadList = NULL;
-
-Thread * ThreadStore::GetThreadList(Thread * pThread)
-{
-    if (pThread == NULL)
-        return g_pThreadList;
-
-    return pThread->m_pNext;
-}
-
-void ThreadStore::AttachCurrentThread(bool fAcquireThreadStoreLock)
-{
-    // TODO: Locks
-
-    Thread * pThread = new Thread();
-    pThread->GetAllocContext()->init();
-    pCurrentThread = pThread;
-
-    pThread->m_pNext = g_pThreadList;
-    g_pThreadList = pThread;
-}
-#endif // 0
-
-#if 0 
-void GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_REASON reason)
-{
-    GCHeap::GetGCHeap()->SetGCInProgress(TRUE);
-
-    // TODO: Implement
-}
-
-void GCToEEInterface::RestartEE(bool bFinishedGC)
-{
-    // TODO: Implement
-
-    GCHeap::GetGCHeap()->SetGCInProgress(FALSE);
-}
-
-void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc)
-{
-    // TODO: Implement - Scan stack roots
-}
-
-void GCToEEInterface::GcStartWork(int condemned, int max_gen)
-{
-}
-
-void GCToEEInterface::AfterGcScanRoots(int condemned, int max_gen, ScanContext* sc)
-{
-}
-
-void GCToEEInterface::GcBeforeBGCSweepWork()
-{
-}
-
-void GCToEEInterface::GcDone(int condemned)
-{
-}
-
-void FinalizerThread::EnableFinalization()
-{
-    // Signal to finalizer thread that there are objects to finalize
-    // TODO: Implement for finalization
-}
-
-bool IsGCSpecialThread()
-{
-    // TODO: Implement for background GC
-    return false;
-}
-
-#endif // 0
-
-WINBASEAPI
-UINT
-WINAPI
-GetWriteWatch(
-    DWORD dwFlags,
-    PVOID lpBaseAddress,
-    SIZE_T dwRegionSize,
-    PVOID *lpAddresses,
-    uintptr_t * lpdwCount,
-    uint32_t * lpdwGranularity
-    )
-{
-    // TODO: Implement for background GC
-    *lpAddresses = NULL;
-    *lpdwCount = 0;
-    // Until it is implemented, return non-zero value as an indicator of failure
-    return 1;
-}
-
-WINBASEAPI
-UINT
-WINAPI
-ResetWriteWatch(
-    LPVOID lpBaseAddress,
-    SIZE_T dwRegionSize
-    )
-{
-    // TODO: Implement for background GC
-    // Until it is implemented, return non-zero value as an indicator of failure
-    return 1;
-}
-
-const int tccSecondsToMillieSeconds = 1000;
-const int tccSecondsToMicroSeconds = 1000000;
-const int tccMillieSecondsToMicroSeconds = 1000;       // 10^3
-
-WINBASEAPI
-DWORD
-WINAPI
-GetTickCount()
-{
-    // TODO: More efficient, platform-specific implementation
-    struct timeval tv;
-    if (gettimeofday(&tv, NULL) == -1)
-    {
-        _ASSERTE(!"gettimeofday() failed");
-        return 0;
-    }
-    return (tv.tv_sec * tccSecondsToMillieSeconds) + (tv.tv_usec / tccMillieSecondsToMicroSeconds);
-}
-
-WINBASEAPI
-BOOL
-WINAPI
-QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)
-{
-    // TODO: More efficient, platform-specific implementation
-    struct timeval tv;
-    if (gettimeofday(&tv, NULL) == -1)
-    {
-        _ASSERTE(!"gettimeofday() failed");
-        return FALSE;
-    }
-    lpPerformanceCount->QuadPart =
-        (int64_t) tv.tv_sec * (int64_t) tccSecondsToMicroSeconds + (int64_t) tv.tv_usec;
-    return TRUE;
-}
-
-WINBASEAPI
-BOOL
-WINAPI
-QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency)
-{
-    lpFrequency->QuadPart = (int64_t) tccSecondsToMicroSeconds;
-    return TRUE;
-}
-
-WINBASEAPI
-DWORD
-WINAPI
-GetCurrentThreadId(
-    void)
-{
-    // TODO: Implement
-    return 1;
-}
-
-WINBASEAPI
-void
-WINAPI
-YieldProcessor()
-{
-    // TODO: Implement
-}
-
-WINBASEAPI
-void
-WINAPI
-DebugBreak()
-{
-    // TODO: Implement
-}
-
-WINBASEAPI
-void
-WINAPI
-MemoryBarrier()
-{
-    // TODO: Implement
-}
-
-// File I/O - Used for tracking only
-
-WINBASEAPI
-BOOL
-WINAPI
-FlushFileBuffers(
-    HANDLE hFile)
-{
-    // TODO: Reimplement callers using CRT
-    return FALSE;
-}
-
-WINBASEAPI
-BOOL
-WINAPI
-WriteFile(
-    HANDLE hFile,
-    LPCVOID lpBuffer,
-    DWORD nNumberOfBytesToWrite,
-    DWORD * lpNumberOfBytesWritten,
-    PVOID lpOverlapped)
-{
-    // TODO: Reimplement callers using CRT
-    return FALSE;
-}
-
-WINBASEAPI
-BOOL
-WINAPI
-CloseHandle(
-    HANDLE hObject)
-{
-    // TODO: Reimplement callers using CRT
-    return FALSE;
-}
-
-WINBASEAPI
-DWORD
-WINAPI
-GetLastError()
-{
-    return 1;
-}
+// TODO: Implement