diff options
author | Jan Kotas <jkotas@microsoft.com> | 2017-10-11 13:04:43 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-11 13:04:43 -0700 |
commit | 27a25bd37fa1fe6201c27709b1884e1b328f8beb (patch) | |
tree | 18b7773a7d8e18cca609417940804d8dff491da2 /src/vm/i386 | |
parent | d07f1b24c4a69e6a205f8510f3dcfae0ad96aae8 (diff) | |
download | coreclr-27a25bd37fa1fe6201c27709b1884e1b328f8beb.tar.gz coreclr-27a25bd37fa1fe6201c27709b1884e1b328f8beb.tar.bz2 coreclr-27a25bd37fa1fe6201c27709b1884e1b328f8beb.zip |
Delete !FEATURE_IMPLICIT_TLS (#14398)
Linux and Windows arm64 are using the regular C/C++ thread local statics. This change unifies the remaining Windows architectures to be on the same plan.
Diffstat (limited to 'src/vm/i386')
-rw-r--r-- | src/vm/i386/asmconstants.h | 3 | ||||
-rw-r--r-- | src/vm/i386/asmhelpers.asm | 63 | ||||
-rw-r--r-- | src/vm/i386/cgencpu.h | 15 | ||||
-rw-r--r-- | src/vm/i386/cgenx86.cpp | 2 | ||||
-rw-r--r-- | src/vm/i386/jithelp.asm | 51 | ||||
-rw-r--r-- | src/vm/i386/jitinterfacex86.cpp | 47 | ||||
-rw-r--r-- | src/vm/i386/stublinkerx86.cpp | 229 | ||||
-rw-r--r-- | src/vm/i386/stublinkerx86.h | 8 |
8 files changed, 40 insertions, 378 deletions
diff --git a/src/vm/i386/asmconstants.h b/src/vm/i386/asmconstants.h index f7d5f709dc..aa420428f7 100644 --- a/src/vm/i386/asmconstants.h +++ b/src/vm/i386/asmconstants.h @@ -317,9 +317,6 @@ ASMCONSTANTS_C_ASSERT(ASM__VTABLE_SLOTS_PER_CHUNK == VTABLE_SLOTS_PER_CHUNK) #define ASM__VTABLE_SLOTS_PER_CHUNK_LOG2 3 ASMCONSTANTS_C_ASSERT(ASM__VTABLE_SLOTS_PER_CHUNK_LOG2 == VTABLE_SLOTS_PER_CHUNK_LOG2) -#define TLS_GETTER_MAX_SIZE_ASM DBG_FRE(0x20, 0x10) -ASMCONSTANTS_C_ASSERT(TLS_GETTER_MAX_SIZE_ASM == TLS_GETTER_MAX_SIZE) - #define JIT_TailCall_StackOffsetToFlags 0x08 #define CallDescrData__pSrc 0x00 diff --git a/src/vm/i386/asmhelpers.asm b/src/vm/i386/asmhelpers.asm index 9df33219ac..17d521fb92 100644 --- a/src/vm/i386/asmhelpers.asm +++ b/src/vm/i386/asmhelpers.asm @@ -47,23 +47,10 @@ endif ; FEATURE_COMINTEROP EXTERN __alloca_probe:PROC EXTERN _NDirectImportWorker@4:PROC EXTERN _UMThunkStubRareDisableWorker@8:PROC -ifndef FEATURE_IMPLICIT_TLS -ifdef ENABLE_GET_THREAD_GENERIC_FULL_CHECK -; This is defined in C (threads.cpp) and enforces EE_THREAD_NOT_REQUIRED contracts -GetThreadGenericFullCheck EQU ?GetThreadGenericFullCheck@@YGPAVThread@@XZ -EXTERN GetThreadGenericFullCheck:PROC -endif ; ENABLE_GET_THREAD_GENERIC_FULL_CHECK - -EXTERN _gThreadTLSIndex:DWORD -EXTERN _gAppDomainTLSIndex:DWORD -endif ; FEATURE_IMPLICIT_TLS EXTERN _VarargPInvokeStubWorker@12:PROC EXTERN _GenericPInvokeCalliStubWorker@12:PROC -EXTERN _GetThread@0:PROC -EXTERN _GetAppDomain@0:PROC - ifdef MDA_SUPPORTED EXTERN _PInvokeStackImbalanceWorker@8:PROC endif @@ -716,56 +703,6 @@ doRet: FASTCALL_ENDFUNC HelperMethodFrameRestoreState -ifndef FEATURE_IMPLICIT_TLS -;--------------------------------------------------------------------------- -; Portable GetThread() function: used if no platform-specific optimizations apply. -; This is in assembly code because we count on edx not getting trashed on calls -; to this function. -;--------------------------------------------------------------------------- -; Thread* __stdcall GetThreadGeneric(void); -GetThreadGeneric PROC stdcall public USES ecx edx - -ifdef _DEBUG - cmp dword ptr [_gThreadTLSIndex], -1 - jnz @F - int 3 -@@: -endif -ifdef ENABLE_GET_THREAD_GENERIC_FULL_CHECK - ; non-PAL, debug-only GetThreadGeneric should defer to GetThreadGenericFullCheck - ; to do extra contract enforcement. (See GetThreadGenericFullCheck for details.) - ; This code is intentionally not added to asmhelper.s, as this enforcement is only - ; implemented for non-PAL builds. - call GetThreadGenericFullCheck -else - push dword ptr [_gThreadTLSIndex] - call dword ptr [__imp__TlsGetValue@4] -endif - ret -GetThreadGeneric ENDP - -;--------------------------------------------------------------------------- -; Portable GetAppdomain() function: used if no platform-specific optimizations apply. -; This is in assembly code because we count on edx not getting trashed on calls -; to this function. -;--------------------------------------------------------------------------- -; Appdomain* __stdcall GetAppDomainGeneric(void); -GetAppDomainGeneric PROC stdcall public USES ecx edx - -ifdef _DEBUG - cmp dword ptr [_gAppDomainTLSIndex], -1 - jnz @F - int 3 -@@: -endif - - push dword ptr [_gAppDomainTLSIndex] - call dword ptr [__imp__TlsGetValue@4] - ret -GetAppDomainGeneric ENDP -endif - - ifdef FEATURE_HIJACK ; A JITted method's return address was hijacked to return to us here. diff --git a/src/vm/i386/cgencpu.h b/src/vm/i386/cgencpu.h index 5360b3eb0e..ffdfb82b14 100644 --- a/src/vm/i386/cgencpu.h +++ b/src/vm/i386/cgencpu.h @@ -108,14 +108,6 @@ BOOL Runtime_Test_For_SSE2(); #define ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE 4 #define CALLDESCR_ARGREGS 1 // CallDescrWorker has ArgumentRegister parameter -// Max size of patched TLS helpers -#ifdef _DEBUG -// Debug build needs extra space for last error trashing -#define TLS_GETTER_MAX_SIZE 0x20 -#else -#define TLS_GETTER_MAX_SIZE 0x10 -#endif - //======================================================================= // IMPORTANT: This value is used to figure out how much to allocate // for a fixed array of FieldMarshaler's. That means it must be at least @@ -558,6 +550,12 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode) return TRUE; } +// +// JIT HELPER ALIASING FOR PORTABILITY. +// +// Create alias for optimized implementations of helpers provided on this platform +// + // optimized static helpers generated dynamically at runtime // #define JIT_GetSharedGCStaticBase // #define JIT_GetSharedNonGCStaticBase @@ -573,4 +571,5 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode) #define JIT_NewCrossContext JIT_NewCrossContext #define JIT_Stelem_Ref JIT_Stelem_Ref #endif // FEATURE_PAL + #endif // __cgenx86_h__ diff --git a/src/vm/i386/cgenx86.cpp b/src/vm/i386/cgenx86.cpp index 3b523c9c28..c91a716137 100644 --- a/src/vm/i386/cgenx86.cpp +++ b/src/vm/i386/cgenx86.cpp @@ -1076,7 +1076,7 @@ Stub *GenerateInitPInvokeFrameHelper() unsigned negSpace = FrameInfo.offsetOfFrameVptr; // mov esi, GetThread() - psl->X86EmitCurrentThreadFetch(kESI, (1<<kEDI)|(1<<kEBX)|(1<<kECX)|(1<<kEDX)); + psl->X86EmitCurrentThreadFetch(kESI); // mov [edi + FrameInfo.offsetOfGSCookie], GetProcessGSCookie() psl->X86EmitOffsetModRM(0xc7, (X86Reg)0x0, kEDI, FrameInfo.offsetOfGSCookie - negSpace); diff --git a/src/vm/i386/jithelp.asm b/src/vm/i386/jithelp.asm index 85e824040a..5d64b18c94 100644 --- a/src/vm/i386/jithelp.asm +++ b/src/vm/i386/jithelp.asm @@ -2,11 +2,6 @@ ; The .NET Foundation licenses this file to you under the MIT license. ; See the LICENSE file in the project root for more information. -; ==++== -; - -; -; ==--== ; *********************************************************************** ; File: JIThelp.asm ; @@ -70,13 +65,11 @@ endif EXTERN _g_TailCallFrameVptr:DWORD EXTERN @JIT_FailFast@0:PROC EXTERN _s_gsCookie:DWORD +EXTERN _GetThread@0:PROC EXTERN @JITutil_IsInstanceOfInterface@8:PROC EXTERN @JITutil_ChkCastInterface@8:PROC EXTERN @JITutil_IsInstanceOfAny@8:PROC EXTERN @JITutil_ChkCastAny@8:PROC -ifdef FEATURE_IMPLICIT_TLS -EXTERN _GetThread@0:PROC -endif ifdef WRITE_BARRIER_CHECK ; Those global variables are always defined, but should be 0 for Server GC @@ -963,13 +956,15 @@ NewArgs equ 20 ; extra space is incremented as we push things on the stack along the way ExtraSpace = 0 - call _GetThread@0; eax = Thread* - push eax ; Thread* + push 0 ; Thread* ; save ArgumentRegisters push ecx push edx + call _GetThread@0; eax = Thread* + mov [esp + 8], eax + ExtraSpace = 12 ; pThread, ecx, edx ifdef FEATURE_HIJACK @@ -1247,44 +1242,8 @@ _JIT_PatchedCodeStart@0 proc public ret _JIT_PatchedCodeStart@0 endp -; -; Optimized TLS getters -; - - ALIGN 4 - -ifndef FEATURE_IMPLICIT_TLS -_GetThread@0 proc public - ; This will be overwritten at runtime with optimized GetThread implementation - jmp short _GetTLSDummy@0 - ; Just allocate space that will be filled in at runtime - db (TLS_GETTER_MAX_SIZE_ASM - 2) DUP (0CCh) -_GetThread@0 endp - - ALIGN 4 - -_GetAppDomain@0 proc public - ; This will be overwritten at runtime with optimized GetAppDomain implementation - jmp short _GetTLSDummy@0 - ; Just allocate space that will be filled in at runtime - db (TLS_GETTER_MAX_SIZE_ASM - 2) DUP (0CCh) -_GetAppDomain@0 endp - -_GetTLSDummy@0 proc public - xor eax,eax - ret -_GetTLSDummy@0 endp - ALIGN 4 -_ClrFlsGetBlock@0 proc public - ; This will be overwritten at runtime with optimized ClrFlsGetBlock implementation - jmp short _GetTLSDummy@0 - ; Just allocate space that will be filled in at runtime - db (TLS_GETTER_MAX_SIZE_ASM - 2) DUP (0CCh) -_ClrFlsGetBlock@0 endp -endif - ;********************************************************************** ; Write barriers generated at runtime diff --git a/src/vm/i386/jitinterfacex86.cpp b/src/vm/i386/jitinterfacex86.cpp index 8463b084ac..1b470c9533 100644 --- a/src/vm/i386/jitinterfacex86.cpp +++ b/src/vm/i386/jitinterfacex86.cpp @@ -539,7 +539,7 @@ void JIT_TrialAlloc::EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel * && "EAX should contain size for allocation and it doesnt!!!"); // Fetch current thread into EDX, preserving EAX and ECX - psl->X86EmitCurrentThreadFetch(kEDX, (1<<kEAX)|(1<<kECX)); + psl->X86EmitCurrentThreadFetch(kEDX); // Try the allocation. @@ -1253,7 +1253,7 @@ FastPrimitiveArrayAllocatorFuncPtr fastPrimitiveArrayAllocator = UnframedAllocat // "init" should be the address of a routine which takes an argument of // the module domain ID, the class domain ID, and returns the static base pointer -void EmitFastGetSharedStaticBase(CPUSTUBLINKER *psl, CodeLabel *init, bool bCCtorCheck, bool bGCStatic, bool bSingleAppDomain) +void EmitFastGetSharedStaticBase(CPUSTUBLINKER *psl, CodeLabel *init, bool bCCtorCheck, bool bGCStatic) { STANDARD_VM_CONTRACT; @@ -1267,35 +1267,6 @@ void EmitFastGetSharedStaticBase(CPUSTUBLINKER *psl, CodeLabel *init, bool bCCto psl->Emit8(0x89); psl->Emit8(0xc8); - if(!bSingleAppDomain) - { - // Check tag - CodeLabel *cctorCheck = psl->NewCodeLabel(); - - - // test eax, 1 - psl->Emit8(0xa9); - psl->Emit32(1); - - // jz cctorCheck - psl->X86EmitCondJump(cctorCheck, X86CondCode::kJZ); - - // mov eax GetAppDomain() - psl->X86EmitCurrentAppDomainFetch(kEAX, (1<<kECX)|(1<<kEDX)); - - // mov eax [eax->m_sDomainLocalBlock.m_pModuleSlots] - psl->X86EmitIndexRegLoad(kEAX, kEAX, (__int32) AppDomain::GetOffsetOfModuleSlotsPointer()); - - // Note: weird address arithmetic effectively does: - // shift over 1 to remove tag bit (which is always 1), then multiply by 4. - // mov eax [eax + ecx*2 - 2] - psl->X86EmitOp(0x8b, kEAX, kEAX, -2, kECX, 2); - - // cctorCheck: - psl->EmitLabel(cctorCheck); - - } - if (bCCtorCheck) { // test [eax + edx + offsetof(DomainLocalModule, m_pDataBlob], ClassInitFlags::INITIALIZED_FLAG // Is class inited @@ -1356,7 +1327,7 @@ void EmitFastGetSharedStaticBase(CPUSTUBLINKER *psl, CodeLabel *init, bool bCCto } -void *GenFastGetSharedStaticBase(bool bCheckCCtor, bool bGCStatic, bool bSingleAppDomain) +void *GenFastGetSharedStaticBase(bool bCheckCCtor, bool bGCStatic) { STANDARD_VM_CONTRACT; @@ -1372,7 +1343,7 @@ void *GenFastGetSharedStaticBase(bool bCheckCCtor, bool bGCStatic, bool bSingleA init = sl.NewExternalCodeLabel((LPVOID)JIT_GetSharedNonGCStaticBase); } - EmitFastGetSharedStaticBase(&sl, init, bCheckCCtor, bGCStatic, bSingleAppDomain); + EmitFastGetSharedStaticBase(&sl, init, bCheckCCtor, bGCStatic); Stub *pStub = sl.Link(SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap()); @@ -1521,16 +1492,14 @@ void InitJITHelpers1() //UnframedAllocateString; } - bool bSingleAppDomain = IsSingleAppDomain(); - // Replace static helpers with faster assembly versions - pMethodAddresses[6] = GenFastGetSharedStaticBase(true, true, bSingleAppDomain); + pMethodAddresses[6] = GenFastGetSharedStaticBase(true, true); SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE, pMethodAddresses[6]); - pMethodAddresses[7] = GenFastGetSharedStaticBase(true, false, bSingleAppDomain); + pMethodAddresses[7] = GenFastGetSharedStaticBase(true, false); SetJitHelperFunction(CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE, pMethodAddresses[7]); - pMethodAddresses[8] = GenFastGetSharedStaticBase(false, true, bSingleAppDomain); + pMethodAddresses[8] = GenFastGetSharedStaticBase(false, true); SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR, pMethodAddresses[8]); - pMethodAddresses[9] = GenFastGetSharedStaticBase(false, false, bSingleAppDomain); + pMethodAddresses[9] = GenFastGetSharedStaticBase(false, false); SetJitHelperFunction(CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR, pMethodAddresses[9]); ETW::MethodLog::StubsInitialized(pMethodAddresses, (PVOID *)pHelperNames, ETW_NUM_JIT_HELPERS); diff --git a/src/vm/i386/stublinkerx86.cpp b/src/vm/i386/stublinkerx86.cpp index b77609822b..3b376be26d 100644 --- a/src/vm/i386/stublinkerx86.cpp +++ b/src/vm/i386/stublinkerx86.cpp @@ -2320,7 +2320,7 @@ static const X86Reg c_argRegs[] = { #ifndef CROSSGEN_COMPILE -#if defined(_DEBUG) && (defined(_TARGET_AMD64_) || defined(_TARGET_X86_)) && !defined(FEATURE_PAL) +#if defined(_DEBUG) && !defined(FEATURE_PAL) void StubLinkerCPU::EmitJITHelperLoggingThunk(PCODE pJitHelper, LPVOID helperFuncCount) { STANDARD_VM_CONTRACT; @@ -2358,181 +2358,36 @@ void StubLinkerCPU::EmitJITHelperLoggingThunk(PCODE pJitHelper, LPVOID helperFun #endif X86EmitTailcallWithSinglePop(NewExternalCodeLabel(pJitHelper), kECX); } -#endif // _DEBUG && (_TARGET_AMD64_ || _TARGET_X86_) && !FEATURE_PAL +#endif // _DEBUG && !FEATURE_PAL -#ifndef FEATURE_IMPLICIT_TLS -//--------------------------------------------------------------- -// Emit code to store the current Thread structure in dstreg -// preservedRegSet is a set of registers to be preserved -// TRASHES EAX, EDX, ECX unless they are in preservedRegSet. -// RESULTS dstreg = current Thread -//--------------------------------------------------------------- -VOID StubLinkerCPU::X86EmitTLSFetch(DWORD idx, X86Reg dstreg, unsigned preservedRegSet) +#if !defined(FEATURE_STUBS_AS_IL) +VOID StubLinkerCPU::X86EmitCurrentThreadFetch(X86Reg dstreg) { CONTRACTL { STANDARD_VM_CHECK; - // It doesn't make sense to have the destination register be preserved - PRECONDITION((preservedRegSet & (1<<dstreg)) == 0); AMD64_ONLY(PRECONDITION(dstreg < 8)); // code below doesn't support high registers } CONTRACTL_END; - TLSACCESSMODE mode = GetTLSAccessMode(idx); - -#ifdef _DEBUG - { - static BOOL f = TRUE; - f = !f; - if (f) - { - mode = TLSACCESS_GENERIC; - } - } -#endif - - switch (mode) - { - case TLSACCESS_WNT: - { - unsigned __int32 tlsofs = offsetof(TEB, TlsSlots) + (idx * sizeof(void*)); -#ifdef _TARGET_AMD64_ - BYTE code[] = {0x65,0x48,0x8b,0x04,0x25}; // mov dstreg, qword ptr gs:[IMM32] - static const int regByteIndex = 3; -#elif defined(_TARGET_X86_) - BYTE code[] = {0x64,0x8b,0x05}; // mov dstreg, dword ptr fs:[IMM32] - static const int regByteIndex = 2; -#endif - code[regByteIndex] |= (dstreg << 3); - - EmitBytes(code, sizeof(code)); - Emit32(tlsofs); - } - break; - - case TLSACCESS_GENERIC: - - X86EmitPushRegs(preservedRegSet & ((1<<kEAX)|(1<<kEDX)|(1<<kECX))); - - X86EmitPushImm32(idx); #ifdef _TARGET_AMD64_ - X86EmitPopReg (kECX); // arg in reg -#endif - - // call TLSGetValue - X86EmitCall(NewExternalCodeLabel((LPVOID) TlsGetValue), sizeof(void*)); - - // mov dstreg, eax - X86EmitMovRegReg(dstreg, kEAX); - - X86EmitPopRegs(preservedRegSet & ((1<<kEAX)|(1<<kEDX)|(1<<kECX))); - - break; - - default: - _ASSERTE(0); - } - -#ifdef _DEBUG - // Trash caller saved regs that we were not told to preserve, and that aren't the dstreg. - preservedRegSet |= 1<<dstreg; - if (!(preservedRegSet & (1<<kEAX))) - X86EmitDebugTrashReg(kEAX); - if (!(preservedRegSet & (1<<kEDX))) - X86EmitDebugTrashReg(kEDX); - if (!(preservedRegSet & (1<<kECX))) - X86EmitDebugTrashReg(kECX); -#endif - -} -#endif // FEATURE_IMPLICIT_TLS - -VOID StubLinkerCPU::X86EmitCurrentThreadFetch(X86Reg dstreg, unsigned preservedRegSet) -{ - CONTRACTL - { - STANDARD_VM_CHECK; - - // It doesn't make sense to have the destination register be preserved - PRECONDITION((preservedRegSet & (1<<dstreg)) == 0); - AMD64_ONLY(PRECONDITION(dstreg < 8)); // code below doesn't support high registers - } - CONTRACTL_END; - -#ifdef FEATURE_IMPLICIT_TLS - - X86EmitPushRegs(preservedRegSet & ((1<<kEAX)|(1<<kEDX)|(1<<kECX))); - - //TODO: Inline the instruction instead of a call - // call GetThread - X86EmitCall(NewExternalCodeLabel((LPVOID) GetThread), sizeof(void*)); - - // mov dstreg, eax - X86EmitMovRegReg(dstreg, kEAX); - - X86EmitPopRegs(preservedRegSet & ((1<<kEAX)|(1<<kEDX)|(1<<kECX))); - -#ifdef _DEBUG - // Trash caller saved regs that we were not told to preserve, and that aren't the dstreg. - preservedRegSet |= 1<<dstreg; - if (!(preservedRegSet & (1<<kEAX))) - X86EmitDebugTrashReg(kEAX); - if (!(preservedRegSet & (1<<kEDX))) - X86EmitDebugTrashReg(kEDX); - if (!(preservedRegSet & (1<<kECX))) - X86EmitDebugTrashReg(kECX); -#endif // _DEBUG - -#else // FEATURE_IMPLICIT_TLS - - X86EmitTLSFetch(GetThreadTLSIndex(), dstreg, preservedRegSet); - -#endif // FEATURE_IMPLICIT_TLS - -} - -VOID StubLinkerCPU::X86EmitCurrentAppDomainFetch(X86Reg dstreg, unsigned preservedRegSet) -{ - CONTRACTL - { - STANDARD_VM_CHECK; - - // It doesn't make sense to have the destination register be preserved - PRECONDITION((preservedRegSet & (1<<dstreg)) == 0); - AMD64_ONLY(PRECONDITION(dstreg < 8)); // code below doesn't support high registers - } - CONTRACTL_END; - -#ifdef FEATURE_IMPLICIT_TLS - X86EmitPushRegs(preservedRegSet & ((1<<kEAX)|(1<<kEDX)|(1<<kECX))); - - //TODO: Inline the instruction instead of a call - // call GetThread - X86EmitCall(NewExternalCodeLabel((LPVOID) GetAppDomain), sizeof(void*)); - - // mov dstreg, eax - X86EmitMovRegReg(dstreg, kEAX); - - X86EmitPopRegs(preservedRegSet & ((1<<kEAX)|(1<<kEDX)|(1<<kECX))); - -#ifdef _DEBUG - // Trash caller saved regs that we were not told to preserve, and that aren't the dstreg. - preservedRegSet |= 1<<dstreg; - if (!(preservedRegSet & (1<<kEAX))) - X86EmitDebugTrashReg(kEAX); - if (!(preservedRegSet & (1<<kEDX))) - X86EmitDebugTrashReg(kEDX); - if (!(preservedRegSet & (1<<kECX))) - X86EmitDebugTrashReg(kECX); + BYTE code[] = { 0x65,0x48,0x8b,0x04,0x25 }; // mov dstreg, qword ptr gs:[IMM32] + static const int regByteIndex = 3; +#elif defined(_TARGET_X86_) + BYTE code[] = { 0x64,0x8b,0x05 }; // mov dstreg, dword ptr fs:[IMM32] + static const int regByteIndex = 2; #endif + code[regByteIndex] |= (dstreg << 3); -#else // FEATURE_IMPLICIT_TLS + EmitBytes(code, sizeof(code)); + Emit32(offsetof(TEB, ThreadLocalStoragePointer)); - X86EmitTLSFetch(GetAppDomainTLSIndex(), dstreg, preservedRegSet); + X86EmitIndexRegLoad(dstreg, dstreg, sizeof(void *) * (g_TlsIndex & 0xFFFF)); -#endif // FEATURE_IMPLICIT_TLS + X86EmitIndexRegLoad(dstreg, dstreg, (g_TlsIndex & 0x7FFF0000) >> 16); } +#endif // !FEATURE_STUBS_AS_IL #if defined(_TARGET_X86_) @@ -2861,56 +2716,7 @@ VOID StubLinkerCPU::EmitSetup(CodeLabel *pForwardRef) { STANDARD_VM_CONTRACT; -#ifdef FEATURE_IMPLICIT_TLS - DWORD idx = 0; - TLSACCESSMODE mode = TLSACCESS_GENERIC; -#else - DWORD idx = GetThreadTLSIndex(); - TLSACCESSMODE mode = GetTLSAccessMode(idx); -#endif - -#ifdef _DEBUG - { - static BOOL f = TRUE; - f = !f; - if (f) - { - mode = TLSACCESS_GENERIC; - } - } -#endif - - switch (mode) - { - case TLSACCESS_WNT: -#ifndef FEATURE_PAL - { - unsigned __int32 tlsofs = offsetof(TEB, TlsSlots) + (idx * sizeof(void*)); - - static const BYTE code[] = {0x64,0x8b,0x1d}; // mov ebx, dword ptr fs:[IMM32] - EmitBytes(code, sizeof(code)); - Emit32(tlsofs); - } -#else // !FEATURE_PAL - _ASSERTE("TLSACCESS_WNT mode is not supported"); -#endif // !FEATURE_PAL - break; - - case TLSACCESS_GENERIC: -#ifdef FEATURE_IMPLICIT_TLS - X86EmitCall(NewExternalCodeLabel((LPVOID) GetThread), sizeof(void*)); -#else - X86EmitPushImm32(idx); - - // call TLSGetValue - X86EmitCall(NewExternalCodeLabel((LPVOID) TlsGetValue), sizeof(void*)); -#endif - // mov ebx,eax - Emit16(0xc389); - break; - default: - _ASSERTE(0); - } + X86EmitCurrentThreadFetch(kEBX); // cmp ebx, 0 static const BYTE b[] = { 0x83, 0xFB, 0x0}; @@ -3150,8 +2956,7 @@ VOID StubLinkerCPU::EmitMethodStubProlog(TADDR pFrameVptr, int transitionBlockOf #endif // _TARGET_X86_ // ebx <-- GetThread() - // Trashes X86TLSFetch_TRASHABLE_REGS - X86EmitCurrentThreadFetch(kEBX, 0); + X86EmitCurrentThreadFetch(kEBX); #if _DEBUG diff --git a/src/vm/i386/stublinkerx86.h b/src/vm/i386/stublinkerx86.h index 76d1f95845..d523bb0461 100644 --- a/src/vm/i386/stublinkerx86.h +++ b/src/vm/i386/stublinkerx86.h @@ -219,11 +219,7 @@ class StubLinkerCPU : public StubLinker VOID X86EmitLeaRIP(CodeLabel *target, X86Reg reg); #endif - static const unsigned X86TLSFetch_TRASHABLE_REGS = (1<<kEAX) | (1<<kEDX) | (1<<kECX); - VOID X86EmitTLSFetch(DWORD idx, X86Reg dstreg, unsigned preservedRegSet); - - VOID X86EmitCurrentThreadFetch(X86Reg dstreg, unsigned preservedRegSet); - VOID X86EmitCurrentAppDomainFetch(X86Reg dstreg, unsigned preservedRegSet); + VOID X86EmitCurrentThreadFetch(X86Reg dstreg); VOID X86EmitIndexRegLoad(X86Reg dstreg, X86Reg srcreg, __int32 ofs = 0); VOID X86EmitIndexRegStore(X86Reg dstreg, __int32 ofs, X86Reg srcreg); @@ -421,7 +417,7 @@ class StubLinkerCPU : public StubLinker VOID EmitDebugBreak(); #endif // !FEATURE_STUBS_AS_IL -#if defined(_DEBUG) && (defined(_TARGET_AMD64_) || defined(_TARGET_X86_)) && !defined(FEATURE_PAL) +#if defined(_DEBUG) && !defined(FEATURE_PAL) //=========================================================================== // Emits code to log JITHelper access void EmitJITHelperLoggingThunk(PCODE pJitHelper, LPVOID helperFuncCount); |