diff options
Diffstat (limited to 'src/vm/arm/stubs.cpp')
-rw-r--r-- | src/vm/arm/stubs.cpp | 292 |
1 files changed, 53 insertions, 239 deletions
diff --git a/src/vm/arm/stubs.cpp b/src/vm/arm/stubs.cpp index 6d9b3d0dca..e0574762b1 100644 --- a/src/vm/arm/stubs.cpp +++ b/src/vm/arm/stubs.cpp @@ -1403,30 +1403,21 @@ Stub *GenerateInitPInvokeFrameHelper() ThumbReg regThread = ThumbReg(5); ThumbReg regScratch = ThumbReg(6); -#ifdef FEATURE_IMPLICIT_TLS - TLSACCESSMODE mode = TLSACCESS_GENERIC; -#else - TLSACCESSMODE mode = GetTLSAccessMode(GetThreadTLSIndex()); -#endif +#ifdef FEATURE_PAL + // Erect frame to perform call to GetThread + psl->ThumbEmitProlog(1, sizeof(ArgumentRegisters), FALSE); // Save r4 for aligned stack + // Save argument registers around the GetThread call. Don't bother with using ldm/stm since this inefficient path anyway. + for (int reg = 0; reg < 4; reg++) + psl->ThumbEmitStoreRegIndirect(ThumbReg(reg), thumbRegSp, offsetof(ArgumentRegisters, r[reg])); +#endif - if (mode == TLSACCESS_GENERIC) - { - // Erect frame to perform call to GetThread - psl->ThumbEmitProlog(1, sizeof(ArgumentRegisters), FALSE); // Save r4 for aligned stack - - // Save argument registers around the GetThread call. Don't bother with using ldm/stm since this inefficient path anyway. - for (int reg = 0; reg < 4; reg++) - psl->ThumbEmitStoreRegIndirect(ThumbReg(reg), thumbRegSp, offsetof(ArgumentRegisters, r[reg])); - } - - psl->ThumbEmitGetThread(mode, regThread); + psl->ThumbEmitGetThread(regThread); - if (mode == TLSACCESS_GENERIC) - { - for (int reg = 0; reg < 4; reg++) - psl->ThumbEmitLoadRegIndirect(ThumbReg(reg), thumbRegSp, offsetof(ArgumentRegisters, r[reg])); - } +#ifdef FEATURE_PAL + for (int reg = 0; reg < 4; reg++) + psl->ThumbEmitLoadRegIndirect(ThumbReg(reg), thumbRegSp, offsetof(ArgumentRegisters, r[reg])); +#endif // mov [regFrame + FrameInfo.offsetOfGSCookie], GetProcessGSCookie() psl->ThumbEmitMovConstant(regScratch, GetProcessGSCookie()); @@ -1448,82 +1439,36 @@ Stub *GenerateInitPInvokeFrameHelper() psl->ThumbEmitMovConstant(regScratch, 0); psl->ThumbEmitStoreRegIndirect(regScratch, regFrame, FrameInfo.offsetOfReturnAddress - negSpace); - if (mode == TLSACCESS_GENERIC) - { - DWORD cbSavedRegs = sizeof(ArgumentRegisters) + 2 * 4; // r0-r3, r4, lr - psl->ThumbEmitAdd(regScratch, thumbRegSp, cbSavedRegs); - psl->ThumbEmitStoreRegIndirect(regScratch, regFrame, FrameInfo.offsetOfCallSiteSP - negSpace); - } - else - { - // str SP, [regFrame + FrameInfo.offsetOfCallSiteSP] - psl->ThumbEmitStoreRegIndirect(thumbRegSp, regFrame, FrameInfo.offsetOfCallSiteSP - negSpace); - } +#ifdef FEATURE_PAL + DWORD cbSavedRegs = sizeof(ArgumentRegisters) + 2 * 4; // r0-r3, r4, lr + psl->ThumbEmitAdd(regScratch, thumbRegSp, cbSavedRegs); + psl->ThumbEmitStoreRegIndirect(regScratch, regFrame, FrameInfo.offsetOfCallSiteSP - negSpace); +#else + // str SP, [regFrame + FrameInfo.offsetOfCallSiteSP] + psl->ThumbEmitStoreRegIndirect(thumbRegSp, regFrame, FrameInfo.offsetOfCallSiteSP - negSpace); +#endif // mov [regThread + offsetof(Thread, m_pFrame)], regFrame psl->ThumbEmitStoreRegIndirect(regFrame, regThread, offsetof(Thread, m_pFrame)); // leave current Thread in R4 - if (mode == TLSACCESS_GENERIC) - { - psl->ThumbEmitEpilog(); - } - else - { - // Return. The return address has been restored into LR at this point. - // bx lr - psl->ThumbEmitJumpRegister(thumbRegLr); - } +#ifdef FEATURE_PAL + psl->ThumbEmitEpilog(); +#else + // Return. The return address has been restored into LR at this point. + // bx lr + psl->ThumbEmitJumpRegister(thumbRegLr); +#endif // A single process-wide stub that will never unload RETURN psl->Link(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap()); } -void StubLinkerCPU::ThumbEmitGetThread(TLSACCESSMODE mode, ThumbReg dest) +void StubLinkerCPU::ThumbEmitGetThread(ThumbReg dest) { -#ifndef FEATURE_IMPLICIT_TLS - DWORD idxThread = GetThreadTLSIndex(); - - if (mode != TLSACCESS_GENERIC) - { - // mrc p15, 0, dest, c13, c0, 2 - Emit16(0xee1d); - Emit16((WORD)(0x0f50 | (dest << 12))); +#ifdef FEATURE_PAL - if (mode == TLSACCESS_WNT) - { - // ldr dest, [dest, #(WINNT_TLS_OFFSET + (idxThread * sizeof(void*)))] - ThumbEmitLoadRegIndirect(dest, dest, offsetof(TEB, TlsSlots) + (idxThread * sizeof(void*))); - } - else - { - _ASSERTE(mode == TLSACCESS_WNT_HIGH); - - // ldr dest, [dest, #WINNT5_TLSEXPANSIONPTR_OFFSET] - ThumbEmitLoadRegIndirect(dest, dest, offsetof(TEB, TlsExpansionSlots)); - - // ldr dest, [dest + #(idxThread * 4)] - ThumbEmitLoadRegIndirect(dest, dest, (idxThread - TLS_MINIMUM_AVAILABLE) * sizeof(void*)); - } - } - else - { - ThumbEmitMovConstant(ThumbReg(0), idxThread); - -#pragma push_macro("TlsGetValue") -#undef TlsGetValue - ThumbEmitMovConstant(ThumbReg(1), (TADDR)TlsGetValue); -#pragma pop_macro("TlsGetValue") - - ThumbEmitCallRegister(ThumbReg(1)); - - if (dest != ThumbReg(0)) - { - ThumbEmitMovRegReg(dest, ThumbReg(0)); - } - } -#else ThumbEmitMovConstant(ThumbReg(0), (TADDR)GetThread); ThumbEmitCallRegister(ThumbReg(0)); @@ -1532,7 +1477,20 @@ void StubLinkerCPU::ThumbEmitGetThread(TLSACCESSMODE mode, ThumbReg dest) { ThumbEmitMovRegReg(dest, ThumbReg(0)); } -#endif + +#else // FEATURE_PAL + + // mrc p15, 0, dest, c13, c0, 2 + Emit16(0xee1d); + Emit16((WORD)(0x0f50 | (dest << 12))); + + ThumbEmitLoadRegIndirect(dest, dest, offsetof(TEB, ThreadLocalStoragePointer)); + + ThumbEmitLoadRegIndirect(dest, dest, sizeof(void *) * (g_TlsIndex & 0xFFFF)); + + ThumbEmitLoadRegIndirect(dest, dest, (g_TlsIndex & 0x7FFF0000) >> 16); + +#endif // FEATURE_PAL } #endif // CROSSGEN_COMPILE @@ -2537,110 +2495,12 @@ void UMEntryThunkCode::Poison() #ifndef CROSSGEN_COMPILE - -EXTERN_C DWORD gThreadTLSIndex; -EXTERN_C DWORD gAppDomainTLSIndex; - - -EXTERN_C Object* JIT_TrialAllocSFastMP_InlineGetThread(CORINFO_CLASS_HANDLE typeHnd_); -EXTERN_C Object* JIT_BoxFastMP_InlineGetThread (CORINFO_CLASS_HANDLE type, void* unboxedData); -EXTERN_C Object* AllocateStringFastMP_InlineGetThread (CLR_I4 cch); -EXTERN_C Object* JIT_NewArr1OBJ_MP_InlineGetThread (CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size); -EXTERN_C Object* JIT_NewArr1VC_MP_InlineGetThread (CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size); - -EXTERN_C void JIT_TrialAllocSFastMP_InlineGetThread__PatchTLSOffset(); -EXTERN_C void JIT_BoxFastMP_InlineGetThread__PatchTLSOffset(); -EXTERN_C void AllocateStringFastMP_InlineGetThread__PatchTLSOffset(); -EXTERN_C void JIT_NewArr1VC_MP_InlineGetThread__PatchTLSOffset(); -EXTERN_C void JIT_NewArr1OBJ_MP_InlineGetThread__PatchTLSOffset(); - extern "C" void STDCALL JIT_PatchedCodeStart(); extern "C" void STDCALL JIT_PatchedCodeLast(); -#ifndef FEATURE_IMPLICIT_TLS -static const LPVOID InlineGetThreadLocations[] = { - (PVOID)JIT_TrialAllocSFastMP_InlineGetThread__PatchTLSOffset, - (PVOID)JIT_BoxFastMP_InlineGetThread__PatchTLSOffset, - (PVOID)AllocateStringFastMP_InlineGetThread__PatchTLSOffset, - (PVOID)JIT_NewArr1VC_MP_InlineGetThread__PatchTLSOffset, - (PVOID)JIT_NewArr1OBJ_MP_InlineGetThread__PatchTLSOffset, -}; -#endif - -//EXTERN_C Object* JIT_TrialAllocSFastMP(CORINFO_CLASS_HANDLE typeHnd_); -Object* JIT_TrialAllocSFastMP(CORINFO_CLASS_HANDLE typeHnd_); -EXTERN_C Object* JIT_NewArr1OBJ_MP(CORINFO_CLASS_HANDLE arrayMT, INT_PTR size); -EXTERN_C Object* AllocateStringFastMP(CLR_I4 cch); -EXTERN_C Object* JIT_NewArr1VC_MP(CORINFO_CLASS_HANDLE arrayMT, INT_PTR size); -EXTERN_C Object* JIT_BoxFastMP(CORINFO_CLASS_HANDLE type, void* unboxedData); - - -EXTERN_C void JIT_GetSharedNonGCStaticBase__PatchTLSLabel(); -EXTERN_C void JIT_GetSharedNonGCStaticBaseNoCtor__PatchTLSLabel(); -EXTERN_C void JIT_GetSharedGCStaticBase__PatchTLSLabel(); -EXTERN_C void JIT_GetSharedGCStaticBaseNoCtor__PatchTLSLabel(); - -EXTERN_C void JIT_GetSharedNonGCStaticBase_SingleAppDomain(); -EXTERN_C void JIT_GetSharedNonGCStaticBaseNoCtor_SingleAppDomain(); -EXTERN_C void JIT_GetSharedGCStaticBase_SingleAppDomain(); -EXTERN_C void JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain(); - - -static const LPVOID InlineGetAppDomainLocations[] = { - (PVOID)JIT_GetSharedNonGCStaticBase__PatchTLSLabel, - (PVOID)JIT_GetSharedNonGCStaticBaseNoCtor__PatchTLSLabel, - (PVOID)JIT_GetSharedGCStaticBase__PatchTLSLabel, - (PVOID)JIT_GetSharedGCStaticBaseNoCtor__PatchTLSLabel -}; - -#ifndef FEATURE_IMPLICIT_TLS -void FixupInlineGetters(DWORD tlsSlot, const LPVOID * pLocations, int nLocations) -{ - STANDARD_VM_CONTRACT; - - for (int i=0; i<nLocations; i++) - { - BYTE * pInlineGetter = (BYTE *)PCODEToPINSTR(GetEEFuncEntryPoint(pLocations[i])); - - DWORD offset = (tlsSlot * sizeof(LPVOID) + offsetof(TEB, TlsSlots)); - - // ldr r??, [r??, #offset] - _ASSERTE_ALL_BUILDS("clr/src/VM/arm/stubs.cpp", - pInlineGetter[0] == 0x1d && - pInlineGetter[1] == 0xee && - pInlineGetter[2] == 0x50 && - pInlineGetter[5] == 0xf8 && - "Initialization failure while stomping instructions for the TLS slot offset: " - "the instruction at the given offset did not match what we expect"); - - *((WORD*)(pInlineGetter + 6)) &= 0xf000; - - _ASSERTE(offset <=4095); - *((WORD*)(pInlineGetter + 6)) |= (WORD)offset; - } -} -#endif - void InitJITHelpers1() { STANDARD_VM_CONTRACT; - -#ifndef FEATURE_IMPLICIT_TLS - - if (gThreadTLSIndex < TLS_MINIMUM_AVAILABLE) - { - FixupInlineGetters(gThreadTLSIndex, InlineGetThreadLocations, COUNTOF(InlineGetThreadLocations)); - } - - if (gAppDomainTLSIndex < TLS_MINIMUM_AVAILABLE) - { - FixupInlineGetters(gAppDomainTLSIndex, InlineGetAppDomainLocations, COUNTOF(InlineGetAppDomainLocations)); - } - - if(gThreadTLSIndex < TLS_MINIMUM_AVAILABLE || gAppDomainTLSIndex < TLS_MINIMUM_AVAILABLE) - { - FlushInstructionCache(GetCurrentProcess(), JIT_PatchedCodeStart, (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart); - } #if CHECK_APP_DOMAIN_LEAKS if(g_pConfig->AppDomainLeaks()) @@ -2655,54 +2515,14 @@ void InitJITHelpers1() #endif // _DEBUG )) { - _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts()); - // If the TLS for Thread is low enough use the super-fast helpers - if (gThreadTLSIndex < TLS_MINIMUM_AVAILABLE) - { - SetJitHelperFunction(CORINFO_HELP_NEWSFAST, JIT_TrialAllocSFastMP_InlineGetThread); - SetJitHelperFunction(CORINFO_HELP_BOX, JIT_BoxFastMP_InlineGetThread); - SetJitHelperFunction(CORINFO_HELP_NEWARR_1_VC, JIT_NewArr1VC_MP_InlineGetThread); - SetJitHelperFunction(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1OBJ_MP_InlineGetThread); - ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateStringFastMP_InlineGetThread), ECall::FastAllocateString); - } - else - { -/* - SetJitHelperFunction(CORINFO_HELP_NEWSFAST, JIT_TrialAllocSFastMP); - SetJitHelperFunction(CORINFO_HELP_BOX, JIT_BoxFastMP); - SetJitHelperFunction(CORINFO_HELP_NEWARR_1_VC, JIT_NewArr1VC_MP); - SetJitHelperFunction(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1OBJ_MP); + SetJitHelperFunction(CORINFO_HELP_NEWSFAST, JIT_NewS_MP_FastPortable); + SetJitHelperFunction(CORINFO_HELP_NEWARR_1_VC, JIT_NewArr1VC_MP_FastPortable); + SetJitHelperFunction(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1OBJ_MP_FastPortable); - ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateStringFastMP), ECall::FastAllocateString); -*/ - } + ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateString_MP_FastPortable), ECall::FastAllocateString); } - - - if(IsSingleAppDomain()) - { - SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE, JIT_GetSharedGCStaticBase_SingleAppDomain); - SetJitHelperFunction(CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE, JIT_GetSharedNonGCStaticBase_SingleAppDomain); - SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR, JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain); - SetJitHelperFunction(CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR,JIT_GetSharedNonGCStaticBaseNoCtor_SingleAppDomain); - } - else - if (gAppDomainTLSIndex >= TLS_MINIMUM_AVAILABLE) - { - SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE, JIT_GetSharedGCStaticBase_Portable); - SetJitHelperFunction(CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE, JIT_GetSharedNonGCStaticBase_Portable); - SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR, JIT_GetSharedGCStaticBaseNoCtor_Portable); - SetJitHelperFunction(CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR,JIT_GetSharedNonGCStaticBaseNoCtor_Portable); - } -#endif -} - -extern "C" Object *SetAppDomainInObject(Object *pObject) -{ - pObject->SetAppDomain(); - return pObject; } // +64 stack-based arguments here @@ -3041,19 +2861,13 @@ void StubLinkerCPU::EmitStubLinkFrame(TADDR pFrameVptr, int offsetOfFrame, int o // str r6, [r4 + #offsetof(MulticastFrame, m_Next)] // str r4, [r5 + #offsetof(Thread, m_pFrame)] -#ifdef FEATURE_IMPLICIT_TLS - TLSACCESSMODE mode = TLSACCESS_GENERIC; -#else - TLSACCESSMODE mode = GetTLSAccessMode(GetThreadTLSIndex()); + ThumbEmitGetThread(ThumbReg(5)); +#ifdef FEATURE_PAL + // reload argument registers that could have been corrupted by the call + for (int reg = 0; reg < 4; reg++) + ThumbEmitLoadRegIndirect(ThumbReg(reg), ThumbReg(4), + offsetOfTransitionBlock + TransitionBlock::GetOffsetOfArgumentRegisters() + offsetof(ArgumentRegisters, r[reg])); #endif - ThumbEmitGetThread(mode, ThumbReg(5)); - if (mode == TLSACCESS_GENERIC) - { - // reload argument registers that could have been corrupted by the call - for (int reg = 0; reg < 4; reg++) - ThumbEmitLoadRegIndirect(ThumbReg(reg), ThumbReg(4), - offsetOfTransitionBlock + TransitionBlock::GetOffsetOfArgumentRegisters() + offsetof(ArgumentRegisters, r[reg])); - } ThumbEmitLoadRegIndirect(ThumbReg(6), ThumbReg(5), Thread::GetOffsetOfCurrentFrame()); ThumbEmitStoreRegIndirect(ThumbReg(6), ThumbReg(4), Frame::GetOffsetOfNextLink()); |