2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
20 // Scanning dependent handles for promotion can become a complex operation due to cascaded dependencies and
21 // other issues (see the comments for GcDhInitialScan and friends in gcscan.cpp for further details). As a
22 // result we need to maintain a context between all the DH scanning methods called during a single mark phase.
23 // The structure below describes this context. We allocate one of these per GC heap at Ref_Initialize time and
24 // select between them based on the ScanContext passed to us by the GC during the mark phase.
27 bool m_fUnpromotedPrimaries; // Did last scan find at least one non-null unpromoted primary?
28 bool m_fPromoted; // Did last scan promote at least one secondary?
29 promote_func *m_pfnPromoteFunction; // GC promote callback to be used for all secondary promotions
30 int m_iCondemned; // The condemned generation
31 int m_iMaxGen; // The maximum generation
32 ScanContext *m_pScanContext; // The GC's scan context for this phase
37 // @TODO (JSW): For compatibility with the existing GC code we use CNamespace
38 // as the name of this class. I'm planning on changing it to
39 // something like GCDomain....
42 typedef void enum_alloc_context_func(alloc_context*);
46 friend struct ::_DacGlobals;
51 static void GcStartDoWork();
53 static void GcScanSizedRefs(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
55 // Regular stack Roots
56 static void GcScanRoots (promote_func* fn, int condemned, int max_gen, ScanContext* sc);
59 static void GcScanHandles (promote_func* fn, int condemned, int max_gen, ScanContext* sc);
61 static void GcRuntimeStructuresValid (BOOL bValid);
63 static BOOL GetGcRuntimeStructuresValid ();
64 #ifdef DACCESS_COMPILE
65 static void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
66 #endif // DACCESS_COMPILE
68 #if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
69 static void GcScanHandlesForProfilerAndETW (int max_gen, ScanContext* sc);
70 static void GcScanDependentHandlesForProfilerAndETW (int max_gen, ProfilingScanContext* sc);
71 #endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
73 // scan for dead weak pointers
74 static void GcWeakPtrScan (promote_func* fn, int condemned, int max_gen, ScanContext*sc );
75 static void GcWeakPtrScanBySingleThread (int condemned, int max_gen, ScanContext*sc );
77 // scan for dead weak pointers
78 static void GcShortWeakPtrScan (promote_func* fn, int condemned, int max_gen,
82 // Dependent handle promotion scan support
85 // Perform initial (incomplete) scan which will deterimine if there's any further work required.
86 static void GcDhInitialScan(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
88 // Called between scans to ask if any handles with an unpromoted secondary existed at the end of the last
90 static bool GcDhUnpromotedHandlesExist(ScanContext* sc);
92 // Rescan the handles for additonal primaries that have been promoted since the last scan. Return true if
93 // any objects were promoted as a result.
94 static bool GcDhReScan(ScanContext* sc);
96 // post-promotions callback
97 static void GcPromotionsGranted (int condemned, int max_gen,
100 // post-promotions callback some roots were demoted
101 static void GcDemote (int condemned, int max_gen, ScanContext* sc);
103 static void GcEnumAllocContexts (enum_alloc_context_func* fn);
105 static void GcFixAllocContexts (void* arg, void *heap);
107 static size_t AskForMoreReservedMemory (size_t old_size, size_t need_size);
109 static void VerifyHandleTable(int condemned, int max_gen, ScanContext* sc);
112 #ifdef DACCESS_COMPILE
113 SVAL_DECL(LONG, m_GcStructuresInvalidCnt);
115 static VOLATILE(LONG) m_GcStructuresInvalidCnt;
116 #endif //DACCESS_COMPILE