READYTORUN_HELPER_GenericNonGcTlsBase = 0x67,
READYTORUN_HELPER_VirtualFuncPtr = 0x68,
READYTORUN_HELPER_IsInstanceOfException = 0x69,
+ READYTORUN_HELPER_NewMaybeFrozenArray = 0x6A,
+ READYTORUN_HELPER_NewMaybeFrozenObject = 0x6B,
// Long mul/div/shift ops
READYTORUN_HELPER_LMul = 0xC0,
which is the right helper to use to allocate an object of a given type. */
CORINFO_HELP_NEWFAST,
+ CORINFO_HELP_NEWFAST_MAYBEFROZEN, // allocator for objects that *might* allocate them on a frozen segment
CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object
CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object
CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned
CORINFO_HELP_NEW_MDARR,// multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array)
CORINFO_HELP_NEW_MDARR_RARE,// rare multi-dim array helper (Rank == 1)
CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation
+ CORINFO_HELP_NEWARR_1_MAYBEFROZEN, // allocator for arrays that *might* allocate them on a frozen segment
CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays
CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays
CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start
CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time
CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time, handle might point to a null type
- CORINFO_HELP_ARE_TYPES_EQUIVALENT, // Check whether two TypeHandles (native structure pointers) are equivalent
-
CORINFO_HELP_VIRTUAL_FUNC_PTR, // look up a virtual method at run-time
// Not a real helpers. Instead of taking handle arguments, these helpers point to a small stub that loads the handle argument and calls the static helper.
CORINFO_CLASS_HANDLE parent // base type
) = 0;
- // TRUE if cls1 and cls2 are considered equivalent types.
- virtual bool areTypesEquivalent(
- CORINFO_CLASS_HANDLE cls1,
- CORINFO_CLASS_HANDLE cls2
- ) = 0;
-
// See if a cast from fromClass to toClass will succeed, fail, or needs
// to be resolved at runtime.
virtual TypeCompareState compareTypesForCast(
CORJIT_FLAG_OSR = 13, // Generate alternate method for On Stack Replacement
CORJIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT
- CORJIT_FLAG_UNUSED8 = 15,
+ CORJIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_MAYBEFROZEN allocators
CORJIT_FLAG_UNUSED9 = 16,
CORJIT_FLAG_UNUSED10 = 17,
CORINFO_CLASS_HANDLE child,
CORINFO_CLASS_HANDLE parent) override;
-bool areTypesEquivalent(
- CORINFO_CLASS_HANDLE cls1,
- CORINFO_CLASS_HANDLE cls2) override;
-
TypeCompareState compareTypesForCast(
CORINFO_CLASS_HANDLE fromClass,
CORINFO_CLASS_HANDLE toClass) override;
#define GUID_DEFINED
#endif // !GUID_DEFINED
-constexpr GUID JITEEVersionIdentifier = { /* 387bcec3-9a71-4422-a11c-e7ce3b73c592 */
- 0x387bcec3,
- 0x9a71,
- 0x4422,
- {0xa1, 0x1c, 0xe7, 0xce, 0x3b, 0x73, 0xc5, 0x92}
+constexpr GUID JITEEVersionIdentifier = { /* 4e6355a0-3844-45e2-8cef-082c18217e14 */
+ 0x4e6355a0,
+ 0x3844,
+ 0x45e2,
+ {0x8c, 0xef, 0x8, 0x2c, 0x18, 0x21, 0x7e, 0x14}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Allocating a new object
JITHELPER(CORINFO_HELP_NEWFAST, JIT_New, CORINFO_HELP_SIG_REG_ONLY)
+ JITHELPER(CORINFO_HELP_NEWFAST_MAYBEFROZEN, JIT_NewMaybeFrozen,CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST, JIT_New, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_NEWSFAST_FINALIZE, NULL, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST_ALIGN8, JIT_New, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_NEW_MDARR, JIT_NewMDArr,CORINFO_HELP_SIG_4_STACK)
JITHELPER(CORINFO_HELP_NEW_MDARR_RARE, JIT_NewMDArr,CORINFO_HELP_SIG_4_STACK)
JITHELPER(CORINFO_HELP_NEWARR_1_DIRECT, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
+ JITHELPER(CORINFO_HELP_NEWARR_1_MAYBEFROZEN, JIT_NewArr1MaybeFrozen,CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_VC, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_ALIGN8, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, JIT_GetRuntimeType, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, JIT_GetRuntimeType_MaybeNull, CORINFO_HELP_SIG_REG_ONLY)
- JITHELPER(CORINFO_HELP_ARE_TYPES_EQUIVALENT, NULL, CORINFO_HELP_SIG_REG_ONLY)
-
JITHELPER(CORINFO_HELP_VIRTUAL_FUNC_PTR, JIT_VirtualFunctionPointer, CORINFO_HELP_SIG_4_STACK)
JITHELPER(CORINFO_HELP_READYTORUN_NEW, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
// src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs
// src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h
#define READYTORUN_MAJOR_VERSION 0x0009
-#define READYTORUN_MINOR_VERSION 0x0000
+#define READYTORUN_MINOR_VERSION 0x0001
#define MINIMUM_READYTORUN_MAJOR_VERSION 0x009
// R2R 6.0 is not backward compatible with 5.x or earlier.
// R2R Version 8.0 Changes the alignment of the Int128 type
// R2R Version 9.0 adds support for the Vector512 type
+// R2R Version 9.1 adds new helpers to allocate objects on frozen segments
struct READYTORUN_CORE_HEADER
{
READYTORUN_HELPER_GenericNonGcTlsBase = 0x67,
READYTORUN_HELPER_VirtualFuncPtr = 0x68,
READYTORUN_HELPER_IsInstanceOfException = 0x69,
+ READYTORUN_HELPER_NewMaybeFrozenArray = 0x6A,
+ READYTORUN_HELPER_NewMaybeFrozenObject = 0x6B,
// Long mul/div/shift ops
READYTORUN_HELPER_LMul = 0xC0,
HELPER(READYTORUN_HELPER_VirtualFuncPtr, CORINFO_HELP_VIRTUAL_FUNC_PTR, )
HELPER(READYTORUN_HELPER_IsInstanceOfException, CORINFO_HELP_ISINSTANCEOF_EXCEPTION, )
+HELPER(READYTORUN_HELPER_NewMaybeFrozenArray, CORINFO_HELP_NEWARR_1_MAYBEFROZEN, )
+HELPER(READYTORUN_HELPER_NewMaybeFrozenObject, CORINFO_HELP_NEWFAST_MAYBEFROZEN, )
HELPER(READYTORUN_HELPER_LMul, CORINFO_HELP_LMUL, )
HELPER(READYTORUN_HELPER_LMulOfv, CORINFO_HELP_LMUL_OVF, )
DEF_CLR_API(getTypeForPrimitiveValueClass)
DEF_CLR_API(getTypeForPrimitiveNumericClass)
DEF_CLR_API(canCast)
-DEF_CLR_API(areTypesEquivalent)
DEF_CLR_API(compareTypesForCast)
DEF_CLR_API(compareTypesForEquality)
DEF_CLR_API(mergeClasses)
return temp;
}
-bool WrapICorJitInfo::areTypesEquivalent(
- CORINFO_CLASS_HANDLE cls1,
- CORINFO_CLASS_HANDLE cls2)
-{
- API_ENTER(areTypesEquivalent);
- bool temp = wrapHnd->areTypesEquivalent(cls1, cls2);
- API_LEAVE(areTypesEquivalent);
- return temp;
-}
-
TypeCompareState WrapICorJitInfo::compareTypesForCast(
CORINFO_CLASS_HANDLE fromClass,
CORINFO_CLASS_HANDLE toClass)
GenTree* gtFoldBoxNullable(GenTree* tree);
GenTree* gtFoldExprCompare(GenTree* tree);
GenTree* gtFoldExprConditional(GenTree* tree);
- GenTree* gtCreateHandleCompare(genTreeOps oper,
- GenTree* op1,
- GenTree* op2,
- CorInfoInlineTypeCheck typeCheckInliningResult);
GenTree* gtFoldExprCall(GenTreeCall* call);
GenTree* gtFoldTypeCompare(GenTree* tree);
GenTree* gtFoldTypeEqualityCall(bool isEq, GenTree* op1, GenTree* op2);
if (call->gtCallType == CT_HELPER)
{
- switch (eeGetHelperNum(call->gtCallMethHnd))
+ CorInfoHelpFunc helper = eeGetHelperNum(call->gtCallMethHnd);
+ switch (helper)
{
+ case CORINFO_HELP_NEWARR_1_MAYBEFROZEN:
case CORINFO_HELP_NEWARR_1_DIRECT:
case CORINFO_HELP_NEWARR_1_OBJ:
case CORINFO_HELP_NEWARR_1_VC:
case CORINFO_HELP_NEWARR_1_ALIGN8:
{
// This is an array allocation site. Grab the array length node.
- arrayLength = call->gtArgs.GetArgByIndex(1)->GetNode();
- break;
- }
-
- case CORINFO_HELP_READYTORUN_NEWARR_1:
- {
- // On arm when compiling on certain platforms for ready to
- // run, a handle will be inserted before the length. To
- // handle this case, we will grab the last argument as
- // that's always the length. See
- // CallArgs::AddFinalArgsAndDetermineABIInfo for where the
- // handle is inserted.
- for (CallArg& arg : call->gtArgs.Args())
- {
- arrayLength = arg.GetNode();
- }
+ arrayLength = call->gtArgs.GetUserArgByIndex(1)->GetNode();
break;
}
}
//------------------------------------------------------------------------
-// gtCreateHandleCompare: generate a type handle comparison
-//
-// Arguments:
-// oper -- comparison operation (equal/not equal)
-// op1 -- first operand
-// op2 -- second operand
-// typeCheckInliningResult -- indicates how the comparison should happen
-//
-// Returns:
-// Type comparison tree
-//
-
-GenTree* Compiler::gtCreateHandleCompare(genTreeOps oper,
- GenTree* op1,
- GenTree* op2,
- CorInfoInlineTypeCheck typeCheckInliningResult)
-{
- // If we can compare pointers directly, just emit the binary operation
- if (typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_PASS)
- {
- return gtNewOperNode(oper, TYP_INT, op1, op2);
- }
-
- assert(typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_USE_HELPER);
-
- // Emit a call to a runtime helper
- GenTree* ret = gtNewHelperCallNode(CORINFO_HELP_ARE_TYPES_EQUIVALENT, TYP_INT, op1, op2);
- if (oper == GT_EQ)
- {
- ret = gtNewOperNode(GT_NE, TYP_INT, ret, gtNewIconNode(0, TYP_INT));
- }
- else
- {
- assert(oper == GT_NE);
- ret = gtNewOperNode(GT_EQ, TYP_INT, ret, gtNewIconNode(0, TYP_INT));
- }
-
- return ret;
-}
-
-//------------------------------------------------------------------------
// gtFoldTypeCompare: see if a type comparison can be further simplified
//
// Arguments:
inliningKind = info.compCompHnd->canInlineTypeCheck(cls2Hnd, CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN);
}
- assert(inliningKind == CORINFO_INLINE_TYPECHECK_PASS || inliningKind == CORINFO_INLINE_TYPECHECK_USE_HELPER);
+ assert(inliningKind == CORINFO_INLINE_TYPECHECK_PASS);
- GenTree* compare = gtCreateHandleCompare(oper, op1ClassFromHandle, op2ClassFromHandle, inliningKind);
+ GenTree* compare = gtNewOperNode(oper, TYP_INT, op1ClassFromHandle, op2ClassFromHandle);
// Drop any now-irrelevant flags
compare->gtFlags |= tree->gtFlags & (GTF_RELOP_JMP_USED | GTF_DONT_CSE);
arg2 = gtNewMethodTableLookup(arg2);
- CorInfoInlineTypeCheck inliningKind =
- info.compCompHnd->canInlineTypeCheck(nullptr, CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE);
- assert(inliningKind == CORINFO_INLINE_TYPECHECK_PASS || inliningKind == CORINFO_INLINE_TYPECHECK_USE_HELPER);
+ assert(info.compCompHnd->canInlineTypeCheck(nullptr, CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE) ==
+ CORINFO_INLINE_TYPECHECK_PASS);
- GenTree* compare = gtCreateHandleCompare(oper, arg1, arg2, inliningKind);
+ GenTree* compare = gtNewOperNode(oper, TYP_INT, arg1, arg2);
// Drop any now-irrelevant flags
compare->gtFlags |= tree->gtFlags & (GTF_RELOP_JMP_USED | GTF_DONT_CSE);
GenTree* const objMT = gtNewMethodTableLookup(objOp);
// Compare the two method tables
- GenTree* const compare = gtCreateHandleCompare(oper, objMT, knownMT, typeCheckInliningResult);
+ assert(typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_PASS);
+ GenTree* const compare = gtNewOperNode(oper, TYP_INT, objMT, knownMT);
// Drop any now irrelevant flags
compare->gtFlags |= tree->gtFlags & (GTF_RELOP_JMP_USED | GTF_DONT_CSE);
}
case CORINFO_HELP_NEWARR_1_DIRECT:
+ case CORINFO_HELP_NEWARR_1_MAYBEFROZEN:
case CORINFO_HELP_NEWARR_1_OBJ:
case CORINFO_HELP_NEWARR_1_VC:
case CORINFO_HELP_NEWARR_1_ALIGN8:
// So if we have an int, explicitly extend it to be a native int.
op2 = impImplicitIorI4Cast(op2, TYP_I_IMPL);
+ bool isFrozenAllocator = false;
+ // If we're jitting a static constructor and detect the following code pattern:
+ //
+ // newarr
+ // stsfld
+ // ret
+ //
+ // we emit a "frozen" allocator for newarr to, hopefully, allocate that array on a frozen segment.
+ // This is a very simple and conservative implementation targeting Array.Empty<T>()'s shape
+ // Ideally, we want to be able to use frozen allocators more broadly, but such an analysis is
+ // not trivial.
+ //
+ if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) &&
+ // Does VM allow us to use frozen allocators?
+ opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED))
+ {
+ // Check next two opcodes (have to be STSFLD and RET)
+ const BYTE* nextOpcode1 = codeAddr + sizeof(mdToken);
+ const BYTE* nextOpcode2 = nextOpcode1 + sizeof(mdToken) + 1;
+ if ((nextOpcode2 < codeEndp) && (getU1LittleEndian(nextOpcode1) == CEE_STSFLD))
+ {
+ if (getU1LittleEndian(nextOpcode2) == CEE_RET)
+ {
+ // Check that the field is "static readonly", we don't want to waste memory
+ // for potentially mutable fields.
+ CORINFO_RESOLVED_TOKEN fldToken;
+ impResolveToken(nextOpcode1 + 1, &fldToken, CORINFO_TOKENKIND_Field);
+ CORINFO_FIELD_INFO fi;
+ eeGetFieldInfo(&fldToken, CORINFO_ACCESS_SET, &fi);
+ unsigned flagsToCheck = CORINFO_FLG_FIELD_STATIC | CORINFO_FLG_FIELD_FINAL;
+ if ((fi.fieldFlags & flagsToCheck) == flagsToCheck)
+ {
#ifdef FEATURE_READYTORUN
- if (opts.IsReadyToRun())
+ if (opts.IsReadyToRun())
+ {
+ // Need to restore array classes before creating array objects on the heap
+ op1 = impTokenToHandle(&resolvedToken, nullptr, true /*mustRestoreHandle*/);
+ }
+#endif
+ op1 = gtNewHelperCallNode(CORINFO_HELP_NEWARR_1_MAYBEFROZEN, TYP_REF, op1, op2);
+ isFrozenAllocator = true;
+ }
+ }
+ }
+ }
+
+#ifdef FEATURE_READYTORUN
+ if (opts.IsReadyToRun() && !isFrozenAllocator)
{
- op1 = impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_NEWARR_1, TYP_REF, nullptr,
- op2);
+ helper = CORINFO_HELP_READYTORUN_NEWARR_1;
+ op1 = impReadyToRunHelperToTree(&resolvedToken, helper, TYP_REF, nullptr, op2);
usingReadyToRunHelper = (op1 != nullptr);
if (!usingReadyToRunHelper)
// 3) Allocate the new array
// Reason: performance (today, we'll always use the slow helper for the R2R generics case)
- // Need to restore array classes before creating array objects on the heap
op1 = impTokenToHandle(&resolvedToken, nullptr, true /*mustRestoreHandle*/);
if (op1 == nullptr)
{ // compDonotInline()
}
}
- if (!usingReadyToRunHelper)
+ if (!usingReadyToRunHelper && !isFrozenAllocator)
#endif
{
/* Create a call to 'new' */
+ helper = info.compCompHnd->getNewArrHelper(resolvedToken.hClass);
// Note that this only works for shared generic code because the same helper is used for all
// reference array types
- op1 =
- gtNewHelperCallNode(info.compCompHnd->getNewArrHelper(resolvedToken.hClass), TYP_REF, op1, op2);
+ op1 = gtNewHelperCallNode(helper, TYP_REF, op1, op2);
}
op1->AsCall()->compileTimeHelperArgumentHandle = (CORINFO_GENERIC_HANDLE)resolvedToken.hClass;
bool isMDArray = false;
if (newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_DIRECT) &&
+ newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_MAYBEFROZEN) &&
newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_OBJ) &&
newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_VC) &&
newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_ALIGN8)
GenTree* arrayLengthNode;
#ifdef FEATURE_READYTORUN
- if (newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_READYTORUN_NEWARR_1))
+ if (newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_READYTORUN_NEWARR_1) ||
+ newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_MAYBEFROZEN))
{
// Array length is 1st argument for readytorun helper
arrayLengthNode = newArrayCall->AsCall()->gtArgs.GetArgByIndex(0)->GetNode();
JIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement
JIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT
- JIT_FLAG_UNUSED8 = 15,
+ JIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_MAYBEFROZEN allocators
JIT_FLAG_UNUSED9 = 16,
#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64)
#endif
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT, JIT_FLAG_ALT_JIT);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_FROZEN_ALLOC_ALLOWED, JIT_FLAG_FROZEN_ALLOC_ALLOWED);
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE, JIT_FLAG_MAKEFINALCODE);
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_READYTORUN, JIT_FLAG_READYTORUN);
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE, JIT_FLAG_PROF_ENTERLEAVE);
case CORINFO_HELP_NEWSFAST_ALIGN8:
case CORINFO_HELP_NEWSFAST_ALIGN8_VC:
case CORINFO_HELP_NEWFAST:
+ case CORINFO_HELP_NEWFAST_MAYBEFROZEN:
case CORINFO_HELP_NEWSFAST_FINALIZE:
case CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE:
case CORINFO_HELP_READYTORUN_NEW:
case CORINFO_HELP_NEW_MDARR:
case CORINFO_HELP_NEW_MDARR_RARE:
case CORINFO_HELP_NEWARR_1_DIRECT:
+ case CORINFO_HELP_NEWARR_1_MAYBEFROZEN:
case CORINFO_HELP_NEWARR_1_OBJ:
case CORINFO_HELP_READYTORUN_NEWARR_1:
noThrow = true; // These return null for a failing cast
break;
- case CORINFO_HELP_ARE_TYPES_EQUIVALENT:
case CORINFO_HELP_GETCURRENTMANAGEDTHREADID:
isPure = true;
noThrow = true;
vnf = VNF_JitReadyToRunNewArr;
break;
+ case CORINFO_HELP_NEWFAST_MAYBEFROZEN:
+ vnf = opts.IsReadyToRun() ? VNF_JitReadyToRunNew : VNF_JitNew;
+ break;
+
+ case CORINFO_HELP_NEWARR_1_MAYBEFROZEN:
+ vnf = opts.IsReadyToRun() ? VNF_JitReadyToRunNewArr : VNF_JitNewArr;
+ break;
+
case CORINFO_HELP_GETGENERICS_GCSTATIC_BASE:
vnf = VNF_GetgenericsGcstaticBase;
break;
vnf = VNF_TypeHandleToRuntimeTypeHandle;
break;
- case CORINFO_HELP_ARE_TYPES_EQUIVALENT:
- vnf = VNF_AreTypesEquivalent;
- break;
-
case CORINFO_HELP_READYTORUN_ISINSTANCEOF:
vnf = VNF_ReadyToRunIsInstanceOf;
break;
ValueNumFuncDef(TypeHandleToRuntimeType, 1, false, false, false) // Args: 0: TypeHandle to translate
ValueNumFuncDef(TypeHandleToRuntimeTypeHandle, 1, false, false, false) // Args: 0: TypeHandle to translate
-ValueNumFuncDef(AreTypesEquivalent, 2, false, false, false) // Args: 0: first TypeHandle, 1: second TypeHandle
-
ValueNumFuncDef(LdElemA, 3, false, false, false) // Args: 0: array value; 1: index value; 2: type handle of element.
ValueNumFuncDef(ByrefExposedLoad, 3, false, false, false) // Args: 0: type handle/id, 1: pointer value; 2: ByrefExposed heap value
static const uint32_t Signature = 0x00525452; // 'RTR'
static const uint32_t CurrentMajorVersion = 9;
- static const uint32_t CurrentMinorVersion = 0;
+ static const uint32_t CurrentMinorVersion = 1;
};
struct ReadyToRunHeader
public const uint Signature = 0x00525452; // 'RTR'
public const ushort CurrentMajorVersion = 9;
- public const ushort CurrentMinorVersion = 0;
+ public const ushort CurrentMinorVersion = 1;
}
#if READYTORUN
#pragma warning disable 0169
GenericNonGcTlsBase = 0x67,
VirtualFuncPtr = 0x68,
IsInstanceOfException = 0x69,
+ NewMaybeFrozenArray = 0x6A,
+ NewMaybeFrozenObject = 0x6B,
// Long mul/div/shift ops
LMul = 0xC0,
which is the right helper to use to allocate an object of a given type. */
CORINFO_HELP_NEWFAST,
+ CORINFO_HELP_NEWFAST_MAYBEFROZEN, // allocator for objects that *might* allocate them on a frozen segment
CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object
CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object
CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned
CORINFO_HELP_NEW_MDARR, // multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array)
CORINFO_HELP_NEW_MDARR_RARE, // rare multi-dim array helper (Rank == 1)
CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation
+ CORINFO_HELP_NEWARR_1_MAYBEFROZEN, // allocator for arrays that *might* allocate them on a frozen segment
CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays
CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays
CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start
CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time
CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time, handle might point to a null type
- CORINFO_HELP_ARE_TYPES_EQUIVALENT, // Check whether two TypeHandles (native structure pointers) are equivalent
-
CORINFO_HELP_VIRTUAL_FUNC_PTR, // look up a virtual method at run-time
// Not a real helpers. Instead of taking handle arguments, these helpers point to a small stub that loads the handle argument and calls the static helper.
private bool canCast(CORINFO_CLASS_STRUCT_* child, CORINFO_CLASS_STRUCT_* parent)
{ throw new NotImplementedException("canCast"); }
- private bool areTypesEquivalent(CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2)
- { throw new NotImplementedException("areTypesEquivalent"); }
private TypeCompareState compareTypesForCast(CORINFO_CLASS_STRUCT_* fromClass, CORINFO_CLASS_STRUCT_* toClass)
{
}
[UnmanagedCallersOnly]
- private static byte _areTypesEquivalent(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2)
- {
- var _this = GetThis(thisHandle);
- try
- {
- return _this.areTypesEquivalent(cls1, cls2) ? (byte)1 : (byte)0;
- }
- catch (Exception ex)
- {
- *ppException = _this.AllocException(ex);
- return default;
- }
- }
-
- [UnmanagedCallersOnly]
private static TypeCompareState _compareTypesForCast(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* fromClass, CORINFO_CLASS_STRUCT_* toClass)
{
var _this = GetThis(thisHandle);
private static IntPtr GetUnmanagedCallbacks()
{
- void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 185);
+ void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 184);
callbacks[0] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte>)&_isIntrinsic;
callbacks[1] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint>)&_getMethodAttribs;
callbacks[77] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_getTypeForPrimitiveValueClass;
callbacks[78] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_getTypeForPrimitiveNumericClass;
callbacks[79] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_canCast;
- callbacks[80] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_areTypesEquivalent;
- callbacks[81] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, TypeCompareState>)&_compareTypesForCast;
- callbacks[82] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, TypeCompareState>)&_compareTypesForEquality;
- callbacks[83] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_mergeClasses;
- callbacks[84] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_isMoreSpecificType;
- callbacks[85] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_**, TypeCompareState>)&_isEnum;
- callbacks[86] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getParentType;
- callbacks[87] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_**, CorInfoType>)&_getChildType;
- callbacks[88] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_satisfiesClassConstraints;
- callbacks[89] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isSDArray;
- callbacks[90] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getArrayRank;
- callbacks[91] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CorInfoArrayIntrinsic>)&_getArrayIntrinsicID;
- callbacks[92] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, uint, void*>)&_getArrayInitializationData;
- callbacks[93] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_HELPER_DESC*, CorInfoIsAccessAllowedResult>)&_canAccessClass;
- callbacks[94] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte*, UIntPtr, UIntPtr*, UIntPtr>)&_printFieldName;
- callbacks[95] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getFieldClass;
- callbacks[96] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_CLASS_STRUCT_**, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_getFieldType;
- callbacks[97] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, uint>)&_getFieldOffset;
- callbacks[98] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_ACCESS_FLAGS, CORINFO_FIELD_INFO*, void>)&_getFieldInfo;
- callbacks[99] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, uint>)&_getThreadLocalFieldInfo;
- callbacks[100] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_THREAD_STATIC_BLOCKS_INFO*, void>)&_getThreadLocalStaticBlocksInfo;
- callbacks[101] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte>)&_isFieldStatic;
- callbacks[102] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_OBJECT_STRUCT_*, int>)&_getArrayOrStringLength;
- callbacks[103] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint*, uint**, BoundaryTypes*, void>)&_getBoundaries;
- callbacks[104] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint, OffsetMapping*, void>)&_setBoundaries;
- callbacks[105] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint*, ILVarInfo**, bool*, void>)&_getVars;
- callbacks[106] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint, NativeVarInfo*, void>)&_setVars;
- callbacks[107] = (delegate* unmanaged<IntPtr, IntPtr*, InlineTreeNode*, uint, RichOffsetMapping*, uint, void>)&_reportRichMappings;
- callbacks[108] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_allocateArray;
- callbacks[109] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void>)&_freeArray;
- callbacks[110] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_ARG_LIST_STRUCT_*>)&_getArgNext;
- callbacks[111] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_CLASS_STRUCT_**, CorInfoTypeWithMod>)&_getArgType;
- callbacks[112] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, int, CORINFO_CLASS_STRUCT_**, int>)&_getExactClasses;
- callbacks[113] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getArgClass;
- callbacks[114] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHFAElemType>)&_getHFAType;
- callbacks[115] = (delegate* unmanaged<IntPtr, IntPtr*, _EXCEPTION_POINTERS*, HRESULT>)&_GetErrorHRESULT;
- callbacks[116] = (delegate* unmanaged<IntPtr, IntPtr*, char*, uint, uint>)&_GetErrorMessage;
- callbacks[117] = (delegate* unmanaged<IntPtr, IntPtr*, _EXCEPTION_POINTERS*, int>)&_FilterException;
- callbacks[118] = (delegate* unmanaged<IntPtr, IntPtr*, HRESULT, void>)&_ThrowExceptionForJitResult;
- callbacks[119] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_HELPER_DESC*, void>)&_ThrowExceptionForHelper;
- callbacks[120] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, byte>)&_runWithErrorTrap;
- callbacks[121] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, byte>)&_runWithSPMIErrorTrap;
- callbacks[122] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_EE_INFO*, void>)&_getEEInfo;
- callbacks[123] = (delegate* unmanaged<IntPtr, IntPtr*, char*>)&_getJitTimeLogFilename;
- callbacks[124] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, mdToken>)&_getMethodDefFromMethod;
- callbacks[125] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte*, UIntPtr, UIntPtr*, UIntPtr>)&_printMethodName;
- callbacks[126] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte**, byte**, byte**, byte*>)&_getMethodNameFromMetadata;
- callbacks[127] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint>)&_getMethodHash;
- callbacks[128] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, byte*, UIntPtr, UIntPtr>)&_findNameOfToken;
- callbacks[129] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR*, byte>)&_getSystemVAmd64PassStructInRegisterDescriptor;
- callbacks[130] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getLoongArch64PassStructInRegisterFlags;
- callbacks[131] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getRISCV64PassStructInRegisterFlags;
- callbacks[132] = (delegate* unmanaged<IntPtr, IntPtr*, void**, uint>)&_getThreadTLSIndex;
- callbacks[133] = (delegate* unmanaged<IntPtr, IntPtr*, void**, void*>)&_getInlinedCallFrameVptr;
- callbacks[134] = (delegate* unmanaged<IntPtr, IntPtr*, void**, int*>)&_getAddrOfCaptureThreadGlobal;
- callbacks[135] = (delegate* unmanaged<IntPtr, IntPtr*, CorInfoHelpFunc, void**, void*>)&_getHelperFtn;
- callbacks[136] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, CORINFO_ACCESS_FLAGS, void>)&_getFunctionEntryPoint;
- callbacks[137] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte, CORINFO_CONST_LOOKUP*, void>)&_getFunctionFixedEntryPoint;
- callbacks[138] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, void*>)&_getMethodSync;
- callbacks[139] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CorInfoHelpFunc>)&_getLazyStringLiteralHelper;
- callbacks[140] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, void**, CORINFO_MODULE_STRUCT_*>)&_embedModuleHandle;
- callbacks[141] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, CORINFO_CLASS_STRUCT_*>)&_embedClassHandle;
- callbacks[142] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, CORINFO_METHOD_STRUCT_*>)&_embedMethodHandle;
- callbacks[143] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, CORINFO_FIELD_STRUCT_*>)&_embedFieldHandle;
- callbacks[144] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, CORINFO_GENERICHANDLE_RESULT*, void>)&_embedGenericHandle;
- callbacks[145] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_LOOKUP_KIND*, void>)&_getLocationOfThisType;
- callbacks[146] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, void>)&_getAddressOfPInvokeTarget;
- callbacks[147] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, void*>)&_GetCookieForPInvokeCalliSig;
- callbacks[148] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetCookieForPInvokeCalliSig;
- callbacks[149] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_JUST_MY_CODE_HANDLE_**, CORINFO_JUST_MY_CODE_HANDLE_*>)&_getJustMyCodeHandle;
- callbacks[150] = (delegate* unmanaged<IntPtr, IntPtr*, bool*, void**, bool*, void>)&_GetProfilingHandle;
- callbacks[151] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_CALLINFO_FLAGS, CORINFO_CALL_INFO*, void>)&_getCallInfo;
- callbacks[152] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_canAccessFamily;
- callbacks[153] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isRIDClassDomainID;
- callbacks[154] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, uint>)&_getClassDomainID;
- callbacks[155] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte*, int, int, byte, byte>)&_getStaticFieldContent;
- callbacks[156] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_OBJECT_STRUCT_*, byte*, int, int, byte>)&_getObjectContent;
- callbacks[157] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte*, CORINFO_CLASS_STRUCT_*>)&_getStaticFieldCurrentClass;
- callbacks[158] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, IntPtr>)&_getVarArgsHandle;
- callbacks[159] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetVarArgsHandle;
- callbacks[160] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, void**, InfoAccessType>)&_constructStringLiteral;
- callbacks[161] = (delegate* unmanaged<IntPtr, IntPtr*, void**, InfoAccessType>)&_emptyStringLiteral;
- callbacks[162] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, uint>)&_getFieldThreadLocalStoreID;
- callbacks[163] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_METHOD_STRUCT_*, DelegateCtorArgs*, CORINFO_METHOD_STRUCT_*>)&_GetDelegateCtor;
- callbacks[164] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void>)&_MethodCompileComplete;
- callbacks[165] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_SIG_INFO*, CORINFO_GET_TAILCALL_HELPERS_FLAGS, CORINFO_TAILCALL_HELPERS*, byte>)&_getTailCallHelpers;
- callbacks[166] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, byte>)&_convertPInvokeCalliToCall;
- callbacks[167] = (delegate* unmanaged<IntPtr, IntPtr*, InstructionSet, byte, byte>)&_notifyInstructionSetUsage;
- callbacks[168] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CONST_LOOKUP*, void>)&_updateEntryPointForTailCall;
- callbacks[169] = (delegate* unmanaged<IntPtr, IntPtr*, AllocMemArgs*, void>)&_allocMem;
- callbacks[170] = (delegate* unmanaged<IntPtr, IntPtr*, byte, byte, uint, void>)&_reserveUnwindInfo;
- callbacks[171] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, byte*, uint, uint, uint, byte*, CorJitFuncKind, void>)&_allocUnwindInfo;
- callbacks[172] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_allocGCInfo;
- callbacks[173] = (delegate* unmanaged<IntPtr, IntPtr*, uint, void>)&_setEHcount;
- callbacks[174] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_EH_CLAUSE*, void>)&_setEHinfo;
- callbacks[175] = (delegate* unmanaged<IntPtr, IntPtr*, uint, byte*, IntPtr, byte>)&_logMsg;
- callbacks[176] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, int, byte*, int>)&_doAssert;
- callbacks[177] = (delegate* unmanaged<IntPtr, IntPtr*, CorJitResult, void>)&_reportFatalError;
- callbacks[178] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema**, uint*, byte**, PgoSource*, HRESULT>)&_getPgoInstrumentationResults;
- callbacks[179] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema*, uint, byte**, HRESULT>)&_allocPgoInstrumentationBySchema;
- callbacks[180] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_SIG_INFO*, CORINFO_METHOD_STRUCT_*, void>)&_recordCallSite;
- callbacks[181] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, void*, ushort, ushort, int, void>)&_recordRelocation;
- callbacks[182] = (delegate* unmanaged<IntPtr, IntPtr*, void*, ushort>)&_getRelocTypeHint;
- callbacks[183] = (delegate* unmanaged<IntPtr, IntPtr*, uint>)&_getExpectedTargetArchitecture;
- callbacks[184] = (delegate* unmanaged<IntPtr, IntPtr*, CORJIT_FLAGS*, uint, uint>)&_getJitFlags;
+ callbacks[80] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, TypeCompareState>)&_compareTypesForCast;
+ callbacks[81] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, TypeCompareState>)&_compareTypesForEquality;
+ callbacks[82] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_mergeClasses;
+ callbacks[83] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_isMoreSpecificType;
+ callbacks[84] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_**, TypeCompareState>)&_isEnum;
+ callbacks[85] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getParentType;
+ callbacks[86] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_**, CorInfoType>)&_getChildType;
+ callbacks[87] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_satisfiesClassConstraints;
+ callbacks[88] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isSDArray;
+ callbacks[89] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getArrayRank;
+ callbacks[90] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CorInfoArrayIntrinsic>)&_getArrayIntrinsicID;
+ callbacks[91] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, uint, void*>)&_getArrayInitializationData;
+ callbacks[92] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_HELPER_DESC*, CorInfoIsAccessAllowedResult>)&_canAccessClass;
+ callbacks[93] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte*, UIntPtr, UIntPtr*, UIntPtr>)&_printFieldName;
+ callbacks[94] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getFieldClass;
+ callbacks[95] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_CLASS_STRUCT_**, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_getFieldType;
+ callbacks[96] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, uint>)&_getFieldOffset;
+ callbacks[97] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_ACCESS_FLAGS, CORINFO_FIELD_INFO*, void>)&_getFieldInfo;
+ callbacks[98] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, uint>)&_getThreadLocalFieldInfo;
+ callbacks[99] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_THREAD_STATIC_BLOCKS_INFO*, void>)&_getThreadLocalStaticBlocksInfo;
+ callbacks[100] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte>)&_isFieldStatic;
+ callbacks[101] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_OBJECT_STRUCT_*, int>)&_getArrayOrStringLength;
+ callbacks[102] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint*, uint**, BoundaryTypes*, void>)&_getBoundaries;
+ callbacks[103] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint, OffsetMapping*, void>)&_setBoundaries;
+ callbacks[104] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint*, ILVarInfo**, bool*, void>)&_getVars;
+ callbacks[105] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint, NativeVarInfo*, void>)&_setVars;
+ callbacks[106] = (delegate* unmanaged<IntPtr, IntPtr*, InlineTreeNode*, uint, RichOffsetMapping*, uint, void>)&_reportRichMappings;
+ callbacks[107] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_allocateArray;
+ callbacks[108] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void>)&_freeArray;
+ callbacks[109] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_ARG_LIST_STRUCT_*>)&_getArgNext;
+ callbacks[110] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_CLASS_STRUCT_**, CorInfoTypeWithMod>)&_getArgType;
+ callbacks[111] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, int, CORINFO_CLASS_STRUCT_**, int>)&_getExactClasses;
+ callbacks[112] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getArgClass;
+ callbacks[113] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHFAElemType>)&_getHFAType;
+ callbacks[114] = (delegate* unmanaged<IntPtr, IntPtr*, _EXCEPTION_POINTERS*, HRESULT>)&_GetErrorHRESULT;
+ callbacks[115] = (delegate* unmanaged<IntPtr, IntPtr*, char*, uint, uint>)&_GetErrorMessage;
+ callbacks[116] = (delegate* unmanaged<IntPtr, IntPtr*, _EXCEPTION_POINTERS*, int>)&_FilterException;
+ callbacks[117] = (delegate* unmanaged<IntPtr, IntPtr*, HRESULT, void>)&_ThrowExceptionForJitResult;
+ callbacks[118] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_HELPER_DESC*, void>)&_ThrowExceptionForHelper;
+ callbacks[119] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, byte>)&_runWithErrorTrap;
+ callbacks[120] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, byte>)&_runWithSPMIErrorTrap;
+ callbacks[121] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_EE_INFO*, void>)&_getEEInfo;
+ callbacks[122] = (delegate* unmanaged<IntPtr, IntPtr*, char*>)&_getJitTimeLogFilename;
+ callbacks[123] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, mdToken>)&_getMethodDefFromMethod;
+ callbacks[124] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte*, UIntPtr, UIntPtr*, UIntPtr>)&_printMethodName;
+ callbacks[125] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte**, byte**, byte**, byte*>)&_getMethodNameFromMetadata;
+ callbacks[126] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint>)&_getMethodHash;
+ callbacks[127] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, byte*, UIntPtr, UIntPtr>)&_findNameOfToken;
+ callbacks[128] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR*, byte>)&_getSystemVAmd64PassStructInRegisterDescriptor;
+ callbacks[129] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getLoongArch64PassStructInRegisterFlags;
+ callbacks[130] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getRISCV64PassStructInRegisterFlags;
+ callbacks[131] = (delegate* unmanaged<IntPtr, IntPtr*, void**, uint>)&_getThreadTLSIndex;
+ callbacks[132] = (delegate* unmanaged<IntPtr, IntPtr*, void**, void*>)&_getInlinedCallFrameVptr;
+ callbacks[133] = (delegate* unmanaged<IntPtr, IntPtr*, void**, int*>)&_getAddrOfCaptureThreadGlobal;
+ callbacks[134] = (delegate* unmanaged<IntPtr, IntPtr*, CorInfoHelpFunc, void**, void*>)&_getHelperFtn;
+ callbacks[135] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, CORINFO_ACCESS_FLAGS, void>)&_getFunctionEntryPoint;
+ callbacks[136] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte, CORINFO_CONST_LOOKUP*, void>)&_getFunctionFixedEntryPoint;
+ callbacks[137] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, void*>)&_getMethodSync;
+ callbacks[138] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CorInfoHelpFunc>)&_getLazyStringLiteralHelper;
+ callbacks[139] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, void**, CORINFO_MODULE_STRUCT_*>)&_embedModuleHandle;
+ callbacks[140] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, CORINFO_CLASS_STRUCT_*>)&_embedClassHandle;
+ callbacks[141] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, CORINFO_METHOD_STRUCT_*>)&_embedMethodHandle;
+ callbacks[142] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, CORINFO_FIELD_STRUCT_*>)&_embedFieldHandle;
+ callbacks[143] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, CORINFO_GENERICHANDLE_RESULT*, void>)&_embedGenericHandle;
+ callbacks[144] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_LOOKUP_KIND*, void>)&_getLocationOfThisType;
+ callbacks[145] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, void>)&_getAddressOfPInvokeTarget;
+ callbacks[146] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, void*>)&_GetCookieForPInvokeCalliSig;
+ callbacks[147] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetCookieForPInvokeCalliSig;
+ callbacks[148] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_JUST_MY_CODE_HANDLE_**, CORINFO_JUST_MY_CODE_HANDLE_*>)&_getJustMyCodeHandle;
+ callbacks[149] = (delegate* unmanaged<IntPtr, IntPtr*, bool*, void**, bool*, void>)&_GetProfilingHandle;
+ callbacks[150] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_CALLINFO_FLAGS, CORINFO_CALL_INFO*, void>)&_getCallInfo;
+ callbacks[151] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_canAccessFamily;
+ callbacks[152] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isRIDClassDomainID;
+ callbacks[153] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, uint>)&_getClassDomainID;
+ callbacks[154] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte*, int, int, byte, byte>)&_getStaticFieldContent;
+ callbacks[155] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_OBJECT_STRUCT_*, byte*, int, int, byte>)&_getObjectContent;
+ callbacks[156] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte*, CORINFO_CLASS_STRUCT_*>)&_getStaticFieldCurrentClass;
+ callbacks[157] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, IntPtr>)&_getVarArgsHandle;
+ callbacks[158] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetVarArgsHandle;
+ callbacks[159] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, void**, InfoAccessType>)&_constructStringLiteral;
+ callbacks[160] = (delegate* unmanaged<IntPtr, IntPtr*, void**, InfoAccessType>)&_emptyStringLiteral;
+ callbacks[161] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, uint>)&_getFieldThreadLocalStoreID;
+ callbacks[162] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_METHOD_STRUCT_*, DelegateCtorArgs*, CORINFO_METHOD_STRUCT_*>)&_GetDelegateCtor;
+ callbacks[163] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void>)&_MethodCompileComplete;
+ callbacks[164] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_SIG_INFO*, CORINFO_GET_TAILCALL_HELPERS_FLAGS, CORINFO_TAILCALL_HELPERS*, byte>)&_getTailCallHelpers;
+ callbacks[165] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, byte>)&_convertPInvokeCalliToCall;
+ callbacks[166] = (delegate* unmanaged<IntPtr, IntPtr*, InstructionSet, byte, byte>)&_notifyInstructionSetUsage;
+ callbacks[167] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CONST_LOOKUP*, void>)&_updateEntryPointForTailCall;
+ callbacks[168] = (delegate* unmanaged<IntPtr, IntPtr*, AllocMemArgs*, void>)&_allocMem;
+ callbacks[169] = (delegate* unmanaged<IntPtr, IntPtr*, byte, byte, uint, void>)&_reserveUnwindInfo;
+ callbacks[170] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, byte*, uint, uint, uint, byte*, CorJitFuncKind, void>)&_allocUnwindInfo;
+ callbacks[171] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_allocGCInfo;
+ callbacks[172] = (delegate* unmanaged<IntPtr, IntPtr*, uint, void>)&_setEHcount;
+ callbacks[173] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_EH_CLAUSE*, void>)&_setEHinfo;
+ callbacks[174] = (delegate* unmanaged<IntPtr, IntPtr*, uint, byte*, IntPtr, byte>)&_logMsg;
+ callbacks[175] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, int, byte*, int>)&_doAssert;
+ callbacks[176] = (delegate* unmanaged<IntPtr, IntPtr*, CorJitResult, void>)&_reportFatalError;
+ callbacks[177] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema**, uint*, byte**, PgoSource*, HRESULT>)&_getPgoInstrumentationResults;
+ callbacks[178] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema*, uint, byte**, HRESULT>)&_allocPgoInstrumentationBySchema;
+ callbacks[179] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_SIG_INFO*, CORINFO_METHOD_STRUCT_*, void>)&_recordCallSite;
+ callbacks[180] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, void*, ushort, ushort, int, void>)&_recordRelocation;
+ callbacks[181] = (delegate* unmanaged<IntPtr, IntPtr*, void*, ushort>)&_getRelocTypeHint;
+ callbacks[182] = (delegate* unmanaged<IntPtr, IntPtr*, uint>)&_getExpectedTargetArchitecture;
+ callbacks[183] = (delegate* unmanaged<IntPtr, IntPtr*, CORJIT_FLAGS*, uint, uint>)&_getJitFlags;
return (IntPtr)callbacks;
}
CORJIT_FLAG_UNUSED6 = 12,
CORJIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement
CORJIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT
+ CORJIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_MAYBEFROZEN allocators
CORJIT_FLAG_UNUSED10 = 17,
CORJIT_FLAG_MAKEFINALCODE = 18, // Use the final code generator, i.e., not the interpreter.
CORJIT_FLAG_READYTORUN = 19, // Use version-resilient code generation
CorInfoType getTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls)
CorInfoType getTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls)
bool canCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent)
- bool areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
TypeCompareState compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass)
TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
CORINFO_CLASS_HANDLE mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
return FALSE;
// Structures are compatible if they are equivalent
- return jitInfo->areTypesEquivalent(child.m_cls, parent.m_cls);
+ // return jitInfo->areTypesEquivalent(child.m_cls, parent.m_cls);
+ return child.m_cls == parent.m_cls;
}
else if (parent.IsByRef())
{
break;
}
+ // Always allow frozen allocators for R2R (NativeAOT is able to preinitialize objects on
+ // frozen segments without JIT's help)
+ corJitFlags.Add(CorJitFlag.CORJIT_FLAG_FROZEN_ALLOC_ALLOWED);
+
if (!_isJitInitialized)
{
JitConfigProvider.Initialize(_context.Target, corJitFlags, _ryujitOptions, _jitPath);
case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_DIRECT:
id = ReadyToRunHelper.NewArray;
break;
+ case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_MAYBEFROZEN:
+ id = ReadyToRunHelper.NewMaybeFrozenArray;
+ break;
+ case CorInfoHelpFunc.CORINFO_HELP_NEWFAST_MAYBEFROZEN:
+ id = ReadyToRunHelper.NewMaybeFrozenObject;
+ break;
case CorInfoHelpFunc.CORINFO_HELP_VIRTUAL_FUNC_PTR:
id = ReadyToRunHelper.VirtualFuncPtr;
break;
builder.Append("NEW_ARRAY");
break;
+ case ReadyToRunHelper.NewMaybeFrozenArray:
+ builder.Append("NEW_MAYBEFROZEN_ARRAY");
+ break;
+
+ case ReadyToRunHelper.NewMaybeFrozenObject:
+ builder.Append("NEW_MAYBEFROZEN_OBJECT");
+ break;
+
case ReadyToRunHelper.CheckCastAny:
builder.Append("CHECK_CAST_ANY");
break;
CorInfoType (* getTypeForPrimitiveValueClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls);
CorInfoType (* getTypeForPrimitiveNumericClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls);
bool (* canCast)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent);
- bool (* areTypesEquivalent)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
TypeCompareState (* compareTypesForCast)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass);
TypeCompareState (* compareTypesForEquality)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
CORINFO_CLASS_HANDLE (* mergeClasses)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
return temp;
}
- virtual bool areTypesEquivalent(
- CORINFO_CLASS_HANDLE cls1,
- CORINFO_CLASS_HANDLE cls2)
-{
- CorInfoExceptionClass* pException = nullptr;
- bool temp = _callbacks->areTypesEquivalent(_thisHandle, &pException, cls1, cls2);
- if (pException != nullptr) throw pException;
- return temp;
-}
-
virtual TypeCompareState compareTypesForCast(
CORINFO_CLASS_HANDLE fromClass,
CORINFO_CLASS_HANDLE toClass)
LWM(AllocPgoInstrumentationBySchema, DWORDLONG, Agnostic_AllocPgoInstrumentationBySchema)
LWM(GetPgoInstrumentationResults, DWORDLONG, Agnostic_GetPgoInstrumentationResults)
-LWM(AreTypesEquivalent, DLDL, DWORD)
LWM(AsCorInfoType, DWORDLONG, DWORD)
LWM(CanAccessClass, Agnostic_CanAccessClassIn, Agnostic_CanAccessClassOut)
LWM(CanAccessFamily, DLDL, DWORD)
return "CORJIT_FLAG_OSR";
case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_ALT_JIT:
return "CORJIT_FLAG_ALT_JIT";
+ case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_FROZEN_ALLOC_ALLOWED:
+ return "CORJIT_FLAG_FROZEN_ALLOC_ALLOWED";
case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_MAKEFINALCODE:
return "CORJIT_FLAG_MAKEFINALCODE";
case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_READYTORUN:
return (CORINFO_FIELD_HANDLE)value.B;
}
-void MethodContext::recAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result)
-{
- if (AreTypesEquivalent == nullptr)
- AreTypesEquivalent = new LightWeightMap<DLDL, DWORD>();
-
- DLDL key;
- ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding
- key.A = CastHandle(cls1);
- key.B = CastHandle(cls2);
-
- DWORD value = result ? 1 : 0;
- AreTypesEquivalent->Add(key, value);
- DEBUG_REC(dmpAreTypesEquivalent(key, value));
-}
-void MethodContext::dmpAreTypesEquivalent(DLDL key, DWORD value)
-{
- printf("AreTypesEquivalent NYI");
-}
-bool MethodContext::repAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
-{
- DLDL key;
- ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding
- key.A = CastHandle(cls1);
- key.B = CastHandle(cls2);
-
- DWORD value = LookupByKeyOrMiss(AreTypesEquivalent, key, ": key %016" PRIX64 " %016" PRIX64 "", key.A, key.B);
-
- DEBUG_REP(dmpAreTypesEquivalent(key, value));
- return value != 0;
-}
-
void MethodContext::recCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass,
CORINFO_CLASS_HANDLE toClass,
TypeCompareState result)
void dmpEmbedFieldHandle(DWORDLONG key, DLDL value);
CORINFO_FIELD_HANDLE repEmbedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection);
- void recAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result);
- void dmpAreTypesEquivalent(DLDL key, DWORD value);
- bool repAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
-
void recCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass, TypeCompareState result);
void dmpCompareTypesForCast(DLDL key, DWORD value);
TypeCompareState repCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass);
enum mcPackets
{
- Packet_AreTypesEquivalent = 1,
+ //Packet_AreTypesEquivalent = 1,
Packet_AsCorInfoType = 2,
Packet_CanAccessClass = 3,
Packet_CanAccessFamily = 4,
return temp;
}
-// TRUE if cls1 and cls2 are considered equivalent types.
-bool interceptor_ICJI::areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
-{
- mc->cr->AddCall("areTypesEquivalent");
- bool temp = original_ICorJitInfo->areTypesEquivalent(cls1, cls2);
- mc->recAreTypesEquivalent(cls1, cls2, temp);
- return temp;
-}
-
// See if a cast from fromClass to toClass will succeed, fail, or needs
// to be resolved at runtime.
TypeCompareState interceptor_ICJI::compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass)
return original_ICorJitInfo->canCast(child, parent);
}
-bool interceptor_ICJI::areTypesEquivalent(
- CORINFO_CLASS_HANDLE cls1,
- CORINFO_CLASS_HANDLE cls2)
-{
- mcs->AddCall("areTypesEquivalent");
- return original_ICorJitInfo->areTypesEquivalent(cls1, cls2);
-}
-
TypeCompareState interceptor_ICJI::compareTypesForCast(
CORINFO_CLASS_HANDLE fromClass,
CORINFO_CLASS_HANDLE toClass)
return original_ICorJitInfo->canCast(child, parent);
}
-bool interceptor_ICJI::areTypesEquivalent(
- CORINFO_CLASS_HANDLE cls1,
- CORINFO_CLASS_HANDLE cls2)
-{
- return original_ICorJitInfo->areTypesEquivalent(cls1, cls2);
-}
-
TypeCompareState interceptor_ICJI::compareTypesForCast(
CORINFO_CLASS_HANDLE fromClass,
CORINFO_CLASS_HANDLE toClass)
return jitInstance->mc->repCanCast(child, parent);
}
-// TRUE if cls1 and cls2 are considered equivalent types.
-bool MyICJI::areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
-{
- jitInstance->mc->cr->AddCall("areTypesEquivalent");
- return jitInstance->mc->repAreTypesEquivalent(cls1, cls2);
-}
-
// See if a cast from fromClass to toClass will succeed, fail, or needs
// to be resolved at runtime.
TypeCompareState MyICJI::compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass)
{
_ASSERT(m_pStart != nullptr && m_Size > 0 && m_SegmentHandle != nullptr); // Expected to be inited
_ASSERT(IS_ALIGNED(m_pCurrent, DATA_ALIGNMENT));
+ _ASSERT(IS_ALIGNED(objectSize, DATA_ALIGNMENT));
_ASSERT(objectSize <= FOH_COMMIT_SIZE);
_ASSERT(m_pCurrent >= m_pStart + sizeof(ObjHeader));
return ObjectToOBJECTREF((Object*)orArray);
}
+OBJECTREF TryAllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements)
+{
+ CONTRACTL{
+ THROWS;
+ GC_TRIGGERS;
+ MODE_COOPERATIVE;
+ } CONTRACTL_END;
+
+ SetTypeHandleOnThreadForAlloc(TypeHandle(pArrayMT));
+
+ _ASSERTE(pArrayMT->CheckInstanceActivated());
+ _ASSERTE(pArrayMT->GetInternalCorElementType() == ELEMENT_TYPE_SZARRAY);
+
+ // The initial validation is copied from AllocateSzArray impl
+
+ CorElementType elemType = pArrayMT->GetArrayElementType();
+
+ if (pArrayMT->ContainsPointers() && cElements > 0)
+ {
+ // For arrays with GC pointers we can only work with empty arrays
+ return NULL;
+ }
+
+ // Disallow the creation of void[] (an array of System.Void)
+ if (elemType == ELEMENT_TYPE_VOID)
+ COMPlusThrow(kArgumentException);
+
+ if (cElements < 0)
+ COMPlusThrow(kOverflowException);
+
+ if ((SIZE_T)cElements > MaxArrayLength())
+ ThrowOutOfMemoryDimensionsExceeded();
+
+ SIZE_T componentSize = pArrayMT->GetComponentSize();
+#ifdef TARGET_64BIT
+ // POSITIVE_INT32 * UINT16 + SMALL_CONST
+ // this cannot overflow on 64bit
+ size_t totalSize = cElements * componentSize + pArrayMT->GetBaseSize();
+
+#else
+ S_SIZE_T safeTotalSize = S_SIZE_T((DWORD)cElements) * S_SIZE_T((DWORD)componentSize) + S_SIZE_T((DWORD)pArrayMT->GetBaseSize());
+ if (safeTotalSize.IsOverflow())
+ ThrowOutOfMemoryDimensionsExceeded();
+
+ size_t totalSize = safeTotalSize.Value();
+#endif
+
+ // FrozenObjectHeapManager doesn't yet support objects with a custom alignment,
+ // so we give up on arrays of value types requiring 8 byte alignment on 32bit platforms.
+ if ((DATA_ALIGNMENT < sizeof(double)) && (elemType == ELEMENT_TYPE_R8))
+ {
+ return NULL;
+ }
+#ifdef FEATURE_64BIT_ALIGNMENT
+ MethodTable* pElementMT = pArrayMT->GetArrayElementTypeHandle().GetMethodTable();
+ if (pElementMT->RequiresAlign8() && pElementMT->IsValueType())
+ {
+ return NULL;
+ }
+#endif
+
+ FrozenObjectHeapManager* foh = SystemDomain::GetFrozenObjectHeapManager();
+ ArrayBase* orArray = static_cast<ArrayBase*>(foh->TryAllocateObject(pArrayMT, PtrAlign(totalSize), /*publish*/ false));
+ if (orArray == nullptr)
+ {
+ // We failed to allocate on a frozen segment, fallback to AllocateSzArray
+ // E.g. if the array is too big to fit on a frozen segment
+ return NULL;
+ }
+ orArray->m_NumComponents = cElements;
+
+ // Publish needs to be postponed in this case because we need to specify array length
+ PublishObjectAndNotify(orArray, GC_ALLOC_NO_FLAGS);
+
+ return ObjectToOBJECTREF(orArray);
+}
+
void ThrowOutOfMemoryDimensionsExceeded()
{
CONTRACTL {
return UNCHECKED_OBJECTREF_TO_OBJECTREF(oref);
}
+OBJECTREF TryAllocateFrozenObject(MethodTable* pObjMT)
+{
+ CONTRACTL {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_COOPERATIVE;
+ PRECONDITION(CheckPointer(pObjMT));
+ PRECONDITION(pObjMT->CheckInstanceActivated());
+ } CONTRACTL_END;
+
+ SetTypeHandleOnThreadForAlloc(TypeHandle(pObjMT));
+
+ if (pObjMT->ContainsPointers() || pObjMT->IsComObjectType())
+ {
+ return NULL;
+ }
+
+#ifdef FEATURE_64BIT_ALIGNMENT
+ if (pObjMT->RequiresAlign8())
+ {
+ // Custom alignment is not supported for frozen objects yet.
+ return NULL;
+ }
+#endif // FEATURE_64BIT_ALIGNMENT
+
+ FrozenObjectHeapManager* foh = SystemDomain::GetFrozenObjectHeapManager();
+ Object* orObject = foh->TryAllocateObject(pObjMT, PtrAlign(pObjMT->GetBaseSize()), /*publish*/ true);
+
+ return ObjectToOBJECTREF(orObject);
+}
+
//========================================================================
//
// WRITE BARRIER HELPERS
OBJECTREF AllocateSzArray(MethodTable *pArrayMT, INT32 length, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS);
OBJECTREF AllocateSzArray(TypeHandle arrayType, INT32 length, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS);
+// Allocate single-dimensional array on a frozen segment
+// Returns nullptr if it's not possible.
+OBJECTREF TryAllocateFrozenSzArray(MethodTable* pArrayMT, INT32 length);
+// Same for non-array objects
+OBJECTREF TryAllocateFrozenObject(MethodTable* pObjMT);
+
// The main Array allocation routine, can do multi-dimensional
OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS);
OBJECTREF AllocateArrayEx(TypeHandle arrayType, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS);
}
HCIMPLEND
+/*************************************************************/
+HCIMPL1(Object*, JIT_NewMaybeFrozen, CORINFO_CLASS_HANDLE typeHnd_)
+{
+ FCALL_CONTRACT;
+
+ OBJECTREF newobj = NULL;
+ HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame
+
+ TypeHandle typeHnd(typeHnd_);
+
+ _ASSERTE(!typeHnd.IsTypeDesc()); // heap objects must have method tables
+ MethodTable* pMT = typeHnd.AsMethodTable();
+ _ASSERTE(pMT->IsRestored_NoLogging());
+
+#ifdef _DEBUG
+ if (g_pConfig->FastGCStressLevel()) {
+ GetThread()->DisableStressHeap();
+ }
+#endif // _DEBUG
+
+ newobj = TryAllocateFrozenObject(pMT);
+ if (newobj == NULL)
+ {
+ // Fallback to normal heap allocation.
+ newobj = AllocateObject(pMT);
+ }
+
+ HELPER_METHOD_FRAME_END();
+ return(OBJECTREFToObject(newobj));
+}
+HCIMPLEND
//========================================================================
}
HCIMPLEND
+
+/*************************************************************/
+HCIMPL2(Object*, JIT_NewArr1MaybeFrozen, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size)
+{
+ FCALL_CONTRACT;
+
+ OBJECTREF newArray = NULL;
+
+ HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame
+
+ MethodTable* pArrayMT = (MethodTable*)arrayMT;
+
+ _ASSERTE(pArrayMT->IsFullyLoaded());
+ _ASSERTE(pArrayMT->IsArray());
+ _ASSERTE(!pArrayMT->IsMultiDimArray());
+
+ if (size < 0)
+ COMPlusThrow(kOverflowException);
+
+#ifdef HOST_64BIT
+ // Even though ECMA allows using a native int as the argument to newarr instruction
+ // (therefore size is INT_PTR), ArrayBase::m_NumComponents is 32-bit, so even on 64-bit
+ // platforms we can't create an array whose size exceeds 32 bits.
+ if (size > INT_MAX)
+ EX_THROW(EEMessageException, (kOverflowException, IDS_EE_ARRAY_DIMENSIONS_EXCEEDED));
+#endif
+
+#ifdef _DEBUG
+ if (g_pConfig->FastGCStressLevel()) {
+ GetThread()->DisableStressHeap();
+ }
+#endif // _DEBUG
+
+ newArray = TryAllocateFrozenSzArray(pArrayMT, (INT32)size);
+ if (newArray == NULL)
+ {
+ // Fallback to default heap allocation
+ newArray = AllocateSzArray(pArrayMT, (INT32)size);
+ }
+ _ASSERTE(newArray != NULL);
+
+ HELPER_METHOD_FRAME_END();
+
+ return(OBJECTREFToObject(newArray));
+}
+HCIMPLEND
+
/*************************************************************/
HCIMPL3(Object*, JIT_NewMDArr, CORINFO_CLASS_HANDLE classHnd, unsigned dwNumArgs, INT32 * pArgList)
{
}
else
{
- _ASSERTE(!"Unexpected object type");
+ obj->GetMethodTable()->_GetFullyQualifiedNameForClass(stackStr);
}
const UTF8* utf8data = stackStr.GetUTF8();
}
/*********************************************************************/
-// TRUE if cls1 and cls2 are considered equivalent types.
-bool CEEInfo::areTypesEquivalent(
- CORINFO_CLASS_HANDLE cls1,
- CORINFO_CLASS_HANDLE cls2)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- } CONTRACTL_END;
-
- bool result = false;
-
- JIT_TO_EE_TRANSITION();
-
- result = !!((TypeHandle)cls1).IsEquivalentTo((TypeHandle)cls2);
-
- EE_TO_JIT_TRANSITION();
-
- return result;
-}
-
-/*********************************************************************/
// See if a cast from fromClass to toClass will succeed, fail, or needs
// to be resolved at runtime.
TypeCompareState CEEInfo::compareTypesForCast(
_ASSERT(objHandle != NULL);
-#ifdef DEBUG
+ bool isImmutable = false;
+
JIT_TO_EE_TRANSITION();
GCX_COOP();
OBJECTREF obj = getObjectFromJitHandle(objHandle);
MethodTable* type = obj->GetMethodTable();
- _ASSERTE(type->IsString() || type == g_pRuntimeTypeClass);
+ if (type->IsString() || type == g_pRuntimeTypeClass)
+ {
+ // These types are always immutable
+ isImmutable = true;
+ }
+ else if (type->IsArray() && ((ArrayBase*)OBJECTREFToObject(obj))->GetComponentSize() == 0)
+ {
+ // Empty arrays are always immutable
+ isImmutable = true;
+ }
+ else if (type->IsDelegate() || type->GetNumInstanceFields() == 0)
+ {
+ // Delegates and types without fields are always immutable
+ isImmutable = true;
+ }
EE_TO_JIT_TRANSITION();
-#endif
- // All currently allocated frozen objects can be treated as immutable
- return true;
+ return isImmutable;
}
/***********************************************************************/
flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE);
#endif // PROFILING_SUPPORTED
+ // Don't allow allocations on FOH from collectible contexts to avoid memory leaks
+ if (!ftn->GetLoaderAllocator()->CanUnload())
+ {
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_FROZEN_ALLOC_ALLOWED);
+ }
+
// Set optimization flags
if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT))
{
friend class CObjectHeader;
friend class Object;
friend OBJECTREF AllocateSzArray(MethodTable *pArrayMT, INT32 length, GC_ALLOC_FLAGS flags);
+ friend OBJECTREF TryAllocateFrozenSzArray(MethodTable* pArrayMT, INT32 length);
friend OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags);
friend FCDECL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
friend FCDECL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);