1 | // |
2 | // Copyright (c) Microsoft. All rights reserved. |
3 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
4 | // |
5 | |
6 | #ifndef _ICorJitInfoImpl |
7 | #define _ICorJitInfoImpl |
8 | |
9 | // ICorJitInfoImpl: declare for implementation all the members of the ICorJitInfo interface (which are |
10 | // specified as pure virtual methods). This is done once, here, and all implementations share it, |
11 | // to avoid duplicated declarations. This file is #include'd within all the ICorJitInfo implementation |
12 | // classes. |
13 | // |
14 | // NOTE: this file is in exactly the same order, with exactly the same whitespace, as the ICorJitInfo |
15 | // interface declaration (with the "virtual" and "= 0" syntax removed). This is to make it easy to compare |
16 | // against the interface declaration. |
17 | |
18 | // clang-format off |
19 | |
20 | public: |
21 | /**********************************************************************************/ |
22 | // |
23 | // ICorMethodInfo |
24 | // |
25 | /**********************************************************************************/ |
26 | |
27 | // return flags (defined above, CORINFO_FLG_PUBLIC ...) |
28 | DWORD getMethodAttribs(CORINFO_METHOD_HANDLE ftn /* IN */ |
29 | ); |
30 | |
31 | // sets private JIT flags, which can be, retrieved using getAttrib. |
32 | void setMethodAttribs(CORINFO_METHOD_HANDLE ftn, /* IN */ |
33 | CorInfoMethodRuntimeFlags attribs /* IN */ |
34 | ); |
35 | |
36 | // Given a method descriptor ftnHnd, extract signature information into sigInfo |
37 | // |
38 | // 'memberParent' is typically only set when verifying. It should be the |
39 | // result of calling getMemberParent. |
40 | void getMethodSig(CORINFO_METHOD_HANDLE ftn, /* IN */ |
41 | CORINFO_SIG_INFO* sig, /* OUT */ |
42 | CORINFO_CLASS_HANDLE memberParent = NULL /* IN */ |
43 | ); |
44 | |
45 | /********************************************************************* |
46 | * Note the following methods can only be used on functions known |
47 | * to be IL. This includes the method being compiled and any method |
48 | * that 'getMethodInfo' returns true for |
49 | *********************************************************************/ |
50 | |
51 | // return information about a method private to the implementation |
52 | // returns false if method is not IL, or is otherwise unavailable. |
53 | // This method is used to fetch data needed to inline functions |
54 | bool getMethodInfo(CORINFO_METHOD_HANDLE ftn, /* IN */ |
55 | CORINFO_METHOD_INFO* info /* OUT */ |
56 | ); |
57 | |
58 | // Decides if you have any limitations for inlining. If everything's OK, it will return |
59 | // INLINE_PASS and will fill out pRestrictions with a mask of restrictions the caller of this |
60 | // function must respect. If caller passes pRestrictions = NULL, if there are any restrictions |
61 | // INLINE_FAIL will be returned |
62 | // |
63 | // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls) |
64 | // |
65 | // The inlined method need not be verified |
66 | |
67 | CorInfoInline canInline(CORINFO_METHOD_HANDLE callerHnd, /* IN */ |
68 | CORINFO_METHOD_HANDLE calleeHnd, /* IN */ |
69 | DWORD* pRestrictions /* OUT */ |
70 | ); |
71 | |
72 | // Reports whether or not a method can be inlined, and why. canInline is responsible for reporting all |
73 | // inlining results when it returns INLINE_FAIL and INLINE_NEVER. All other results are reported by the |
74 | // JIT. |
75 | void reportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd, |
76 | CORINFO_METHOD_HANDLE inlineeHnd, |
77 | CorInfoInline inlineResult, |
78 | const char* reason); |
79 | |
80 | // Returns false if the call is across security boundaries thus we cannot tailcall |
81 | // |
82 | // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls) |
83 | bool canTailCall(CORINFO_METHOD_HANDLE callerHnd, /* IN */ |
84 | CORINFO_METHOD_HANDLE declaredCalleeHnd, /* IN */ |
85 | CORINFO_METHOD_HANDLE exactCalleeHnd, /* IN */ |
86 | bool fIsTailPrefix /* IN */ |
87 | ); |
88 | |
89 | // Reports whether or not a method can be tail called, and why. |
90 | // canTailCall is responsible for reporting all results when it returns |
91 | // false. All other results are reported by the JIT. |
92 | void reportTailCallDecision(CORINFO_METHOD_HANDLE callerHnd, |
93 | CORINFO_METHOD_HANDLE calleeHnd, |
94 | bool fIsTailPrefix, |
95 | CorInfoTailCall tailCallResult, |
96 | const char* reason); |
97 | |
98 | // get individual exception handler |
99 | void getEHinfo(CORINFO_METHOD_HANDLE ftn, /* IN */ |
100 | unsigned EHnumber, /* IN */ |
101 | CORINFO_EH_CLAUSE* clause /* OUT */ |
102 | ); |
103 | |
104 | // return class it belongs to |
105 | CORINFO_CLASS_HANDLE getMethodClass(CORINFO_METHOD_HANDLE method); |
106 | |
107 | // return module it belongs to |
108 | CORINFO_MODULE_HANDLE getMethodModule(CORINFO_METHOD_HANDLE method); |
109 | |
110 | // This function returns the offset of the specified method in the |
111 | // vtable of it's owning class or interface. |
112 | void getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */ |
113 | unsigned* offsetOfIndirection, /* OUT */ |
114 | unsigned* offsetAfterIndirection,/* OUT */ |
115 | bool* isRelative /* OUT */ |
116 | ); |
117 | |
118 | // Find the virtual method in implementingClass that overrides virtualMethod. |
119 | // Return null if devirtualization is not possible. |
120 | CORINFO_METHOD_HANDLE resolveVirtualMethod(CORINFO_METHOD_HANDLE virtualMethod, |
121 | CORINFO_CLASS_HANDLE implementingClass, |
122 | CORINFO_CONTEXT_HANDLE ownerType); |
123 | |
124 | // Get the unboxed entry point for a method, if possible. |
125 | CORINFO_METHOD_HANDLE getUnboxedEntry( |
126 | CORINFO_METHOD_HANDLE ftn, |
127 | bool* requiresInstMethodTableArg /* OUT */); |
128 | |
129 | // Given T, return the type of the default EqualityComparer<T>. |
130 | // Returns null if the type can't be determined exactly. |
131 | CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE elemType); |
132 | |
133 | // Given resolved token that corresponds to an intrinsic classified as |
134 | // a CORINFO_INTRINSIC_GetRawHandle intrinsic, fetch the handle associated |
135 | // with the token. If this is not possible at compile-time (because the current method's |
136 | // code is shared and the token contains generic parameters) then indicate |
137 | // how the handle should be looked up at runtime. |
138 | void expandRawHandleIntrinsic( |
139 | CORINFO_RESOLVED_TOKEN * pResolvedToken, |
140 | CORINFO_GENERICHANDLE_RESULT * pResult); |
141 | |
142 | // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set, |
143 | // getIntrinsicID() returns the intrinsic ID. |
144 | // *pMustExpand tells whether or not JIT must expand the intrinsic. |
145 | CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method, bool* pMustExpand = NULL /* OUT */); |
146 | |
147 | // Is the given module the System.Numerics.Vectors module? |
148 | // This defaults to false. |
149 | bool isInSIMDModule(CORINFO_CLASS_HANDLE classHnd); /* { return false; } */ |
150 | |
151 | // return the unmanaged calling convention for a PInvoke |
152 | CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method); |
153 | |
154 | // return if any marshaling is required for PInvoke methods. Note that |
155 | // method == 0 => calli. The call site sig is only needed for the varargs or calli case |
156 | BOOL pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); |
157 | |
158 | // Check constraints on method type arguments (only). |
159 | // The parent class should be checked separately using satisfiesClassConstraints(parent). |
160 | BOOL satisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, // the exact parent of the method |
161 | CORINFO_METHOD_HANDLE method); |
162 | |
163 | // Given a delegate target class, a target method parent class, a target method, |
164 | // a delegate class, check if the method signature is compatible with the Invoke method of the delegate |
165 | // (under the typical instantiation of any free type variables in the memberref signatures). |
166 | BOOL isCompatibleDelegate(CORINFO_CLASS_HANDLE objCls, /* type of the delegate target, if any */ |
167 | CORINFO_CLASS_HANDLE methodParentCls, /* exact parent of the target method, if any */ |
168 | CORINFO_METHOD_HANDLE method, /* (representative) target method, if any */ |
169 | CORINFO_CLASS_HANDLE delegateCls, /* exact type of the delegate */ |
170 | BOOL* pfIsOpenDelegate /* is the delegate open */ |
171 | ); |
172 | |
173 | // Indicates if the method is an instance of the generic |
174 | // method that passes (or has passed) verification |
175 | CorInfoInstantiationVerification isInstantiationOfVerifiedGeneric(CORINFO_METHOD_HANDLE method /* IN */ |
176 | ); |
177 | |
178 | // Loads the constraints on a typical method definition, detecting cycles; |
179 | // for use in verification. |
180 | void initConstraintsForVerification(CORINFO_METHOD_HANDLE method, /* IN */ |
181 | BOOL* pfHasCircularClassConstraints, /* OUT */ |
182 | BOOL* pfHasCircularMethodConstraint /* OUT */ |
183 | ); |
184 | |
185 | // Returns enum whether the method does not require verification |
186 | // Also see ICorModuleInfo::canSkipVerification |
187 | CorInfoCanSkipVerificationResult canSkipMethodVerification(CORINFO_METHOD_HANDLE ftnHandle); |
188 | |
189 | // load and restore the method |
190 | void methodMustBeLoadedBeforeCodeIsRun(CORINFO_METHOD_HANDLE method); |
191 | |
192 | CORINFO_METHOD_HANDLE mapMethodDeclToMethodImpl(CORINFO_METHOD_HANDLE method); |
193 | |
194 | // Returns the global cookie for the /GS unsafe buffer checks |
195 | // The cookie might be a constant value (JIT), or a handle to memory location (Ngen) |
196 | void getGSCookie(GSCookie* pCookieVal, // OUT |
197 | GSCookie** ppCookieVal // OUT |
198 | ); |
199 | |
200 | /**********************************************************************************/ |
201 | // |
202 | // ICorModuleInfo |
203 | // |
204 | /**********************************************************************************/ |
205 | |
206 | // Resolve metadata token into runtime method handles. This function may not |
207 | // return normally (e.g. it may throw) if it encounters invalid metadata or other |
208 | // failures during token resolution. |
209 | void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN* pResolvedToken); |
210 | |
211 | // Attempt to resolve a metadata token into a runtime method handle. Returns true |
212 | // if resolution succeeded and false otherwise (e.g. if it encounters invalid metadata |
213 | // during token reoslution). This method should be used instead of `resolveToken` in |
214 | // situations that need to be resilient to invalid metadata. |
215 | bool tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN* pResolvedToken); |
216 | |
217 | // Signature information about the call sig |
218 | void findSig(CORINFO_MODULE_HANDLE module, /* IN */ |
219 | unsigned sigTOK, /* IN */ |
220 | CORINFO_CONTEXT_HANDLE context, /* IN */ |
221 | CORINFO_SIG_INFO* sig /* OUT */ |
222 | ); |
223 | |
224 | // for Varargs, the signature at the call site may differ from |
225 | // the signature at the definition. Thus we need a way of |
226 | // fetching the call site information |
227 | void findCallSiteSig(CORINFO_MODULE_HANDLE module, /* IN */ |
228 | unsigned methTOK, /* IN */ |
229 | CORINFO_CONTEXT_HANDLE context, /* IN */ |
230 | CORINFO_SIG_INFO* sig /* OUT */ |
231 | ); |
232 | |
233 | CORINFO_CLASS_HANDLE getTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken /* IN */); |
234 | |
235 | // Returns true if the module does not require verification |
236 | // |
237 | // If fQuickCheckOnlyWithoutCommit=TRUE, the function only checks that the |
238 | // module does not currently require verification in the current AppDomain. |
239 | // This decision could change in the future, and so should not be cached. |
240 | // If it is cached, it should only be used as a hint. |
241 | // This is only used by ngen for calculating certain hints. |
242 | // |
243 | |
244 | // Returns enum whether the module does not require verification |
245 | // Also see ICorMethodInfo::canSkipMethodVerification(); |
246 | CorInfoCanSkipVerificationResult canSkipVerification(CORINFO_MODULE_HANDLE module /* IN */ |
247 | ); |
248 | |
249 | // Checks if the given metadata token is valid |
250 | BOOL isValidToken(CORINFO_MODULE_HANDLE module, /* IN */ |
251 | unsigned metaTOK /* IN */ |
252 | ); |
253 | |
254 | // Checks if the given metadata token is valid StringRef |
255 | BOOL isValidStringRef(CORINFO_MODULE_HANDLE module, /* IN */ |
256 | unsigned metaTOK /* IN */ |
257 | ); |
258 | |
259 | BOOL shouldEnforceCallvirtRestriction(CORINFO_MODULE_HANDLE scope); |
260 | |
261 | /**********************************************************************************/ |
262 | // |
263 | // ICorClassInfo |
264 | // |
265 | /**********************************************************************************/ |
266 | |
267 | // If the value class 'cls' is isomorphic to a primitive type it will |
268 | // return that type, otherwise it will return CORINFO_TYPE_VALUECLASS |
269 | CorInfoType asCorInfoType(CORINFO_CLASS_HANDLE cls); |
270 | |
271 | // for completeness |
272 | const char* getClassName(CORINFO_CLASS_HANDLE cls); |
273 | |
274 | const char* getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName); |
275 | |
276 | CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index); |
277 | |
278 | // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen |
279 | // If fNamespace=TRUE, include the namespace/enclosing classes |
280 | // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters |
281 | // If fAssembly=TRUE, suffix with a comma and the full assembly qualification |
282 | // return size of representation |
283 | int appendClassName(__deref_inout_ecount(*pnBufLen) WCHAR** ppBuf, |
284 | int* pnBufLen, |
285 | CORINFO_CLASS_HANDLE cls, |
286 | BOOL fNamespace, |
287 | BOOL fFullInst, |
288 | BOOL fAssembly); |
289 | |
290 | // Quick check whether the type is a value class. Returns the same value as getClassAttribs(cls) & |
291 | // CORINFO_FLG_VALUECLASS, except faster. |
292 | BOOL isValueClass(CORINFO_CLASS_HANDLE cls); |
293 | |
294 | // Decides how the JIT should do the optimization to inline the check for |
295 | // GetTypeFromHandle(handle) == obj.GetType() (for CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE) |
296 | // GetTypeFromHandle(X) == GetTypeFromHandle(Y) (for CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN) |
297 | CorInfoInlineTypeCheck canInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source); |
298 | |
299 | // If this method returns true, JIT will do optimization to inline the check for |
300 | // GetTypeFromHandle(handle) == obj.GetType() |
301 | BOOL canInlineTypeCheckWithObjectVTable(CORINFO_CLASS_HANDLE cls); |
302 | |
303 | // return flags (defined above, CORINFO_FLG_PUBLIC ...) |
304 | DWORD getClassAttribs(CORINFO_CLASS_HANDLE cls); |
305 | |
306 | // Returns "TRUE" iff "cls" is a struct type such that return buffers used for returning a value |
307 | // of this type must be stack-allocated. This will generally be true only if the struct |
308 | // contains GC pointers, and does not exceed some size limit. Maintaining this as an invariant allows |
309 | // an optimization: the JIT may assume that return buffer pointers for return types for which this predicate |
310 | // returns TRUE are always stack allocated, and thus, that stores to the GC-pointer fields of such return |
311 | // buffers do not require GC write barriers. |
312 | BOOL isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls); |
313 | |
314 | CORINFO_MODULE_HANDLE getClassModule(CORINFO_CLASS_HANDLE cls); |
315 | |
316 | // Returns the assembly that contains the module "mod". |
317 | CORINFO_ASSEMBLY_HANDLE getModuleAssembly(CORINFO_MODULE_HANDLE mod); |
318 | |
319 | // Returns the name of the assembly "assem". |
320 | const char* getAssemblyName(CORINFO_ASSEMBLY_HANDLE assem); |
321 | |
322 | // Allocate and delete process-lifetime objects. Should only be |
323 | // referred to from static fields, lest a leak occur. |
324 | // Note that "LongLifetimeFree" does not execute destructors, if "obj" |
325 | // is an array of a struct type with a destructor. |
326 | void* LongLifetimeMalloc(size_t sz); |
327 | void LongLifetimeFree(void* obj); |
328 | |
329 | size_t getClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls, CORINFO_MODULE_HANDLE* pModule, void** ppIndirection); |
330 | |
331 | // return the number of bytes needed by an instance of the class |
332 | unsigned getClassSize(CORINFO_CLASS_HANDLE cls); |
333 | |
334 | // return the number of bytes needed by an instance of the class allocated on the heap |
335 | unsigned getHeapClassSize(CORINFO_CLASS_HANDLE cls); |
336 | |
337 | BOOL canAllocateOnStack(CORINFO_CLASS_HANDLE cls); |
338 | |
339 | unsigned getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint = FALSE); |
340 | |
341 | // This is only called for Value classes. It returns a boolean array |
342 | // in representing of 'cls' from a GC perspective. The class is |
343 | // assumed to be an array of machine words |
344 | // (of length // getClassSize(cls) / sizeof(void*)), |
345 | // 'gcPtrs' is a pointer to an array of BYTEs of this length. |
346 | // getClassGClayout fills in this array so that gcPtrs[i] is set |
347 | // to one of the CorInfoGCType values which is the GC type of |
348 | // the i-th machine word of an object of type 'cls' |
349 | // returns the number of GC pointers in the array |
350 | unsigned getClassGClayout(CORINFO_CLASS_HANDLE cls, /* IN */ |
351 | BYTE* gcPtrs /* OUT */ |
352 | ); |
353 | |
354 | // returns the number of instance fields in a class |
355 | unsigned getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls /* IN */ |
356 | ); |
357 | |
358 | CORINFO_FIELD_HANDLE getFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num); |
359 | |
360 | BOOL checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional); |
361 | |
362 | // returns the "NEW" helper optimized for "newCls." |
363 | CorInfoHelpFunc getNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, bool* pHasSideEffects = NULL /* OUT */); |
364 | |
365 | // returns the newArr (1-Dim array) helper optimized for "arrayCls." |
366 | CorInfoHelpFunc getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls); |
367 | |
368 | // returns the optimized "IsInstanceOf" or "ChkCast" helper |
369 | CorInfoHelpFunc getCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing); |
370 | |
371 | // returns helper to trigger static constructor |
372 | CorInfoHelpFunc getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd); |
373 | |
374 | CorInfoHelpFunc getSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn); |
375 | |
376 | // This is not pretty. Boxing nullable<T> actually returns |
377 | // a boxed<T> not a boxed Nullable<T>. This call allows the verifier |
378 | // to call back to the EE on the 'box' instruction and get the transformed |
379 | // type to use for verification. |
380 | CORINFO_CLASS_HANDLE getTypeForBox(CORINFO_CLASS_HANDLE cls); |
381 | |
382 | // returns the correct box helper for a particular class. Note |
383 | // that if this returns CORINFO_HELP_BOX, the JIT can assume |
384 | // 'standard' boxing (allocate object and copy), and optimize |
385 | CorInfoHelpFunc getBoxHelper(CORINFO_CLASS_HANDLE cls); |
386 | |
387 | // returns the unbox helper. If 'helperCopies' points to a true |
388 | // value it means the JIT is requesting a helper that unboxes the |
389 | // value into a particular location and thus has the signature |
390 | // void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj) |
391 | // Otherwise (it is null or points at a FALSE value) it is requesting |
392 | // a helper that returns a pointer to the unboxed data |
393 | // void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj) |
394 | // The EE has the option of NOT returning the copy style helper |
395 | // (But must be able to always honor the non-copy style helper) |
396 | // The EE set 'helperCopies' on return to indicate what kind of |
397 | // helper has been created. |
398 | |
399 | CorInfoHelpFunc getUnBoxHelper(CORINFO_CLASS_HANDLE cls); |
400 | |
401 | bool getReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
402 | CORINFO_LOOKUP_KIND* pGenericLookupKind, |
403 | CorInfoHelpFunc id, |
404 | CORINFO_CONST_LOOKUP* pLookup); |
405 | |
406 | void getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, |
407 | CORINFO_CLASS_HANDLE delegateType, |
408 | CORINFO_LOOKUP* pLookup); |
409 | |
410 | const char* getHelperName(CorInfoHelpFunc); |
411 | |
412 | // This function tries to initialize the class (run the class constructor). |
413 | // this function returns whether the JIT must insert helper calls before |
414 | // accessing static field or method. |
415 | // |
416 | // See code:ICorClassInfo#ClassConstruction. |
417 | CorInfoInitClassResult initClass(CORINFO_FIELD_HANDLE field, // Non-NULL - inquire about cctor trigger before static |
418 | // field access NULL - inquire about cctor trigger in |
419 | // method prolog |
420 | CORINFO_METHOD_HANDLE method, // Method referencing the field or prolog |
421 | CORINFO_CONTEXT_HANDLE context, // Exact context of method |
422 | BOOL speculative = FALSE // TRUE means don't actually run it |
423 | ); |
424 | |
425 | // This used to be called "loadClass". This records the fact |
426 | // that the class must be loaded (including restored if necessary) before we execute the |
427 | // code that we are currently generating. When jitting code |
428 | // the function loads the class immediately. When zapping code |
429 | // the zapper will if necessary use the call to record the fact that we have |
430 | // to do a fixup/restore before running the method currently being generated. |
431 | // |
432 | // This is typically used to ensure value types are loaded before zapped |
433 | // code that manipulates them is executed, so that the GC can access information |
434 | // about those value types. |
435 | void classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE cls); |
436 | |
437 | // returns the class handle for the special builtin classes |
438 | CORINFO_CLASS_HANDLE getBuiltinClass(CorInfoClassId classId); |
439 | |
440 | // "System.Int32" ==> CORINFO_TYPE_INT.. |
441 | CorInfoType getTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls); |
442 | |
443 | // "System.Int32" ==> CORINFO_TYPE_INT.. |
444 | // "System.UInt32" ==> CORINFO_TYPE_UINT.. |
445 | CorInfoType getTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls); |
446 | |
447 | // TRUE if child is a subtype of parent |
448 | // if parent is an interface, then does child implement / extend parent |
449 | BOOL canCast(CORINFO_CLASS_HANDLE child, // subtype (extends parent) |
450 | CORINFO_CLASS_HANDLE parent // base type |
451 | ); |
452 | |
453 | // TRUE if cls1 and cls2 are considered equivalent types. |
454 | BOOL areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); |
455 | |
456 | // See if a cast from fromClass to toClass will succeed, fail, or needs |
457 | // to be resolved at runtime. |
458 | TypeCompareState compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass); |
459 | |
460 | // See if types represented by cls1 and cls2 compare equal, not |
461 | // equal, or the comparison needs to be resolved at runtime. |
462 | TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); |
463 | |
464 | // returns is the intersection of cls1 and cls2. |
465 | CORINFO_CLASS_HANDLE mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); |
466 | |
467 | // Given a class handle, returns the Parent type. |
468 | // For COMObjectType, it returns Class Handle of System.Object. |
469 | // Returns 0 if System.Object is passed in. |
470 | CORINFO_CLASS_HANDLE getParentType(CORINFO_CLASS_HANDLE cls); |
471 | |
472 | // Returns the CorInfoType of the "child type". If the child type is |
473 | // not a primitive type, *clsRet will be set. |
474 | // Given an Array of Type Foo, returns Foo. |
475 | // Given BYREF Foo, returns Foo |
476 | CorInfoType getChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet); |
477 | |
478 | // Check constraints on type arguments of this class and parent classes |
479 | BOOL satisfiesClassConstraints(CORINFO_CLASS_HANDLE cls); |
480 | |
481 | // Check if this is a single dimensional array type |
482 | BOOL isSDArray(CORINFO_CLASS_HANDLE cls); |
483 | |
484 | // Get the numbmer of dimensions in an array |
485 | unsigned getArrayRank(CORINFO_CLASS_HANDLE cls); |
486 | |
487 | // Get static field data for an array |
488 | void* getArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size); |
489 | |
490 | // Check Visibility rules. |
491 | CorInfoIsAccessAllowedResult canAccessClass(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
492 | CORINFO_METHOD_HANDLE callerHandle, |
493 | CORINFO_HELPER_DESC* pAccessHelper /* If canAccessMethod returns something |
494 | other than ALLOWED, then this is |
495 | filled in. */ |
496 | ); |
497 | |
498 | /**********************************************************************************/ |
499 | // |
500 | // ICorFieldInfo |
501 | // |
502 | /**********************************************************************************/ |
503 | |
504 | // this function is for debugging only. It returns the field name |
505 | // and if 'moduleName' is non-null, it sets it to something that will |
506 | // says which method (a class name, or a module name) |
507 | const char* getFieldName(CORINFO_FIELD_HANDLE ftn, /* IN */ |
508 | const char** moduleName /* OUT */ |
509 | ); |
510 | |
511 | // return class it belongs to |
512 | CORINFO_CLASS_HANDLE getFieldClass(CORINFO_FIELD_HANDLE field); |
513 | |
514 | // Return the field's type, if it is CORINFO_TYPE_VALUECLASS 'structType' is set |
515 | // the field's value class (if 'structType' == 0, then don't bother |
516 | // the structure info). |
517 | // |
518 | // 'memberParent' is typically only set when verifying. It should be the |
519 | // result of calling getMemberParent. |
520 | CorInfoType getFieldType(CORINFO_FIELD_HANDLE field, |
521 | CORINFO_CLASS_HANDLE* structType = NULL, |
522 | CORINFO_CLASS_HANDLE memberParent = NULL /* IN */ |
523 | ); |
524 | |
525 | // return the data member's instance offset |
526 | unsigned getFieldOffset(CORINFO_FIELD_HANDLE field); |
527 | |
528 | // TODO: jit64 should be switched to the same plan as the i386 jits - use |
529 | // getClassGClayout to figure out the need for writebarrier helper, and inline the copying. |
530 | // The interpretted value class copy is slow. Once this happens, USE_WRITE_BARRIER_HELPERS |
531 | bool isWriteBarrierHelperRequired(CORINFO_FIELD_HANDLE field); |
532 | |
533 | void getFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
534 | CORINFO_METHOD_HANDLE callerHandle, |
535 | CORINFO_ACCESS_FLAGS flags, |
536 | CORINFO_FIELD_INFO* pResult); |
537 | |
538 | // Returns true iff "fldHnd" represents a static field. |
539 | bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd); |
540 | |
541 | /*********************************************************************************/ |
542 | // |
543 | // ICorDebugInfo |
544 | // |
545 | /*********************************************************************************/ |
546 | |
547 | // Query the EE to find out where interesting break points |
548 | // in the code are. The native compiler will ensure that these places |
549 | // have a corresponding break point in native code. |
550 | // |
551 | // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will |
552 | // be used only as a hint and the native compiler should not change its |
553 | // code generation. |
554 | void getBoundaries(CORINFO_METHOD_HANDLE ftn, // [IN] method of interest |
555 | unsigned int* cILOffsets, // [OUT] size of pILOffsets |
556 | DWORD** pILOffsets, // [OUT] IL offsets of interest |
557 | // jit MUST free with freeArray! |
558 | ICorDebugInfo::BoundaryTypes* implictBoundaries // [OUT] tell jit, all boundries of this type |
559 | ); |
560 | |
561 | // Report back the mapping from IL to native code, |
562 | // this map should include all boundaries that 'getBoundaries' |
563 | // reported as interesting to the debugger. |
564 | |
565 | // Note that debugger (and profiler) is assuming that all of the |
566 | // offsets form a contiguous block of memory, and that the |
567 | // OffsetMapping is sorted in order of increasing native offset. |
568 | void setBoundaries(CORINFO_METHOD_HANDLE ftn, // [IN] method of interest |
569 | ULONG32 cMap, // [IN] size of pMap |
570 | ICorDebugInfo::OffsetMapping* pMap // [IN] map including all points of interest. |
571 | // jit allocated with allocateArray, EE frees |
572 | ); |
573 | |
574 | // Query the EE to find out the scope of local varables. |
575 | // normally the JIT would trash variables after last use, but |
576 | // under debugging, the JIT needs to keep them live over their |
577 | // entire scope so that they can be inspected. |
578 | // |
579 | // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will |
580 | // be used only as a hint and the native compiler should not change its |
581 | // code generation. |
582 | void getVars(CORINFO_METHOD_HANDLE ftn, // [IN] method of interest |
583 | ULONG32* cVars, // [OUT] size of 'vars' |
584 | ICorDebugInfo::ILVarInfo** vars, // [OUT] scopes of variables of interest |
585 | // jit MUST free with freeArray! |
586 | bool* extendOthers // [OUT] it TRUE, then assume the scope |
587 | // of unmentioned vars is entire method |
588 | ); |
589 | |
590 | // Report back to the EE the location of every variable. |
591 | // note that the JIT might split lifetimes into different |
592 | // locations etc. |
593 | |
594 | void setVars(CORINFO_METHOD_HANDLE ftn, // [IN] method of interest |
595 | ULONG32 cVars, // [IN] size of 'vars' |
596 | ICorDebugInfo::NativeVarInfo* vars // [IN] map telling where local vars are stored at what points |
597 | // jit allocated with allocateArray, EE frees |
598 | ); |
599 | |
600 | /*-------------------------- Misc ---------------------------------------*/ |
601 | |
602 | // Used to allocate memory that needs to handed to the EE. |
603 | // For eg, use this to allocated memory for reporting debug info, |
604 | // which will be handed to the EE by setVars() and setBoundaries() |
605 | void* allocateArray(ULONG cBytes); |
606 | |
607 | // JitCompiler will free arrays passed by the EE using this |
608 | // For eg, The EE returns memory in getVars() and getBoundaries() |
609 | // to the JitCompiler, which the JitCompiler should release using |
610 | // freeArray() |
611 | void freeArray(void* array); |
612 | |
613 | /*********************************************************************************/ |
614 | // |
615 | // ICorArgInfo |
616 | // |
617 | /*********************************************************************************/ |
618 | |
619 | // advance the pointer to the argument list. |
620 | // a ptr of 0, is special and always means the first argument |
621 | CORINFO_ARG_LIST_HANDLE getArgNext(CORINFO_ARG_LIST_HANDLE args /* IN */ |
622 | ); |
623 | |
624 | // Get the type of a particular argument |
625 | // CORINFO_TYPE_UNDEF is returned when there are no more arguments |
626 | // If the type returned is a primitive type (or an enum) *vcTypeRet set to NULL |
627 | // otherwise it is set to the TypeHandle associted with the type |
628 | // Enumerations will always look their underlying type (probably should fix this) |
629 | // Otherwise vcTypeRet is the type as would be seen by the IL, |
630 | // The return value is the type that is used for calling convention purposes |
631 | // (Thus if the EE wants a value class to be passed like an int, then it will |
632 | // return CORINFO_TYPE_INT |
633 | CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, /* IN */ |
634 | CORINFO_ARG_LIST_HANDLE args, /* IN */ |
635 | CORINFO_CLASS_HANDLE* vcTypeRet /* OUT */ |
636 | ); |
637 | |
638 | // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it |
639 | CORINFO_CLASS_HANDLE getArgClass(CORINFO_SIG_INFO* sig, /* IN */ |
640 | CORINFO_ARG_LIST_HANDLE args /* IN */ |
641 | ); |
642 | |
643 | // Returns type of HFA for valuetype |
644 | CorInfoType getHFAType(CORINFO_CLASS_HANDLE hClass); |
645 | |
646 | /***************************************************************************** |
647 | * ICorErrorInfo contains methods to deal with SEH exceptions being thrown |
648 | * from the corinfo interface. These methods may be called when an exception |
649 | * with code EXCEPTION_COMPLUS is caught. |
650 | *****************************************************************************/ |
651 | |
652 | // Returns the HRESULT of the current exception |
653 | HRESULT GetErrorHRESULT(struct _EXCEPTION_POINTERS* pExceptionPointers); |
654 | |
655 | // Fetches the message of the current exception |
656 | // Returns the size of the message (including terminating null). This can be |
657 | // greater than bufferLength if the buffer is insufficient. |
658 | ULONG GetErrorMessage(__inout_ecount(bufferLength) LPWSTR buffer, ULONG bufferLength); |
659 | |
660 | // returns EXCEPTION_EXECUTE_HANDLER if it is OK for the compile to handle the |
661 | // exception, abort some work (like the inlining) and continue compilation |
662 | // returns EXCEPTION_CONTINUE_SEARCH if exception must always be handled by the EE |
663 | // things like ThreadStoppedException ... |
664 | // returns EXCEPTION_CONTINUE_EXECUTION if exception is fixed up by the EE |
665 | |
666 | int FilterException(struct _EXCEPTION_POINTERS* pExceptionPointers); |
667 | |
668 | // Cleans up internal EE tracking when an exception is caught. |
669 | void HandleException(struct _EXCEPTION_POINTERS* pExceptionPointers); |
670 | |
671 | void ThrowExceptionForJitResult(HRESULT result); |
672 | |
673 | // Throws an exception defined by the given throw helper. |
674 | void ThrowExceptionForHelper(const CORINFO_HELPER_DESC* throwHelper); |
675 | |
676 | // Runs the given function under an error trap. This allows the JIT to make calls |
677 | // to interface functions that may throw exceptions without needing to be aware of |
678 | // the EH ABI, exception types, etc. Returns true if the given function completed |
679 | // successfully and false otherwise. |
680 | bool runWithErrorTrap(void (*function)(void*), // The function to run |
681 | void* parameter // The context parameter that will be passed to the function and the handler |
682 | ); |
683 | |
684 | /***************************************************************************** |
685 | * ICorStaticInfo contains EE interface methods which return values that are |
686 | * constant from invocation to invocation. Thus they may be embedded in |
687 | * persisted information like statically generated code. (This is of course |
688 | * assuming that all code versions are identical each time.) |
689 | *****************************************************************************/ |
690 | |
691 | // Return details about EE internal data structures |
692 | void getEEInfo(CORINFO_EE_INFO* pEEInfoOut); |
693 | |
694 | // Returns name of the JIT timer log |
695 | LPCWSTR getJitTimeLogFilename(); |
696 | |
697 | /*********************************************************************************/ |
698 | // |
699 | // Diagnostic methods |
700 | // |
701 | /*********************************************************************************/ |
702 | |
703 | // this function is for debugging only. Returns method token. |
704 | // Returns mdMethodDefNil for dynamic methods. |
705 | mdMethodDef getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod); |
706 | |
707 | // this function is for debugging only. It returns the method name |
708 | // and if 'moduleName' is non-null, it sets it to something that will |
709 | // says which method (a class name, or a module name) |
710 | const char* getMethodName(CORINFO_METHOD_HANDLE ftn, /* IN */ |
711 | const char** moduleName /* OUT */ |
712 | ); |
713 | |
714 | // Return method name as in metadata, or nullptr if there is none, |
715 | // and optionally return the class name as in metadata. |
716 | // Suitable for non-debugging use. |
717 | const char* getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, /* IN */ |
718 | const char** className, /* OUT */ |
719 | const char** namespaceName, /* OUT */ |
720 | const char** enclosingClassName /* OUT */ |
721 | ); |
722 | |
723 | // this function is for debugging only. It returns a value that |
724 | // is will always be the same for a given method. It is used |
725 | // to implement the 'jitRange' functionality |
726 | unsigned getMethodHash(CORINFO_METHOD_HANDLE ftn /* IN */ |
727 | ); |
728 | |
729 | // this function is for debugging only. |
730 | size_t findNameOfToken(CORINFO_MODULE_HANDLE module, /* IN */ |
731 | mdToken metaTOK, /* IN */ |
732 | __out_ecount(FQNameCapacity) char* szFQName, /* OUT */ |
733 | size_t FQNameCapacity /* IN */ |
734 | ); |
735 | |
736 | // returns whether the struct is enregisterable. Only valid on a System V VM. Returns true on success, false on failure. |
737 | bool getSystemVAmd64PassStructInRegisterDescriptor( |
738 | /* IN */ CORINFO_CLASS_HANDLE structHnd, |
739 | /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr); |
740 | |
741 | /***************************************************************************** |
742 | * ICorDynamicInfo contains EE interface methods which return values that may |
743 | * change from invocation to invocation. They cannot be embedded in persisted |
744 | * data; they must be requeried each time the EE is run. |
745 | *****************************************************************************/ |
746 | |
747 | // |
748 | // These methods return values to the JIT which are not constant |
749 | // from session to session. |
750 | // |
751 | // These methods take an extra parameter : void **ppIndirection. |
752 | // If a JIT supports generation of prejit code (install-o-jit), it |
753 | // must pass a non-null value for this parameter, and check the |
754 | // resulting value. If *ppIndirection is NULL, code should be |
755 | // generated normally. If non-null, then the value of |
756 | // *ppIndirection is an address in the cookie table, and the code |
757 | // generator needs to generate an indirection through the table to |
758 | // get the resulting value. In this case, the return result of the |
759 | // function must NOT be directly embedded in the generated code. |
760 | // |
761 | // Note that if a JIT does not support prejit code generation, it |
762 | // may ignore the extra parameter & pass the default of NULL - the |
763 | // prejit ICorDynamicInfo implementation will see this & generate |
764 | // an error if the jitter is used in a prejit scenario. |
765 | // |
766 | |
767 | // Return details about EE internal data structures |
768 | |
769 | DWORD getThreadTLSIndex(void** ppIndirection = NULL); |
770 | |
771 | const void* getInlinedCallFrameVptr(void** ppIndirection = NULL); |
772 | |
773 | LONG* getAddrOfCaptureThreadGlobal(void** ppIndirection = NULL); |
774 | |
775 | // return the native entry point to an EE helper (see CorInfoHelpFunc) |
776 | void* getHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection = NULL); |
777 | |
778 | // return a callable address of the function (native code). This function |
779 | // may return a different value (depending on whether the method has |
780 | // been JITed or not. |
781 | void getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, /* IN */ |
782 | CORINFO_CONST_LOOKUP* pResult, /* OUT */ |
783 | CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY); |
784 | |
785 | // return a directly callable address. This can be used similarly to the |
786 | // value returned by getFunctionEntryPoint() except that it is |
787 | // guaranteed to be multi callable entrypoint. |
788 | void getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, CORINFO_CONST_LOOKUP* pResult); |
789 | |
790 | // get the synchronization handle that is passed to monXstatic function |
791 | void* getMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection = NULL); |
792 | |
793 | // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*). |
794 | // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used. |
795 | CorInfoHelpFunc getLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle); |
796 | |
797 | CORINFO_MODULE_HANDLE embedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection = NULL); |
798 | |
799 | CORINFO_CLASS_HANDLE embedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection = NULL); |
800 | |
801 | CORINFO_METHOD_HANDLE embedMethodHandle(CORINFO_METHOD_HANDLE handle, void** ppIndirection = NULL); |
802 | |
803 | CORINFO_FIELD_HANDLE embedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection = NULL); |
804 | |
805 | // Given a module scope (module), a method handle (context) and |
806 | // a metadata token (metaTOK), fetch the handle |
807 | // (type, field or method) associated with the token. |
808 | // If this is not possible at compile-time (because the current method's |
809 | // code is shared and the token contains generic parameters) |
810 | // then indicate how the handle should be looked up at run-time. |
811 | // |
812 | void embedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
813 | BOOL fEmbedParent, // TRUE - embeds parent type handle of the field/method handle |
814 | CORINFO_GENERICHANDLE_RESULT* pResult); |
815 | |
816 | // Return information used to locate the exact enclosing type of the current method. |
817 | // Used only to invoke .cctor method from code shared across generic instantiations |
818 | // !needsRuntimeLookup statically known (enclosing type of method itself) |
819 | // needsRuntimeLookup: |
820 | // CORINFO_LOOKUP_THISOBJ use vtable pointer of 'this' param |
821 | // CORINFO_LOOKUP_CLASSPARAM use vtable hidden param |
822 | // CORINFO_LOOKUP_METHODPARAM use enclosing type of method-desc hidden param |
823 | CORINFO_LOOKUP_KIND getLocationOfThisType(CORINFO_METHOD_HANDLE context); |
824 | |
825 | // NOTE: the two methods below--getPInvokeUnmanagedTarget and getAddressOfPInvokeFixup--are |
826 | // deprecated. New code should instead use getAddressOfPInvokeTarget, which subsumes the |
827 | // functionality of these methods. |
828 | |
829 | // return the unmanaged target *if method has already been prelinked.* |
830 | void* getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void** ppIndirection = NULL); |
831 | |
832 | // return address of fixup area for late-bound PInvoke calls. |
833 | void* getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void** ppIndirection = NULL); |
834 | |
835 | // return the address of the PInvoke target. May be a fixup area in the |
836 | // case of late-bound PInvoke calls. |
837 | void getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup); |
838 | |
839 | // Generate a cookie based on the signature that would needs to be passed |
840 | // to CORINFO_HELP_PINVOKE_CALLI |
841 | LPVOID GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection = NULL); |
842 | |
843 | // returns true if a VM cookie can be generated for it (might be false due to cross-module |
844 | // inlining, in which case the inlining should be aborted) |
845 | bool canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig); |
846 | |
847 | // Gets a handle that is checked to see if the current method is |
848 | // included in "JustMyCode" |
849 | CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(CORINFO_METHOD_HANDLE method, |
850 | CORINFO_JUST_MY_CODE_HANDLE** ppIndirection = NULL); |
851 | |
852 | // Gets a method handle that can be used to correlate profiling data. |
853 | // This is the IP of a native method, or the address of the descriptor struct |
854 | // for IL. Always guaranteed to be unique per process, and not to move. */ |
855 | void GetProfilingHandle(BOOL* pbHookFunction, void** pProfilerHandle, BOOL* pbIndirectedHandles); |
856 | |
857 | // Returns instructions on how to make the call. See code:CORINFO_CALL_INFO for possible return values. |
858 | void getCallInfo( |
859 | // Token info |
860 | CORINFO_RESOLVED_TOKEN* pResolvedToken, |
861 | |
862 | // Generics info |
863 | CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, |
864 | |
865 | // Security info |
866 | CORINFO_METHOD_HANDLE callerHandle, |
867 | |
868 | // Jit info |
869 | CORINFO_CALLINFO_FLAGS flags, |
870 | |
871 | // out params |
872 | CORINFO_CALL_INFO* pResult); |
873 | |
874 | BOOL canAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType); |
875 | |
876 | // Returns TRUE if the Class Domain ID is the RID of the class (currently true for every class |
877 | // except reflection emitted classes and generics) |
878 | BOOL isRIDClassDomainID(CORINFO_CLASS_HANDLE cls); |
879 | |
880 | // returns the class's domain ID for accessing shared statics |
881 | unsigned getClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection = NULL); |
882 | |
883 | // return the data's address (for static fields only) |
884 | void* getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection = NULL); |
885 | |
886 | // return the class handle for the current value of a static field |
887 | CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool *pIsSpeculative); |
888 | |
889 | // registers a vararg sig & returns a VM cookie for it (which can contain other stuff) |
890 | CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection = NULL); |
891 | |
892 | // returns true if a VM cookie can be generated for it (might be false due to cross-module |
893 | // inlining, in which case the inlining should be aborted) |
894 | bool canGetVarArgsHandle(CORINFO_SIG_INFO* pSig); |
895 | |
896 | // Allocate a string literal on the heap and return a handle to it |
897 | InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void** ppValue); |
898 | |
899 | InfoAccessType emptyStringLiteral(void** ppValue); |
900 | |
901 | // (static fields only) given that 'field' refers to thread local store, |
902 | // return the ID (TLS index), which is used to find the begining of the |
903 | // TLS data area for the particular DLL 'field' is associated with. |
904 | DWORD getFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection = NULL); |
905 | |
906 | // Sets another object to intercept calls to "self" and current method being compiled |
907 | void setOverride(ICorDynamicInfo* pOverride, CORINFO_METHOD_HANDLE currentMethod); |
908 | |
909 | // Adds an active dependency from the context method's module to the given module |
910 | // This is internal callback for the EE. JIT should not call it directly. |
911 | void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo); |
912 | |
913 | CORINFO_METHOD_HANDLE GetDelegateCtor(CORINFO_METHOD_HANDLE methHnd, |
914 | CORINFO_CLASS_HANDLE clsHnd, |
915 | CORINFO_METHOD_HANDLE targetMethodHnd, |
916 | DelegateCtorArgs* pCtorData); |
917 | |
918 | void MethodCompileComplete(CORINFO_METHOD_HANDLE methHnd); |
919 | |
920 | // return a thunk that will copy the arguments for the given signature. |
921 | void* getTailCallCopyArgsThunk(CORINFO_SIG_INFO* pSig, CorInfoHelperTailCallSpecialHandling flags); |
922 | |
923 | bool convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert); |
924 | |
925 | // return memory manager that the JIT can use to allocate a regular memory |
926 | IEEMemoryManager* getMemoryManager(); |
927 | |
928 | // get a block of memory for the code, readonly data, and read-write data |
929 | void allocMem(ULONG hotCodeSize, /* IN */ |
930 | ULONG coldCodeSize, /* IN */ |
931 | ULONG roDataSize, /* IN */ |
932 | ULONG xcptnsCount, /* IN */ |
933 | CorJitAllocMemFlag flag, /* IN */ |
934 | void** hotCodeBlock, /* OUT */ |
935 | void** coldCodeBlock, /* OUT */ |
936 | void** roDataBlock /* OUT */ |
937 | ); |
938 | |
939 | // Reserve memory for the method/funclet's unwind information. |
940 | // Note that this must be called before allocMem. It should be |
941 | // called once for the main method, once for every funclet, and |
942 | // once for every block of cold code for which allocUnwindInfo |
943 | // will be called. |
944 | // |
945 | // This is necessary because jitted code must allocate all the |
946 | // memory needed for the unwindInfo at the allocMem call. |
947 | // For prejitted code we split up the unwinding information into |
948 | // separate sections .rdata and .pdata. |
949 | // |
950 | void reserveUnwindInfo(BOOL isFunclet, /* IN */ |
951 | BOOL isColdCode, /* IN */ |
952 | ULONG unwindSize /* IN */ |
953 | ); |
954 | |
955 | // Allocate and initialize the .rdata and .pdata for this method or |
956 | // funclet, and get the block of memory needed for the machine-specific |
957 | // unwind information (the info for crawling the stack frame). |
958 | // Note that allocMem must be called first. |
959 | // |
960 | // Parameters: |
961 | // |
962 | // pHotCode main method code buffer, always filled in |
963 | // pColdCode cold code buffer, only filled in if this is cold code, |
964 | // null otherwise |
965 | // startOffset start of code block, relative to appropriate code buffer |
966 | // (e.g. pColdCode if cold, pHotCode if hot). |
967 | // endOffset end of code block, relative to appropriate code buffer |
968 | // unwindSize size of unwind info pointed to by pUnwindBlock |
969 | // pUnwindBlock pointer to unwind info |
970 | // funcKind type of funclet (main method code, handler, filter) |
971 | // |
972 | void allocUnwindInfo(BYTE* pHotCode, /* IN */ |
973 | BYTE* pColdCode, /* IN */ |
974 | ULONG startOffset, /* IN */ |
975 | ULONG endOffset, /* IN */ |
976 | ULONG unwindSize, /* IN */ |
977 | BYTE* pUnwindBlock, /* IN */ |
978 | CorJitFuncKind funcKind /* IN */ |
979 | ); |
980 | |
981 | // Get a block of memory needed for the code manager information, |
982 | // (the info for enumerating the GC pointers while crawling the |
983 | // stack frame). |
984 | // Note that allocMem must be called first |
985 | void* allocGCInfo(size_t size /* IN */ |
986 | ); |
987 | |
988 | void yieldExecution(); |
989 | |
990 | // Indicate how many exception handler blocks are to be returned. |
991 | // This is guaranteed to be called before any 'setEHinfo' call. |
992 | // Note that allocMem must be called before this method can be called. |
993 | void setEHcount(unsigned cEH /* IN */ |
994 | ); |
995 | |
996 | // Set the values for one particular exception handler block. |
997 | // |
998 | // Handler regions should be lexically contiguous. |
999 | // This is because FinallyIsUnwinding() uses lexicality to |
1000 | // determine if a "finally" clause is executing. |
1001 | void setEHinfo(unsigned EHnumber, /* IN */ |
1002 | const CORINFO_EH_CLAUSE* clause /* IN */ |
1003 | ); |
1004 | |
1005 | // Level -> fatalError, Level 2 -> Error, Level 3 -> Warning |
1006 | // Level 4 means happens 10 times in a run, level 5 means 100, level 6 means 1000 ... |
1007 | // returns non-zero if the logging succeeded |
1008 | BOOL logMsg(unsigned level, const char* fmt, va_list args); |
1009 | |
1010 | // do an assert. will return true if the code should retry (DebugBreak) |
1011 | // returns false, if the assert should be igored. |
1012 | int doAssert(const char* szFile, int iLine, const char* szExpr); |
1013 | |
1014 | void reportFatalError(CorJitResult result); |
1015 | |
1016 | /* |
1017 | struct ProfileBuffer // Also defined here: code:CORBBTPROF_BLOCK_DATA |
1018 | { |
1019 | ULONG ILOffset; |
1020 | ULONG ExecutionCount; |
1021 | }; |
1022 | */ |
1023 | |
1024 | // allocate a basic block profile buffer where execution counts will be stored |
1025 | // for jitted basic blocks. |
1026 | HRESULT allocBBProfileBuffer(ULONG count, // The number of basic blocks that we have |
1027 | ProfileBuffer** profileBuffer); |
1028 | |
1029 | // get profile information to be used for optimizing the current method. The format |
1030 | // of the buffer is the same as the format the JIT passes to allocBBProfileBuffer. |
1031 | HRESULT getBBProfileData(CORINFO_METHOD_HANDLE ftnHnd, |
1032 | ULONG* count, // The number of basic blocks that we have |
1033 | ProfileBuffer** profileBuffer, |
1034 | ULONG* numRuns); |
1035 | |
1036 | // Associates a native call site, identified by its offset in the native code stream, with |
1037 | // the signature information and method handle the JIT used to lay out the call site. If |
1038 | // the call site has no signature information (e.g. a helper call) or has no method handle |
1039 | // (e.g. a CALLI P/Invoke), then null should be passed instead. |
1040 | void recordCallSite(ULONG instrOffset, /* IN */ |
1041 | CORINFO_SIG_INFO* callSig, /* IN */ |
1042 | CORINFO_METHOD_HANDLE methodHandle /* IN */ |
1043 | ); |
1044 | |
1045 | // A relocation is recorded if we are pre-jitting. |
1046 | // A jump thunk may be inserted if we are jitting |
1047 | void recordRelocation(void* location, /* IN */ |
1048 | void* target, /* IN */ |
1049 | WORD fRelocType, /* IN */ |
1050 | WORD slotNum, /* IN */ |
1051 | INT32 addlDelta /* IN */ |
1052 | ); |
1053 | |
1054 | WORD getRelocTypeHint(void* target); |
1055 | |
1056 | // A callback to identify the range of address known to point to |
1057 | // compiler-generated native entry points that call back into |
1058 | // MSIL. |
1059 | void getModuleNativeEntryPointRange(void** pStart, /* OUT */ |
1060 | void** pEnd /* OUT */ |
1061 | ); |
1062 | |
1063 | // For what machine does the VM expect the JIT to generate code? The VM |
1064 | // returns one of the IMAGE_FILE_MACHINE_* values. Note that if the VM |
1065 | // is cross-compiling (such as the case for crossgen), it will return a |
1066 | // different value than if it was compiling for the host architecture. |
1067 | // |
1068 | DWORD getExpectedTargetArchitecture(); |
1069 | |
1070 | // Fetches extended flags for a particular compilation instance. Returns |
1071 | // the number of bytes written to the provided buffer. |
1072 | DWORD getJitFlags(CORJIT_FLAGS* flags, /* IN: Points to a buffer that will hold the extended flags. */ |
1073 | DWORD sizeInBytes /* IN: The size of the buffer. Note that this is effectively a |
1074 | version number for the CORJIT_FLAGS value. */ |
1075 | ); |
1076 | |
1077 | #endif // _ICorJitInfoImpl |
1078 | |