summaryrefslogtreecommitdiff
path: root/src/gc/gcimpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gc/gcimpl.h')
-rw-r--r--src/gc/gcimpl.h316
1 files changed, 316 insertions, 0 deletions
diff --git a/src/gc/gcimpl.h b/src/gc/gcimpl.h
new file mode 100644
index 0000000000..6a4ee86cd8
--- /dev/null
+++ b/src/gc/gcimpl.h
@@ -0,0 +1,316 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+
+#ifndef GCIMPL_H_
+#define GCIMPL_H_
+
+#define CLREvent CLREventStatic
+
+#ifdef SERVER_GC
+#define MULTIPLE_HEAPS 1
+#endif // SERVER_GC
+
+#ifdef MULTIPLE_HEAPS
+
+#define PER_HEAP
+
+#else //MULTIPLE_HEAPS
+
+#define PER_HEAP static
+
+#endif // MULTIPLE_HEAPS
+
+#define PER_HEAP_ISOLATED static
+
+#if defined(WRITE_BARRIER_CHECK) && !defined (MULTIPLE_HEAPS)
+void initGCShadow();
+void deleteGCShadow();
+void checkGCWriteBarrier();
+#else
+inline void initGCShadow() {}
+inline void deleteGCShadow() {}
+inline void checkGCWriteBarrier() {}
+#endif
+
+void GCProfileWalkHeap();
+
+class GCHeap;
+class gc_heap;
+class CFinalize;
+
+// TODO : it would be easier to make this an ORed value
+enum gc_reason
+{
+ reason_alloc_soh = 0,
+ reason_induced = 1,
+ reason_lowmemory = 2,
+ reason_empty = 3,
+ reason_alloc_loh = 4,
+ reason_oos_soh = 5,
+ reason_oos_loh = 6,
+ reason_induced_noforce = 7, // it's an induced GC and doesn't have to be blocking.
+ reason_gcstress = 8, // this turns into reason_induced & gc_mechanisms.stress_induced = true
+ reason_lowmemory_blocking = 9,
+ reason_induced_compacting = 10,
+ reason_lowmemory_host = 11,
+ reason_max
+};
+
+class GCHeap : public ::GCHeap
+{
+protected:
+
+#ifdef MULTIPLE_HEAPS
+ gc_heap* pGenGCHeap;
+#else
+ #define pGenGCHeap ((gc_heap*)0)
+#endif //MULTIPLE_HEAPS
+
+ friend class CFinalize;
+ friend class gc_heap;
+ friend struct ::alloc_context;
+ friend void EnterAllocLock();
+ friend void LeaveAllocLock();
+ friend void ProfScanRootsHelper(Object** object, ScanContext *pSC, uint32_t dwFlags);
+ friend void GCProfileWalkHeap();
+
+public:
+ //In order to keep gc.cpp cleaner, ugly EE specific code is relegated to methods.
+ static void UpdatePreGCCounters();
+ static void UpdatePostGCCounters();
+
+public:
+ GCHeap(){};
+ ~GCHeap(){};
+
+ /* BaseGCHeap Methods*/
+ PER_HEAP_ISOLATED HRESULT Shutdown ();
+
+ size_t GetTotalBytesInUse ();
+ // Gets the amount of bytes objects currently occupy on the GC heap.
+ size_t GetCurrentObjSize();
+
+ size_t GetLastGCStartTime(int generation);
+ size_t GetLastGCDuration(int generation);
+ size_t GetNow();
+
+ void TraceGCSegments ();
+ void PublishObject(uint8_t* obj);
+
+ BOOL IsGCInProgressHelper (BOOL bConsiderGCStart = FALSE);
+
+ uint32_t WaitUntilGCComplete (BOOL bConsiderGCStart = FALSE);
+
+ void SetGCInProgress(BOOL fInProgress);
+
+ CLREvent * GetWaitForGCEvent();
+
+ HRESULT Initialize ();
+
+ //flags can be GC_ALLOC_CONTAINS_REF GC_ALLOC_FINALIZE
+ Object* Alloc (size_t size, uint32_t flags);
+#ifdef FEATURE_64BIT_ALIGNMENT
+ Object* AllocAlign8 (size_t size, uint32_t flags);
+ Object* AllocAlign8 (alloc_context* acontext, size_t size, uint32_t flags);
+private:
+ Object* AllocAlign8Common (void* hp, alloc_context* acontext, size_t size, uint32_t flags);
+public:
+#endif // FEATURE_64BIT_ALIGNMENT
+ Object* AllocLHeap (size_t size, uint32_t flags);
+ Object* Alloc (alloc_context* acontext, size_t size, uint32_t flags);
+
+ void FixAllocContext (alloc_context* acontext,
+ BOOL lockp, void* arg, void *heap);
+
+ Object* GetContainingObject(void *pInteriorPtr);
+
+#ifdef MULTIPLE_HEAPS
+ static void AssignHeap (alloc_context* acontext);
+ static GCHeap* GetHeap (int);
+#endif //MULTIPLE_HEAPS
+
+ int GetHomeHeapNumber ();
+ bool IsThreadUsingAllocationContextHeap(alloc_context* acontext, int thread_number);
+ int GetNumberOfHeaps ();
+ void HideAllocContext(alloc_context*);
+ void RevealAllocContext(alloc_context*);
+
+ BOOL IsObjectInFixedHeap(Object *pObj);
+
+ HRESULT GarbageCollect (int generation = -1, BOOL low_memory_p=FALSE, int mode=collection_blocking);
+
+ ////
+ // GC callback functions
+ // Check if an argument is promoted (ONLY CALL DURING
+ // THE PROMOTIONSGRANTED CALLBACK.)
+ BOOL IsPromoted (Object *object);
+
+ size_t GetPromotedBytes (int heap_index);
+
+ int CollectionCount (int generation, int get_bgc_fgc_count = 0);
+
+ // promote an object
+ PER_HEAP_ISOLATED void Promote (Object** object,
+ ScanContext* sc,
+ uint32_t flags=0);
+
+ // Find the relocation address for an object
+ PER_HEAP_ISOLATED void Relocate (Object** object,
+ ScanContext* sc,
+ uint32_t flags=0);
+
+
+ HRESULT Init (size_t heapSize);
+
+ //Register an object for finalization
+ bool RegisterForFinalization (int gen, Object* obj);
+
+ //Unregister an object for finalization
+ void SetFinalizationRun (Object* obj);
+
+ //returns the generation number of an object (not valid during relocation)
+ unsigned WhichGeneration (Object* object);
+ // returns TRUE is the object is ephemeral
+ BOOL IsEphemeral (Object* object);
+ BOOL IsHeapPointer (void* object, BOOL small_heap_only = FALSE);
+
+#ifdef VERIFY_HEAP
+ void ValidateObjectMember (Object *obj);
+#endif //_DEBUG
+
+ PER_HEAP size_t ApproxTotalBytesInUse(BOOL small_heap_only = FALSE);
+ PER_HEAP size_t ApproxFreeBytes();
+
+ unsigned GetCondemnedGeneration();
+
+ int GetGcLatencyMode();
+ int SetGcLatencyMode(int newLatencyMode);
+
+ int GetLOHCompactionMode();
+ void SetLOHCompactionMode(int newLOHCompactionyMode);
+
+ BOOL RegisterForFullGCNotification(uint32_t gen2Percentage,
+ uint32_t lohPercentage);
+ BOOL CancelFullGCNotification();
+ int WaitForFullGCApproach(int millisecondsTimeout);
+ int WaitForFullGCComplete(int millisecondsTimeout);
+
+ int StartNoGCRegion(uint64_t totalSize, BOOL lohSizeKnown, uint64_t lohSize, BOOL disallowFullBlockingGC);
+ int EndNoGCRegion();
+
+ PER_HEAP_ISOLATED unsigned GetMaxGeneration();
+
+ unsigned GetGcCount();
+
+ Object* GetNextFinalizable() { return GetNextFinalizableObject(); };
+ size_t GetNumberOfFinalizable() { return GetNumberFinalizableObjects(); }
+
+ PER_HEAP_ISOLATED HRESULT GetGcCounters(int gen, gc_counters* counters);
+
+ size_t GetValidSegmentSize(BOOL large_seg = FALSE);
+
+ static size_t GetValidGen0MaxSize(size_t seg_size);
+
+ void SetReservedVMLimit (size_t vmlimit);
+
+ PER_HEAP_ISOLATED Object* GetNextFinalizableObject();
+ PER_HEAP_ISOLATED size_t GetNumberFinalizableObjects();
+ PER_HEAP_ISOLATED size_t GetFinalizablePromotedCount();
+
+ void SetFinalizeQueueForShutdown(BOOL fHasLock);
+ BOOL FinalizeAppDomain(AppDomain *pDomain, BOOL fRunFinalizers);
+ BOOL ShouldRestartFinalizerWatchDog();
+
+ void SetCardsAfterBulkCopy( Object**, size_t);
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ void WalkObject (Object* obj, walk_fn fn, void* context);
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+
+public: // FIX
+
+ // Lock for finalization
+ PER_HEAP_ISOLATED
+ VOLATILE(int32_t) m_GCFLock;
+
+ PER_HEAP_ISOLATED BOOL GcCollectClasses;
+ PER_HEAP_ISOLATED
+ VOLATILE(BOOL) GcInProgress; // used for syncing w/GC
+ PER_HEAP_ISOLATED VOLATILE(unsigned) GcCount;
+ PER_HEAP_ISOLATED unsigned GcCondemnedGeneration;
+ // calculated at the end of a GC.
+ PER_HEAP_ISOLATED size_t totalSurvivedSize;
+
+ // Use only for GC tracing.
+ PER_HEAP unsigned int GcDuration;
+
+ size_t GarbageCollectGeneration (unsigned int gen=0, gc_reason reason=reason_empty);
+ // Interface with gc_heap
+ size_t GarbageCollectTry (int generation, BOOL low_memory_p=FALSE, int mode=collection_blocking);
+
+#ifdef FEATURE_BASICFREEZE
+ // frozen segment management functions
+ virtual segment_handle RegisterFrozenSegment(segment_info *pseginfo);
+ virtual void UnregisterFrozenSegment(segment_handle seg);
+#endif // FEATURE_BASICFREEZE
+
+ void WaitUntilConcurrentGCComplete (); // Use in managd threads
+#ifndef DACCESS_COMPILE
+ HRESULT WaitUntilConcurrentGCCompleteAsync(int millisecondsTimeout); // Use in native threads. TRUE if succeed. FALSE if failed or timeout
+#endif
+ BOOL IsConcurrentGCInProgress();
+
+ // Enable/disable concurrent GC
+ void TemporaryEnableConcurrentGC();
+ void TemporaryDisableConcurrentGC();
+ BOOL IsConcurrentGCEnabled();
+
+ PER_HEAP_ISOLATED CLREvent *WaitForGCEvent; // used for syncing w/GC
+
+ PER_HEAP_ISOLATED CFinalize* m_Finalize;
+
+ PER_HEAP_ISOLATED gc_heap* Getgc_heap();
+
+private:
+ static bool SafeToRestartManagedThreads()
+ {
+ // Note: this routine should return true when the last barrier
+ // to threads returning to cooperative mode is down after gc.
+ // In other words, if the sequence in GCHeap::RestartEE changes,
+ // the condition here may have to change as well.
+ return g_TrapReturningThreads == 0;
+ }
+#ifndef FEATURE_REDHAWK // Redhawk forces relocation a different way
+#ifdef STRESS_HEAP
+public:
+ //return TRUE if GC actually happens, otherwise FALSE
+ BOOL StressHeap(alloc_context * acontext = 0);
+protected:
+
+ // only used in BACKGROUND_GC, but the symbol is not defined yet...
+ PER_HEAP_ISOLATED int gc_stress_fgcs_in_bgc;
+
+#if !defined(MULTIPLE_HEAPS)
+ // handles to hold the string objects that will force GC movement
+ enum { NUM_HEAP_STRESS_OBJS = 8 };
+ PER_HEAP OBJECTHANDLE m_StressObjs[NUM_HEAP_STRESS_OBJS];
+ PER_HEAP int m_CurStressObj;
+#endif // !defined(MULTIPLE_HEAPS)
+#endif // STRESS_HEAP
+#endif // FEATURE_REDHAWK
+
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ virtual void DescrGenerationsToProfiler (gen_walk_fn fn, void *context);
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+
+#ifdef VERIFY_HEAP
+public:
+ Object * NextObj (Object * object);
+#ifdef FEATURE_BASICFREEZE
+ BOOL IsInFrozenSegment (Object * object);
+#endif //FEATURE_BASICFREEZE
+#endif //VERIFY_HEAP
+};
+
+#endif // GCIMPL_H_