From ab485a0886a71b0815624b6d9a4a292c4046b668 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Mon, 25 Jun 2018 09:17:00 -0700 Subject: [PATCH] Cross-bitness in instance fields placement and CORINFO structs (dotnet/coreclr#18366) * Replace sizeof(OBJECTREF*) with TARGET_POINTER_SIZE * Define IN_TARGET_32BIT IN_TARGET_64BIT macros * Replace IN_WIN32 IN_WIN64 with IN_TARGET_32BIT IN_TARGET_64BIT in src/vm/jitinterface.cpp src/vm/methodtablebuilder.cpp * Define and use OFFSETOF__CORINFO_* constants in clrjit * Define for all 64-bit targets * Use unsigned __int32 to emphasize that this is 32-bit number * Rename Array__u1Elems to Array__data * Eliminate OFFSETOF__CORINFO_RefArray__length * Rename OFFSETOF__CORINFO_RefAny__ to OFFSETOF__CORINFO_TypedReference__ * Fix OFFSETOF__CORINFO_TypedReference__dataPtr macro value Commit migrated from https://github.com/dotnet/coreclr/commit/c77ef768fc969d6875426e76e51485f2d67ac51c --- src/coreclr/src/inc/corinfo.h | 15 +++++++++++++++ src/coreclr/src/inc/utilcode.h | 8 ++++++++ src/coreclr/src/jit/ee_il_dll.cpp | 2 +- src/coreclr/src/jit/flowgraph.cpp | 4 ++-- src/coreclr/src/jit/importer.cpp | 14 +++++++------- src/coreclr/src/jit/loopcloning.cpp | 2 +- src/coreclr/src/jit/morph.cpp | 18 +++++++++--------- src/coreclr/src/jit/rationalize.cpp | 2 +- src/coreclr/src/jit/simd.cpp | 10 +++++----- src/coreclr/src/vm/ceeload.cpp | 4 ++-- src/coreclr/src/vm/jitinterface.cpp | 10 +++++----- src/coreclr/src/vm/methodtablebuilder.cpp | 8 ++++---- 12 files changed, 60 insertions(+), 37 deletions(-) diff --git a/src/coreclr/src/inc/corinfo.h b/src/coreclr/src/inc/corinfo.h index 1e4bb96..b7fd02e 100644 --- a/src/coreclr/src/inc/corinfo.h +++ b/src/coreclr/src/inc/corinfo.h @@ -1926,6 +1926,21 @@ struct CORINFO_VarArgInfo #include +#define SIZEOF__CORINFO_Object TARGET_POINTER_SIZE /* methTable */ + +#define OFFSETOF__CORINFO_Array__length SIZEOF__CORINFO_Object +#ifdef _TARGET_64BIT_ +#define OFFSETOF__CORINFO_Array__data (OFFSETOF__CORINFO_Array__length + sizeof(unsigned __int32) /* length */ + sizeof(unsigned __int32) /* alignpad */) +#else +#define OFFSETOF__CORINFO_Array__data (OFFSETOF__CORINFO_Array__length + sizeof(unsigned __int32) /* length */) +#endif + +#define OFFSETOF__CORINFO_TypedReference__dataPtr 0 +#define OFFSETOF__CORINFO_TypedReference__type (OFFSETOF__CORINFO_TypedReference__dataPtr + TARGET_POINTER_SIZE /* dataPtr */) + +#define OFFSETOF__CORINFO_String__stringLen SIZEOF__CORINFO_Object +#define OFFSETOF__CORINFO_String__chars (OFFSETOF__CORINFO_String__stringLen + sizeof(unsigned __int32) /* stringLen */) + enum CorInfoSecurityRuntimeChecks { CORINFO_ACCESS_SECURITY_NONE = 0, diff --git a/src/coreclr/src/inc/utilcode.h b/src/coreclr/src/inc/utilcode.h index de9ba01..a6d7557 100644 --- a/src/coreclr/src/inc/utilcode.h +++ b/src/coreclr/src/inc/utilcode.h @@ -521,6 +521,14 @@ inline void *__cdecl operator new(size_t, void *_P) #define IN_WIN32(x) x #endif +#ifdef _TARGET_64BIT_ +#define IN_TARGET_64BIT(x) x +#define IN_TARGET_32BIT(x) +#else +#define IN_TARGET_64BIT(x) +#define IN_TARGET_32BIT(x) x +#endif + void * __cdecl operator new(size_t n); diff --git a/src/coreclr/src/jit/ee_il_dll.cpp b/src/coreclr/src/jit/ee_il_dll.cpp index 11e765a..94cf81c 100644 --- a/src/coreclr/src/jit/ee_il_dll.cpp +++ b/src/coreclr/src/jit/ee_il_dll.cpp @@ -533,7 +533,7 @@ GenTree* Compiler::eeGetPInvokeCookie(CORINFO_SIG_INFO* szMetaSig) unsigned Compiler::eeGetArrayDataOffset(var_types type) { - return varTypeIsGC(type) ? eeGetEEInfo()->offsetOfObjArrayData : offsetof(CORINFO_Array, u1Elems); + return varTypeIsGC(type) ? eeGetEEInfo()->offsetOfObjArrayData : OFFSETOF__CORINFO_Array__data; } //------------------------------------------------------------------------ diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index fb35965..a852fb3 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -9551,8 +9551,8 @@ void Compiler::fgSimpleLowering() noway_assert(arr->gtNext == tree); - noway_assert(arrLen->ArrLenOffset() == offsetof(CORINFO_Array, length) || - arrLen->ArrLenOffset() == offsetof(CORINFO_String, stringLen)); + noway_assert(arrLen->ArrLenOffset() == OFFSETOF__CORINFO_Array__length || + arrLen->ArrLenOffset() == OFFSETOF__CORINFO_String__stringLen); if ((arr->gtOper == GT_CNS_INT) && (arr->gtIntCon.gtIconVal == 0)) { diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index fe30580..1b2e357 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -1269,11 +1269,11 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr, destAddr = impCloneExpr(destAddr, &destAddrClone, structHnd, curLevel, pAfterStmt DEBUGARG("MKREFANY assignment")); - assert(offsetof(CORINFO_RefAny, dataPtr) == 0); + assert(OFFSETOF__CORINFO_TypedReference__dataPtr == 0); assert(destAddr->gtType == TYP_I_IMPL || destAddr->gtType == TYP_BYREF); GetZeroOffsetFieldMap()->Set(destAddr, GetFieldSeqStore()->CreateSingleton(GetRefanyDataField())); GenTree* ptrSlot = gtNewOperNode(GT_IND, TYP_I_IMPL, destAddr); - GenTreeIntCon* typeFieldOffset = gtNewIconNode(offsetof(CORINFO_RefAny, type), TYP_I_IMPL); + GenTreeIntCon* typeFieldOffset = gtNewIconNode(OFFSETOF__CORINFO_TypedReference__type, TYP_I_IMPL); typeFieldOffset->gtFieldSeq = GetFieldSeqStore()->CreateSingleton(GetRefanyTypeField()); GenTree* typeSlot = gtNewOperNode(GT_IND, TYP_I_IMPL, gtNewOperNode(GT_ADD, destAddr->gtType, destAddrClone, typeFieldOffset)); @@ -3530,14 +3530,14 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, op1 = impPopStack().val; if (!opts.MinOpts() && !opts.compDbgCode) { - GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, op1, offsetof(CORINFO_String, stringLen)); + GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, op1, OFFSETOF__CORINFO_String__stringLen); op1 = arrLen; } else { /* Create the expression "*(str_addr + stringLengthOffset)" */ op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1, - gtNewIconNode(offsetof(CORINFO_String, stringLen), TYP_I_IMPL)); + gtNewIconNode(OFFSETOF__CORINFO_String__stringLen, TYP_I_IMPL)); op1 = gtNewOperNode(GT_IND, TYP_INT, op1); } @@ -14519,7 +14519,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // Fetch the type from the correct slot op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1, - gtNewIconNode(offsetof(CORINFO_RefAny, type), TYP_I_IMPL)); + gtNewIconNode(OFFSETOF__CORINFO_TypedReference__type, TYP_I_IMPL)); op1 = gtNewOperNode(GT_IND, TYP_BYREF, op1); } else @@ -15429,7 +15429,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) if (!opts.MinOpts() && !opts.compDbgCode) { /* Use GT_ARR_LENGTH operator so rng check opts see this */ - GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, op1, offsetof(CORINFO_Array, length)); + GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, op1, OFFSETOF__CORINFO_Array__length); /* Mark the block as containing a length expression */ @@ -15444,7 +15444,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) { /* Create the expression "*(array_addr + ArrLenOffs)" */ op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1, - gtNewIconNode(offsetof(CORINFO_Array, length), TYP_I_IMPL)); + gtNewIconNode(OFFSETOF__CORINFO_Array__length, TYP_I_IMPL)); op1 = gtNewIndir(TYP_INT, op1); op1->gtFlags |= GTF_IND_ARR_LEN; } diff --git a/src/coreclr/src/jit/loopcloning.cpp b/src/coreclr/src/jit/loopcloning.cpp index 5eea37c..cc988b1 100644 --- a/src/coreclr/src/jit/loopcloning.cpp +++ b/src/coreclr/src/jit/loopcloning.cpp @@ -43,7 +43,7 @@ GenTree* LC_Array::ToGenTree(Compiler* comp) // If asked for arrlen invoke arr length operator. if (oper == ArrLen) { - GenTree* arrLen = comp->gtNewArrLen(TYP_INT, arr, offsetof(CORINFO_Array, length)); + GenTree* arrLen = comp->gtNewArrLen(TYP_INT, arr, OFFSETOF__CORINFO_Array__length); return arrLen; } else diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index f9c8181..6778de6 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -4267,9 +4267,9 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) // Build the mkrefany as a GT_FIELD_LIST GenTreeFieldList* fieldList = new (this, GT_FIELD_LIST) - GenTreeFieldList(argx->gtOp.gtOp1, offsetof(CORINFO_RefAny, dataPtr), TYP_BYREF, nullptr); + GenTreeFieldList(argx->gtOp.gtOp1, OFFSETOF__CORINFO_TypedReference__dataPtr, TYP_BYREF, nullptr); (void)new (this, GT_FIELD_LIST) - GenTreeFieldList(argx->gtOp.gtOp2, offsetof(CORINFO_RefAny, type), TYP_I_IMPL, fieldList); + GenTreeFieldList(argx->gtOp.gtOp2, OFFSETOF__CORINFO_TypedReference__type, TYP_I_IMPL, fieldList); fgArgTabEntry* fp = Compiler::gtArgEntryByNode(call, argx); fp->node = fieldList; args->gtOp.gtOp1 = fieldList; @@ -4283,8 +4283,8 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) // Build the mkrefany as a comma node: // (tmp.ptr=argx),(tmp.type=handle) - GenTreeLclFld* destPtrSlot = gtNewLclFldNode(tmp, TYP_I_IMPL, offsetof(CORINFO_RefAny, dataPtr)); - GenTreeLclFld* destTypeSlot = gtNewLclFldNode(tmp, TYP_I_IMPL, offsetof(CORINFO_RefAny, type)); + GenTreeLclFld* destPtrSlot = gtNewLclFldNode(tmp, TYP_I_IMPL, OFFSETOF__CORINFO_TypedReference__dataPtr); + GenTreeLclFld* destTypeSlot = gtNewLclFldNode(tmp, TYP_I_IMPL, OFFSETOF__CORINFO_TypedReference__type); destPtrSlot->gtFieldSeq = GetFieldSeqStore()->CreateSingleton(GetRefanyDataField()); destPtrSlot->gtFlags |= GTF_VAR_DEF; destTypeSlot->gtFieldSeq = GetFieldSeqStore()->CreateSingleton(GetRefanyTypeField()); @@ -5756,19 +5756,19 @@ GenTree* Compiler::fgMorphArrayIndex(GenTree* tree) ssize_t elemOffs; if (tree->gtFlags & GTF_INX_STRING_LAYOUT) { - lenOffs = offsetof(CORINFO_String, stringLen); - elemOffs = offsetof(CORINFO_String, chars); + lenOffs = OFFSETOF__CORINFO_String__stringLen; + elemOffs = OFFSETOF__CORINFO_String__chars; tree->gtFlags &= ~GTF_INX_STRING_LAYOUT; // Clear this flag as it is used for GTF_IND_VOLATILE } else if (tree->gtFlags & GTF_INX_REFARR_LAYOUT) { - lenOffs = offsetof(CORINFO_RefArray, length); + lenOffs = OFFSETOF__CORINFO_Array__length; elemOffs = eeGetEEInfo()->offsetOfObjArrayData; } else // We have a standard array { - lenOffs = offsetof(CORINFO_Array, length); - elemOffs = offsetof(CORINFO_Array, u1Elems); + lenOffs = OFFSETOF__CORINFO_Array__length; + elemOffs = OFFSETOF__CORINFO_Array__data; } // In minopts, we expand GT_INDEX to GT_IND(GT_INDEX_ADDR) in order to minimize the size of the IR. As minopts diff --git a/src/coreclr/src/jit/rationalize.cpp b/src/coreclr/src/jit/rationalize.cpp index ad99a27..89e4167 100644 --- a/src/coreclr/src/jit/rationalize.cpp +++ b/src/coreclr/src/jit/rationalize.cpp @@ -888,7 +888,7 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, ArrayStackgtSIMDBaseType); GenTree* address = new (comp, GT_LEA) GenTreeAddrMode(TYP_BYREF, simdNode->gtOp1, simdNode->gtOp2, - baseTypeSize, offsetof(CORINFO_Array, u1Elems)); + baseTypeSize, OFFSETOF__CORINFO_Array__data); GenTree* ind = comp->gtNewOperNode(GT_IND, simdType, address); BlockRange().InsertBefore(simdNode, address, ind); diff --git a/src/coreclr/src/jit/simd.cpp b/src/coreclr/src/jit/simd.cpp index c45aa89..5931b83 100644 --- a/src/coreclr/src/jit/simd.cpp +++ b/src/coreclr/src/jit/simd.cpp @@ -2200,11 +2200,11 @@ GenTree* Compiler::createAddressNodeForSIMDInit(GenTree* tree, unsigned simdSize // = indexVal + arrayElementsCount - 1 unsigned arrayElementsCount = simdSize / genTypeSize(baseType); checkIndexExpr = new (this, GT_CNS_INT) GenTreeIntCon(TYP_INT, indexVal + arrayElementsCount - 1); - GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, arrayRef, (int)offsetof(CORINFO_Array, length)); + GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, arrayRef, (int)OFFSETOF__CORINFO_Array__length); GenTreeBoundsChk* arrBndsChk = new (this, GT_ARR_BOUNDS_CHECK) GenTreeBoundsChk(GT_ARR_BOUNDS_CHECK, TYP_VOID, checkIndexExpr, arrLen, SCK_RNGCHK_FAIL); - offset += offsetof(CORINFO_Array, u1Elems); + offset += OFFSETOF__CORINFO_Array__data; byrefNode = gtNewOperNode(GT_COMMA, arrayRef->TypeGet(), arrBndsChk, gtCloneExpr(arrayRef)); } else @@ -2631,7 +2631,7 @@ GenTree* Compiler::impSIMDIntrinsic(OPCODE opcode, } GenTreeArrLen* arrLen = - gtNewArrLen(TYP_INT, arrayRefForArgRngChk, (int)offsetof(CORINFO_Array, length)); + gtNewArrLen(TYP_INT, arrayRefForArgRngChk, (int)OFFSETOF__CORINFO_Array__length); argRngChk = new (this, GT_ARR_BOUNDS_CHECK) GenTreeBoundsChk(GT_ARR_BOUNDS_CHECK, TYP_VOID, index, arrLen, op3CheckKind); // Now, clone op3 to create another node for the argChk @@ -2651,7 +2651,7 @@ GenTree* Compiler::impSIMDIntrinsic(OPCODE opcode, { op2CheckKind = SCK_ARG_EXCPN; } - GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, arrayRefForArgChk, (int)offsetof(CORINFO_Array, length)); + GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, arrayRefForArgChk, (int)OFFSETOF__CORINFO_Array__length); GenTreeBoundsChk* argChk = new (this, GT_ARR_BOUNDS_CHECK) GenTreeBoundsChk(GT_ARR_BOUNDS_CHECK, TYP_VOID, checkIndexExpr, arrLen, op2CheckKind); @@ -2681,7 +2681,7 @@ GenTree* Compiler::impSIMDIntrinsic(OPCODE opcode, // TODO-Cleanup: Though it happens to just work fine front-end phases are not aware of GT_LEA node. // Therefore, convert these to use GT_ADDR . copyBlkDst = new (this, GT_LEA) - GenTreeAddrMode(TYP_BYREF, op2, op3, genTypeSize(baseType), offsetof(CORINFO_Array, u1Elems)); + GenTreeAddrMode(TYP_BYREF, op2, op3, genTypeSize(baseType), OFFSETOF__CORINFO_Array__data); doCopyBlk = true; } } diff --git a/src/coreclr/src/vm/ceeload.cpp b/src/coreclr/src/vm/ceeload.cpp index 2155c37..6ab01ed 100644 --- a/src/coreclr/src/vm/ceeload.cpp +++ b/src/coreclr/src/vm/ceeload.cpp @@ -2255,7 +2255,7 @@ void Module::GetOffsetsForRegularStaticData( *pOutNonGCStaticOffset = m_pRegularStaticOffsets[index*2 + 1]; // Check we didnt go out of what we predicted we would need for the class - if (*pOutStaticHandleOffset + sizeof(OBJECTREF*)*dwGCStaticHandles > + if (*pOutStaticHandleOffset + TARGET_POINTER_SIZE*dwGCStaticHandles > m_pRegularStaticOffsets[(index+1)*2] || *pOutNonGCStaticOffset + dwNonGCStaticBytes > m_pRegularStaticOffsets[(index+1)*2 + 1]) @@ -2313,7 +2313,7 @@ void Module::GetOffsetsForThreadStaticData( *pOutNonGCStaticOffset = m_pThreadStaticOffsets[index*2 + 1]; // Check we didnt go out of what we predicted we would need for the class - if (*pOutStaticHandleOffset + sizeof(OBJECTREF*)*dwGCStaticHandles > + if (*pOutStaticHandleOffset + TARGET_POINTER_SIZE*dwGCStaticHandles > m_pThreadStaticOffsets[(index+1)*2] || *pOutNonGCStaticOffset + dwNonGCStaticBytes > m_pThreadStaticOffsets[(index+1)*2 + 1]) diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 367dfb09..ccd99df 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -1458,12 +1458,12 @@ static CorInfoHelpFunc getInstanceFieldHelper(FieldDesc * pField, CORINFO_ACCESS break; case ELEMENT_TYPE_I4: case ELEMENT_TYPE_U4: - IN_WIN32(default:) + IN_TARGET_32BIT(default:) helper = CORINFO_HELP_GETFIELD32; break; case ELEMENT_TYPE_I8: case ELEMENT_TYPE_U8: - IN_WIN64(default:) + IN_TARGET_64BIT(default:) helper = CORINFO_HELP_GETFIELD64; break; case ELEMENT_TYPE_R4: @@ -7303,9 +7303,9 @@ bool getILIntrinsicImplementationForVolatile(MethodDesc * ftn, // The implementation in mscorlib already does this, so we will only substitute a new // IL body if we're running on a 64-bit platform. // - IN_WIN64(VOLATILE_IMPL(Long, CEE_LDIND_I8, CEE_STIND_I8)) - IN_WIN64(VOLATILE_IMPL(ULong, CEE_LDIND_I8, CEE_STIND_I8)) - IN_WIN64(VOLATILE_IMPL(Dbl, CEE_LDIND_R8, CEE_STIND_R8)) + IN_TARGET_64BIT(VOLATILE_IMPL(Long, CEE_LDIND_I8, CEE_STIND_I8)) + IN_TARGET_64BIT(VOLATILE_IMPL(ULong, CEE_LDIND_I8, CEE_STIND_I8)) + IN_TARGET_64BIT(VOLATILE_IMPL(Dbl, CEE_LDIND_R8, CEE_STIND_R8)) }; mdMethodDef md = ftn->GetMemberDef(); diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 63ea7a1..bae784f 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -3863,8 +3863,8 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, case ELEMENT_TYPE_I4: case ELEMENT_TYPE_U4: - IN_WIN32(case ELEMENT_TYPE_I:) - IN_WIN32(case ELEMENT_TYPE_U:) + IN_TARGET_32BIT(case ELEMENT_TYPE_I:) + IN_TARGET_32BIT(case ELEMENT_TYPE_U:) case ELEMENT_TYPE_R4: { dwLog2FieldSize = 2; @@ -3894,8 +3894,8 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, case ELEMENT_TYPE_I8: case ELEMENT_TYPE_U8: - IN_WIN64(case ELEMENT_TYPE_I:) - IN_WIN64(case ELEMENT_TYPE_U:) + IN_TARGET_64BIT(case ELEMENT_TYPE_I:) + IN_TARGET_64BIT(case ELEMENT_TYPE_U:) { #ifdef FEATURE_64BIT_ALIGNMENT // Record that this field requires alignment for Int64/UInt64. -- 2.7.4