From 1b827b5a82f8c6f8a9ed760ee127938dea5a7ea4 Mon Sep 17 00:00:00 2001 From: Sean Gillespie Date: Thu, 16 Mar 2017 17:18:28 -0700 Subject: [Local GC] Break EE dependency on GC's generation table and alloc lock in single-proc scenarios (#10065) * Remove usage of the generation table from the EE by introducing an EE-owned GC alloc context used for allocations on single-proc machines. * Move the GC alloc lock to the EE side of the interface * Repair the Windows ARM build * Move the decision to use per-thread alloc contexts to the EE * Rename the lock used by StartNoGCRegion and EndNoGCRegion to be more indicative of what it is protecting * Address code review feedback 2 (enumerate the global alloc context as a part of GCToEEInterface) * Code review feedback (3) * Address code review feedback (move some GC-internal globals to gcimpl.h and gc.cpp) * g_global_alloc_lock is a dword, not a qword - fixes a deadlock * Move GlobalAllocLock to gchelpers.cpp and switch to preemptive mode when spinning * Repair the Windows x86 build --- src/vm/gcheaputilities.h | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'src/vm/gcheaputilities.h') diff --git a/src/vm/gcheaputilities.h b/src/vm/gcheaputilities.h index 48481146b4..d5ce46c60d 100644 --- a/src/vm/gcheaputilities.h +++ b/src/vm/gcheaputilities.h @@ -20,6 +20,12 @@ GPTR_DECL(uint32_t,g_card_table); } #endif // !DACCESS_COMPILE +// For single-proc machines, the EE will use a single, shared alloc context +// for all allocations. In order to avoid extra indirections in assembly +// allocation helpers, the EE owns the global allocation context and the +// GC will update it when it needs to. +extern "C" gc_alloc_context g_global_alloc_context; + extern "C" uint32_t* g_card_bundle_table; extern "C" uint8_t* g_ephemeral_low; extern "C" uint8_t* g_ephemeral_high; @@ -100,22 +106,6 @@ public: GetGCHeap()->WaitUntilGCComplete(bConsiderGCStart); } - // Returns true if we should be using allocation contexts, false otherwise. - inline static bool UseAllocationContexts() - { - WRAPPER_NO_CONTRACT; -#ifdef FEATURE_REDHAWK - // SIMPLIFY: only use allocation contexts - return true; -#else -#if defined(_TARGET_ARM_) || defined(FEATURE_PAL) - return true; -#else - return ((IsServerHeap() ? true : (g_SystemInfo.dwNumberOfProcessors >= 2))); -#endif -#endif - } - // Returns true if the held GC heap is a Server GC heap, false otherwise. inline static bool IsServerHeap() { @@ -128,6 +118,18 @@ public: #endif // FEATURE_SVR_GC } + static bool UseThreadAllocationContexts() + { + // When running on a single-proc system, it's more efficient to use a single global + // allocation context for SOH allocations than to use one for every thread. +#if defined(_TARGET_ARM_) || defined(FEATURE_PAL) || defined(FEATURE_REDHAWK) + return true; +#else + return IsServerHeap() || ::GetCurrentProcessCpuCount() != 1; +#endif + + } + #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP // Returns True if software write watch is currently enabled for the GC Heap, @@ -192,7 +194,6 @@ public: } #endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP - private: // This class should never be instantiated. GCHeapUtilities() = delete; -- cgit v1.2.3