1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/*
6 * GCSCAN.H
7 *
8 * GC Root Scanning
9 *
10
11 *
12 */
13
14#ifndef _GCSCAN_H_
15#define _GCSCAN_H_
16
17#include "gc.h"
18
19// Scanning dependent handles for promotion can become a complex operation due to cascaded dependencies and
20// other issues (see the comments for GcDhInitialScan and friends in gcscan.cpp for further details). As a
21// result we need to maintain a context between all the DH scanning methods called during a single mark phase.
22// The structure below describes this context. We allocate one of these per GC heap at Ref_Initialize time and
23// select between them based on the ScanContext passed to us by the GC during the mark phase.
24struct DhContext
25{
26 bool m_fUnpromotedPrimaries; // Did last scan find at least one non-null unpromoted primary?
27 bool m_fPromoted; // Did last scan promote at least one secondary?
28 promote_func *m_pfnPromoteFunction; // GC promote callback to be used for all secondary promotions
29 int m_iCondemned; // The condemned generation
30 int m_iMaxGen; // The maximum generation
31 ScanContext *m_pScanContext; // The GC's scan context for this phase
32};
33
34class GCScan
35{
36 public:
37
38 static void GcScanSizedRefs(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
39
40 // Regular stack Roots
41 static void GcScanRoots (promote_func* fn, int condemned, int max_gen, ScanContext* sc);
42
43 //
44 static void GcScanHandles (promote_func* fn, int condemned, int max_gen, ScanContext* sc);
45
46 static void GcRuntimeStructuresValid (BOOL bValid);
47
48 static bool GetGcRuntimeStructuresValid ();
49#ifdef DACCESS_COMPILE
50 static void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
51#endif // DACCESS_COMPILE
52
53 static void GcScanHandlesForProfilerAndETW (int max_gen, ScanContext* sc, handle_scan_fn fn);
54 static void GcScanDependentHandlesForProfilerAndETW (int max_gen, ScanContext* sc, handle_scan_fn fn);
55
56 // scan for dead weak pointers
57 static void GcWeakPtrScan (promote_func* fn, int condemned, int max_gen, ScanContext*sc );
58 static void GcWeakPtrScanBySingleThread (int condemned, int max_gen, ScanContext*sc );
59
60 // scan for dead weak pointers
61 static void GcShortWeakPtrScan (promote_func* fn, int condemned, int max_gen,
62 ScanContext* sc);
63
64 //
65 // Dependent handle promotion scan support
66 //
67
68 // Perform initial (incomplete) scan which will deterimine if there's any further work required.
69 static void GcDhInitialScan(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
70
71 // Called between scans to ask if any handles with an unpromoted secondary existed at the end of the last
72 // scan.
73 static bool GcDhUnpromotedHandlesExist(ScanContext* sc);
74
75 // Rescan the handles for additonal primaries that have been promoted since the last scan. Return true if
76 // any objects were promoted as a result.
77 static bool GcDhReScan(ScanContext* sc);
78
79 // post-promotions callback
80 static void GcPromotionsGranted (int condemned, int max_gen,
81 ScanContext* sc);
82
83 // post-promotions callback some roots were demoted
84 static void GcDemote (int condemned, int max_gen, ScanContext* sc);
85
86 static size_t AskForMoreReservedMemory (size_t old_size, size_t need_size);
87
88 static void VerifyHandleTable(int condemned, int max_gen, ScanContext* sc);
89
90 static VOLATILE(int32_t) m_GcStructuresInvalidCnt;
91};
92
93#endif // _GCSCAN_H_
94