Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gcrhinterface.h « Runtime « Native « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2cea660732a223e951d198c1e05b6febe1b5f53f (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
// 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.

//
// This header contains the definition of an interface between the GC/HandleTable portions of the Redhawk
// codebase and the regular Redhawk code. The former has all sorts of legacy environmental requirements (see
// gcrhenv.h) that we don't wish to pull into the rest of Redhawk.
//
// Since this file is included in both worlds it has no dependencies and uses a very simple subset of types
// etc. so that it will build cleanly in both. The actual implementation of the class defined here is in
// gcrhenv.cpp, since the implementation needs access to the guts of the GC/HandleTable.
//
// This is just an initial stab at the interface.
//

#ifndef __GCRHINTERFACE_INCLUDED
#define __GCRHINTERFACE_INCLUDED

#ifndef DACCESS_COMPILE
// Global data cells exported by the GC.
extern "C" unsigned char *g_ephemeral_low;
extern "C" unsigned char *g_ephemeral_high;
extern "C" unsigned char *g_lowest_address;
extern "C" unsigned char *g_highest_address;
#endif

struct gc_alloc_context;
class MethodInfo;
struct REGDISPLAY;
class Thread;
enum GCRefKind : unsigned char;
class ICodeManager;
class EEType;

// -----------------------------------------------------------------------------------------------------------
// RtuObjectRef
// -----------------------------------------------------------------------------------------------------------
//
// READ THIS!
//
// This struct exists for type description purposes, but you must never directly refer to the object 
// reference.  The only code allowed to do this is the code inherited directly from the CLR, which all 
// includes gcrhenv.h.  If your code is outside the namespace of gcrhenv.h, direct object reference 
// manipulation is prohibited--use C# instead.
//
// To enforce this, we declare RtuObjectRef as a class with no public members.
//
class RtuObjectRef
{
#ifndef DACCESS_COMPILE
private:
#else
public:
#endif 
    TADDR pvObject;
};

typedef DPTR(RtuObjectRef) PTR_RtuObjectRef;

// -----------------------------------------------------------------------------------------------------------

// We provide various ways to enumerate GC objects or roots, each of which calls back to a user supplied
// function for each object (within the context of a garbage collection). The following function types
// describe these callbacks. Unfortunately the signatures aren't very specific: we don't want to reference
// Object* or Object** from this module, see the comment for RtuObjectRef, but this very narrow category of
// callers can't use RtuObjectRef (they really do need to drill down into the Object). The lesser evil here is
// to be a bit loose in the signature rather than exposing the Object class to the rest of Redhawk.

// Callback when enumerating objects on the GC heap or objects referenced from instance fields of another
// object. The GC dictates the shape of this signature (we're hijacking functionality originally developed for
// profiling). The real signature is:
//      int ScanFunction(Object* pObject, void* pContext)
// where:
//      return      : treated as a boolean, zero indicates the enumeration should terminate, all other values
//                    say continue
//      pObject     : pointer to the current object being scanned
//      pContext    : user context passed to the original scan function and otherwise uninterpreted
typedef int (*GcScanObjectFunction)(void*, void*);

// Callback when enumerating GC roots (stack locations, statics and handles). Similar to the callback above
// except there is no means to terminate the scan (no return value) and the root location (pointer to pointer
// to object) is returned instead of a direct pointer to the object:
//      void ScanFunction(Object** pRoot, void* pContext)
typedef void (*GcScanRootFunction)(void**, void*);

typedef void * GcSegmentHandle;

#define RH_LARGE_OBJECT_SIZE 85000

// A 'clump' is defined as the size of memory covered by 1 byte in the card table.  These constants are 
// verified against gcpriv.h in gcrhee.cpp.
#if (POINTER_SIZE == 8)
#define CLUMP_SIZE 0x800
#define LOG2_CLUMP_SIZE 11
#elif (POINTER_SIZE == 4)
#define CLUMP_SIZE 0x400
#define LOG2_CLUMP_SIZE 10
#else
#error unexpected pointer size
#endif

class RedhawkGCInterface
{
public:
    enum GCType
    {
        GCType_Workstation,
        GCType_Server,
    };

    // Perform any runtime-startup initialization needed by the GC, HandleTable or environmental code in
    // gcrhenv. The enum parameter is used to choose between workstation and server GC.
    // Returns true on success or false if a subsystem failed to initialize.
    // todo: figure out the final error reporting strategy
    static bool InitializeSubsystems(GCType gcType);

    static void InitAllocContext(gc_alloc_context * pAllocContext);
    static void ReleaseAllocContext(gc_alloc_context * pAllocContext);

    static void WaitForGCCompletion();

    static void EnumGcRef(PTR_RtuObjectRef pRef, GCRefKind kind, void * pfnEnumCallback, void * pvCallbackData);

    static void BulkEnumGcObjRef(PTR_RtuObjectRef pRefs, UInt32 cRefs, void * pfnEnumCallback, void * pvCallbackData);

    static void EnumGcRefs(ICodeManager * pCodeManager,
                           MethodInfo * pMethodInfo, 
                           PTR_VOID safePointAddress,
                           REGDISPLAY * pRegisterSet,
                           void * pfnEnumCallback,
                           void * pvCallbackData);

    static void EnumGcRefsInRegionConservatively(PTR_RtuObjectRef pLowerBound,
                                                 PTR_RtuObjectRef pUpperBound,
                                                 void * pfnEnumCallback,
                                                 void * pvCallbackData);

    static GcSegmentHandle RegisterFrozenSection(void * pSection, UInt32 SizeSection);
    static void UnregisterFrozenSection(GcSegmentHandle segment);

#ifdef FEATURE_GC_STRESS
    static void StressGc();
#endif // FEATURE_GC_STRESS

    // Various routines used to enumerate objects contained within a given scope (on the GC heap, as reference
    // fields of an object, on a thread stack, in a static or in one of the handle tables).
    static void ScanObject(void *pObject, GcScanObjectFunction pfnScanCallback, void *pContext);
    static void ScanStackRoots(Thread *pThread, GcScanRootFunction pfnScanCallback, void *pContext);
    static void ScanStaticRoots(GcScanRootFunction pfnScanCallback, void *pContext);
    static void ScanHandleTableRoots(GcScanRootFunction pfnScanCallback, void *pContext);

    // Returns size GCDesc. Used by type cloning.
    static UInt32 GetGCDescSize(void * pType);

    // These methods are used to get and set the type information for the last allocation on each thread.
    static EEType * GetLastAllocEEType();
    static void SetLastAllocEEType(EEType *pEEType);

    // Used by debugger hook
    static void* CreateTypedHandle(void* object, int type);
    static void DestroyTypedHandle(void* handle);

private:
    // The EEType for the last allocation.  This value is used inside of the GC allocator
    // to emit allocation ETW events with type information.  We set this value unconditionally to avoid
    // race conditions where ETW is enabled after the value is set.
    DECLSPEC_THREAD static EEType * tls_pLastAllocationEEType;
};

#endif // __GCRHINTERFACE_INCLUDED