summaryrefslogtreecommitdiff
path: root/src/gc/gcinterface.ee.h
blob: 1e08043b02d76369d1c4e2207b31e5684cfeaaf3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// 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 _GCINTERFACE_EE_H_
#define _GCINTERFACE_EE_H_

// This interface provides the interface that the GC will use to speak to the rest
// of the execution engine. Everything that the GC does that requires the EE
// to be informed or that requires EE action must go through this interface.
//
// When BUILD_AS_STANDALONE is defined, this class is named IGCToCLR and is
// an abstract class. The EE will provide a class that fulfills this interface,
// and the GC will dispatch virtually on it to call into the EE. When BUILD_AS_STANDALONE
// is not defined, this class is named GCToEEInterface and the GC will dispatch statically on it.
class IGCToCLR {
public:
    // Suspends the EE for the given reason.
    virtual
    void SuspendEE(SUSPEND_REASON reason) = 0;

    // Resumes all paused threads, with a boolean indicating
    // if the EE is being restarted because a GC is complete.
    virtual
    void RestartEE(bool bFinishedGC) = 0;

    // Performs a stack walk of all managed threads and invokes the given promote_func
    // on all GC roots encountered on the stack. Depending on the condemned generation,
    // this function may also enumerate all static GC refs if necessary.
    virtual
    void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc) = 0;

    // Callback from the GC informing the EE that it is preparing to start working.
    virtual
    void GcStartWork(int condemned, int max_gen) = 0;

    // Callback from the GC informing the EE that it has completed the managed stack
    // scan. User threads are still suspended at this point.
    virtual
    void AfterGcScanRoots(int condemned, int max_gen, ScanContext* sc) = 0;

    // Callback from the GC informing the EE that the background sweep phase of a BGC is
    // about to begin.
    virtual
    void GcBeforeBGCSweepWork() = 0;

    // Callback from the GC informing the EE that a GC has completed.
    virtual
    void GcDone(int condemned) = 0;

    // Predicate for the GC to query whether or not a given refcounted handle should
    // be promoted.
    virtual
    bool RefCountedHandleCallbacks(Object * pObject) = 0;

    // Performs a weak pointer scan of the sync block cache.
    virtual
    void SyncBlockCacheWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintptr_t lp2) = 0;

    // Indicates to the EE that the GC intends to demote objects in the sync block cache.
    virtual
    void SyncBlockCacheDemote(int max_gen) = 0;

    // Indicates to the EE that the GC has granted promotion to objects in the sync block cache.
    virtual
    void SyncBlockCachePromotionsGranted(int max_gen) = 0;

    // Queries whether or not the given thread has preemptive GC disabled.
    virtual
    bool IsPreemptiveGCDisabled(Thread * pThread) = 0;

    // Enables preemptive GC on the given thread.
    virtual
    void EnablePreemptiveGC(Thread * pThread) = 0;

    // Disables preemptive GC on the given thread.
    virtual
    void DisablePreemptiveGC(Thread * pThread) = 0;

    // Gets the Thread instance for the current thread, or null if no thread
    // instance is associated with this thread.
    virtual
    Thread* GetThread() = 0;

    // Returns whether or not a thread suspension is pending.
    virtual
    bool TrapReturningThreads() = 0;

    // Retrieves the alloc context associated with a given thread.
    virtual
    gc_alloc_context * GetAllocContext(Thread * pThread) = 0;

    // Returns true if this thread is waiting to reach a safe point.
    virtual
    bool CatchAtSafePoint(Thread * pThread) = 0;

    // Calls the given enum_alloc_context_func with every active alloc context.
    virtual
    void GcEnumAllocContexts(enum_alloc_context_func* fn, void* param) = 0;

    // Creates and returns a new background thread.
    virtual
    Thread* CreateBackgroundThread(GCBackgroundThreadFunction threadStart, void* arg) = 0;

    // When a GC starts, gives the diagnostics code a chance to run.
    virtual
    void DiagGCStart(int gen, bool isInduced) = 0;

    // When GC heap segments change, gives the diagnostics code a chance to run.
    virtual
    void DiagUpdateGenerationBounds() = 0;

    // When a GC ends, gives the diagnostics code a chance to run.
    virtual
    void DiagGCEnd(size_t index, int gen, int reason, bool fConcurrent) = 0;

    // During a GC after we discover what objects' finalizers should run, gives the diagnostics code a chance to run.
    virtual
    void DiagWalkFReachableObjects(void* gcContext) = 0;

    // During a GC after we discover the survivors and the relocation info, 
    // gives the diagnostics code a chance to run. This includes LOH if we are 
    // compacting LOH.
    virtual
    void DiagWalkSurvivors(void* gcContext) = 0;

    // During a full GC after we discover what objects to survive on LOH,
    // gives the diagnostics code a chance to run.
    virtual
    void DiagWalkLOHSurvivors(void* gcContext) = 0;

    // At the end of a background GC, gives the diagnostics code a chance to run.
    virtual
    void DiagWalkBGCSurvivors(void* gcContext) = 0;

    // Informs the EE of changes to the location of the card table, potentially updating the write
    // barrier if it needs to be updated.
    virtual
    void StompWriteBarrier(WriteBarrierParameters* args) = 0;

    // Signals to the finalizer thread that there are objects ready to
    // be finalized.
    virtual
    void EnableFinalization(bool foundFinalizers) = 0;

    // Signals to the EE that the GC encountered a fatal error and can't recover.
    virtual
    void HandleFatalError(unsigned int exitCode) = 0;

    // Asks the EE if it wants a particular object to be finalized when unloading
    // an app domain.
    virtual
    bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj) = 0;

    // Offers the EE the option to finalize the given object eagerly, i.e.
    // not on the finalizer thread but on the current thread. The
    // EE returns true if it finalized the object eagerly and the GC does not
    // need to do so, and false if it chose not to eagerly finalize the object
    // and it's up to the GC to finalize it later.
    virtual
    bool EagerFinalized(Object* obj) = 0;

    // Asks the EE if it wishes for the current GC to be a blocking GC. The GC will
    // only invoke this callback when it intends to do a full GC, so at this point
    // the EE can opt to elevate that collection to be a blocking GC and not a background one.
    virtual
    bool ForceFullGCToBeBlocking() = 0;

    // Retrieves the method table for the free object, a special kind of object used by the GC
    // to keep the heap traversable. Conceptually, the free object is similar to a managed array
    // of bytes: it consists of an object header (like all objects) and a "numComponents" field,
    // followed by some number of bytes of space that's free on the heap.
    //
    // The free object allows the GC to traverse the heap because it can inspect the numComponents
    // field to see how many bytes to skip before the next object on a heap segment begins.
    virtual
    MethodTable* GetFreeObjectMethodTable() = 0;

    // Asks the EE for the value of a given configuration key. If the EE does not know or does not
    // have a value for the requeested config key, false is returned and the value of the passed-in
    // pointer is undefined. Otherwise, true is returned and the config key's value is written to
    // the passed-in pointer.
    virtual
    bool GetBooleanConfigValue(const char* key, bool* value) = 0;

    virtual
    bool GetIntConfigValue(const char* key, int64_t* value) = 0;

    virtual
    bool GetStringConfigValue(const char* key, const char** value) = 0;

    virtual
    void FreeStringConfigValue(const char* value) = 0;
};

#endif // _GCINTERFACE_EE_H_