diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs index dbc3d064acc7a0..c2333f3854eedb 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs @@ -463,7 +463,6 @@ private static void StelemRef_Helper_NoCacheLookup(ref object? element, void* el WriteBarrier(ref element, obj); } -#if FEATURE_ARRAYSTUB_AS_IL [DebuggerHidden] private static unsafe void ArrayTypeCheck(object obj, Array array) { @@ -493,6 +492,5 @@ private static unsafe void ArrayTypeCheck_Helper(object obj, void* elementType) ThrowArrayMismatchException(); } } -#endif } } diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props index 7905f8a573d738..82dded497b6f9c 100644 --- a/src/coreclr/clr.featuredefines.props +++ b/src/coreclr/clr.featuredefines.props @@ -10,13 +10,11 @@ true - true true true - true true true true @@ -32,7 +30,6 @@ - $(DefineConstants);FEATURE_ARRAYSTUB_AS_IL $(DefineConstants);FEATURE_MULTICASTSTUB_AS_IL $(DefineConstants);FEATURE_COMWRAPPERS $(DefineConstants);FEATURE_COMINTEROP diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 73de2d5bce2579..e376c63f758470 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -70,11 +70,9 @@ endif(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) # Features - please keep them alphabetically sorted if(CLR_CMAKE_TARGET_WIN32) if(NOT CLR_CMAKE_TARGET_ARCH_I386) - add_definitions(-DFEATURE_ARRAYSTUB_AS_IL) add_definitions(-DFEATURE_MULTICASTSTUB_AS_IL) endif() else(CLR_CMAKE_TARGET_WIN32) - add_definitions(-DFEATURE_ARRAYSTUB_AS_IL) add_definitions(-DFEATURE_MULTICASTSTUB_AS_IL) endif(CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/vm/.vscode/c_cpp_properties.json b/src/coreclr/vm/.vscode/c_cpp_properties.json index ae1a019f9c05f7..30f8ba3e8f5c44 100644 --- a/src/coreclr/vm/.vscode/c_cpp_properties.json +++ b/src/coreclr/vm/.vscode/c_cpp_properties.json @@ -41,7 +41,6 @@ "TARGET_64BIT=1", "DEBUGGING_SUPPORTED", "FEATURE_METADATA_UPDATER", - "FEATURE_ARRAYSTUB_AS_IL", "FEATURE_BASICFREEZE", "FEATURE_CODE_VERSIONING", "FEATURE_COLLECTIBLE_TYPES", diff --git a/src/coreclr/vm/amd64/AsmHelpers.asm b/src/coreclr/vm/amd64/AsmHelpers.asm index 3fb2ca02e15a8f..39bee849fa19e2 100644 --- a/src/coreclr/vm/amd64/AsmHelpers.asm +++ b/src/coreclr/vm/amd64/AsmHelpers.asm @@ -18,74 +18,6 @@ extern DebugCheckStubUnwindInfoWorker:proc endif -GenerateArrayOpStubExceptionCase macro ErrorCaseName, ExceptionName - -NESTED_ENTRY ErrorCaseName&_RSIRDI_ScratchArea, _TEXT - - ; account for scratch area, rsi, rdi already on the stack - .allocstack 38h - END_PROLOGUE - - mov rcx, CORINFO_&ExceptionName&_ASM - - ; begin epilogue - - add rsp, 28h ; pop callee scratch area - pop rdi - pop rsi - jmp JIT_InternalThrow - -NESTED_END ErrorCaseName&_RSIRDI_ScratchArea, _TEXT - -NESTED_ENTRY ErrorCaseName&_ScratchArea, _TEXT - - ; account for scratch area already on the stack - .allocstack 28h - END_PROLOGUE - - mov rcx, CORINFO_&ExceptionName&_ASM - - ; begin epilogue - - add rsp, 28h ; pop callee scratch area - jmp JIT_InternalThrow - -NESTED_END ErrorCaseName&_ScratchArea, _TEXT - -NESTED_ENTRY ErrorCaseName&_RSIRDI, _TEXT - - ; account for rsi, rdi already on the stack - .allocstack 10h - END_PROLOGUE - - mov rcx, CORINFO_&ExceptionName&_ASM - - ; begin epilogue - - pop rdi - pop rsi - jmp JIT_InternalThrow - -NESTED_END ErrorCaseName&_RSIRDI, _TEXT - -LEAF_ENTRY ErrorCaseName, _TEXT - - mov rcx, CORINFO_&ExceptionName&_ASM - - ; begin epilogue - - jmp JIT_InternalThrow - -LEAF_END ErrorCaseName, _TEXT - - endm - - -GenerateArrayOpStubExceptionCase ArrayOpStubNullException, NullReferenceException -GenerateArrayOpStubExceptionCase ArrayOpStubRangeException, IndexOutOfRangeException -GenerateArrayOpStubExceptionCase ArrayOpStubTypeMismatchException, ArrayTypeMismatchException - - ; EXTERN_C int __fastcall HelperMethodFrameRestoreState( ; INDEBUG_COMMA(HelperMethodFrame *pFrame) ; MachState *pState diff --git a/src/coreclr/vm/amd64/asmconstants.h b/src/coreclr/vm/amd64/asmconstants.h index 89e2039888d0ce..1f44fca2719f9e 100644 --- a/src/coreclr/vm/amd64/asmconstants.h +++ b/src/coreclr/vm/amd64/asmconstants.h @@ -208,22 +208,10 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__DynamicStaticsInfo__m_pGCStatics ASMCONSTANTS_C_ASSERT( CORINFO_NullReferenceException_ASM == CORINFO_NullReferenceException); -#define CORINFO_InvalidCastException_ASM 2 -ASMCONSTANTS_C_ASSERT( CORINFO_InvalidCastException_ASM - == CORINFO_InvalidCastException); - #define CORINFO_IndexOutOfRangeException_ASM 3 ASMCONSTANTS_C_ASSERT( CORINFO_IndexOutOfRangeException_ASM == CORINFO_IndexOutOfRangeException); -#define CORINFO_ArrayTypeMismatchException_ASM 6 -ASMCONSTANTS_C_ASSERT( CORINFO_ArrayTypeMismatchException_ASM - == CORINFO_ArrayTypeMismatchException); - -#define CORINFO_ArgumentNullException_ASM 8 -ASMCONSTANTS_C_ASSERT( CORINFO_ArgumentNullException_ASM - == CORINFO_ArgumentNullException); - #define CORINFO_ArgumentException_ASM 9 ASMCONSTANTS_C_ASSERT( CORINFO_ArgumentException_ASM == CORINFO_ArgumentException); diff --git a/src/coreclr/vm/arm/cgencpu.h b/src/coreclr/vm/arm/cgencpu.h index 1f25c1b9f1876e..7c2e3b8160bc67 100644 --- a/src/coreclr/vm/arm/cgencpu.h +++ b/src/coreclr/vm/arm/cgencpu.h @@ -363,7 +363,6 @@ inline PCODE decodeBackToBackJump(PCODE pBuffer) //---------------------------------------------------------------------- #include "stublink.h" -struct ArrayOpScript; inline BOOL IsThumbCode(PCODE pCode) { diff --git a/src/coreclr/vm/array.cpp b/src/coreclr/vm/array.cpp index 806db9309f0fb3..3b2b778f4c50f0 100644 --- a/src/coreclr/vm/array.cpp +++ b/src/coreclr/vm/array.cpp @@ -72,10 +72,8 @@ VOID ArrayClass::GenerateArrayAccessorCallSig( PCCOR_SIGNATURE *ppSig,// Generated signature DWORD * pcSig, // Generated signature size LoaderAllocator *pLoaderAllocator, - AllocMemTracker *pamTracker -#ifdef FEATURE_ARRAYSTUB_AS_IL - ,BOOL fForStubAsIL -#endif + AllocMemTracker *pamTracker, + BOOL fForStubAsIL ) { CONTRACTL { @@ -109,9 +107,7 @@ VOID ArrayClass::GenerateArrayAccessorCallSig( // BYREF VAR 0 I4 , ... , I4 case ArrayMethodDesc::ARRAY_FUNC_ADDRESS: dwCallSigSize += 5; -#ifdef FEATURE_ARRAYSTUB_AS_IL if(fForStubAsIL) {dwArgCount++; dwCallSigSize++;} -#endif break; } @@ -124,11 +120,7 @@ VOID ArrayClass::GenerateArrayAccessorCallSig( pSig = pSigMemory; BYTE callConv = IMAGE_CEE_CS_CALLCONV_DEFAULT + IMAGE_CEE_CS_CALLCONV_HASTHIS; - if (dwFuncType == ArrayMethodDesc::ARRAY_FUNC_ADDRESS -#ifdef FEATURE_ARRAYSTUB_AS_IL - && !fForStubAsIL -#endif - ) + if (dwFuncType == ArrayMethodDesc::ARRAY_FUNC_ADDRESS && !fForStubAsIL) { callConv |= CORINFO_CALLCONV_PARAMTYPE; // Address routine needs special hidden arg } @@ -154,7 +146,7 @@ VOID ArrayClass::GenerateArrayAccessorCallSig( break; } -#if defined(FEATURE_ARRAYSTUB_AS_IL ) && !defined(TARGET_X86) +#ifndef TARGET_X86 if(dwFuncType == ArrayMethodDesc::ARRAY_FUNC_ADDRESS && fForStubAsIL) { *pSig++ = ELEMENT_TYPE_I; @@ -169,7 +161,7 @@ VOID ArrayClass::GenerateArrayAccessorCallSig( *pSig++ = ELEMENT_TYPE_VAR; *pSig++ = 0; // variable 0 } -#if defined(FEATURE_ARRAYSTUB_AS_IL ) && defined(TARGET_X86) +#ifdef TARGET_X86 else if(dwFuncType == ArrayMethodDesc::ARRAY_FUNC_ADDRESS && fForStubAsIL) { *pSig++ = ELEMENT_TYPE_I; @@ -515,11 +507,7 @@ MethodTable* Module::CreateArrayMethodTable(TypeHandle elemTypeHnd, CorElementTy PCCOR_SIGNATURE pSig; DWORD cSig; - pClass->GenerateArrayAccessorCallSig(dwFuncRank, dwFuncType, &pSig, &cSig, pAllocator, pamTracker - #ifdef FEATURE_ARRAYSTUB_AS_IL - ,0 - #endif - ); + pClass->GenerateArrayAccessorCallSig(dwFuncRank, dwFuncType, &pSig, &cSig, pAllocator, pamTracker, FALSE); pClass->InitArrayMethodDesc(pNewMD, pSig, cSig, numVirtuals + dwMethodIndex, pAllocator, pamTracker); @@ -628,8 +616,6 @@ MethodTable* Module::CreateArrayMethodTable(TypeHandle elemTypeHnd, CorElementTy } // Module::CreateArrayMethodTable -#ifdef FEATURE_ARRAYSTUB_AS_IL - class ArrayOpLinker : public ILStubLinker { ILCodeStream * m_pCode; @@ -930,237 +916,6 @@ Stub *GenerateArrayOpStub(ArrayMethodDesc* pMD) return Stub::NewStub(JitILStub(pStubMD)); } -#else // FEATURE_ARRAYSTUB_AS_IL -//======================================================================== -// Generates the platform-independent arrayop stub. -//======================================================================== -void GenerateArrayOpScript(ArrayMethodDesc *pMD, ArrayOpScript *paos) -{ - STANDARD_VM_CONTRACT; - - ArrayOpIndexSpec *pai = NULL; - MethodTable *pMT = pMD->GetMethodTable(); - ArrayClass *pcls = (ArrayClass*)(pMT->GetClass()); - - // The ArrayOpScript and ArrayOpIndexSpec structs double as hash keys - // for the ArrayStubCache. Thus, it's imperative that there be no - // unused "pad" fields that contain unstable values. - // pMT->GetRank() is bounded so the arithmetics here is safe. - memset(paos, 0, sizeof(ArrayOpScript) + sizeof(ArrayOpIndexSpec) * pMT->GetRank()); - - paos->m_rank = (BYTE)(pMT->GetRank()); - paos->m_fHasLowerBounds = (pMT->GetInternalCorElementType() == ELEMENT_TYPE_ARRAY); - - paos->m_ofsoffirst = ArrayBase::GetDataPtrOffset(pMT); - - switch (pMD->GetArrayFuncIndex()) - { - case ArrayMethodDesc::ARRAY_FUNC_GET: - paos->m_op = ArrayOpScript::LOAD; - break; - case ArrayMethodDesc::ARRAY_FUNC_SET: - paos->m_op = ArrayOpScript::STORE; - break; - case ArrayMethodDesc::ARRAY_FUNC_ADDRESS: - paos->m_op = ArrayOpScript::LOADADDR; - break; - default: - _ASSERTE(!"Unknown array func!"); - } - - MetaSig msig(pMD); - _ASSERTE(!msig.IsVarArg()); // No array signature is varargs, code below does not expect it. - - switch (pMT->GetArrayElementTypeHandle().GetInternalCorElementType()) - { - // These are all different because of sign extension - - case ELEMENT_TYPE_I1: - paos->m_elemsize = 1; - paos->m_signed = TRUE; - break; - - case ELEMENT_TYPE_BOOLEAN: - case ELEMENT_TYPE_U1: - paos->m_elemsize = 1; - break; - - case ELEMENT_TYPE_I2: - paos->m_elemsize = 2; - paos->m_signed = TRUE; - break; - - case ELEMENT_TYPE_CHAR: - case ELEMENT_TYPE_U2: - paos->m_elemsize = 2; - break; - - case ELEMENT_TYPE_I4: - IN_TARGET_32BIT(case ELEMENT_TYPE_I:) - paos->m_elemsize = 4; - paos->m_signed = TRUE; - break; - - case ELEMENT_TYPE_U4: - IN_TARGET_32BIT(case ELEMENT_TYPE_U:) - IN_TARGET_32BIT(case ELEMENT_TYPE_PTR:) - paos->m_elemsize = 4; - break; - - case ELEMENT_TYPE_I8: - IN_TARGET_64BIT(case ELEMENT_TYPE_I:) - paos->m_elemsize = 8; - paos->m_signed = TRUE; - break; - - case ELEMENT_TYPE_U8: - IN_TARGET_64BIT(case ELEMENT_TYPE_U:) - IN_TARGET_64BIT(case ELEMENT_TYPE_PTR:) - paos->m_elemsize = 8; - break; - - case ELEMENT_TYPE_R4: - paos->m_elemsize = 4; - paos->m_flags |= paos->ISFPUTYPE; - break; - - case ELEMENT_TYPE_R8: - paos->m_elemsize = 8; - paos->m_flags |= paos->ISFPUTYPE; - break; - - case ELEMENT_TYPE_SZARRAY: - case ELEMENT_TYPE_ARRAY: - case ELEMENT_TYPE_CLASS: - case ELEMENT_TYPE_STRING: - case ELEMENT_TYPE_OBJECT: - paos->m_elemsize = sizeof(LPVOID); - paos->m_flags |= paos->NEEDSWRITEBARRIER; - if (paos->m_op != ArrayOpScript::LOAD) - { - paos->m_flags |= paos->NEEDSTYPECHECK; - } - - break; - - case ELEMENT_TYPE_VALUETYPE: - paos->m_elemsize = pMT->GetComponentSize(); - if (pMT->ContainsPointers()) - { - paos->m_gcDesc = CGCDesc::GetCGCDescFromMT(pMT); - paos->m_flags |= paos->NEEDSWRITEBARRIER; - } - break; - - default: - _ASSERTE(!"Unsupported Array Type!"); - } - - ArgIterator argit(&msig); - -#ifdef TARGET_X86 - UINT stackPop = argit.CbStackPop(); - _ASSERTE(stackPop <= USHRT_MAX); - paos->m_cbretpop = (UINT16)stackPop; -#endif - - if (argit.HasRetBuffArg()) - { - paos->m_flags |= ArrayOpScript::HASRETVALBUFFER; - UINT refBuffOffset = argit.GetRetBuffArgOffset(); - _ASSERTE(refBuffOffset <= USHRT_MAX); - paos->m_fRetBufLoc = (UINT16)refBuffOffset; - } - - if (paos->m_op == ArrayOpScript::LOADADDR) - { - paos->m_typeParamOffs = argit.GetParamTypeArgOffset(); - } - - for (UINT idx = 0; idx < paos->m_rank; idx++) - { - pai = (ArrayOpIndexSpec*)(paos->GetArrayOpIndexSpecs() + idx); - - pai->m_idxloc = argit.GetNextOffset(); - pai->m_lboundofs = paos->m_fHasLowerBounds ? (UINT32) (ArrayBase::GetLowerBoundsOffset(pMT) + idx*sizeof(DWORD)) : 0; - pai->m_lengthofs = ArrayBase::GetBoundsOffset(pMT) + idx*sizeof(DWORD); - } - - if (paos->m_op == paos->STORE) - { - UINT offset = argit.GetNextOffset(); - _ASSERTE(offset <= USHRT_MAX); - paos->m_fValLoc = (UINT16)offset; - } -} - -//--------------------------------------------------------- -// Cache for array stubs -//--------------------------------------------------------- -class ArrayStubCache : public StubCacheBase -{ - virtual DWORD CompileStub(const BYTE *pRawStub, - StubLinker *psl); - virtual UINT Length(const BYTE *pRawStub); - -public: -public: - ArrayStubCache(LoaderHeap* heap) : StubCacheBase(heap) - { - } - - static ArrayStubCache * GetArrayStubCache() - { - STANDARD_VM_CONTRACT; - - static ArrayStubCache * s_pArrayStubCache = NULL; - - if (s_pArrayStubCache == NULL) - { - ArrayStubCache * pArrayStubCache = new ArrayStubCache(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap()); - if (InterlockedCompareExchangeT(&s_pArrayStubCache, pArrayStubCache, NULL) != NULL) - delete pArrayStubCache; - } - - return s_pArrayStubCache; - } -}; - -Stub *GenerateArrayOpStub(ArrayMethodDesc* pMD) -{ - STANDARD_VM_CONTRACT; - - MethodTable *pMT = pMD->GetMethodTable(); - - ArrayOpScript *paos = (ArrayOpScript*)_alloca(sizeof(ArrayOpScript) + sizeof(ArrayOpIndexSpec) * pMT->GetRank()); - - GenerateArrayOpScript(pMD, paos); - - Stub *pArrayOpStub; - pArrayOpStub = ArrayStubCache::GetArrayStubCache()->Canonicalize((const BYTE *)paos); - if (pArrayOpStub == NULL) - COMPlusThrowOM(); - - return pArrayOpStub; -} - -DWORD ArrayStubCache::CompileStub(const BYTE *pRawStub, - StubLinker *psl) -{ - STANDARD_VM_CONTRACT; - - ((CPUSTUBLINKER*)psl)->EmitArrayOpStub((ArrayOpScript*)pRawStub); - return NEWSTUB_FL_NONE; -} - -UINT ArrayStubCache::Length(const BYTE *pRawStub) -{ - LIMITED_METHOD_CONTRACT; - return ((ArrayOpScript*)pRawStub)->Length(); -} - -#endif // FEATURE_ARRAYSTUB_AS_IL - //--------------------------------------------------------------------- // This method returns TRUE if pInterfaceMT could be one of the interfaces diff --git a/src/coreclr/vm/array.h b/src/coreclr/vm/array.h index 51a7c988c4afd1..1f687f140eef3b 100644 --- a/src/coreclr/vm/array.h +++ b/src/coreclr/vm/array.h @@ -14,90 +14,6 @@ class MethodTable; -#ifndef FEATURE_ARRAYSTUB_AS_IL - -//====================================================================== -// The following structures double as hash keys for the ArrayStubCache. -// Thus, it's imperative that there be no -// unused "pad" fields that contain unstable values. -#include - - -// Specifies one index spec. This is used mostly to get the argument -// location done early when we still have a signature to work with. -struct ArrayOpIndexSpec -{ - UINT32 m_idxloc; //if (m_fref) offset in ArgumentReg else base-frame offset into stack. - UINT32 m_lboundofs; //offset within array of lowerbound - UINT32 m_lengthofs; //offset within array of lengths -}; - - -struct ArrayOpScript -{ - enum - { - LOAD = 0, - STORE = 1, - LOADADDR = 2, - }; - - - // FLAGS - enum - { - ISFPUTYPE = 0x01, - NEEDSWRITEBARRIER = 0x02, - HASRETVALBUFFER = 0x04, - NEEDSTYPECHECK = 0x10, - }; - - // - // these args have been reordered for better packing.. - // - - BYTE m_rank; // # of ArrayOpIndexSpec's - BYTE m_fHasLowerBounds; // if FALSE, all lowerbounds are 0 - BYTE m_flags; - BYTE m_signed; // whether to sign-extend or zero-extend (for short types) - - BYTE m_op; // STORE/LOAD/LOADADDR - BYTE m_pad1; - - UINT16 m_fRetBufLoc; // if HASRETVALBUFFER, stack offset or argreg offset of retbuf ptr - UINT16 m_fValLoc; // for STORES, stack offset or argreg offset of value - - UINT16 m_cbretpop; // how much to pop - - UINT32 m_elemsize; // size in bytes of element. - UINT m_ofsoffirst; // offset of first element - INT m_typeParamOffs; // offset of type param - CGCDesc* m_gcDesc; // layout of GC stuff (0 if not needed) - - // Array of ArrayOpIndexSpec's follow (one for each dimension). - - const ArrayOpIndexSpec *GetArrayOpIndexSpecs() const - { - LIMITED_METHOD_CONTRACT; - - return (const ArrayOpIndexSpec *)(1+ this); - } - - UINT Length() const - { - LIMITED_METHOD_CONTRACT; - - return sizeof(*this) + m_rank * sizeof(ArrayOpIndexSpec); - } - -}; - -#include -//====================================================================== - -#endif // FEATURE_ARRAYSTUB_AS_IL - - Stub *GenerateArrayOpStub(ArrayMethodDesc* pMD); diff --git a/src/coreclr/vm/class.h b/src/coreclr/vm/class.h index 77535d9ef4b239..e20b29b9e5f122 100644 --- a/src/coreclr/vm/class.h +++ b/src/coreclr/vm/class.h @@ -1984,10 +1984,8 @@ class ArrayClass : public EEClass PCCOR_SIGNATURE *ppSig, // Generated signature DWORD * pcSig, // Generated signature size LoaderAllocator *pLoaderAllocator, - AllocMemTracker *pamTracker -#ifdef FEATURE_ARRAYSTUB_AS_IL - ,BOOL fForStubAsIL -#endif + AllocMemTracker *pamTracker, + BOOL fForStubAsIL ); diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 3974434e5c93a5..2e1a7e970563f7 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1164,9 +1164,7 @@ DEFINE_METHOD(CASTHELPERS, CHKCASTCLASSSPECIAL, ChkCastClassSpecial, SM_Ptr DEFINE_METHOD(CASTHELPERS, UNBOX, Unbox, SM_PtrVoid_Obj_RetRefByte) DEFINE_METHOD(CASTHELPERS, STELEMREF, StelemRef, SM_ArrObject_IntPtr_Obj_RetVoid) DEFINE_METHOD(CASTHELPERS, LDELEMAREF, LdelemaRef, SM_ArrObject_IntPtr_PtrVoid_RetRefObj) -#ifdef FEATURE_ARRAYSTUB_AS_IL DEFINE_METHOD(CASTHELPERS, ARRAYTYPECHECK, ArrayTypeCheck, SM_Obj_Array_RetVoid) -#endif #ifdef FEATURE_EH_FUNCLETS DEFINE_CLASS(EH, Runtime, EH) diff --git a/src/coreclr/vm/dllimport.h b/src/coreclr/vm/dllimport.h index 9a7b1575bff06e..891221cff6b846 100644 --- a/src/coreclr/vm/dllimport.h +++ b/src/coreclr/vm/dllimport.h @@ -191,11 +191,9 @@ enum NDirectStubFlags enum ILStubTypes { ILSTUB_INVALID = 0x80000000, -#ifdef FEATURE_ARRAYSTUB_AS_IL ILSTUB_ARRAYOP_GET = 0x80000001, ILSTUB_ARRAYOP_SET = 0x80000002, ILSTUB_ARRAYOP_ADDRESS = 0x80000003, -#endif #ifdef FEATURE_MULTICASTSTUB_AS_IL ILSTUB_MULTICASTDELEGATE_INVOKE = 0x80000004, #endif @@ -229,11 +227,9 @@ inline bool SF_IsCheckPendingException (DWORD dwStubFlags) { LIMITED_METHOD_CONT inline bool SF_IsVirtualStaticMethodDispatchStub(DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return dwStubFlags == ILSTUB_STATIC_VIRTUAL_DISPATCH_STUB; } -#ifdef FEATURE_ARRAYSTUB_AS_IL inline bool SF_IsArrayOpStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return ((dwStubFlags == ILSTUB_ARRAYOP_GET) || (dwStubFlags == ILSTUB_ARRAYOP_SET) || (dwStubFlags == ILSTUB_ARRAYOP_ADDRESS)); } -#endif #ifdef FEATURE_MULTICASTSTUB_AS_IL inline bool SF_IsMulticastDelegateStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags == ILSTUB_MULTICASTDELEGATE_INVOKE); } diff --git a/src/coreclr/vm/i386/asmconstants.h b/src/coreclr/vm/i386/asmconstants.h index 392c04ac92b98c..8c8fec685e0f82 100644 --- a/src/coreclr/vm/i386/asmconstants.h +++ b/src/coreclr/vm/i386/asmconstants.h @@ -163,12 +163,6 @@ ASMCONSTANTS_C_ASSERT(CORINFO_IndexOutOfRangeException_ASM == CORINFO_IndexOutOf #define CORINFO_OverflowException_ASM 4 ASMCONSTANTS_C_ASSERT(CORINFO_OverflowException_ASM == CORINFO_OverflowException) -#define CORINFO_ArrayTypeMismatchException_ASM 6 -ASMCONSTANTS_C_ASSERT(CORINFO_ArrayTypeMismatchException_ASM == CORINFO_ArrayTypeMismatchException) - -#define CORINFO_ArgumentNullException_ASM 8 -ASMCONSTANTS_C_ASSERT(CORINFO_ArgumentNullException_ASM == CORINFO_ArgumentNullException) - #define CORINFO_ArgumentException_ASM 9 ASMCONSTANTS_C_ASSERT(CORINFO_ArgumentException_ASM == CORINFO_ArgumentException) diff --git a/src/coreclr/vm/i386/asmhelpers.asm b/src/coreclr/vm/i386/asmhelpers.asm index 6a12bc9870b1cb..07f6e8b955d038 100644 --- a/src/coreclr/vm/i386/asmhelpers.asm +++ b/src/coreclr/vm/i386/asmhelpers.asm @@ -425,39 +425,6 @@ InternalExceptionWorker proc public jmp @JIT_InternalThrow@4 InternalExceptionWorker endp -; EAX -> number of caller arg bytes on the stack that we must remove before going -; to the throw helper, which assumes the stack is clean. -_ArrayOpStubNullException proc public - ; kFactorReg and kTotalReg could not have been modified, but let's pop - ; them anyway for consistency and to avoid future bugs. - pop esi - pop edi - mov ecx, CORINFO_NullReferenceException_ASM - jmp InternalExceptionWorker -_ArrayOpStubNullException endp - -; EAX -> number of caller arg bytes on the stack that we must remove before going -; to the throw helper, which assumes the stack is clean. -_ArrayOpStubRangeException proc public - ; kFactorReg and kTotalReg could not have been modified, but let's pop - ; them anyway for consistency and to avoid future bugs. - pop esi - pop edi - mov ecx, CORINFO_IndexOutOfRangeException_ASM - jmp InternalExceptionWorker -_ArrayOpStubRangeException endp - -; EAX -> number of caller arg bytes on the stack that we must remove before going -; to the throw helper, which assumes the stack is clean. -_ArrayOpStubTypeMismatchException proc public - ; kFactorReg and kTotalReg could not have been modified, but let's pop - ; them anyway for consistency and to avoid future bugs. - pop esi - pop edi - mov ecx, CORINFO_ArrayTypeMismatchException_ASM - jmp InternalExceptionWorker -_ArrayOpStubTypeMismatchException endp - ;------------------------------------------------------------------------------ ; This helper routine enregisters the appropriate arguments and makes the ; actual call. diff --git a/src/coreclr/vm/i386/cgenx86.cpp b/src/coreclr/vm/i386/cgenx86.cpp index d9dc22d148193b..69e2fe9e5360b0 100644 --- a/src/coreclr/vm/i386/cgenx86.cpp +++ b/src/coreclr/vm/i386/cgenx86.cpp @@ -45,8 +45,6 @@ // if someone changes the frame size. You are expected to keep this hard coded constant // up to date so that changes in the frame size trigger errors at compile time if the code is not altered -void generate_noref_copy (unsigned nbytes, StubLinkerCPU* sl); - #ifdef FEATURE_EH_FUNCLETS void UpdateRegDisplayFromCalleeSavedRegisters(REGDISPLAY * pRD, CalleeSavedRegisters * regs) { diff --git a/src/coreclr/vm/i386/stublinkerx86.cpp b/src/coreclr/vm/i386/stublinkerx86.cpp index aa4214bd42e834..7261dd0c67b9a6 100644 --- a/src/coreclr/vm/i386/stublinkerx86.cpp +++ b/src/coreclr/vm/i386/stublinkerx86.cpp @@ -50,24 +50,6 @@ extern "C" HRESULT __cdecl StubRareDisableHR(Thread *pThread); #endif // FEATURE_COMINTEROP extern "C" VOID __cdecl StubRareDisableTHROW(Thread *pThread, Frame *pFrame); -#ifndef FEATURE_ARRAYSTUB_AS_IL -extern "C" VOID __cdecl ArrayOpStubNullException(void); -extern "C" VOID __cdecl ArrayOpStubRangeException(void); -extern "C" VOID __cdecl ArrayOpStubTypeMismatchException(void); - -#if defined(TARGET_AMD64) -#define EXCEPTION_HELPERS(base) \ - extern "C" VOID __cdecl base##_RSIRDI_ScratchArea(void); \ - extern "C" VOID __cdecl base##_ScratchArea(void); \ - extern "C" VOID __cdecl base##_RSIRDI(void); \ - extern "C" VOID __cdecl base(void) -EXCEPTION_HELPERS(ArrayOpStubNullException); -EXCEPTION_HELPERS(ArrayOpStubRangeException); -EXCEPTION_HELPERS(ArrayOpStubTypeMismatchException); -#undef EXCEPTION_HELPERS -#endif // !TARGET_AMD64 -#endif // !FEATURE_ARRAYSTUB_AS_IL - #if defined(TARGET_AMD64) #if defined(_DEBUG) extern "C" VOID __cdecl DebugCheckStubUnwindInfo(); @@ -3863,959 +3845,6 @@ VOID StubLinkerCPU::EmitMulticastInvoke(UINT_PTR hash) #endif // !FEATURE_STUBS_AS_IL -#if !defined(FEATURE_ARRAYSTUB_AS_IL) - -// Little helper to generate code to move nbytes bytes of non Ref memory - -void generate_noref_copy (unsigned nbytes, StubLinkerCPU* sl) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - // If the size is pointer-aligned, we'll use movsd - if (IS_ALIGNED(nbytes, sizeof(void*))) - { - // If there are less than 4 pointers to copy, "unroll" the "rep movsd" - if (nbytes <= 3*sizeof(void*)) - { - while (nbytes > 0) - { - // movsd - sl->X86_64BitOperands(); - sl->Emit8(0xa5); - - nbytes -= sizeof(void*); - } - } - else - { - // mov ECX, size / 4 - sl->Emit8(0xb8+kECX); - sl->Emit32(nbytes / sizeof(void*)); - - // repe movsd - sl->Emit8(0xf3); - sl->X86_64BitOperands(); - sl->Emit8(0xa5); - } - } - else - { - // mov ECX, size - sl->Emit8(0xb8+kECX); - sl->Emit32(nbytes); - - // repe movsb - sl->Emit16(0xa4f3); - } -} - - -X86Reg LoadArrayOpArg ( - UINT32 idxloc, - StubLinkerCPU *psl, - X86Reg kRegIfFromMem, - UINT ofsadjust - AMD64_ARG(StubLinkerCPU::X86OperandSize OperandSize = StubLinkerCPU::k64BitOp) - ) -{ - STANDARD_VM_CONTRACT; - - if (!TransitionBlock::IsStackArgumentOffset(idxloc)) - return GetX86ArgumentRegisterFromOffset(idxloc - TransitionBlock::GetOffsetOfArgumentRegisters()); - - psl->X86EmitEspOffset(0x8b, kRegIfFromMem, idxloc + ofsadjust AMD64_ARG(OperandSize)); - return kRegIfFromMem; -} - -VOID StubLinkerCPU::EmitArrayOpStubThrow(unsigned exConst, unsigned cbRetArg) -{ - STANDARD_VM_CONTRACT; - - //ArrayOpStub*Exception - X86EmitPopReg(kESI); - X86EmitPopReg(kEDI); - - //mov CORINFO_NullReferenceException_ASM, %ecx - Emit8(0xb8 | kECX); - Emit32(exConst); - //InternalExceptionWorker - - X86EmitPopReg(kEDX); - // add pArrayOpScript->m_cbretpop, %esp (was add %eax, %esp) - Emit8(0x81); - Emit8(0xc0 | 0x4); - Emit32(cbRetArg); - X86EmitPushReg(kEDX); - X86EmitNearJump(NewExternalCodeLabel((PVOID)JIT_InternalThrow)); -} - -//=========================================================================== -// Emits code to do an array operation. -#ifdef _PREFAST_ -#pragma warning(push) -#pragma warning(disable:21000) // Suppress PREFast warning about overly large function -#endif -VOID StubLinkerCPU::EmitArrayOpStub(const ArrayOpScript* pArrayOpScript) -{ - STANDARD_VM_CONTRACT; - - // This is the offset to the parameters/what's already pushed on the stack: - // return address. - const INT locsize = sizeof(void*); - - // ArrayOpScript's stack offsets are built using ArgIterator, which - // assumes a TransitionBlock has been pushed, which is not the case - // here. rsp + ofsadjust should point at the first argument. Any further - // stack modifications below need to adjust ofsadjust appropriately. - // baseofsadjust needs to be the stack adjustment at the entry point - - // this is used further below to compute how much stack space was used. - - INT ofsadjust = locsize - (INT)sizeof(TransitionBlock); - - // Register usage - // - // x86 AMD64 - // Inputs: - // managed array THIS_kREG (ecx) THIS_kREG (rcx) - // index 0 edx rdx - // index 1/value r8 - // index 2/value r9 - // expected element type for LOADADDR eax rax rdx - // Working registers: - // total (accumulates unscaled offset) edi r10 - // factor (accumulates the slice factor) esi r11 - X86Reg kArrayRefReg = THIS_kREG; -#ifdef TARGET_AMD64 - const X86Reg kArrayMTReg = kR10; - const X86Reg kTotalReg = kR10; - const X86Reg kFactorReg = kR11; -#else - const X86Reg kArrayMTReg = kESI; - const X86Reg kTotalReg = kEDI; - const X86Reg kFactorReg = kESI; -#endif - -#ifdef TARGET_AMD64 - // Simplifying assumption for fNeedPrologue. - _ASSERTE(!pArrayOpScript->m_gcDesc || (pArrayOpScript->m_flags & ArrayOpScript::NEEDSWRITEBARRIER)); - // Simplifying assumption for saving rsi and rdi. - _ASSERTE(!(pArrayOpScript->m_flags & ArrayOpScript::HASRETVALBUFFER) || ArgIterator::IsArgPassedByRef(pArrayOpScript->m_elemsize)); - - // Cases where we need to make calls - BOOL fNeedScratchArea = ( (pArrayOpScript->m_flags & (ArrayOpScript::NEEDSTYPECHECK | ArrayOpScript::NEEDSWRITEBARRIER)) - && ( pArrayOpScript->m_op == ArrayOpScript::STORE - || ( pArrayOpScript->m_op == ArrayOpScript::LOAD - && (pArrayOpScript->m_flags & ArrayOpScript::HASRETVALBUFFER)))); - - // Cases where we need to copy large values - BOOL fNeedRSIRDI = ( ArgIterator::IsArgPassedByRef(pArrayOpScript->m_elemsize) - && ArrayOpScript::LOADADDR != pArrayOpScript->m_op); - - BOOL fNeedPrologue = ( fNeedScratchArea - || fNeedRSIRDI); -#endif - - X86Reg kValueReg; - - CodeLabel *Epilog = NewCodeLabel(); - CodeLabel *Inner_nullexception = NewCodeLabel(); - CodeLabel *Inner_rangeexception = NewCodeLabel(); - CodeLabel *Inner_typeMismatchexception = NULL; - - // - // Set up the stack frame. - // - // - // x86: - // value - // - // ... - // - // return address - // saved edi - // esp -> saved esi - // - // - // AMD64: - // value, if rank > 2 - // ... - // + 0x48 more indices - // + 0x40 r9 home - // + 0x38 r8 home - // + 0x30 rdx home - // + 0x28 rcx home - // + 0x20 return address - // + 0x18 scratch area (callee's r9) - // + 0x10 scratch area (callee's r8) - // + 8 scratch area (callee's rdx) - // rsp -> scratch area (callee's rcx) - // - // If the element type is a value class w/ object references, then rsi - // and rdi will also be saved above the scratch area: - // - // ... - // + 0x28 saved rsi - // + 0x20 saved rdi - // + 0x18 scratch area (callee's r9) - // + 0x10 scratch area (callee's r8) - // + 8 scratch area (callee's rdx) - // rsp -> scratch area (callee's rcx) - // - // And if no call or movsb is necessary, then the scratch area sits - // directly under the MethodDesc*. - - BOOL fSavedESI = FALSE; - BOOL fSavedEDI = FALSE; - -#ifdef TARGET_AMD64 - if (fNeedPrologue) - { - // Save argument registers if we'll be making a call before using - // them. Note that in this case the element value will always be an - // object type, and never be in an xmm register. - - if ( (pArrayOpScript->m_flags & ArrayOpScript::NEEDSTYPECHECK) - && ArrayOpScript::STORE == pArrayOpScript->m_op) - { - // mov [rsp+0x08], rcx - X86EmitEspOffset(0x89, kRCX, 0x08); - X86EmitEspOffset(0x89, kRDX, 0x10); - X86EmitEspOffset(0x89, kR8, 0x18); - - if (pArrayOpScript->m_rank >= 2) - X86EmitEspOffset(0x89, kR9, 0x20); - } - - if (fNeedRSIRDI) - { - X86EmitPushReg(kRSI); - X86EmitPushReg(kRDI); - - fSavedESI = fSavedEDI = TRUE; - - ofsadjust += 0x10; - } - - if (fNeedScratchArea) - { - // Callee scratch area (0x8 for aligned esp) - X86EmitSubEsp(sizeof(ArgumentRegisters) + 0x8); - ofsadjust += sizeof(ArgumentRegisters) + 0x8; - } - } -#else - // Preserve the callee-saved registers - // NOTE: if you change the sequence of these pushes, you must also update: - // ArrayOpStubNullException - // ArrayOpStubRangeException - // ArrayOpStubTypeMismatchException - _ASSERTE( kTotalReg == kEDI); - X86EmitPushReg(kTotalReg); - _ASSERTE( kFactorReg == kESI); - X86EmitPushReg(kFactorReg); - - fSavedESI = fSavedEDI = TRUE; - - ofsadjust += 2*sizeof(void*); -#endif - - // Check for null. - X86EmitR2ROp(0x85, kArrayRefReg, kArrayRefReg); // TEST ECX, ECX - X86EmitCondJump(Inner_nullexception, X86CondCode::kJZ); // jz Inner_nullexception - - // Do Type Check if needed - if (pArrayOpScript->m_flags & ArrayOpScript::NEEDSTYPECHECK) - { - if (pArrayOpScript->m_op == ArrayOpScript::STORE) - { - // Get the value to be stored. - kValueReg = LoadArrayOpArg(pArrayOpScript->m_fValLoc, this, kEAX, ofsadjust); - - X86EmitR2ROp(0x85, kValueReg, kValueReg); // TEST kValueReg, kValueReg - CodeLabel *CheckPassed = NewCodeLabel(); - X86EmitCondJump(CheckPassed, X86CondCode::kJZ); // storing NULL is OK - - // mov EAX, element type ; possibly trashes kValueReg - X86EmitOp(0x8b, kArrayMTReg, kArrayRefReg, 0 AMD64_ARG(k64BitOp)); // mov ESI/R10, [kArrayRefReg] - - X86EmitOp(0x8b, kEAX, kValueReg, 0 AMD64_ARG(k64BitOp)); // mov EAX, [kValueReg] ; possibly trashes kValueReg - // cmp EAX, [ESI/R10+m_ElementType] - - X86EmitOp(0x3b, kEAX, kArrayMTReg, MethodTable::GetOffsetOfArrayElementTypeHandle() AMD64_ARG(k64BitOp)); - X86EmitCondJump(CheckPassed, X86CondCode::kJZ); // Exact match is OK - - X86EmitRegLoad(kEAX, (UINT_PTR)g_pObjectClass); // mov EAX, g_pObjectMethodTable - // cmp EAX, [ESI/R10+m_ElementType] - - X86EmitOp(0x3b, kEAX, kArrayMTReg, MethodTable::GetOffsetOfArrayElementTypeHandle() AMD64_ARG(k64BitOp)); - X86EmitCondJump(CheckPassed, X86CondCode::kJZ); // Assigning to array of object is OK - - // Try to call the fast helper first ( ObjIsInstanceOfCached ). - // If that fails we will fall back to calling the slow helper ( ArrayStoreCheck ) that erects a frame. - -#ifdef TARGET_AMD64 - // RCX contains pointer to object to check (Object*) - // RDX contains array type handle - - // mov RCX, [rsp+offsetToObject] ; RCX = Object* - X86EmitEspOffset(0x8b, kRCX, ofsadjust + pArrayOpScript->m_fValLoc); - - // get Array TypeHandle - // mov RDX, [RSP+offsetOfTypeHandle] - - X86EmitEspOffset(0x8b, kRDX, ofsadjust - + TransitionBlock::GetOffsetOfArgumentRegisters() - + offsetof(ArgumentRegisters, THIS_REG)); - - // mov RDX, [kArrayMTReg+offsetof(MethodTable, m_ElementType)] - X86EmitIndexRegLoad(kRDX, kArrayMTReg, MethodTable::GetOffsetOfArrayElementTypeHandle()); - -#else - X86EmitPushReg(kEDX); // Save EDX - X86EmitPushReg(kECX); // Pass array object - - X86EmitIndexPush(kArrayMTReg, MethodTable::GetOffsetOfArrayElementTypeHandle()); // push [kArrayMTReg + m_ElementType] ; Array element type handle - - // get address of value to store - _ASSERTE(TransitionBlock::IsStackArgumentOffset(pArrayOpScript->m_fValLoc)); // on x86, value will never get a register - X86EmitSPIndexPush(pArrayOpScript->m_fValLoc + ofsadjust + 3*sizeof(void*)); // push [ESP+offset] ; the object pointer - -#endif //_AMD64 - - - // emit a call to the fast helper - // One side effect of this is that we are going to generate a "jnz Epilog" and we DON'T need it - // in the fast path, however there are no side effects in emitting - // it in the fast path anyway. the reason for that is that it makes - // the cleanup code much easier ( we have only 1 place to cleanup the stack and - // restore it to the original state ) - X86EmitCall(NewExternalCodeLabel((LPVOID)ObjIsInstanceOfCached), 0); - X86EmitCmpRegImm32( kEAX, TypeHandle::CanCast); // CMP EAX, CanCast ; if ObjIsInstanceOfCached returns CanCast, we will go the fast path - CodeLabel * Cleanup = NewCodeLabel(); - X86EmitCondJump(Cleanup, X86CondCode::kJZ); - -#ifdef TARGET_AMD64 - // get address of value to store - // lea rcx, [rsp+offs] - X86EmitEspOffset(0x8d, kRCX, ofsadjust + pArrayOpScript->m_fValLoc); - - // get address of 'this'/rcx - // lea rdx, [rsp+offs] - X86EmitEspOffset(0x8d, kRDX, ofsadjust - + TransitionBlock::GetOffsetOfArgumentRegisters() - + offsetof(ArgumentRegisters, THIS_REG)); - -#else - // The stack is already setup correctly for the slow helper. - _ASSERTE(TransitionBlock::IsStackArgumentOffset(pArrayOpScript->m_fValLoc)); // on x86, value will never get a register - X86EmitEspOffset(0x8d, kECX, pArrayOpScript->m_fValLoc + ofsadjust + 2*sizeof(void*)); // lea ECX, [ESP+offset] - - // get address of 'this' - X86EmitEspOffset(0x8d, kEDX, 0); // lea EDX, [ESP] ; (address of ECX) - - -#endif - AMD64_ONLY(_ASSERTE(fNeedScratchArea)); - X86EmitCall(NewExternalCodeLabel((LPVOID)ArrayStoreCheck), 0); - - EmitLabel(Cleanup); -#ifdef TARGET_AMD64 - X86EmitEspOffset(0x8b, kRCX, 0x00 + ofsadjust + TransitionBlock::GetOffsetOfArgumentRegisters()); - X86EmitEspOffset(0x8b, kRDX, 0x08 + ofsadjust + TransitionBlock::GetOffsetOfArgumentRegisters()); - X86EmitEspOffset(0x8b, kR8, 0x10 + ofsadjust + TransitionBlock::GetOffsetOfArgumentRegisters()); - - if (pArrayOpScript->m_rank >= 2) - X86EmitEspOffset(0x8b, kR9, 0x18 + ofsadjust + TransitionBlock::GetOffsetOfArgumentRegisters()); -#else - X86EmitPopReg(kECX); // restore regs - X86EmitPopReg(kEDX); - - - X86EmitR2ROp(0x3B, kEAX, kEAX); // CMP EAX, EAX - X86EmitCondJump(Epilog, X86CondCode::kJNZ); // This branch never taken, but epilog walker uses it -#endif - - EmitLabel(CheckPassed); - } - else - { - _ASSERTE(pArrayOpScript->m_op == ArrayOpScript::LOADADDR); - - // Load up the hidden type parameter into 'typeReg' - X86Reg typeReg = LoadArrayOpArg(pArrayOpScript->m_typeParamOffs, this, kEAX, ofsadjust); - - // 'typeReg' holds the typeHandle/MethodTable for the ARRAY. - // If 'typeReg' is NULL then we're executing the readonly ::Address and no type check is - // needed. - CodeLabel *Inner_passedTypeCheck = NewCodeLabel(); - - // test typeReg, typeReg - X86EmitR2ROp(0x85, typeReg, typeReg); - X86EmitCondJump(Inner_passedTypeCheck, X86CondCode::kJZ); - - // Compare MT against the MT of the array. - // cmp typeReg, [kArrayRefReg] - X86EmitOp(0x3b, typeReg, kArrayRefReg, 0 AMD64_ARG(k64BitOp)); - - // Throw error if not equal - Inner_typeMismatchexception = NewCodeLabel(); - X86EmitCondJump(Inner_typeMismatchexception, X86CondCode::kJNZ); - EmitLabel(Inner_passedTypeCheck); - } - } - - CodeLabel* DoneCheckLabel = 0; - if (pArrayOpScript->m_rank == 1 && pArrayOpScript->m_fHasLowerBounds) - { - DoneCheckLabel = NewCodeLabel(); - CodeLabel* NotSZArrayLabel = NewCodeLabel(); - - // for rank1 arrays, we might actually have two different layouts depending on - // if we are ELEMENT_TYPE_ARRAY or ELEMENT_TYPE_SZARRAY. - - // mov EAX, [ARRAY] // EAX holds the method table - X86_64BitOperands(); - X86EmitOp(0x8b, kEAX, kArrayRefReg); - - // test [EAX + m_dwFlags], enum_flag_Category_IfArrayThenSzArray - X86_64BitOperands(); - X86EmitOffsetModRM(0xf7, (X86Reg)0, kEAX, MethodTable::GetOffsetOfFlags()); - Emit32(MethodTable::GetIfArrayThenSzArrayFlag()); - - // jz NotSZArrayLabel - X86EmitCondJump(NotSZArrayLabel, X86CondCode::kJZ); - - //Load the passed-in index into the scratch register. - const ArrayOpIndexSpec *pai = pArrayOpScript->GetArrayOpIndexSpecs(); - X86Reg idxReg = LoadArrayOpArg(pai->m_idxloc, this, SCRATCH_REGISTER_X86REG, ofsadjust); - - // cmp idxReg, [kArrayRefReg + LENGTH] - X86EmitOp(0x3b, idxReg, kArrayRefReg, ArrayBase::GetOffsetOfNumComponents()); - - // jae Inner_rangeexception - X86EmitCondJump(Inner_rangeexception, X86CondCode::kJAE); - - // if we cared efficiency of this, this move can be optimized - X86EmitR2ROp(0x8b, kTotalReg, idxReg AMD64_ARG(k32BitOp)); - - // sub ARRAY. 8 // 8 is accounts for the Lower bound and Dim count in the ARRAY - X86EmitSubReg(kArrayRefReg, 8); // adjust this pointer so that indexing works out for SZARRAY - - X86EmitNearJump(DoneCheckLabel); - EmitLabel(NotSZArrayLabel); - } - - // For each index, range-check and mix into accumulated total. - UINT idx = pArrayOpScript->m_rank; - BOOL firstTime = TRUE; - while (idx--) - { - const ArrayOpIndexSpec *pai = pArrayOpScript->GetArrayOpIndexSpecs() + idx; - - //Load the passed-in index into the scratch register. - X86Reg srcreg = LoadArrayOpArg(pai->m_idxloc, this, SCRATCH_REGISTER_X86REG, ofsadjust AMD64_ARG(k32BitOp)); - if (SCRATCH_REGISTER_X86REG != srcreg) - X86EmitR2ROp(0x8b, SCRATCH_REGISTER_X86REG, srcreg AMD64_ARG(k32BitOp)); - - // sub SCRATCH, dword ptr [kArrayRefReg + LOWERBOUND] - if (pArrayOpScript->m_fHasLowerBounds) - { - X86EmitOp(0x2b, SCRATCH_REGISTER_X86REG, kArrayRefReg, pai->m_lboundofs); - } - - // cmp SCRATCH, dword ptr [kArrayRefReg + LENGTH] - X86EmitOp(0x3b, SCRATCH_REGISTER_X86REG, kArrayRefReg, pai->m_lengthofs); - - // jae Inner_rangeexception - X86EmitCondJump(Inner_rangeexception, X86CondCode::kJAE); - - - // SCRATCH == idx - LOWERBOUND - // - // imul SCRATCH, FACTOR - if (!firstTime) - { - //Can skip the first time since FACTOR==1 - X86EmitR2ROp(0xaf0f, SCRATCH_REGISTER_X86REG, kFactorReg AMD64_ARG(k32BitOp)); - } - - // TOTAL += SCRATCH - if (firstTime) - { - // First time, we must zero-init TOTAL. Since - // zero-initing and then adding is just equivalent to a - // "mov", emit a "mov" - // mov TOTAL, SCRATCH - X86EmitR2ROp(0x8b, kTotalReg, SCRATCH_REGISTER_X86REG AMD64_ARG(k32BitOp)); - } - else - { - // add TOTAL, SCRATCH - X86EmitR2ROp(0x03, kTotalReg, SCRATCH_REGISTER_X86REG AMD64_ARG(k32BitOp)); - } - - // FACTOR *= [kArrayRefReg + LENGTH] - if (idx != 0) - { - // No need to update FACTOR on the last iteration - // since we won't use it again - - if (firstTime) - { - // must init FACTOR to 1 first: hence, - // the "imul" becomes a "mov" - // mov FACTOR, [kArrayRefReg + LENGTH] - X86EmitOp(0x8b, kFactorReg, kArrayRefReg, pai->m_lengthofs); - } - else - { - // imul FACTOR, [kArrayRefReg + LENGTH] - X86EmitOp(0xaf0f, kFactorReg, kArrayRefReg, pai->m_lengthofs); - } - } - - firstTime = FALSE; - } - - if (DoneCheckLabel != 0) - EmitLabel(DoneCheckLabel); - - // Pass these values to X86EmitArrayOp() to generate the element address. - X86Reg elemBaseReg = kArrayRefReg; - X86Reg elemScaledReg = kTotalReg; - UINT32 elemSize = pArrayOpScript->m_elemsize; - UINT32 elemOfs = pArrayOpScript->m_ofsoffirst; - - if (!(elemSize == 1 || elemSize == 2 || elemSize == 4 || elemSize == 8)) - { - switch (elemSize) - { - // No way to express this as a SIB byte. Fold the scale - // into TOTAL. - - case 16: - // shl TOTAL,4 - X86EmitR2ROp(0xc1, (X86Reg)4, kTotalReg AMD64_ARG(k32BitOp)); - Emit8(4); - break; - - case 32: - // shl TOTAL,5 - X86EmitR2ROp(0xc1, (X86Reg)4, kTotalReg AMD64_ARG(k32BitOp)); - Emit8(5); - break; - - case 64: - // shl TOTAL,6 - X86EmitR2ROp(0xc1, (X86Reg)4, kTotalReg AMD64_ARG(k32BitOp)); - Emit8(6); - break; - - default: - // imul TOTAL, elemScale - X86EmitR2ROp(0x69, kTotalReg, kTotalReg AMD64_ARG(k32BitOp)); - Emit32(elemSize); - break; - } - elemSize = 1; - } - - _ASSERTE(FitsInU1(elemSize)); - BYTE elemScale = static_cast(elemSize); - - // Now, do the operation: - - switch (pArrayOpScript->m_op) - { - case ArrayOpScript::LOADADDR: - // lea eax, ELEMADDR - X86EmitOp(0x8d, kEAX, elemBaseReg, elemOfs, elemScaledReg, elemScale AMD64_ARG(k64BitOp)); - break; - - case ArrayOpScript::LOAD: - if (pArrayOpScript->m_flags & ArrayOpScript::HASRETVALBUFFER) - { - // Ensure that these registers have been saved! - _ASSERTE(fSavedESI && fSavedEDI); - - //lea esi, ELEMADDR - X86EmitOp(0x8d, kESI, elemBaseReg, elemOfs, elemScaledReg, elemScale AMD64_ARG(k64BitOp)); - - _ASSERTE(!TransitionBlock::IsStackArgumentOffset(pArrayOpScript->m_fRetBufLoc)); - // mov edi, retbufptr - X86EmitR2ROp(0x8b, kEDI, GetX86ArgumentRegisterFromOffset(pArrayOpScript->m_fRetBufLoc - TransitionBlock::GetOffsetOfArgumentRegisters())); - -COPY_VALUE_CLASS: - { - size_t size = pArrayOpScript->m_elemsize; - size_t total = 0; - if(pArrayOpScript->m_gcDesc) - { - CGCDescSeries* cur = pArrayOpScript->m_gcDesc->GetHighestSeries(); - if ((cur->startoffset-elemOfs) > 0) - generate_noref_copy ((unsigned) (cur->startoffset - elemOfs), this); - total += cur->startoffset - elemOfs; - - SSIZE_T cnt = (SSIZE_T) pArrayOpScript->m_gcDesc->GetNumSeries(); - - if (cnt == 1) - { - // all pointers - for (size_t i = 0; i < size; i += sizeof(Object*)) - { - X86EmitCall(NewExternalCodeLabel((LPVOID)JIT_ByRefWriteBarrier), 0); - total += sizeof(Object*); - } - } - else - { - // special array encoding - _ASSERTE(cnt < 0); - - for (SSIZE_T __i = 0; __i > cnt; __i--) - { - HALF_SIZE_T skip = (cur->val_serie + __i)->skip; - HALF_SIZE_T nptrs = (cur->val_serie + __i)->nptrs; - total += nptrs*sizeof (Object*); - do - { - AMD64_ONLY(_ASSERTE(fNeedScratchArea)); - - X86EmitCall(NewExternalCodeLabel((LPVOID) JIT_ByRefWriteBarrier), 0); - } while (--nptrs); - if (skip > 0) - { - //check if we are at the end of the series - if (__i == (cnt + 1)) - skip = skip - (HALF_SIZE_T)(cur->startoffset - elemOfs); - if (skip > 0) - generate_noref_copy (skip, this); - } - total += skip; - } - } - - _ASSERTE (size == total); - } - else - { - // no ref anywhere, just copy the bytes. - _ASSERTE (size); - generate_noref_copy ((unsigned)size, this); - } - } - } - else - { - switch (pArrayOpScript->m_elemsize) - { - case 1: - // mov[zs]x eax, byte ptr ELEMADDR - X86EmitOp(pArrayOpScript->m_signed ? 0xbe0f : 0xb60f, kEAX, elemBaseReg, elemOfs, elemScaledReg, elemScale); - break; - - case 2: - // mov[zs]x eax, word ptr ELEMADDR - X86EmitOp(pArrayOpScript->m_signed ? 0xbf0f : 0xb70f, kEAX, elemBaseReg, elemOfs, elemScaledReg, elemScale); - break; - - case 4: - if (pArrayOpScript->m_flags & ArrayOpScript::ISFPUTYPE) - { -#ifdef TARGET_AMD64 - // movss xmm0, dword ptr ELEMADDR - Emit8(0xf3); - X86EmitOp(0x100f, (X86Reg)0, elemBaseReg, elemOfs, elemScaledReg, elemScale); -#else // !TARGET_AMD64 - // fld dword ptr ELEMADDR - X86EmitOp(0xd9, (X86Reg)0, elemBaseReg, elemOfs, elemScaledReg, elemScale); -#endif // !TARGET_AMD64 - } - else - { - // mov eax, ELEMADDR - X86EmitOp(0x8b, kEAX, elemBaseReg, elemOfs, elemScaledReg, elemScale); - } - break; - - case 8: - if (pArrayOpScript->m_flags & ArrayOpScript::ISFPUTYPE) - { -#ifdef TARGET_AMD64 - // movsd xmm0, qword ptr ELEMADDR - Emit8(0xf2); - X86EmitOp(0x100f, (X86Reg)0, elemBaseReg, elemOfs, elemScaledReg, elemScale); -#else // !TARGET_AMD64 - // fld qword ptr ELEMADDR - X86EmitOp(0xdd, (X86Reg)0, elemBaseReg, elemOfs, elemScaledReg, elemScale); -#endif // !TARGET_AMD64 - } - else - { - // mov eax, ELEMADDR - X86EmitOp(0x8b, kEAX, elemBaseReg, elemOfs, elemScaledReg, elemScale AMD64_ARG(k64BitOp)); -#ifdef TARGET_X86 - // mov edx, ELEMADDR + 4 - X86EmitOp(0x8b, kEDX, elemBaseReg, elemOfs + 4, elemScaledReg, elemScale); -#endif - } - break; - - default: - _ASSERTE(0); - } - } - - break; - - case ArrayOpScript::STORE: - - switch (pArrayOpScript->m_elemsize) - { - case 1: - // mov SCRATCH, [esp + valoffset] - kValueReg = LoadArrayOpArg(pArrayOpScript->m_fValLoc, this, SCRATCH_REGISTER_X86REG, ofsadjust); - // mov byte ptr ELEMADDR, SCRATCH.b - X86EmitOp(0x88, kValueReg, elemBaseReg, elemOfs, elemScaledReg, elemScale); - break; - case 2: - // mov SCRATCH, [esp + valoffset] - kValueReg = LoadArrayOpArg(pArrayOpScript->m_fValLoc, this, SCRATCH_REGISTER_X86REG, ofsadjust); - // mov word ptr ELEMADDR, SCRATCH.w - Emit8(0x66); - X86EmitOp(0x89, kValueReg, elemBaseReg, elemOfs, elemScaledReg, elemScale); - break; - case 4: -#ifndef TARGET_AMD64 - if (pArrayOpScript->m_flags & ArrayOpScript::NEEDSWRITEBARRIER) - { - // mov SCRATCH, [esp + valoffset] - kValueReg = LoadArrayOpArg(pArrayOpScript->m_fValLoc, this, SCRATCH_REGISTER_X86REG, ofsadjust); - - _ASSERTE(SCRATCH_REGISTER_X86REG == kEAX); // value to store is already in EAX where we want it. - // lea edx, ELEMADDR - X86EmitOp(0x8d, kEDX, elemBaseReg, elemOfs, elemScaledReg, elemScale); - - // call JIT_Writeable_Thunks_Buf.WriteBarrierReg[0] (== EAX) - X86EmitCall(NewExternalCodeLabel((LPVOID) GetWriteBarrierCodeLocation(&JIT_WriteBarrierEAX)), 0); - } - else -#else // TARGET_AMD64 - if (pArrayOpScript->m_flags & ArrayOpScript::ISFPUTYPE) - { - if (!TransitionBlock::IsStackArgumentOffset(pArrayOpScript->m_fValLoc)) - { - kValueReg = (X86Reg)TransitionBlock::GetArgumentIndexFromOffset(pArrayOpScript->m_fValLoc); - } - else - { - kValueReg = (X86Reg)0; // xmm0 - - // movss xmm0, dword ptr [rsp+??] - Emit8(0xf3); - X86EmitOp(0x100f, kValueReg, (X86Reg)4 /*rsp*/, ofsadjust + pArrayOpScript->m_fValLoc); - } - - // movss dword ptr ELEMADDR, xmm? - Emit8(0xf3); - X86EmitOp(0x110f, kValueReg, elemBaseReg, elemOfs, elemScaledReg, elemScale); - } - else -#endif // TARGET_AMD64 - { - // mov SCRATCH, [esp + valoffset] - kValueReg = LoadArrayOpArg(pArrayOpScript->m_fValLoc, this, SCRATCH_REGISTER_X86REG, ofsadjust AMD64_ARG(k32BitOp)); - - // mov ELEMADDR, SCRATCH - X86EmitOp(0x89, kValueReg, elemBaseReg, elemOfs, elemScaledReg, elemScale); - } - break; - - case 8: - - if (!(pArrayOpScript->m_flags & ArrayOpScript::NEEDSWRITEBARRIER)) - { -#ifdef TARGET_AMD64 - if (pArrayOpScript->m_flags & ArrayOpScript::ISFPUTYPE) - { - if (!TransitionBlock::IsStackArgumentOffset(pArrayOpScript->m_fValLoc)) - { - kValueReg = (X86Reg)TransitionBlock::GetArgumentIndexFromOffset(pArrayOpScript->m_fValLoc); - } - else - { - kValueReg = (X86Reg)0; // xmm0 - - // movsd xmm0, qword ptr [rsp+??] - Emit8(0xf2); - X86EmitOp(0x100f, kValueReg, (X86Reg)4 /*rsp*/, ofsadjust + pArrayOpScript->m_fValLoc); - } - - // movsd qword ptr ELEMADDR, xmm? - Emit8(0xf2); - X86EmitOp(0x110f, kValueReg, elemBaseReg, elemOfs, elemScaledReg, elemScale); - } - else - { - // mov SCRATCH, [esp + valoffset] - kValueReg = LoadArrayOpArg(pArrayOpScript->m_fValLoc, this, SCRATCH_REGISTER_X86REG, ofsadjust); - - // mov ELEMADDR, SCRATCH - X86EmitOp(0x89, kValueReg, elemBaseReg, elemOfs, elemScaledReg, elemScale, k64BitOp); - } -#else // !TARGET_AMD64 - _ASSERTE(TransitionBlock::IsStackArgumentOffset(pArrayOpScript->m_fValLoc)); // on x86, value will never get a register: so too lazy to implement that case - // mov SCRATCH, [esp + valoffset] - X86EmitEspOffset(0x8b, SCRATCH_REGISTER_X86REG, pArrayOpScript->m_fValLoc + ofsadjust); - // mov ELEMADDR, SCRATCH - X86EmitOp(0x89, SCRATCH_REGISTER_X86REG, elemBaseReg, elemOfs, elemScaledReg, elemScale); - - _ASSERTE(TransitionBlock::IsStackArgumentOffset(pArrayOpScript->m_fValLoc)); // on x86, value will never get a register: so too lazy to implement that case - // mov SCRATCH, [esp + valoffset + 4] - X86EmitEspOffset(0x8b, SCRATCH_REGISTER_X86REG, pArrayOpScript->m_fValLoc + ofsadjust + 4); - // mov ELEMADDR+4, SCRATCH - X86EmitOp(0x89, SCRATCH_REGISTER_X86REG, elemBaseReg, elemOfs+4, elemScaledReg, elemScale); -#endif // !TARGET_AMD64 - break; - } -#ifdef TARGET_AMD64 - else - { - _ASSERTE(SCRATCH_REGISTER_X86REG == kEAX); // value to store is already in EAX where we want it. - // lea rcx, ELEMADDR - X86EmitOp(0x8d, kRCX, elemBaseReg, elemOfs, elemScaledReg, elemScale, k64BitOp); - - // mov rdx, [rsp + valoffset] - kValueReg = LoadArrayOpArg(pArrayOpScript->m_fValLoc, this, kRDX, ofsadjust); - _ASSERT(kRCX != kValueReg); - if (kRDX != kValueReg) - X86EmitR2ROp(0x8b, kRDX, kValueReg); - - _ASSERTE(fNeedScratchArea); - X86EmitCall(NewExternalCodeLabel((PVOID)JIT_WriteBarrier), 0); - break; - } -#endif // TARGET_AMD64 - // FALL THROUGH (on x86) - default: - // Ensure that these registers have been saved! - _ASSERTE(fSavedESI && fSavedEDI); - -#ifdef TARGET_AMD64 - // mov rsi, [rsp + valoffset] - kValueReg = LoadArrayOpArg(pArrayOpScript->m_fValLoc, this, kRSI, ofsadjust); - if (kRSI != kValueReg) - X86EmitR2ROp(0x8b, kRSI, kValueReg); -#else // !TARGET_AMD64 - _ASSERTE(TransitionBlock::IsStackArgumentOffset(pArrayOpScript->m_fValLoc)); - // lea esi, [esp + valoffset] - X86EmitEspOffset(0x8d, kESI, pArrayOpScript->m_fValLoc + ofsadjust); -#endif // !TARGET_AMD64 - - // lea edi, ELEMADDR - X86EmitOp(0x8d, kEDI, elemBaseReg, elemOfs, elemScaledReg, elemScale AMD64_ARG(k64BitOp)); - goto COPY_VALUE_CLASS; - } - break; - - default: - _ASSERTE(0); - } - - EmitLabel(Epilog); - -#ifdef TARGET_AMD64 - if (fNeedPrologue) - { - if (fNeedScratchArea) - { - // Throw away scratch area - X86EmitAddEsp(sizeof(ArgumentRegisters) + 0x8); - } - - if (fSavedEDI) - X86EmitPopReg(kRDI); - - if (fSavedESI) - X86EmitPopReg(kRSI); - } - - X86EmitReturn(0); -#else // !TARGET_AMD64 - // Restore the callee-saved registers - X86EmitPopReg(kFactorReg); - X86EmitPopReg(kTotalReg); - -#ifndef UNIX_X86_ABI - // ret N - X86EmitReturn(pArrayOpScript->m_cbretpop); -#else - X86EmitReturn(0); -#endif -#endif // !TARGET_AMD64 - - // Exception points must clean up the stack for all those extra args. - // kFactorReg and kTotalReg will be popped by the jump targets. - - void *pvExceptionThrowFn; - -#if defined(TARGET_AMD64) -#define ARRAYOP_EXCEPTION_HELPERS(base) { (PVOID)base, (PVOID)base##_RSIRDI, (PVOID)base##_ScratchArea, (PVOID)base##_RSIRDI_ScratchArea } - static void *rgNullExceptionHelpers[] = ARRAYOP_EXCEPTION_HELPERS(ArrayOpStubNullException); - static void *rgRangeExceptionHelpers[] = ARRAYOP_EXCEPTION_HELPERS(ArrayOpStubRangeException); - static void *rgTypeMismatchExceptionHelpers[] = ARRAYOP_EXCEPTION_HELPERS(ArrayOpStubTypeMismatchException); -#undef ARRAYOP_EXCEPTION_HELPERS - - UINT iExceptionHelper = (fNeedRSIRDI ? 1 : 0) + (fNeedScratchArea ? 2 : 0); -#endif // defined(TARGET_AMD64) - - EmitLabel(Inner_nullexception); - -#ifndef TARGET_AMD64 - pvExceptionThrowFn = (LPVOID)ArrayOpStubNullException; - - Emit8(0xb8); // mov EAX, - Emit32(pArrayOpScript->m_cbretpop); -#else //TARGET_AMD64 - pvExceptionThrowFn = rgNullExceptionHelpers[iExceptionHelper]; -#endif //!TARGET_AMD64 - X86EmitNearJump(NewExternalCodeLabel(pvExceptionThrowFn)); - - EmitLabel(Inner_rangeexception); -#ifndef TARGET_AMD64 - pvExceptionThrowFn = (LPVOID)ArrayOpStubRangeException; - Emit8(0xb8); // mov EAX, - Emit32(pArrayOpScript->m_cbretpop); -#else //TARGET_AMD64 - pvExceptionThrowFn = rgRangeExceptionHelpers[iExceptionHelper]; -#endif //!TARGET_AMD64 - X86EmitNearJump(NewExternalCodeLabel(pvExceptionThrowFn)); - - if (Inner_typeMismatchexception != NULL) - { - EmitLabel(Inner_typeMismatchexception); -#ifndef TARGET_AMD64 - pvExceptionThrowFn = (LPVOID)ArrayOpStubTypeMismatchException; - Emit8(0xb8); // mov EAX, - Emit32(pArrayOpScript->m_cbretpop); -#else //TARGET_AMD64 - pvExceptionThrowFn = rgTypeMismatchExceptionHelpers[iExceptionHelper]; -#endif //!TARGET_AMD64 - X86EmitNearJump(NewExternalCodeLabel(pvExceptionThrowFn)); - } -} -#ifdef _PREFAST_ -#pragma warning(pop) -#endif - -#endif // !FEATURE_ARRAYSTUB_AS_IL - #if !defined(FEATURE_STUBS_AS_IL) //=========================================================================== // Emits code to break into debugger diff --git a/src/coreclr/vm/i386/stublinkerx86.h b/src/coreclr/vm/i386/stublinkerx86.h index 35aec1598fd559..38cde92fc9ffd0 100644 --- a/src/coreclr/vm/i386/stublinkerx86.h +++ b/src/coreclr/vm/i386/stublinkerx86.h @@ -6,7 +6,6 @@ #include "stublink.h" -struct ArrayOpScript; class MetaSig; extern PCODE GetPreStubEntryPoint(); @@ -399,15 +398,6 @@ class StubLinkerCPU : public StubLinker VOID EmitShuffleThunk(struct ShuffleEntry *pShuffleEntryArray); -#ifndef FEATURE_ARRAYSTUB_AS_IL - //=========================================================================== - // Emits code to do an array operation. - VOID EmitArrayOpStub(const ArrayOpScript*); - - //Worker function to emit throw helpers for array ops. - VOID EmitArrayOpStubThrow(unsigned exConst, unsigned cbRetArg); -#endif - #ifndef FEATURE_STUBS_AS_IL //=========================================================================== // Emits code to break into debugger diff --git a/src/coreclr/vm/ilstubcache.cpp b/src/coreclr/vm/ilstubcache.cpp index 1d8d14456a1f0b..8d3c4fe20b27f1 100644 --- a/src/coreclr/vm/ilstubcache.cpp +++ b/src/coreclr/vm/ilstubcache.cpp @@ -146,9 +146,7 @@ namespace case DynamicMethodDesc::StubNativeToCLRInterop: return "IL_STUB_ReversePInvoke"; case DynamicMethodDesc::StubCOMToCLRInterop: return "IL_STUB_COMtoCLR"; case DynamicMethodDesc::StubStructMarshalInterop: return "IL_STUB_StructMarshal"; -#ifdef FEATURE_ARRAYSTUB_AS_IL case DynamicMethodDesc::StubArrayOp: return "IL_STUB_Array"; -#endif #ifdef FEATURE_MULTICASTSTUB_AS_IL case DynamicMethodDesc::StubMulticastDelegate: return "IL_STUB_MulticastDelegate_Invoke"; #endif @@ -236,13 +234,11 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa #endif // _DEBUG pMD->m_pResolver = new (pMD->m_pResolver) ILStubResolver(); -#ifdef FEATURE_ARRAYSTUB_AS_IL if (SF_IsArrayOpStub(dwStubFlags)) { pMD->SetILStubType(DynamicMethodDesc::StubArrayOp); } else -#endif #ifdef FEATURE_MULTICASTSTUB_AS_IL if (SF_IsMulticastDelegateStub(dwStubFlags)) { @@ -300,6 +296,11 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa pMD->SetILStubType(DynamicMethodDesc::StubStructMarshalInterop); } else + if (SF_IsVirtualStaticMethodDispatchStub(dwStubFlags)) + { + pMD->SetILStubType(DynamicMethodDesc::StubVirtualStaticMethodDispatch); + } + else { // mark certain types of stub MDs with random flags so ILStubManager recognizes them if (SF_IsReverseStub(dwStubFlags)) @@ -320,13 +321,7 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa } } - if (SF_IsVirtualStaticMethodDispatchStub(dwStubFlags)) - { - pMD->SetILStubType(DynamicMethodDesc::StubVirtualStaticMethodDispatch); - } - // if we made it this far, we can set a more descriptive stub name -#ifdef FEATURE_ARRAYSTUB_AS_IL if (SF_IsArrayOpStub(dwStubFlags)) { switch(dwStubFlags) @@ -341,7 +336,6 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa } } else -#endif { pMD->m_pszMethodName = GetStubMethodName(pMD->GetILStubType()); } diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 95b242b55fc0aa..66d46b10c0c9e3 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -2143,29 +2143,6 @@ HCIMPLEND #include -//=========================================================================== -// This routine is called if the Array store needs a frame constructed -// in order to do the array check. It should only be called from -// the array store check helpers. - -HCIMPL2(LPVOID, ArrayStoreCheck, Object** pElement, PtrArray** pArray) -{ - FCALL_CONTRACT; - - HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, *pElement, *pArray); - - GCStress::MaybeTrigger(); - - // call "Core" version directly since all the callers do the "NoGC" call first and that checks the cache - if (!ObjIsInstanceOfCore(*pElement, (*pArray)->GetArrayElementTypeHandle())) - COMPlusThrow(kArrayTypeMismatchException); - - HELPER_METHOD_FRAME_END(); - - return (LPVOID)0; // Used to aid epilog walker -} -HCIMPLEND - //======================================================================== // // VALUETYPE/BYREF HELPERS diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 488015c37d2d86..ee84883a9a584a 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -1069,8 +1069,6 @@ BOOL OnGcCoverageInterrupt(PT_CONTEXT regs); void DoGcStress (PT_CONTEXT regs, NativeCodeVersion nativeCodeVersion); #endif //HAVE_GCCOVER -EXTERN_C FCDECL2(LPVOID, ArrayStoreCheck, Object** pElement, PtrArray** pArray); - // ppPinnedString: If the string is pinned (e.g. allocated in frozen heap), // the pointer to the pinned string is returned in *ppPinnedPointer. ppPinnedPointer == nullptr // means that the caller does not care whether the string is pinned or not. diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 4642d8d8769da7..488520f2ec3446 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -2432,9 +2432,7 @@ class DynamicMethodDesc : public StoredSigMethodDesc StubNativeToCLRInterop, StubCOMToCLRInterop, StubStructMarshalInterop, -#ifdef FEATURE_ARRAYSTUB_AS_IL StubArrayOp, -#endif #ifdef FEATURE_MULTICASTSTUB_AS_IL StubMulticastDelegate, #endif @@ -2500,6 +2498,7 @@ class DynamicMethodDesc : public StoredSigMethodDesc void SetILStubType(ILStubType type) { _ASSERTE(HasFlags(FlagIsILStub)); + m_dwExtendedFlags &= ~ILStubTypeMask; m_dwExtendedFlags |= type; } diff --git a/src/coreclr/vm/object.h b/src/coreclr/vm/object.h index 412711f8a33bc8..59c3e300b73058 100644 --- a/src/coreclr/vm/object.h +++ b/src/coreclr/vm/object.h @@ -732,9 +732,7 @@ class PtrArray : public ArrayBase } friend class StubLinkerCPU; -#ifdef FEATURE_ARRAYSTUB_AS_IL friend class ArrayOpLinker; -#endif public: OBJECTREF m_Array[1]; }; diff --git a/src/coreclr/vm/typedesc.h b/src/coreclr/vm/typedesc.h index 94f7e99517cc3c..e8d7526bd0b16c 100644 --- a/src/coreclr/vm/typedesc.h +++ b/src/coreclr/vm/typedesc.h @@ -256,9 +256,7 @@ class ParamTypeDesc : public TypeDesc { friend class StubLinkerCPU; -#ifdef FEATURE_ARRAYSTUB_AS_IL friend class ArrayOpLinker; -#endif protected: // the m_typeAndFlags field in TypeDesc tell what kind of parameterized type we have