summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2017-10-11 13:04:43 -0700
committerGitHub <noreply@github.com>2017-10-11 13:04:43 -0700
commit27a25bd37fa1fe6201c27709b1884e1b328f8beb (patch)
tree18b7773a7d8e18cca609417940804d8dff491da2 /src/vm
parentd07f1b24c4a69e6a205f8510f3dcfae0ad96aae8 (diff)
downloadcoreclr-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')
-rw-r--r--src/vm/CMakeLists.txt2
-rw-r--r--src/vm/amd64/AsmMacros.inc30
-rw-r--r--src/vm/amd64/InstantiatingStub.asm8
-rw-r--r--src/vm/amd64/JitHelpers_Fast.asm59
-rw-r--r--src/vm/amd64/JitHelpers_InlineGetAppDomain.asm123
-rw-r--r--src/vm/amd64/JitHelpers_InlineGetThread.asm49
-rw-r--r--src/vm/amd64/JitHelpers_Slow.asm481
-rw-r--r--src/vm/amd64/RedirectedHandledJITCase.asm3
-rw-r--r--src/vm/amd64/TlsGetters.asm120
-rw-r--r--src/vm/amd64/UMThunkStub.asm8
-rw-r--r--src/vm/amd64/asmconstants.h17
-rw-r--r--src/vm/amd64/cgencpu.h19
-rw-r--r--src/vm/appdomain.cpp4
-rw-r--r--src/vm/arm/asmconstants.h3
-rw-r--r--src/vm/arm/asmhelpers.asm2
-rw-r--r--src/vm/arm/cgencpu.h17
-rw-r--r--src/vm/arm/patchedcode.S16
-rw-r--r--src/vm/arm/patchedcode.asm515
-rw-r--r--src/vm/arm/stubs.cpp292
-rw-r--r--src/vm/arm64/cgencpu.h10
-rw-r--r--src/vm/arm64/stubs.cpp39
-rw-r--r--src/vm/ceeload.cpp4
-rw-r--r--src/vm/ceemain.cpp10
-rw-r--r--src/vm/ceemain.h8
-rw-r--r--src/vm/corhost.cpp48
-rw-r--r--src/vm/crossgencompile.cpp21
-rw-r--r--src/vm/eedbginterface.h1
-rw-r--r--src/vm/eedbginterfaceimpl.cpp11
-rw-r--r--src/vm/eedbginterfaceimpl.h1
-rw-r--r--src/vm/i386/asmconstants.h3
-rw-r--r--src/vm/i386/asmhelpers.asm63
-rw-r--r--src/vm/i386/cgencpu.h15
-rw-r--r--src/vm/i386/cgenx86.cpp2
-rw-r--r--src/vm/i386/jithelp.asm51
-rw-r--r--src/vm/i386/jitinterfacex86.cpp47
-rw-r--r--src/vm/i386/stublinkerx86.cpp229
-rw-r--r--src/vm/i386/stublinkerx86.h8
-rw-r--r--src/vm/jitinterface.cpp13
-rw-r--r--src/vm/jitinterfacegen.cpp183
-rw-r--r--src/vm/threads.cpp356
-rw-r--r--src/vm/threads.h32
-rw-r--r--src/vm/threads.inl11
-rw-r--r--src/vm/vars.cpp5
-rw-r--r--src/vm/vars.hpp4
44 files changed, 167 insertions, 2776 deletions
diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt
index f8790cf85d..0aed676d94 100644
--- a/src/vm/CMakeLists.txt
+++ b/src/vm/CMakeLists.txt
@@ -351,7 +351,6 @@ if(CLR_CMAKE_TARGET_ARCH_AMD64)
${ARCH_SOURCES_DIR}/InstantiatingStub.asm
${ARCH_SOURCES_DIR}/JitHelpers_Fast.asm
${ARCH_SOURCES_DIR}/JitHelpers_FastWriteBarriers.asm
- ${ARCH_SOURCES_DIR}/JitHelpers_InlineGetAppDomain.asm
${ARCH_SOURCES_DIR}/JitHelpers_InlineGetThread.asm
${ARCH_SOURCES_DIR}/JitHelpers_SingleAppDomain.asm
${ARCH_SOURCES_DIR}/JitHelpers_Slow.asm
@@ -359,7 +358,6 @@ if(CLR_CMAKE_TARGET_ARCH_AMD64)
${ARCH_SOURCES_DIR}/RedirectedHandledJITCase.asm
${ARCH_SOURCES_DIR}/ThePreStubAMD64.asm
${ARCH_SOURCES_DIR}/ExternalMethodFixupThunk.asm
- ${ARCH_SOURCES_DIR}/TlsGetters.asm # Condition="'$(FeatureImplicitTls)' != 'true'
${ARCH_SOURCES_DIR}/UMThunkStub.asm
${ARCH_SOURCES_DIR}/VirtualCallStubAMD64.asm
)
diff --git a/src/vm/amd64/AsmMacros.inc b/src/vm/amd64/AsmMacros.inc
index f95a291929..58fd8d130f 100644
--- a/src/vm/amd64/AsmMacros.inc
+++ b/src/vm/amd64/AsmMacros.inc
@@ -188,29 +188,25 @@ Section ends
;
-; Macro to Call GetThread() correctly whether it is indirect or direct
-;
-CALL_GETTHREAD macro
-ifndef GetThread
-extern GetThread:proc
-endif
- call GetThread
- endm
+; Inlined version of GetThread
+; Trashes rax and r11
+;
+INLINE_GETTHREAD macro Reg
+
+ EXTERN _tls_index : DWORD
+ EXTERN gCurrentThreadInfo:DWORD
+
+ mov r11d, [_tls_index]
+ mov rax, gs:[OFFSET__TEB__ThreadLocalStoragePointer]
+ mov rax, [rax + r11 * 8]
+ mov r11d, SECTIONREL gCurrentThreadInfo
+ mov Reg, [rax + r11]
-CALL_GETAPPDOMAIN macro
-ifndef GetAppDomain
-extern GetAppDomain:proc
-endif
- call GetAppDomain
endm
-;
; if you change this code there will be corresponding code in JITInterfaceGen.cpp which will need to be changed
;
-; DEFAULT_TARGET needs to always be futher away than the fixed up target will be
-
-
JIT_HELPER_MONITOR_THUNK macro THUNK_NAME, Section
Section segment para 'CODE'
align 16
diff --git a/src/vm/amd64/InstantiatingStub.asm b/src/vm/amd64/InstantiatingStub.asm
index dff1b6f5a6..8601e4ae44 100644
--- a/src/vm/amd64/InstantiatingStub.asm
+++ b/src/vm/amd64/InstantiatingStub.asm
@@ -90,13 +90,11 @@ NESTED_ENTRY InstantiatingMethodStubWorker, _TEXT
;
; link the StubHelperFrame
;
- CALL_GETTHREAD
- mov rdx, [rax + OFFSETOF__Thread__m_pFrame]
+ INLINE_GETTHREAD r12
+ mov rdx, [r12 + OFFSETOF__Thread__m_pFrame]
mov [rbp + OFFSETOF_FRAME + OFFSETOF__Frame__m_Next], rdx
lea rcx, [rbp + OFFSETOF_FRAME]
- mov [rax + OFFSETOF__Thread__m_pFrame], rcx
-
- mov r12, rax ; store the Thread pointer
+ mov [r12 + OFFSETOF__Thread__m_pFrame], rcx
add rsp, SIZEOF_MAX_OUTGOING_ARGUMENT_HOMES
diff --git a/src/vm/amd64/JitHelpers_Fast.asm b/src/vm/amd64/JitHelpers_Fast.asm
index f004be549e..5e0d79f74f 100644
--- a/src/vm/amd64/JitHelpers_Fast.asm
+++ b/src/vm/amd64/JitHelpers_Fast.asm
@@ -583,58 +583,6 @@ endif
nop
LEAF_END_MARKED JIT_WriteBarrier, _TEXT
-ifndef FEATURE_IMPLICIT_TLS
-LEAF_ENTRY GetThread, _TEXT
- ; the default implementation will just jump to one that returns null until
- ; MakeOptimizedTlsGetter is run which will overwrite this with the actual
- ; implementation.
- jmp short GetTLSDummy
-
- ;
- ; insert enough NOPS to be able to insert the largest optimized TLS getter
- ; that we might need, it is important that the TLS getter doesn't overwrite
- ; into the dummy getter.
- ;
- db (TLS_GETTER_MAX_SIZE_ASM - 2) DUP (0CCh)
-
-LEAF_END GetThread, _TEXT
-
-LEAF_ENTRY GetAppDomain, _TEXT
- ; the default implementation will just jump to one that returns null until
- ; MakeOptimizedTlsGetter is run which will overwrite this with the actual
- ; implementation.
- jmp short GetTLSDummy
-
- ;
- ; insert enough NOPS to be able to insert the largest optimized TLS getter
- ; that we might need, it is important that the TLS getter doesn't overwrite
- ; into the dummy getter.
- ;
- db (TLS_GETTER_MAX_SIZE_ASM - 2) DUP (0CCh)
-
-LEAF_END GetAppDomain, _TEXT
-
-LEAF_ENTRY GetTLSDummy, _TEXT
- xor rax, rax
- ret
-LEAF_END GetTLSDummy, _TEXT
-
-LEAF_ENTRY ClrFlsGetBlock, _TEXT
- ; the default implementation will just jump to one that returns null until
- ; MakeOptimizedTlsGetter is run which will overwrite this with the actual
- ; implementation.
- jmp short GetTLSDummy
-
- ;
- ; insert enough NOPS to be able to insert the largest optimized TLS getter
- ; that we might need, it is important that the TLS getter doesn't overwrite
- ; into the dummy getter.
- ;
- db (TLS_GETTER_MAX_SIZE_ASM - 2) DUP (0CCh)
-
-LEAF_END ClrFlsGetBlock, _TEXT
-endif
-
; Mark start of the code region that we patch at runtime
LEAF_ENTRY JIT_PatchedCodeLast, _TEXT
ret
@@ -986,12 +934,11 @@ if 0 ne 0
;
; link the TailCallFrame
;
- CALL_GETTHREAD
- mov r14, rax
- mov r15, [rax + OFFSETOF__Thread__m_pFrame]
+ INLINE_GETTHREAD r14
+ mov r15, [r14 + OFFSETOF__Thread__m_pFrame]
mov [r13 + OFFSETOF_FRAME + OFFSETOF__Frame__m_Next], r15
lea r10, [r13 + OFFSETOF_FRAME]
- mov [rax + OFFSETOF__Thread__m_pFrame], r10
+ mov [r14 + OFFSETOF__Thread__m_pFrame], r10
endif
; the pretend call would be here
diff --git a/src/vm/amd64/JitHelpers_InlineGetAppDomain.asm b/src/vm/amd64/JitHelpers_InlineGetAppDomain.asm
deleted file mode 100644
index 187decf14d..0000000000
--- a/src/vm/amd64/JitHelpers_InlineGetAppDomain.asm
+++ /dev/null
@@ -1,123 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-; See the LICENSE file in the project root for more information.
-
-; ==++==
-;
-
-;
-; ==--==
-; ***********************************************************************
-; File: JitHelpers_InlineGetAppDomain.asm, see history in jithelp.asm
-;
-; Notes: These routinues will be patched at runtime with the location in
-; the TLS to find the AppDomain* and are the fastest implementation
-; of their specific functionality.
-; ***********************************************************************
-
-include AsmMacros.inc
-include asmconstants.inc
-
-; Min amount of stack space that a nested function should allocate.
-MIN_SIZE equ 28h
-
-; Macro to create a patchable inline GetAppdomain, if we decide to create patchable
-; high TLS inline versions then just change this macro to make sure to create enough
-; space in the asm to patch the high TLS getter instructions.
-PATCHABLE_INLINE_GETAPPDOMAIN macro Reg, PatchLabel
-PATCH_LABEL PatchLabel
- mov Reg, gs:[OFFSET__TEB__TlsSlots]
- endm
-
-extern JIT_GetSharedNonGCStaticBase_Helper:proc
-extern JIT_GetSharedGCStaticBase_Helper:proc
-
-LEAF_ENTRY JIT_GetSharedNonGCStaticBase_InlineGetAppDomain, _TEXT
- ; Check if rcx (moduleDomainID) is not a moduleID
- mov rax, rcx
- test rax, 1
- jz HaveLocalModule
-
- PATCHABLE_INLINE_GETAPPDOMAIN rax, JIT_GetSharedNonGCStaticBase__PatchTLSLabel
-
- ; Get the LocalModule, rcx will always be odd, so: rcx * 4 - 4 <=> (rcx >> 1) * 8
- mov rax, [rax + OFFSETOF__AppDomain__m_sDomainLocalBlock + OFFSETOF__DomainLocalBlock__m_pModuleSlots]
- mov rax, [rax + rcx * 4 - 4]
-
- HaveLocalModule:
- ; If class is not initialized, bail to C++ helper
- test byte ptr [rax + OFFSETOF__DomainLocalModule__m_pDataBlob + rdx], 1
- jz CallHelper
- REPRET
-
- align 16
- CallHelper:
- ; Tail call JIT_GetSharedNonGCStaticBase_Helper
- mov rcx, rax
- jmp JIT_GetSharedNonGCStaticBase_Helper
-LEAF_END JIT_GetSharedNonGCStaticBase_InlineGetAppDomain, _TEXT
-
-LEAF_ENTRY JIT_GetSharedNonGCStaticBaseNoCtor_InlineGetAppDomain, _TEXT
- ; Check if rcx (moduleDomainID) is not a moduleID
- mov rax, rcx
- test rax, 1
- jz HaveLocalModule
-
- PATCHABLE_INLINE_GETAPPDOMAIN rax, JIT_GetSharedNonGCStaticBaseNoCtor__PatchTLSLabel
-
- ; Get the LocalModule, rcx will always be odd, so: rcx * 4 - 4 <=> (rcx >> 1) * 8
- mov rax, [rax + OFFSETOF__AppDomain__m_sDomainLocalBlock + OFFSETOF__DomainLocalBlock__m_pModuleSlots]
- mov rax, [rax + rcx * 4 - 4]
- ret
-
- align 16
- HaveLocalModule:
- REPRET
-LEAF_END JIT_GetSharedNonGCStaticBaseNoCtor_InlineGetAppDomain, _TEXT
-
-LEAF_ENTRY JIT_GetSharedGCStaticBase_InlineGetAppDomain, _TEXT
- ; Check if rcx (moduleDomainID) is not a moduleID
- mov rax, rcx
- test rax, 1
- jz HaveLocalModule
-
- PATCHABLE_INLINE_GETAPPDOMAIN rax, JIT_GetSharedGCStaticBase__PatchTLSLabel
-
- ; Get the LocalModule, rcx will always be odd, so: rcx * 4 - 4 <=> (rcx >> 1) * 8
- mov rax, [rax + OFFSETOF__AppDomain__m_sDomainLocalBlock + OFFSETOF__DomainLocalBlock__m_pModuleSlots]
- mov rax, [rax + rcx * 4 - 4]
-
- HaveLocalModule:
- ; If class is not initialized, bail to C++ helper
- test byte ptr [rax + OFFSETOF__DomainLocalModule__m_pDataBlob + rdx], 1
- jz CallHelper
-
- mov rax, [rax + OFFSETOF__DomainLocalModule__m_pGCStatics]
- ret
-
- align 16
- CallHelper:
- ; Tail call Jit_GetSharedGCStaticBase_Helper
- mov rcx, rax
- jmp JIT_GetSharedGCStaticBase_Helper
-LEAF_END JIT_GetSharedGCStaticBase_InlineGetAppDomain, _TEXT
-
-LEAF_ENTRY JIT_GetSharedGCStaticBaseNoCtor_InlineGetAppDomain, _TEXT
- ; Check if rcx (moduleDomainID) is not a moduleID
- mov rax, rcx
- test rax, 1
- jz HaveLocalModule
-
- PATCHABLE_INLINE_GETAPPDOMAIN rax, JIT_GetSharedGCStaticBaseNoCtor__PatchTLSLabel
-
- ; Get the LocalModule, rcx will always be odd, so: rcx * 4 - 4 <=> (rcx >> 1) * 8
- mov rax, [rax + OFFSETOF__AppDomain__m_sDomainLocalBlock + OFFSETOF__DomainLocalBlock__m_pModuleSlots]
- mov rax, [rax + rcx * 4 - 4]
-
- HaveLocalModule:
- mov rax, [rax + OFFSETOF__DomainLocalModule__m_pGCStatics]
- ret
-LEAF_END JIT_GetSharedGCStaticBaseNoCtor_InlineGetAppDomain, _TEXT
-
- end
-
diff --git a/src/vm/amd64/JitHelpers_InlineGetThread.asm b/src/vm/amd64/JitHelpers_InlineGetThread.asm
index 40d63bf729..d9f58cc30f 100644
--- a/src/vm/amd64/JitHelpers_InlineGetThread.asm
+++ b/src/vm/amd64/JitHelpers_InlineGetThread.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: JitHelpers_InlineGetThread.asm, see history in jithelp.asm
;
@@ -21,15 +16,6 @@ include asmconstants.inc
; Min amount of stack space that a nested function should allocate.
MIN_SIZE equ 28h
-; Macro to create a patchable inline GetAppdomain, if we decide to create patchable
-; high TLS inline versions then just change this macro to make sure to create enough
-; space in the asm to patch the high TLS getter instructions.
-PATCHABLE_INLINE_GETTHREAD macro Reg, PatchLabel
-PATCH_LABEL PatchLabel
- mov Reg, gs:[OFFSET__TEB__TlsSlots]
- endm
-
-
JIT_NEW equ ?JIT_New@@YAPEAVObject@@PEAUCORINFO_CLASS_STRUCT_@@@Z
Object__DEBUG_SetAppDomain equ ?DEBUG_SetAppDomain@Object@@QEAAXPEAVAppDomain@@@Z
CopyValueClassUnchecked equ ?CopyValueClassUnchecked@@YAXPEAX0PEAVMethodTable@@@Z
@@ -49,11 +35,6 @@ extern JIT_NewArr1:proc
extern JIT_InternalThrow:proc
-ifdef _DEBUG
-extern DEBUG_TrialAllocSetAppDomain:proc
-extern DEBUG_TrialAllocSetAppDomain_NoScratchArea:proc
-endif
-
; IN: rcx: MethodTable*
; OUT: rax: new object
LEAF_ENTRY JIT_TrialAllocSFastMP_InlineGetThread, _TEXT
@@ -61,7 +42,7 @@ LEAF_ENTRY JIT_TrialAllocSFastMP_InlineGetThread, _TEXT
; m_BaseSize is guaranteed to be a multiple of 8.
- PATCHABLE_INLINE_GETTHREAD r11, JIT_TrialAllocSFastMP_InlineGetThread__PatchTLSOffset
+ INLINE_GETTHREAD r11
mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]
mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]
@@ -73,10 +54,6 @@ LEAF_ENTRY JIT_TrialAllocSFastMP_InlineGetThread, _TEXT
mov [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr], rdx
mov [rax], rcx
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain_NoScratchArea
-endif ; _DEBUG
-
ret
AllocFailed:
@@ -95,7 +72,7 @@ NESTED_ENTRY JIT_BoxFastMP_InlineGetThread, _TEXT
; m_BaseSize is guaranteed to be a multiple of 8.
- PATCHABLE_INLINE_GETTHREAD r11, JIT_BoxFastMPIGT__PatchTLSLabel
+ INLINE_GETTHREAD r11
mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]
mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]
@@ -107,10 +84,6 @@ NESTED_ENTRY JIT_BoxFastMP_InlineGetThread, _TEXT
mov [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr], r8
mov [rax], rcx
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain_NoScratchArea
-endif ; _DEBUG
-
; Check whether the object contains pointers
test dword ptr [rcx + OFFSETOF__MethodTable__m_dwFlags], MethodTable__enum_flag_ContainsPointers
jnz ContainsPointers
@@ -169,7 +142,7 @@ LEAF_ENTRY AllocateStringFastMP_InlineGetThread, _TEXT
lea edx, [edx + ecx*2 + 7]
and edx, -8
- PATCHABLE_INLINE_GETTHREAD r11, AllocateStringFastMP_InlineGetThread__PatchTLSOffset
+ INLINE_GETTHREAD r11
mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]
mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]
@@ -183,10 +156,6 @@ LEAF_ENTRY AllocateStringFastMP_InlineGetThread, _TEXT
mov [rax + OFFSETOF__StringObject__m_StringLength], ecx
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain_NoScratchArea
-endif ; _DEBUG
-
ret
OversizedString:
@@ -226,7 +195,7 @@ LEAF_ENTRY JIT_NewArr1VC_MP_InlineGetThread, _TEXT
and r8d, -8
- PATCHABLE_INLINE_GETTHREAD r11, JIT_NewArr1VC_MP_InlineGetThread__PatchTLSOffset
+ INLINE_GETTHREAD r11
mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]
mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]
@@ -241,10 +210,6 @@ LEAF_ENTRY JIT_NewArr1VC_MP_InlineGetThread, _TEXT
mov dword ptr [rax + OFFSETOF__ArrayBase__m_NumComponents], edx
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain_NoScratchArea
-endif ; _DEBUG
-
ret
OversizedArray:
@@ -279,7 +244,7 @@ LEAF_ENTRY JIT_NewArr1OBJ_MP_InlineGetThread, _TEXT
; No need for rounding in this case - element size is 8, and m_BaseSize is guaranteed
; to be a multiple of 8.
- PATCHABLE_INLINE_GETTHREAD r11, JIT_NewArr1OBJ_MP_InlineGetThread__PatchTLSOffset
+ INLINE_GETTHREAD r11
mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]
mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]
@@ -293,10 +258,6 @@ LEAF_ENTRY JIT_NewArr1OBJ_MP_InlineGetThread, _TEXT
mov dword ptr [rax + OFFSETOF__ArrayBase__m_NumComponents], edx
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain_NoScratchArea
-endif ; _DEBUG
-
ret
OversizedArray:
diff --git a/src/vm/amd64/JitHelpers_Slow.asm b/src/vm/amd64/JitHelpers_Slow.asm
index f86d429e33..0e26ae6dfd 100644
--- a/src/vm/amd64/JitHelpers_Slow.asm
+++ b/src/vm/amd64/JitHelpers_Slow.asm
@@ -42,7 +42,6 @@ EXTERN g_GCShadowEnd:QWORD
endif
JIT_NEW equ ?JIT_New@@YAPEAVObject@@PEAUCORINFO_CLASS_STRUCT_@@@Z
-Object__DEBUG_SetAppDomain equ ?DEBUG_SetAppDomain@Object@@QEAAXPEAVAppDomain@@@Z
CopyValueClassUnchecked equ ?CopyValueClassUnchecked@@YAXPEAX0PEAVMethodTable@@@Z
JIT_Box equ ?JIT_Box@@YAPEAVObject@@PEAUCORINFO_CLASS_STRUCT_@@PEAX@Z
g_pStringClass equ ?g_pStringClass@@3PEAVMethodTable@@EA
@@ -162,290 +161,6 @@ endif
LEAF_END_MARKED JIT_WriteBarrier_Debug, _TEXT
endif
-NESTED_ENTRY JIT_TrialAllocSFastMP, _TEXT
- alloc_stack MIN_SIZE
- END_PROLOGUE
-
- CALL_GETTHREAD
- mov r11, rax
-
- mov r8d, [rcx + OFFSET__MethodTable__m_BaseSize]
-
- ; m_BaseSize is guaranteed to be a multiple of 8.
-
- mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]
- mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]
-
- add r8, rax
-
- cmp r8, r10
- ja AllocFailed
-
- mov [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr], r8
- mov [rax], rcx
-
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain
-endif ; _DEBUG
-
- ; epilog
- add rsp, MIN_SIZE
- ret
-
- AllocFailed:
- add rsp, MIN_SIZE
- jmp JIT_NEW
-NESTED_END JIT_TrialAllocSFastMP, _TEXT
-
-
-; HCIMPL2(Object*, JIT_Box, CORINFO_CLASS_HANDLE type, void* unboxedData)
-NESTED_ENTRY JIT_BoxFastMP, _TEXT
- alloc_stack MIN_SIZE
- END_PROLOGUE
-
- mov rax, [rcx + OFFSETOF__MethodTable__m_pWriteableData]
-
- ; Check whether the class has not been initialized
- test dword ptr [rax + OFFSETOF__MethodTableWriteableData__m_dwFlags], MethodTableWriteableData__enum_flag_Unrestored
- jnz ClassNotInited
-
- CALL_GETTHREAD
- mov r11, rax
-
- mov r8d, [rcx + OFFSET__MethodTable__m_BaseSize]
-
- ; m_BaseSize is guaranteed to be a multiple of 8.
-
- mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]
- mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]
-
- add r8, rax
-
- cmp r8, r10
- ja AllocFailed
-
- mov [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr], r8
- mov [rax], rcx
-
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain
-endif ; _DEBUG
-
- ; Check whether the object contains pointers
- test dword ptr [rcx + OFFSETOF__MethodTable__m_dwFlags], MethodTable__enum_flag_ContainsPointers
- jnz ContainsPointers
-
- ; We have no pointers - emit a simple inline copy loop
-
- mov ecx, [rcx + OFFSET__MethodTable__m_BaseSize]
- sub ecx, 18h ; sizeof(ObjHeader) + sizeof(Object) + last slot
-
- CopyLoop:
- mov r8, [rdx+rcx]
- mov [rax+rcx+8], r8
-
- sub ecx, 8
- jge CopyLoop
-
- add rsp, MIN_SIZE
- ret
-
- ContainsPointers:
- ; Do call to CopyValueClassUnchecked(object, data, pMT)
-
- mov [rsp+20h], rax
-
- mov r8, rcx
- lea rcx, [rax + 8]
- call CopyValueClassUnchecked
-
- mov rax, [rsp+20h]
-
- add rsp, MIN_SIZE
- ret
-
- ClassNotInited:
- AllocFailed:
- add rsp, MIN_SIZE
- jmp JIT_Box
-NESTED_END JIT_BoxFastMP, _TEXT
-
-
-NESTED_ENTRY AllocateStringFastMP, _TEXT
- alloc_stack MIN_SIZE
- END_PROLOGUE
-
- ; Instead of doing elaborate overflow checks, we just limit the number of elements
- ; to (LARGE_OBJECT_SIZE - 256)/sizeof(WCHAR) or less.
- ; This will avoid all overflow problems, as well as making sure
- ; big string objects are correctly allocated in the big object heap.
-
- cmp ecx, (ASM_LARGE_OBJECT_SIZE - 256)/2
- jae OversizedString
-
- CALL_GETTHREAD
- mov r11, rax
-
- mov rdx, [g_pStringClass]
- mov r8d, [rdx + OFFSET__MethodTable__m_BaseSize]
-
- ; Calculate the final size to allocate.
- ; We need to calculate baseSize + cnt*2, then round that up by adding 7 and anding ~7.
-
- lea r8d, [r8d + ecx*2 + 7]
- and r8d, -8
-
- mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]
- mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]
-
- add r8, rax
-
- cmp r8, r10
- ja AllocFailed
-
- mov [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr], r8
- mov [rax], rdx
-
- mov [rax + OFFSETOF__StringObject__m_StringLength], ecx
-
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain
-endif ; _DEBUG
-
- add rsp, MIN_SIZE
- ret
-
- OversizedString:
- AllocFailed:
- add rsp, MIN_SIZE
- jmp FramedAllocateString
-NESTED_END AllocateStringFastMP, _TEXT
-
-; HCIMPL2(Object*, JIT_NewArr1VC_MP, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size)
-NESTED_ENTRY JIT_NewArr1VC_MP, _TEXT
- alloc_stack MIN_SIZE
- END_PROLOGUE
-
- ; We were passed a (shared) method table in RCX, which contains the element type.
-
- ; The element count is in RDX
-
- ; NOTE: if this code is ported for CORINFO_HELP_NEWSFAST_ALIGN8, it will need
- ; to emulate the double-specific behavior of JIT_TrialAlloc::GenAllocArray.
-
- ; Do a conservative check here. This is to avoid overflow while doing the calculations. We don't
- ; have to worry about "large" objects, since the allocation quantum is never big enough for
- ; LARGE_OBJECT_SIZE.
-
- ; For Value Classes, this needs to be 2^16 - slack (2^32 / max component size),
- ; The slack includes the size for the array header and round-up ; for alignment. Use 256 for the
- ; slack value out of laziness.
-
- ; In both cases we do a final overflow check after adding to the alloc_ptr.
-
- CALL_GETTHREAD
- mov r11, rax
-
- cmp rdx, (65535 - 256)
- jae OversizedArray
-
- movzx r8d, word ptr [rcx + OFFSETOF__MethodTable__m_dwFlags] ; component size is low 16 bits
- imul r8d, edx ; signed mul, but won't overflow due to length restriction above
- add r8d, dword ptr [rcx + OFFSET__MethodTable__m_BaseSize]
-
- ; round the size to a multiple of 8
-
- add r8d, 7
- and r8d, -8
-
- mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]
- mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]
-
- add r8, rax
- jc AllocFailed
-
- cmp r8, r10
- ja AllocFailed
-
- mov [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr], r8
- mov [rax], rcx
-
- mov dword ptr [rax + OFFSETOF__ArrayBase__m_NumComponents], edx
-
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain
-endif ; _DEBUG
-
- add rsp, MIN_SIZE
- ret
-
- OversizedArray:
- AllocFailed:
- add rsp, MIN_SIZE
- jmp JIT_NewArr1
-NESTED_END JIT_NewArr1VC_MP, _TEXT
-
-
-; HCIMPL2(Object*, JIT_NewArr1OBJ_MP, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size)
-NESTED_ENTRY JIT_NewArr1OBJ_MP, _TEXT
- alloc_stack MIN_SIZE
- END_PROLOGUE
-
- ; We were passed a (shared) method table in RCX, which contains the element type.
-
- ; The element count is in RDX
-
- ; NOTE: if this code is ported for CORINFO_HELP_NEWSFAST_ALIGN8, it will need
- ; to emulate the double-specific behavior of JIT_TrialAlloc::GenAllocArray.
-
- ; Verifies that LARGE_OBJECT_SIZE fits in 32-bit. This allows us to do array size
- ; arithmetic using 32-bit registers.
- .erre ASM_LARGE_OBJECT_SIZE lt 100000000h
-
- cmp rdx, (ASM_LARGE_OBJECT_SIZE - 256)/8
- jae OversizedArray
-
- CALL_GETTHREAD
- mov r11, rax
-
- ; In this case we know the element size is sizeof(void *), or 8 for x64
- ; This helps us in two ways - we can shift instead of multiplying, and
- ; there's no need to align the size either
-
- mov r8d, dword ptr [rcx + OFFSET__MethodTable__m_BaseSize]
- lea r8d, [r8d + edx * 8]
-
- ; No need for rounding in this case - element size is 8, and m_BaseSize is guaranteed
- ; to be a multiple of 8.
-
- mov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]
- mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]
-
- add r8, rax
-
- cmp r8, r10
- ja AllocFailed
-
- mov [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr], r8
- mov [rax], rcx
-
- mov dword ptr [rax + OFFSETOF__ArrayBase__m_NumComponents], edx
-
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain
-endif ; _DEBUG
-
- add rsp, MIN_SIZE
- ret
-
- OversizedArray:
- AllocFailed:
- add rsp, MIN_SIZE
- jmp JIT_NewArr1
-NESTED_END JIT_NewArr1OBJ_MP, _TEXT
-
-
-
extern g_global_alloc_lock:dword
extern g_global_alloc_context:qword
@@ -471,10 +186,6 @@ LEAF_ENTRY JIT_TrialAllocSFastSP, _TEXT
mov [rax], rcx
mov [g_global_alloc_lock], -1
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain_NoScratchArea
-endif ; _DEBUG
-
ret
AllocFailed:
@@ -511,10 +222,6 @@ NESTED_ENTRY JIT_BoxFastUP, _TEXT
mov [rax], rcx
mov [g_global_alloc_lock], -1
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain_NoScratchArea
-endif ; _DEBUG
-
; Check whether the object contains pointers
test dword ptr [rcx + OFFSETOF__MethodTable__m_dwFlags], MethodTable__enum_flag_ContainsPointers
jnz ContainsPointers
@@ -594,10 +301,6 @@ LEAF_ENTRY AllocateStringFastUP, _TEXT
mov [rax + OFFSETOF__StringObject__m_StringLength], ecx
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain_NoScratchArea
-endif ; _DEBUG
-
ret
AllocFailed:
@@ -655,10 +358,6 @@ LEAF_ENTRY JIT_NewArr1VC_UP, _TEXT
mov dword ptr [rax + OFFSETOF__ArrayBase__m_NumComponents], edx
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain_NoScratchArea
-endif ; _DEBUG
-
ret
AllocFailed:
@@ -711,10 +410,6 @@ LEAF_ENTRY JIT_NewArr1OBJ_UP, _TEXT
mov dword ptr [rax + OFFSETOF__ArrayBase__m_NumComponents], edx
-ifdef _DEBUG
- call DEBUG_TrialAllocSetAppDomain_NoScratchArea
-endif ; _DEBUG
-
ret
AllocFailed:
@@ -725,181 +420,5 @@ endif ; _DEBUG
LEAF_END JIT_NewArr1OBJ_UP, _TEXT
-NESTED_ENTRY JIT_GetSharedNonGCStaticBase_Slow, _TEXT
- alloc_stack MIN_SIZE
- END_PROLOGUE
-
- ; Check if rcx (moduleDomainID) is not a moduleID
- test rcx, 1
- jz HaveLocalModule
-
- CALL_GETAPPDOMAIN
-
- ; Get the LocalModule
- mov rax, [rax + OFFSETOF__AppDomain__m_sDomainLocalBlock + OFFSETOF__DomainLocalBlock__m_pModuleSlots]
- ; rcx will always be odd, so: rcx * 4 - 4 <=> (rcx >> 1) * 8
- mov rcx, [rax + rcx * 4 - 4]
-
- HaveLocalModule:
- ; If class is not initialized, bail to C++ helper
- test [rcx + OFFSETOF__DomainLocalModule__m_pDataBlob + rdx], 1
- jz CallHelper
-
- mov rax, rcx
- add rsp, MIN_SIZE
- ret
-
- align 16
- CallHelper:
- ; Tail call Jit_GetSharedNonGCStaticBase_Helper
- add rsp, MIN_SIZE
- jmp JIT_GetSharedNonGCStaticBase_Helper
-NESTED_END JIT_GetSharedNonGCStaticBase_Slow, _TEXT
-
-NESTED_ENTRY JIT_GetSharedNonGCStaticBaseNoCtor_Slow, _TEXT
- alloc_stack MIN_SIZE
- END_PROLOGUE
-
- ; Check if rcx (moduleDomainID) is not a moduleID
- test rcx, 1
- jz HaveLocalModule
-
- CALL_GETAPPDOMAIN
-
- ; Get the LocalModule
- mov rax, [rax + OFFSETOF__AppDomain__m_sDomainLocalBlock + OFFSETOF__DomainLocalBlock__m_pModuleSlots]
- ; rcx will always be odd, so: rcx * 4 - 4 <=> (rcx >> 1) * 8
- mov rax, [rax + rcx * 4 - 4]
-
- add rsp, MIN_SIZE
- ret
-
- align 16
- HaveLocalModule:
- mov rax, rcx
- add rsp, MIN_SIZE
- ret
-NESTED_END JIT_GetSharedNonGCStaticBaseNoCtor_Slow, _TEXT
-
-NESTED_ENTRY JIT_GetSharedGCStaticBase_Slow, _TEXT
- alloc_stack MIN_SIZE
- END_PROLOGUE
-
- ; Check if rcx (moduleDomainID) is not a moduleID
- test rcx, 1
- jz HaveLocalModule
-
- CALL_GETAPPDOMAIN
-
- ; Get the LocalModule
- mov rax, [rax + OFFSETOF__AppDomain__m_sDomainLocalBlock + OFFSETOF__DomainLocalBlock__m_pModuleSlots]
- ; rcx will always be odd, so: rcx * 4 - 4 <=> (rcx >> 1) * 8
- mov rcx, [rax + rcx * 4 - 4]
-
- HaveLocalModule:
- ; If class is not initialized, bail to C++ helper
- test [rcx + OFFSETOF__DomainLocalModule__m_pDataBlob + rdx], 1
- jz CallHelper
-
- mov rax, [rcx + OFFSETOF__DomainLocalModule__m_pGCStatics]
-
- add rsp, MIN_SIZE
- ret
-
- align 16
- CallHelper:
- ; Tail call Jit_GetSharedGCStaticBase_Helper
- add rsp, MIN_SIZE
- jmp JIT_GetSharedGCStaticBase_Helper
-NESTED_END JIT_GetSharedGCStaticBase_Slow, _TEXT
-
-NESTED_ENTRY JIT_GetSharedGCStaticBaseNoCtor_Slow, _TEXT
- alloc_stack MIN_SIZE
- END_PROLOGUE
-
- ; Check if rcx (moduleDomainID) is not a moduleID
- test rcx, 1
- jz HaveLocalModule
-
- CALL_GETAPPDOMAIN
-
- ; Get the LocalModule
- mov rax, [rax + OFFSETOF__AppDomain__m_sDomainLocalBlock + OFFSETOF__DomainLocalBlock__m_pModuleSlots]
- ; rcx will always be odd, so: rcx * 4 - 4 <=> (rcx >> 1) * 8
- mov rcx, [rax + rcx * 4 - 4]
-
- HaveLocalModule:
- mov rax, [rcx + OFFSETOF__DomainLocalModule__m_pGCStatics]
-
- add rsp, MIN_SIZE
- ret
-NESTED_END JIT_GetSharedGCStaticBaseNoCtor_Slow, _TEXT
-
-
-ifdef _DEBUG
-
-extern Object__DEBUG_SetAppDomain:proc
-
-;
-; IN: rax: new object needing the AppDomain ID set..
-; OUT: rax, returns original value at entry
-;
-; all integer register state is preserved
-;
-DEBUG_TrialAllocSetAppDomain_STACK_SIZE equ MIN_SIZE + 10h
-NESTED_ENTRY DEBUG_TrialAllocSetAppDomain, _TEXT
- push_vol_reg rax
- push_vol_reg rcx
- push_vol_reg rdx
- push_vol_reg r8
- push_vol_reg r9
- push_vol_reg r10
- push_vol_reg r11
- push_nonvol_reg rbx
- alloc_stack MIN_SIZE
- END_PROLOGUE
-
- mov rbx, rax
-
- ; get the app domain ptr
- CALL_GETAPPDOMAIN
-
- ; set the sync block app domain ID
- mov rcx, rbx
- mov rdx, rax
- call Object__DEBUG_SetAppDomain
-
- ; epilog
- add rsp, MIN_SIZE
- pop rbx
- pop r11
- pop r10
- pop r9
- pop r8
- pop rdx
- pop rcx
- pop rax
- ret
-NESTED_END DEBUG_TrialAllocSetAppDomain, _TEXT
-
-NESTED_ENTRY DEBUG_TrialAllocSetAppDomain_NoScratchArea, _TEXT
-
- push_nonvol_reg rbp
- set_frame rbp, 0
- END_PROLOGUE
-
- sub rsp, 20h
- and rsp, -16
-
- call DEBUG_TrialAllocSetAppDomain
-
- lea rsp, [rbp+0]
- pop rbp
- ret
-NESTED_END DEBUG_TrialAllocSetAppDomain_NoScratchArea, _TEXT
-
-endif
-
-
end
diff --git a/src/vm/amd64/RedirectedHandledJITCase.asm b/src/vm/amd64/RedirectedHandledJITCase.asm
index a6d3496357..5ab69475e2 100644
--- a/src/vm/amd64/RedirectedHandledJITCase.asm
+++ b/src/vm/amd64/RedirectedHandledJITCase.asm
@@ -195,9 +195,8 @@ NESTED_ENTRY RedirectForThrowControl2, _TEXT
END_PROLOGUE
; Fetch rip from a CONTEXT, and store it as our return address.
- CALL_GETTHREAD
+ INLINE_GETTHREAD rcx
- mov rcx, rax
call Thread__GetAbortContext
mov rax, [rax + OFFSETOF__CONTEXT__Rip]
diff --git a/src/vm/amd64/TlsGetters.asm b/src/vm/amd64/TlsGetters.asm
deleted file mode 100644
index 7b5a30844b..0000000000
--- a/src/vm/amd64/TlsGetters.asm
+++ /dev/null
@@ -1,120 +0,0 @@
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-; See the LICENSE file in the project root for more information.
-
-; ==++==
-;
-
-;
-; ==--==
-; ***********************************************************************
-; File: TlsGetters.asm, see history in jithelp.asm
-;
-; Notes: These TlsGetters (GetAppDomain(), GetThread()) are implemented
-; in a generic fashion, but might be patched at runtime to contain
-; a much faster implementation which goes straight to the TLS for
-; the Thread* or AppDomain*.
-;
-; Note that the macro takes special care to not have these become
-; non-unwindable after the patching has overwritten the prologue of
-; the generic getter.
-; ***********************************************************************
-
-include AsmMacros.inc
-include asmconstants.inc
-
-; Min amount of stack space that a nested function should allocate.
-MIN_SIZE equ 28h
-
-
-; These generic TLS getters are used for GetThread() and GetAppDomain(), they do a little
-; extra work to ensure that certain registers are preserved, those include the following
-; volatile registers
-;
-; rcx
-; rdx
-; r8
-; r9
-; r10
-; r11
-;
-; The return value is in rax as usual
-;
-; They DO NOT save scratch flowing point registers, if you need those you need to save them.
-
-ifdef ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-GetThreadGenericFullCheck equ ?GetThreadGenericFullCheck@@YAPEAVThread@@XZ
-extern GetThreadGenericFullCheck:proc
-endif ; ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-
-; Creates a generic TLS getter using the value from TLS slot gTLSIndex. Set GenerateGetThread
-; when using this macro to generate GetThread, as that will cause special code to be generated which
-; enables additional debug-only checking, such as enforcement of EE_THREAD_NOT_REQUIRED contracts
-GenerateOptimizedTLSGetter macro name, GenerateGetThread
-
-extern g&name&TLSIndex:dword
-extern __imp_TlsGetValue:qword
-
-SIZEOF_PUSHED_ARGS equ 10h
-
-NESTED_ENTRY Get&name&Generic, _TEXT
- push_vol_reg r10
- push_vol_reg r11
- alloc_stack MIN_SIZE
-
- ; save argument registers in shadow space
- save_reg_postrsp rcx, MIN_SIZE + 8h + SIZEOF_PUSHED_ARGS
- save_reg_postrsp rdx, MIN_SIZE + 10h + SIZEOF_PUSHED_ARGS
- save_reg_postrsp r8, MIN_SIZE + 18h + SIZEOF_PUSHED_ARGS
- save_reg_postrsp r9, MIN_SIZE + 20h + SIZEOF_PUSHED_ARGS
- END_PROLOGUE
-
-ifdef _DEBUG
- cmp dword ptr [g&name&TLSIndex], -1
- jnz @F
- int 3
-@@:
-endif ; _DEBUG
-
-CALL_GET_THREAD_GENERIC_FULL_CHECK=0
-
-ifdef ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-if GenerateGetThread
-
-; Generating the GetThread() tlsgetter, and GetThreadGenericFullCheck is
-; defined in C (in threads.cpp). So we'll want to delegate directly to
-; GetThreadGenericFullCheck, which may choose to do additional checking, such
-; as enforcing EE_THREAD_NOT_REQUIRED contracts
-CALL_GET_THREAD_GENERIC_FULL_CHECK=1
-
-endif ; GenerateGetThread
-endif ; ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-
-if CALL_GET_THREAD_GENERIC_FULL_CHECK
- call GetThreadGenericFullCheck
-else
- ; Not generating the GetThread() tlsgetter (or there is no GetThreadGenericFullCheck
- ; to call), so do nothing special--just look up the value stored at TLS slot gTLSIndex
- mov ecx, [g&name&TLSIndex]
- call [__imp_TlsGetValue]
-endif
-
- ; restore arguments from shadow space
- mov rcx, [rsp + MIN_SIZE + 8h + SIZEOF_PUSHED_ARGS]
- mov rdx, [rsp + MIN_SIZE + 10h + SIZEOF_PUSHED_ARGS]
- mov r8, [rsp + MIN_SIZE + 18h + SIZEOF_PUSHED_ARGS]
- mov r9, [rsp + MIN_SIZE + 20h + SIZEOF_PUSHED_ARGS]
-
- ; epilog
- add rsp, MIN_SIZE
- pop r11
- pop r10
- ret
-NESTED_END Get&name&Generic, _TEXT
-
- endm
-
-GenerateOptimizedTLSGetter Thread, 1
-GenerateOptimizedTLSGetter AppDomain, 0
-
- end
diff --git a/src/vm/amd64/UMThunkStub.asm b/src/vm/amd64/UMThunkStub.asm
index dd6d4ebc3c..8b44e67a7e 100644
--- a/src/vm/amd64/UMThunkStub.asm
+++ b/src/vm/amd64/UMThunkStub.asm
@@ -166,14 +166,12 @@ UMThunkStubAMD64_FIXED_STACK_ALLOC_SIZE = UMThunkStubAMD64_STACK_FRAME_SIZE - (U
;
; Call GetThread()
;
- CALL_GETTHREAD ; will not trash r10
- test rax, rax
+ INLINE_GETTHREAD r12 ; will not trash r10
+ test r12, r12
jz DoThreadSetup
HaveThread:
- mov r12, rax ; r12 <- Thread*
-
;FailFast if a native callable method invoked via ldftn and calli.
cmp dword ptr [r12 + OFFSETOF__Thread__m_fPreemptiveGCDisabled], 1
jz InvalidTransition
@@ -250,6 +248,8 @@ DoThreadSetup:
movdqa xmm1, xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 10h]
movdqa xmm2, xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 20h]
movdqa xmm3, xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 30h]
+
+ mov r12, rax
jmp HaveThread
diff --git a/src/vm/amd64/asmconstants.h b/src/vm/amd64/asmconstants.h
index 1fef80f66d..b6a3c712e7 100644
--- a/src/vm/amd64/asmconstants.h
+++ b/src/vm/amd64/asmconstants.h
@@ -535,22 +535,9 @@ ASMCONSTANTS_C_ASSERT(MethodDescClassification__mdcClassification == mdcClassifi
ASMCONSTANTS_C_ASSERT(MethodDescClassification__mcInstantiated == mcInstantiated);
#ifndef FEATURE_PAL
-
-#define OFFSET__TEB__TlsSlots 0x1480
-ASMCONSTANTS_C_ASSERT(OFFSET__TEB__TlsSlots == offsetof(TEB, TlsSlots));
-
-#define OFFSETOF__TEB__LastErrorValue 0x68
-ASMCONSTANTS_C_ASSERT(OFFSETOF__TEB__LastErrorValue == offsetof(TEB, LastErrorValue));
-
-#endif // !FEATURE_PAL
-
-#ifdef _DEBUG
-#define TLS_GETTER_MAX_SIZE_ASM 0x30
-#else
-#define TLS_GETTER_MAX_SIZE_ASM 0x18
+#define OFFSET__TEB__ThreadLocalStoragePointer 0x58
+ASMCONSTANTS_C_ASSERT(OFFSET__TEB__ThreadLocalStoragePointer == offsetof(TEB, ThreadLocalStoragePointer));
#endif
-ASMCONSTANTS_C_ASSERT(TLS_GETTER_MAX_SIZE_ASM == TLS_GETTER_MAX_SIZE)
-
// If you change these constants, you need to update code in
// RedirectHandledJITCase.asm and ExcepAMD64.cpp.
diff --git a/src/vm/amd64/cgencpu.h b/src/vm/amd64/cgencpu.h
index 98e9770858..b83437039b 100644
--- a/src/vm/amd64/cgencpu.h
+++ b/src/vm/amd64/cgencpu.h
@@ -104,13 +104,6 @@ EXTERN_C void FastCallFinalizeWorker(Object *obj, PCODE funcPtr);
#define X86RegFromAMD64Reg(extended_reg) \
((X86Reg)(((int)extended_reg) & X86_REGISTER_MASK))
-// Max size of optimized TLS helpers
-#ifdef _DEBUG
-// Debug build needs extra space for last error trashing
-#define TLS_GETTER_MAX_SIZE 0x30
-#else
-#define TLS_GETTER_MAX_SIZE 0x18
-#endif
//=======================================================================
// IMPORTANT: This value is used to figure out how much to allocate
@@ -538,26 +531,22 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode)
return TRUE;
}
-#ifndef FEATURE_IMPLICIT_TLS
//
// JIT HELPER ALIASING FOR PORTABILITY.
//
// Create alias for optimized implementations of helpers provided on this platform
//
-#define JIT_GetSharedGCStaticBase JIT_GetSharedGCStaticBase_InlineGetAppDomain
-#define JIT_GetSharedNonGCStaticBase JIT_GetSharedNonGCStaticBase_InlineGetAppDomain
-#define JIT_GetSharedGCStaticBaseNoCtor JIT_GetSharedGCStaticBaseNoCtor_InlineGetAppDomain
-#define JIT_GetSharedNonGCStaticBaseNoCtor JIT_GetSharedNonGCStaticBaseNoCtor_InlineGetAppDomain
-#endif // FEATURE_IMPLICIT_TLS
+#define JIT_GetSharedGCStaticBase JIT_GetSharedGCStaticBase_SingleAppDomain
+#define JIT_GetSharedNonGCStaticBase JIT_GetSharedNonGCStaticBase_SingleAppDomain
+#define JIT_GetSharedGCStaticBaseNoCtor JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain
+#define JIT_GetSharedNonGCStaticBaseNoCtor JIT_GetSharedNonGCStaticBaseNoCtor_SingleAppDomain
#ifndef FEATURE_PAL
-
#define JIT_ChkCastClass JIT_ChkCastClass
#define JIT_ChkCastClassSpecial JIT_ChkCastClassSpecial
#define JIT_IsInstanceOfClass JIT_IsInstanceOfClass
#define JIT_ChkCastInterface JIT_ChkCastInterface
#define JIT_IsInstanceOfInterface JIT_IsInstanceOfInterface
-
#endif // FEATURE_PAL
#define JIT_Stelem_Ref JIT_Stelem_Ref
diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp
index 7b0da7f5a2..edcc3df1d7 100644
--- a/src/vm/appdomain.cpp
+++ b/src/vm/appdomain.cpp
@@ -2406,10 +2406,6 @@ void SystemDomain::Init()
_ASSERTE(curCtx->GetDomain() != NULL);
#endif
-#ifdef _DEBUG
- g_fVerifierOff = g_pConfig->IsVerifierOff();
-#endif
-
#ifdef FEATURE_PREJIT
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ZapDisable) != 0)
g_fAllowNativeImages = false;
diff --git a/src/vm/arm/asmconstants.h b/src/vm/arm/asmconstants.h
index 704fa28556..ab3d16b9a9 100644
--- a/src/vm/arm/asmconstants.h
+++ b/src/vm/arm/asmconstants.h
@@ -256,9 +256,6 @@ ASMCONSTANTS_C_ASSERT(VASigCookie__pNDirectILStub == offsetof(VASigCookie, pNDir
#define CONTEXT_Pc 0x040
ASMCONSTANTS_C_ASSERT(CONTEXT_Pc == offsetof(T_CONTEXT,Pc))
-#define TLS_GETTER_MAX_SIZE_ASM 0x10
-ASMCONSTANTS_C_ASSERT(TLS_GETTER_MAX_SIZE_ASM == TLS_GETTER_MAX_SIZE)
-
#define CallDescrData__pSrc 0x00
#define CallDescrData__numStackSlots 0x04
#define CallDescrData__pArgumentRegisters 0x08
diff --git a/src/vm/arm/asmhelpers.asm b/src/vm/arm/asmhelpers.asm
index e5fd41a513..4d21d07462 100644
--- a/src/vm/arm/asmhelpers.asm
+++ b/src/vm/arm/asmhelpers.asm
@@ -1481,7 +1481,6 @@ stackProbe_loop
NESTED_END
-#ifdef FEATURE_CORECLR
;
; JIT Static access helpers for single appdomain case
;
@@ -1543,7 +1542,6 @@ CallCppHelper3
bx lr
LEAF_END
-#endif
; ------------------------------------------------------------------
; __declspec(naked) void F_CALL_CONV JIT_Stelem_Ref(PtrArray* array, unsigned idx, Object* val)
diff --git a/src/vm/arm/cgencpu.h b/src/vm/arm/cgencpu.h
index 2a369d8f02..8da2b2b3cc 100644
--- a/src/vm/arm/cgencpu.h
+++ b/src/vm/arm/cgencpu.h
@@ -83,9 +83,6 @@ EXTERN_C void setFPReturn(int fpSize, INT64 retVal);
#define CALLDESCR_ARGREGS 1 // CallDescrWorker has ArgumentRegister parameter
#define CALLDESCR_FPARGREGS 1 // CallDescrWorker has FloatArgumentRegisters parameter
-// Max size of optimized TLS helpers
-#define TLS_GETTER_MAX_SIZE 0x10
-
// Given a return address retrieved during stackwalk,
// this is the offset by which it should be decremented to arrive at the callsite.
#define STACKWALK_CONTROLPC_ADJUST_OFFSET 2
@@ -552,7 +549,7 @@ public:
ThumbEmitJumpRegister(thumbRegLr);
}
- void ThumbEmitGetThread(TLSACCESSMODE mode, ThumbReg dest);
+ void ThumbEmitGetThread(ThumbReg dest);
void ThumbEmitNop()
{
@@ -1056,19 +1053,15 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode)
#endif
}
-#ifndef FEATURE_IMPLICIT_TLS
//
// JIT HELPER ALIASING FOR PORTABILITY.
//
// Create alias for optimized implementations of helpers provided on this platform
//
-// optimized static helpers
-#define JIT_GetSharedGCStaticBase JIT_GetSharedGCStaticBase_InlineGetAppDomain
-#define JIT_GetSharedNonGCStaticBase JIT_GetSharedNonGCStaticBase_InlineGetAppDomain
-#define JIT_GetSharedGCStaticBaseNoCtor JIT_GetSharedGCStaticBaseNoCtor_InlineGetAppDomain
-#define JIT_GetSharedNonGCStaticBaseNoCtor JIT_GetSharedNonGCStaticBaseNoCtor_InlineGetAppDomain
-
-#endif
+#define JIT_GetSharedGCStaticBase JIT_GetSharedGCStaticBase_SingleAppDomain
+#define JIT_GetSharedNonGCStaticBase JIT_GetSharedNonGCStaticBase_SingleAppDomain
+#define JIT_GetSharedGCStaticBaseNoCtor JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain
+#define JIT_GetSharedNonGCStaticBaseNoCtor JIT_GetSharedNonGCStaticBaseNoCtor_SingleAppDomain
#ifndef FEATURE_PAL
#define JIT_Stelem_Ref JIT_Stelem_Ref
diff --git a/src/vm/arm/patchedcode.S b/src/vm/arm/patchedcode.S
index 9335fe65fc..43adca25c8 100644
--- a/src/vm/arm/patchedcode.S
+++ b/src/vm/arm/patchedcode.S
@@ -20,22 +20,6 @@
LEAF_END JIT_PatchedCodeStart, _TEXT
// ------------------------------------------------------------------
-// Optimized TLS getters
-
- LEAF_ENTRY GetTLSDummy, _TEXT
- mov r0, #0
- bx lr
- LEAF_END GetTLSDummy, _TEXT
-
- .align 4
- LEAF_ENTRY ClrFlsGetBlock, _TEXT
- // This will be overwritten at runtime with optimized ClrFlsGetBlock implementation
- b C_FUNC(GetTLSDummy)
- // Just allocate space that will be filled in at runtime
- .space (TLS_GETTER_MAX_SIZE_ASM - 2)
- LEAF_END ClrFlsGetBlock, _TEXT
-
-// ------------------------------------------------------------------
// GC write barrier support.
//
// GC Write barriers are defined in asmhelpers.asm. The following functions are used to define
diff --git a/src/vm/arm/patchedcode.asm b/src/vm/arm/patchedcode.asm
index 9fdd60961d..c7e2322e38 100644
--- a/src/vm/arm/patchedcode.asm
+++ b/src/vm/arm/patchedcode.asm
@@ -13,52 +13,6 @@
#include "asmmacros.h"
- SETALIAS JIT_Box,?JIT_Box@@YAPAVObject@@PAUCORINFO_CLASS_STRUCT_@@PAX@Z
- SETALIAS JIT_New, ?JIT_New@@YAPAVObject@@PAUCORINFO_CLASS_STRUCT_@@@Z
- SETALIAS JIT_Box, ?JIT_Box@@YAPAVObject@@PAUCORINFO_CLASS_STRUCT_@@PAX@Z
- SETALIAS FramedAllocateString, ?FramedAllocateString@@YAPAVStringObject@@K@Z
- SETALIAS g_pStringClass, ?g_pStringClass@@3PAVMethodTable@@A
- SETALIAS JIT_NewArr1, ?JIT_NewArr1@@YAPAVObject@@PAUCORINFO_CLASS_STRUCT_@@H@Z
- SETALIAS CopyValueClassUnchecked, ?CopyValueClassUnchecked@@YAXPAX0PAVMethodTable@@@Z
-
- IMPORT $JIT_New
- IMPORT $JIT_Box
- IMPORT $FramedAllocateString
- IMPORT $g_pStringClass
- IMPORT $JIT_NewArr1
- IMPORT $CopyValueClassUnchecked
- IMPORT SetAppDomainInObject
-
-
- IMPORT JIT_GetSharedNonGCStaticBase_Helper
- IMPORT JIT_GetSharedGCStaticBase_Helper
-
-
- EXPORT JIT_TrialAllocSFastMP_InlineGetThread__PatchTLSOffset
- EXPORT JIT_BoxFastMP_InlineGetThread__PatchTLSOffset
- EXPORT AllocateStringFastMP_InlineGetThread__PatchTLSOffset
- EXPORT JIT_NewArr1VC_MP_InlineGetThread__PatchTLSOffset
- EXPORT JIT_NewArr1OBJ_MP_InlineGetThread__PatchTLSOffset
-
- EXPORT JIT_GetSharedNonGCStaticBase__PatchTLSLabel
- EXPORT JIT_GetSharedNonGCStaticBaseNoCtor__PatchTLSLabel
- EXPORT JIT_GetSharedGCStaticBase__PatchTLSLabel
- EXPORT JIT_GetSharedGCStaticBaseNoCtor__PatchTLSLabel
-
- MACRO
- PATCHABLE_INLINE_GETTHREAD $reg, $label
-$label
- mrc p15, 0, $reg, c13, c0, 2
- ldr $reg, [$reg, #0xe10]
- MEND
-
-
- MACRO
- PATCHABLE_INLINE_GETAPPDOMAIN $reg, $label
-$label
- mrc p15, 0, $reg, c13, c0, 2
- ldr $reg, [$reg, #0xe10]
- MEND
TEXTAREA
@@ -70,38 +24,6 @@ $label
LEAF_END
; ------------------------------------------------------------------
-; Optimized TLS getters
-
- ALIGN 4
- LEAF_ENTRY GetThread
- ; This will be overwritten at runtime with optimized GetThread implementation
- b GetTLSDummy
- ; Just allocate space that will be filled in at runtime
- SPACE (TLS_GETTER_MAX_SIZE_ASM - 2)
- LEAF_END
-
- ALIGN 4
- LEAF_ENTRY GetAppDomain
- ; This will be overwritten at runtime with optimized GetThread implementation
- b GetTLSDummy
- ; Just allocate space that will be filled in at runtime
- SPACE (TLS_GETTER_MAX_SIZE_ASM - 2)
- LEAF_END
-
- LEAF_ENTRY GetTLSDummy
- mov r0, #0
- bx lr
- LEAF_END
-
- ALIGN 4
- LEAF_ENTRY ClrFlsGetBlock
- ; This will be overwritten at runtime with optimized ClrFlsGetBlock implementation
- b GetTLSDummy
- ; Just allocate space that will be filled in at runtime
- SPACE (TLS_GETTER_MAX_SIZE_ASM - 2)
- LEAF_END
-
-; ------------------------------------------------------------------
; GC write barrier support.
;
; GC Write barriers are defined in asmhelpers.asm. The following functions are used to define
@@ -134,443 +56,6 @@ $label
bx lr
LEAF_END
-; JIT Allocation helpers when TLS Index for Thread is low enough for fast helpers
-
-;---------------------------------------------------------------------------
-; IN: r0: MethodTable*
-;; OUT: r0: new object
-
- LEAF_ENTRY JIT_TrialAllocSFastMP_InlineGetThread
-
- ;get object size
- ldr r1, [r0, #MethodTable__m_BaseSize]
-
- ; m_BaseSize is guaranteed to be a multiple of 4.
-
- ;getThread
- PATCHABLE_INLINE_GETTHREAD r12, JIT_TrialAllocSFastMP_InlineGetThread__PatchTLSOffset
-
- ;load current allocation pointers
- ldr r2, [r12, #Thread__m_alloc_context__alloc_limit]
- ldr r3, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- ;add object size to current pointer
- add r1, r3
-
- ;if beyond the limit call c++ method
- cmp r1, r2
- bhi AllocFailed
-
- ;r1 is the new alloc_ptr and r3 has object address
- ;update the alloc_ptr in Thread
- str r1, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- ;write methodTable in object
- str r0, [r3]
-
- ;return object in r0
- mov r0, r3
-
-#ifdef _DEBUG
- ; Tail call to a helper that will set the current AppDomain index into the object header and then
- ; return the object pointer back to our original caller.
- b SetAppDomainInObject
-#else
- ;return
- bx lr
-#endif
-
-AllocFailed
- b $JIT_New
- LEAF_END
-
-
-;---------------------------------------------------------------------------
-; HCIMPL2(Object*, JIT_Box, CORINFO_CLASS_HANDLE type, void* unboxedData)
-; IN: r0: MethodTable*
-; IN: r1: data pointer
-;; OUT: r0: new object
-
- LEAF_ENTRY JIT_BoxFastMP_InlineGetThread
-
- ldr r2, [r0, #MethodTable__m_pWriteableData]
-
- ;Check whether the class has been initialized
- ldr r2, [r2, #MethodTableWriteableData__m_dwFlags]
- cmp r2, #MethodTableWriteableData__enum_flag_Unrestored
- bne ClassNotInited
-
- ; Check whether the object contains pointers
- ldr r3, [r0, #MethodTable__m_dwFlags]
- cmp r3, #MethodTable__enum_flag_ContainsPointers
- bne ContainsPointers
-
- ldr r2, [r0, #MethodTable__m_BaseSize]
-
- ;m_BaseSize is guranteed to be a multiple of 4
-
- ;GetThread
- PATCHABLE_INLINE_GETTHREAD r12, JIT_BoxFastMP_InlineGetThread__PatchTLSOffset
-
- ldr r3, [r12, #Thread__m_alloc_context__alloc_ptr]
- add r3, r2
-
- ldr r2, [r12, #Thread__m_alloc_context__alloc_limit]
-
- cmp r3, r2
- bhi AllocFailed2
-
- ldr r2, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- ;advance alloc_ptr in Thread
- str r3, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- ;write methodtable* in the object
- str r0, [r2]
-
- ;copy the contents of value type in the object
-
- ldr r3, [r0, #MethodTable__m_BaseSize]
- sub r3, #0xc
-
- ;r3 = no of bytes to copy
-
- ;move address of object to return register
- mov r0, r2
-
- ;advance r2 to skip methodtable location
- add r2, #4
-
-CopyLoop
- ldr r12, [r1, r3]
- str r12, [r2, r3]
- sub r3, #4
- bne CopyLoop
-
-#ifdef _DEBUG
- ; Tail call to a helper that will set the current AppDomain index into the object header and then
- ; return the object pointer back to our original caller.
- b SetAppDomainInObject
-#else
- ;return
- bx lr
-#endif
-
-ContainsPointers
-ClassNotInited
-AllocFailed2
- b $JIT_Box
- LEAF_END
-
-
-;---------------------------------------------------------------------------
-; IN: r0: number of characters to allocate
-;; OUT: r0: address of newly allocated string
-
- LEAF_ENTRY AllocateStringFastMP_InlineGetThread
-
- ; Instead of doing elaborate overflow checks, we just limit the number of elements to
- ; MAX_FAST_ALLOCATE_STRING_SIZE. This is picked (in asmconstants.h) to avoid any possibility of
- ; overflow and to ensure we never try to allocate anything here that really should go on the large
- ; object heap instead. Additionally the size has been selected so that it will encode into an
- ; immediate in a single cmp instruction.
-
- cmp r0, #MAX_FAST_ALLOCATE_STRING_SIZE
- bhs OversizedString
-
- ; Calculate total string size: Align(base size + (characters * 2), 4).
- mov r1, #(SIZEOF__BaseStringObject + 3) ; r1 == string base size + 3 for alignment round up
- add r1, r1, r0, lsl #1 ; r1 += characters * 2
- bic r1, r1, #3 ; r1 &= ~3; round size to multiple of 4
-
- ;GetThread
- PATCHABLE_INLINE_GETTHREAD r12, AllocateStringFastMP_InlineGetThread__PatchTLSOffset
- ldr r2, [r12, #Thread__m_alloc_context__alloc_limit]
- ldr r3, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- add r1, r3
- cmp r1, r2
- bhi AllocFailed3
-
- ;can allocate
-
- ;advance alloc_ptr
- str r1, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- ; Write MethodTable pointer into new object.
- ldr r1, =$g_pStringClass
- ldr r1, [r1]
- str r1, [r3]
-
- ; Write string length into new object.
- str r0, [r3, #StringObject__m_StringLength]
-
- ;prepare to return new object address
- mov r0, r3
-
-#ifdef _DEBUG
- ; Tail call to a helper that will set the current AppDomain index into the object header and then
- ; return the object pointer back to our original caller.
- b SetAppDomainInObject
-#else
- ;return
- bx lr
-#endif
-
-
-OversizedString
-AllocFailed3
- b $FramedAllocateString
-
- LEAF_END
-
-
-; HCIMPL2(Object*, JIT_NewArr1VC_MP_InlineGetThread, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size)
-;---------------------------------------------------------------------------
-; IN: r0: a (shared) array method table, which contains the element type.
-; IN: r1: number of array elements
-;; OUT: r0: address of newly allocated object
-
- LEAF_ENTRY JIT_NewArr1VC_MP_InlineGetThread
-
- ; Do a conservative check here for number of elements.
- ; This is to avoid overflow while doing the calculations. We don't
- ; have to worry about "large" objects, since the allocation quantum is never big enough for
- ; LARGE_OBJECT_SIZE.
-
- ; For Value Classes, this needs to be < (max_value_in_4byte - size_of_base_array)/(max_size_of_each_element)
- ; This evaluates to (2^32-1 - 0xc)/2^16
-
- ; Additionally the constant has been chosen such that it can be encoded in a
- ; single Thumb2 CMP instruction.
-
- cmp r1, #MAX_FAST_ALLOCATE_ARRAY_VC_SIZE
- bhs OverSizedArray3
-
- ;get element size - stored in low 16bits of m_dwFlags
- ldrh r12, [r0, #MethodTable__m_dwFlags]
-
- ; getting size of object to allocate
-
- ; multiply number of elements with size of each element
- mul r2, r12, r1
-
- ; add the base array size and 3 to align total bytes at 4 byte boundary
- add r2, r2, #SIZEOF__ArrayOfValueType + 3
- bic r2, #3
-
- ;GetThread
- PATCHABLE_INLINE_GETTHREAD r12, JIT_NewArr1VC_MP_InlineGetThread__PatchTLSOffset
- ldr r3, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- add r3, r2
-
- ldr r2, [r12, #Thread__m_alloc_context__alloc_limit]
-
- cmp r3, r2
- bhi AllocFailed6
-
- ; can allocate
-
- ;r2 = address of new object
- ldr r2, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- ;update pointer in allocation context
- str r3, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- ;store number of elements
- str r1, [r2, #ArrayBase__m_NumComponents]
-
- ;store methodtable
- str r0, [r2]
-
- ;copy return value
- mov r0, r2
-
-#ifdef _DEBUG
- ; Tail call to a helper that will set the current AppDomain index into the object header and then
- ; return the object pointer back to our original caller.
- b SetAppDomainInObject
-#else
- ;return
- bx lr
-#endif
-
-
-
-AllocFailed6
-OverSizedArray3
- b $JIT_NewArr1
-
- LEAF_END
-
-
-
-; HCIMPL2(Object*, JIT_NewArr1OBJ_MP_InlineGetThread, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size)
-;---------------------------------------------------------------------------
-; IN: r0: a (shared) array method table, which contains the element type.
-; IN: r1: number of array elements
-;; OUT: r0: address of newly allocated object
-
- LEAF_ENTRY JIT_NewArr1OBJ_MP_InlineGetThread
-
- cmp r1, #MAX_FAST_ALLOCATE_ARRAY_OBJECTREF_SIZE
- bhs OverSizedArray
-
- mov r2, #SIZEOF__ArrayOfObjectRef
- add r2, r2, r1, lsl #2
-
- ;r2 will be a multiple of 4
-
-
- ;GetThread
- PATCHABLE_INLINE_GETTHREAD r12, JIT_NewArr1OBJ_MP_InlineGetThread__PatchTLSOffset
- ldr r3, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- add r3, r2
-
- ldr r2, [r12, #Thread__m_alloc_context__alloc_limit]
-
- cmp r3, r2
- bhi AllocFailed4
-
- ;can allocate
-
- ;r2 = address of new object
- ldr r2, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- ;update pointer in allocation context
- str r3, [r12, #Thread__m_alloc_context__alloc_ptr]
-
- ;store number of elements
- str r1, [r2, #ArrayBase__m_NumComponents]
-
- ;store methodtable
- str r0, [r2]
-
- ;copy return value
- mov r0, r2
-
-#ifdef _DEBUG
- ; Tail call to a helper that will set the current AppDomain index into the object header and then
- ; return the object pointer back to our original caller.
- b SetAppDomainInObject
-#else
- ;return
- bx lr
-#endif
-
-OverSizedArray
-AllocFailed4
- b $JIT_NewArr1
- LEAF_END
-
-;
-; JIT Static access helpers when TLS Index for AppDomain is low enough for fast helpers
-;
-
-; ------------------------------------------------------------------
-; void* JIT_GetSharedNonGCStaticBase(SIZE_T moduleDomainID, DWORD dwClassDomainID)
-
- LEAF_ENTRY JIT_GetSharedNonGCStaticBase_InlineGetAppDomain
- ; Check if r0 (moduleDomainID) is not a moduleID
- tst r0, #1
- beq HaveLocalModule1
-
- PATCHABLE_INLINE_GETAPPDOMAIN r2, JIT_GetSharedNonGCStaticBase__PatchTLSLabel
-
- ; Get the LocalModule, r0 will always be odd, so: r0 * 2 - 2 <=> (r0 >> 1) * 4
- ldr r2, [r2 , #AppDomain__m_sDomainLocalBlock + DomainLocalBlock__m_pModuleSlots]
- add r2, r2, r0, LSL #1
- ldr r0, [r2, #-2]
-
-HaveLocalModule1
- ; If class is not initialized, bail to C++ helper
- add r2, r0, #DomainLocalModule__m_pDataBlob
- ldrb r2, [r2, r1]
- tst r2, #1
- beq CallHelper1
-
- bx lr
-
-CallHelper1
- ; Tail call JIT_GetSharedNonGCStaticBase_Helper
- b JIT_GetSharedNonGCStaticBase_Helper
- LEAF_END
-
-
-; ------------------------------------------------------------------
-; void* JIT_GetSharedNonGCStaticBaseNoCtor(SIZE_T moduleDomainID, DWORD dwClassDomainID)
-
- LEAF_ENTRY JIT_GetSharedNonGCStaticBaseNoCtor_InlineGetAppDomain
- ; Check if r0 (moduleDomainID) is not a moduleID
- tst r0, #1
- beq HaveLocalModule2
-
- PATCHABLE_INLINE_GETAPPDOMAIN r2, JIT_GetSharedNonGCStaticBaseNoCtor__PatchTLSLabel
-
- ; Get the LocalModule, r0 will always be odd, so: r0 * 2 - 2 <=> (r0 >> 1) * 4
- ldr r2, [r2 , #AppDomain__m_sDomainLocalBlock + DomainLocalBlock__m_pModuleSlots]
- add r2, r2, r0, LSL #1
- ldr r0, [r2, #-2]
-
-
-HaveLocalModule2
- bx lr
- LEAF_END
-
-
-; ------------------------------------------------------------------
-; void* JIT_GetSharedGCStaticBase(SIZE_T moduleDomainID, DWORD dwClassDomainID)
-
- LEAF_ENTRY JIT_GetSharedGCStaticBase_InlineGetAppDomain
- ; Check if r0 (moduleDomainID) is not a moduleID
- tst r0, #1
- beq HaveLocalModule3
-
- PATCHABLE_INLINE_GETAPPDOMAIN r2, JIT_GetSharedGCStaticBase__PatchTLSLabel
-
- ; Get the LocalModule, r0 will always be odd, so: r0 * 2 - 2 <=> (r0 >> 1) * 4
- ldr r2, [r2 , #AppDomain__m_sDomainLocalBlock + DomainLocalBlock__m_pModuleSlots]
- add r2, r2, r0, LSL #1
- ldr r0, [r2, #-2]
-
-HaveLocalModule3
- ; If class is not initialized, bail to C++ helper
- add r2, r0, #DomainLocalModule__m_pDataBlob
- ldrb r2, [r2, r1]
- tst r2, #1
- beq CallHelper3
-
- ldr r0, [r0, #DomainLocalModule__m_pGCStatics]
- bx lr
-
-CallHelper3
- ; Tail call Jit_GetSharedGCStaticBase_Helper
- b JIT_GetSharedGCStaticBase_Helper
- LEAF_END
-
-
-; ------------------------------------------------------------------
-; void* JIT_GetSharedGCStaticBaseNoCtor(SIZE_T moduleDomainID, DWORD dwClassDomainID)
-
- LEAF_ENTRY JIT_GetSharedGCStaticBaseNoCtor_InlineGetAppDomain
- ; Check if r0 (moduleDomainID) is not a moduleID
- tst r0, #1
- beq HaveLocalModule4
-
- PATCHABLE_INLINE_GETAPPDOMAIN r2, JIT_GetSharedGCStaticBaseNoCtor__PatchTLSLabel
-
- ; Get the LocalModule, r0 will always be odd, so: r0 * 2 - 2 <=> (r0 >> 1) * 4
- ldr r2, [r2 , #AppDomain__m_sDomainLocalBlock + DomainLocalBlock__m_pModuleSlots]
- add r2, r2, r0, LSL #1
- ldr r0, [r2, #-2]
-
-HaveLocalModule4
- ldr r0, [r0, #DomainLocalModule__m_pGCStatics]
- bx lr
- LEAF_END
-
; ------------------------------------------------------------------
; End of the writeable code region
LEAF_ENTRY JIT_PatchedCodeLast
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());
diff --git a/src/vm/arm64/cgencpu.h b/src/vm/arm64/cgencpu.h
index 8abe4de6ab..a168cdc162 100644
--- a/src/vm/arm64/cgencpu.h
+++ b/src/vm/arm64/cgencpu.h
@@ -84,7 +84,11 @@ typedef INT64 StackElemType;
//
// Create alias for optimized implementations of helpers provided on this platform
//
-// optimized static helpers
+#define JIT_GetSharedGCStaticBase JIT_GetSharedGCStaticBase_SingleAppDomain
+#define JIT_GetSharedNonGCStaticBase JIT_GetSharedNonGCStaticBase_SingleAppDomain
+#define JIT_GetSharedGCStaticBaseNoCtor JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain
+#define JIT_GetSharedNonGCStaticBaseNoCtor JIT_GetSharedNonGCStaticBaseNoCtor_SingleAppDomain
+
#define JIT_Stelem_Ref JIT_Stelem_Ref
//**********************************************************************
@@ -435,10 +439,8 @@ public:
void EmitUnboxMethodStub(MethodDesc* pRealMD);
void EmitCallManagedMethod(MethodDesc *pMD, BOOL fTailCall);
void EmitCallLabel(CodeLabel *target, BOOL fTailCall, BOOL fIndirect);
- void EmitSecureDelegateInvoke(UINT_PTR hash);
- static UINT_PTR HashMulticastInvoke(MetaSig* pSig);
+
void EmitShuffleThunk(struct ShuffleEntry *pShuffleEntryArray);
- void EmitGetThreadInlined(IntReg Xt);
#ifdef _DEBUG
void EmitNop() { Emit32(0xD503201F); }
diff --git a/src/vm/arm64/stubs.cpp b/src/vm/arm64/stubs.cpp
index c57fca94b1..3c56c382ea 100644
--- a/src/vm/arm64/stubs.cpp
+++ b/src/vm/arm64/stubs.cpp
@@ -16,10 +16,6 @@
#include "jitinterface.h"
#include "ecall.h"
-EXTERN_C void JIT_GetSharedNonGCStaticBase_SingleAppDomain();
-EXTERN_C void JIT_GetSharedNonGCStaticBaseNoCtor_SingleAppDomain();
-EXTERN_C void JIT_GetSharedGCStaticBase_SingleAppDomain();
-EXTERN_C void JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain();
EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck);
@@ -1114,14 +1110,6 @@ void InitJITHelpers1()
}
#endif
- 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);
- }
-
JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap());
}
#ifndef FEATURE_PAL // TODO-ARM64-WINDOWS #13592
@@ -1846,33 +1834,6 @@ void StubLinkerCPU::EmitCallManagedMethod(MethodDesc *pMD, BOOL fTailCall)
#ifndef CROSSGEN_COMPILE
-EXTERN_C UINT32 _tls_index;
-void StubLinkerCPU::EmitGetThreadInlined(IntReg Xt)
-{
-#if defined(FEATURE_IMPLICIT_TLS) && !defined(FEATURE_PAL)
- // Trashes x8.
- IntReg X8 = IntReg(8);
- _ASSERTE(Xt != X8);
-
- // Load the _tls_index
- EmitLabelRef(NewExternalCodeLabel((LPVOID)&_tls_index), reinterpret_cast<LoadFromLabelInstructionFormat&>(gLoadFromLabelIF), X8);
-
- // Load Teb->ThreadLocalStoragePointer into x8
- EmitLoadStoreRegImm(eLOAD, Xt, IntReg(18), offsetof(_TEB, ThreadLocalStoragePointer));
-
- // index it with _tls_index, i.e Teb->ThreadLocalStoragePointer[_tls_index].
- // This will give us the TLS section for the module on this thread's context
- EmitLoadRegReg(Xt, Xt, X8, eLSL);
-
- // read the Thread* from TLS section
- EmitAddImm(Xt, Xt, OFFSETOF__TLS__tls_CurrentThread);
- EmitLoadStoreRegImm(eLOAD, Xt, Xt, 0);
-#else
- _ASSERTE(!"NYI:StubLinkerCPU::EmitGetThreadInlined");
-#endif
-
-}
-
void StubLinkerCPU::EmitUnboxMethodStub(MethodDesc *pMD)
{
_ASSERTE(!pMD->RequiresInstMethodDescArg());
diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp
index c64d9e9042..f5173196e3 100644
--- a/src/vm/ceeload.cpp
+++ b/src/vm/ceeload.cpp
@@ -10844,11 +10844,7 @@ void Module::LoadTokenTables()
pEEInfo->emptyString = (CORINFO_Object **)StringObject::GetEmptyStringRefPtr();
}
-#ifdef FEATURE_IMPLICIT_TLS
pEEInfo->threadTlsIndex = TLS_OUT_OF_INDEXES;
-#else
- pEEInfo->threadTlsIndex = GetThreadTLSIndex();
-#endif
pEEInfo->rvaStaticTlsIndex = NULL;
#endif // CROSSGEN_COMPILE
}
diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp
index 44f5d8eb1d..9dbe2b9dff 100644
--- a/src/vm/ceemain.cpp
+++ b/src/vm/ceemain.cpp
@@ -2714,17 +2714,7 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
, TRUE
#endif
);
-#ifdef FEATURE_IMPLICIT_TLS
Thread* thread = GetThread();
-#else
- // Don't use GetThread because perhaps we didn't initialize yet, or we
- // have already shutdown the EE. Note that there is a race here. We
- // might ask for TLS from a slot we just released. We are assuming that
- // nobody re-allocates that same slot while we are doing this. It just
- // isn't worth locking for such an obscure case.
- DWORD tlsVal = GetThreadTLSIndex();
- Thread *thread = (tlsVal != (DWORD)-1)?(Thread *) UnsafeTlsGetValue(tlsVal):NULL;
-#endif
if (thread)
{
#ifdef FEATURE_COMINTEROP
diff --git a/src/vm/ceemain.h b/src/vm/ceemain.h
index ccf763ac80..9a14af54ca 100644
--- a/src/vm/ceemain.h
+++ b/src/vm/ceemain.h
@@ -83,8 +83,6 @@ public:
// Setup FLS simulation block, including ClrDebugState and StressLog.
static void SetupTLSForThread(Thread *pThread);
- static DWORD GetTlsIndex () {return TlsIndex;}
-
static LPVOID* GetTlsData();
static BOOL SetTlsData (void** ppTlsInfo);
@@ -92,12 +90,6 @@ public:
// private implementation:
//***************************************************************************
private:
-
- // The debugger needs access to the TlsIndex so that we can read it from OOP.
- friend class EEDbgInterfaceImpl;
-
- SVAL_DECL (DWORD, TlsIndex);
-
static PTLS_CALLBACK_FUNCTION Callbacks[MAX_PREDEFINED_TLS_SLOT];
//***************************************************************************
diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp
index f6ca34267a..b1e5a8a0f3 100644
--- a/src/vm/corhost.cpp
+++ b/src/vm/corhost.cpp
@@ -51,7 +51,6 @@
GVAL_IMPL_INIT(DWORD, g_fHostConfig, 0);
-#ifdef FEATURE_IMPLICIT_TLS
#ifndef __llvm__
EXTERN_C __declspec(thread) ThreadLocalInfo gCurrentThreadInfo;
#else // !__llvm__
@@ -62,11 +61,6 @@ EXTERN_C UINT32 _tls_index;
#else // FEATURE_PAL
UINT32 _tls_index = 0;
#endif // FEATURE_PAL
-SVAL_IMPL_INIT(DWORD, CExecutionEngine, TlsIndex, _tls_index);
-#else
-SVAL_IMPL_INIT(DWORD, CExecutionEngine, TlsIndex, TLS_OUT_OF_INDEXES);
-#endif
-
#if defined(FEATURE_WINDOWSPHONE)
SVAL_IMPL_INIT(ECustomDumpFlavor, CCLRErrorReportingManager, g_ECustomDumpFlavor, DUMP_FLAVOR_Default);
@@ -3168,7 +3162,6 @@ VOID WINAPI FlsCallback(
#endif // HAS_FLS_SUPPORT
-#ifdef FEATURE_IMPLICIT_TLS
void** CExecutionEngine::GetTlsData()
{
LIMITED_METHOD_CONTRACT;
@@ -3183,28 +3176,6 @@ BOOL CExecutionEngine::SetTlsData (void** ppTlsInfo)
gCurrentThreadInfo.m_EETlsData = ppTlsInfo;
return TRUE;
}
-#else
-void** CExecutionEngine::GetTlsData()
-{
- LIMITED_METHOD_CONTRACT;
-
- if (TlsIndex == TLS_OUT_OF_INDEXES)
- return NULL;
-
- void **ppTlsData = (void **)UnsafeTlsGetValue(TlsIndex);
- return ppTlsData;
-}
-BOOL CExecutionEngine::SetTlsData (void** ppTlsInfo)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (TlsIndex == TLS_OUT_OF_INDEXES)
- return FALSE;
-
- return UnsafeTlsSetValue(TlsIndex, ppTlsInfo);
-}
-
-#endif // FEATURE_IMPLICIT_TLS
//---------------------------------------------------------------------------------------
//
@@ -3295,25 +3266,6 @@ void **CExecutionEngine::CheckThreadState(DWORD slot, BOOL force)
}
#endif // HAS_FLS_SUPPORT
-#ifndef FEATURE_IMPLICIT_TLS
- // Ensure we have a TLS Index
- if (TlsIndex == TLS_OUT_OF_INDEXES)
- {
- DWORD tryTlsIndex = UnsafeTlsAlloc();
- if (tryTlsIndex != TLS_OUT_OF_INDEXES)
- {
- if (FastInterlockCompareExchange((LONG*)&TlsIndex, tryTlsIndex, TLS_OUT_OF_INDEXES) != (LONG)TLS_OUT_OF_INDEXES)
- {
- UnsafeTlsFree(tryTlsIndex);
- }
- }
- if (TlsIndex == TLS_OUT_OF_INDEXES)
- {
- COMPlusThrowOM();
- }
- }
-#endif // FEATURE_IMPLICIT_TLS
-
void** pTlsData = CExecutionEngine::GetTlsData();
BOOL fInTls = (pTlsData != NULL);
diff --git a/src/vm/crossgencompile.cpp b/src/vm/crossgencompile.cpp
index c4b9d3dfc3..411029becd 100644
--- a/src/vm/crossgencompile.cpp
+++ b/src/vm/crossgencompile.cpp
@@ -72,27 +72,6 @@ BOOL Debug_IsLockedViaThreadSuspension()
}
#endif // _DEBUG
-#if defined(FEATURE_MERGE_JIT_AND_ENGINE) && defined(FEATURE_IMPLICIT_TLS)
-void* theJitTls;
-
-extern "C"
-{
-
-void* GetJitTls()
-{
- LIMITED_METHOD_CONTRACT
-
- return theJitTls;
-}
-void SetJitTls(void* v)
-{
- LIMITED_METHOD_CONTRACT
- theJitTls = v;
-}
-
-}
-#endif
-
//---------------------------------------------------------------------------------------
//
// All locks are nops because of there is always only one thread.
diff --git a/src/vm/eedbginterface.h b/src/vm/eedbginterface.h
index 8c8c44d3e2..241ef332e2 100644
--- a/src/vm/eedbginterface.h
+++ b/src/vm/eedbginterface.h
@@ -280,7 +280,6 @@ public:
virtual void GetRuntimeOffsets(SIZE_T *pTLSIndex,
SIZE_T *pTLSIsSpecialIndex,
SIZE_T *pTLSCantStopIndex,
- SIZE_T *pTLSIndexOfPredefs,
SIZE_T *pEEThreadStateOffset,
SIZE_T *pEEThreadStateNCOffset,
SIZE_T *pEEThreadPGCDisabledOffset,
diff --git a/src/vm/eedbginterfaceimpl.cpp b/src/vm/eedbginterfaceimpl.cpp
index ede82c7780..e9f59d25d2 100644
--- a/src/vm/eedbginterfaceimpl.cpp
+++ b/src/vm/eedbginterfaceimpl.cpp
@@ -1387,14 +1387,11 @@ void EEDbgInterfaceImpl::DisableTraceCall(Thread *thread)
thread->DecrementTraceCallCount();
}
-#ifdef FEATURE_IMPLICIT_TLS
EXTERN_C UINT32 _tls_index;
-#endif
void EEDbgInterfaceImpl::GetRuntimeOffsets(SIZE_T *pTLSIndex,
SIZE_T *pTLSIsSpecialIndex,
SIZE_T *pTLSCantStopIndex,
- SIZE_T* pTLSIndexOfPredefs,
SIZE_T *pEEThreadStateOffset,
SIZE_T *pEEThreadStateNCOffset,
SIZE_T *pEEThreadPGCDisabledOffset,
@@ -1417,7 +1414,6 @@ void EEDbgInterfaceImpl::GetRuntimeOffsets(SIZE_T *pTLSIndex,
PRECONDITION(CheckPointer(pTLSIndex));
PRECONDITION(CheckPointer(pTLSIsSpecialIndex));
PRECONDITION(CheckPointer(pEEThreadStateOffset));
- PRECONDITION(CheckPointer(pTLSIndexOfPredefs));
PRECONDITION(CheckPointer(pEEThreadStateNCOffset));
PRECONDITION(CheckPointer(pEEThreadPGCDisabledOffset));
PRECONDITION(CheckPointer(pEEThreadPGCDisabledValue));
@@ -1433,14 +1429,9 @@ void EEDbgInterfaceImpl::GetRuntimeOffsets(SIZE_T *pTLSIndex,
}
CONTRACTL_END;
-#ifdef FEATURE_IMPLICIT_TLS
- *pTLSIndex = _tls_index;
-#else
- *pTLSIndex = GetThreadTLSIndex();
-#endif
+ *pTLSIndex = g_TlsIndex;
*pTLSIsSpecialIndex = TlsIdx_ThreadType;
*pTLSCantStopIndex = TlsIdx_CantStopCount;
- *pTLSIndexOfPredefs = CExecutionEngine::TlsIndex;
*pEEThreadStateOffset = Thread::GetOffsetOfState();
*pEEThreadStateNCOffset = Thread::GetOffsetOfStateNC();
*pEEThreadPGCDisabledOffset = Thread::GetOffsetOfGCFlag();
diff --git a/src/vm/eedbginterfaceimpl.h b/src/vm/eedbginterfaceimpl.h
index 979c706fb2..7451246a21 100644
--- a/src/vm/eedbginterfaceimpl.h
+++ b/src/vm/eedbginterfaceimpl.h
@@ -272,7 +272,6 @@ public:
void GetRuntimeOffsets(SIZE_T *pTLSIndex,
SIZE_T *pTLSIsSpecialIndex,
SIZE_T *pTLSCantStopIndex,
- SIZE_T *pTLSIndexOfPredefs,
SIZE_T *pEEThreadStateOffset,
SIZE_T *pEEThreadStateNCOffset,
SIZE_T *pEEThreadPGCDisabledOffset,
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);
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index d326a92ccb..f49ced56d0 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -9932,19 +9932,6 @@ DWORD CEEInfo::getThreadTLSIndex(void **ppIndirection)
if (ppIndirection != NULL)
*ppIndirection = NULL;
- JIT_TO_EE_TRANSITION();
-
-#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_IMPLICIT_TLS)
- result = GetThreadTLSIndex();
-
- // The JIT can use the optimized TLS access only if the runtime is using it as well.
- // (This is necessaryto make managed code work well under appverifier.)
- if (GetTLSAccessMode(result) == TLSACCESS_GENERIC)
- result = (DWORD)-1;
-#endif
-
- EE_TO_JIT_TRANSITION();
-
return result;
}
diff --git a/src/vm/jitinterfacegen.cpp b/src/vm/jitinterfacegen.cpp
index 38f1a7436a..b630e7f998 100644
--- a/src/vm/jitinterfacegen.cpp
+++ b/src/vm/jitinterfacegen.cpp
@@ -47,24 +47,10 @@ EXTERN_C Object* JIT_NewArr1OBJ_UP (CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
EXTERN_C Object* JIT_NewArr1VC_MP (CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
EXTERN_C Object* JIT_NewArr1VC_UP (CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
-extern "C" void* JIT_GetSharedNonGCStaticBase_Slow(SIZE_T moduleDomainID, DWORD dwModuleClassID);
-extern "C" void* JIT_GetSharedNonGCStaticBaseNoCtor_Slow(SIZE_T moduleDomainID, DWORD dwModuleClassID);
-extern "C" void* JIT_GetSharedGCStaticBase_Slow(SIZE_T moduleDomainID, DWORD dwModuleClassID);
-extern "C" void* JIT_GetSharedGCStaticBaseNoCtor_Slow(SIZE_T moduleDomainID, DWORD dwModuleClassID);
-
-extern "C" void* JIT_GetSharedNonGCStaticBase_SingleAppDomain(SIZE_T moduleDomainID, DWORD dwModuleClassID);
-extern "C" void* JIT_GetSharedNonGCStaticBaseNoCtor_SingleAppDomain(SIZE_T moduleDomainID, DWORD dwModuleClassID);
-extern "C" void* JIT_GetSharedGCStaticBase_SingleAppDomain(SIZE_T moduleDomainID, DWORD dwModuleClassID);
-extern "C" void* JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain(SIZE_T moduleDomainID, DWORD dwModuleClassID);
-
#ifdef _TARGET_AMD64_
extern WriteBarrierManager g_WriteBarrierManager;
#endif // _TARGET_AMD64_
-#ifndef FEATURE_IMPLICIT_TLS
-EXTERN_C DWORD gThreadTLSIndex;
-EXTERN_C DWORD gAppDomainTLSIndex;
-#endif
#endif // _WIN64
/*********************************************************************/
@@ -73,99 +59,6 @@ EXTERN_C DWORD gAppDomainTLSIndex;
/*********************************************************************/
#ifndef _TARGET_X86_
-#if defined(_TARGET_AMD64_)
-
-void MakeIntoJumpStub(LPVOID pStubAddress, LPVOID pTarget)
-{
- BYTE* pbStubAddress = (BYTE*)pStubAddress;
- BYTE* pbTarget = (BYTE*)pTarget;
-
- DWORD dwOldProtect;
- if (!ClrVirtualProtect(pbStubAddress, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect))
- {
- ThrowLastError();
- }
-
- DWORD diff = (DWORD)(pbTarget - (pbStubAddress + 5));
-
- // Make sure that the offset fits in 32-bits
- _ASSERTE( FitsInI4(pbTarget - (pbStubAddress + 5)) );
-
- // Write a jmp pcrel32 instruction
- //
- // 0xe9xxxxxxxx
- pbStubAddress[0] = 0xE9;
- *((DWORD*)&pbStubAddress[1]) = diff;
-
- ClrVirtualProtect(pbStubAddress, 5, dwOldProtect, &dwOldProtect);
-}
-
-EXTERN_C void JIT_TrialAllocSFastMP_InlineGetThread__PatchTLSOffset();
-EXTERN_C void JIT_BoxFastMPIGT__PatchTLSLabel();
-EXTERN_C void AllocateStringFastMP_InlineGetThread__PatchTLSOffset();
-EXTERN_C void JIT_NewArr1VC_MP_InlineGetThread__PatchTLSOffset();
-EXTERN_C void JIT_NewArr1OBJ_MP_InlineGetThread__PatchTLSOffset();
-
-
-static const LPVOID InlineGetThreadLocations[] = {
- (PVOID)JIT_TrialAllocSFastMP_InlineGetThread__PatchTLSOffset,
- (PVOID)JIT_BoxFastMPIGT__PatchTLSLabel,
- (PVOID)AllocateStringFastMP_InlineGetThread__PatchTLSOffset,
- (PVOID)JIT_NewArr1VC_MP_InlineGetThread__PatchTLSOffset,
- (PVOID)JIT_NewArr1OBJ_MP_InlineGetThread__PatchTLSOffset,
-};
-
-EXTERN_C void JIT_GetSharedNonGCStaticBase__PatchTLSLabel();
-EXTERN_C void JIT_GetSharedNonGCStaticBaseNoCtor__PatchTLSLabel();
-EXTERN_C void JIT_GetSharedGCStaticBase__PatchTLSLabel();
-EXTERN_C void JIT_GetSharedGCStaticBaseNoCtor__PatchTLSLabel();
-
-static const LPVOID InlineGetAppDomainLocations[] = {
- (PVOID)JIT_GetSharedNonGCStaticBase__PatchTLSLabel,
- (PVOID)JIT_GetSharedNonGCStaticBaseNoCtor__PatchTLSLabel,
- (PVOID)JIT_GetSharedGCStaticBase__PatchTLSLabel,
- (PVOID)JIT_GetSharedGCStaticBaseNoCtor__PatchTLSLabel
-};
-
-
-#endif // defined(_TARGET_AMD64_)
-
-#if defined(_WIN64) && !defined(FEATURE_IMPLICIT_TLS)
-void FixupInlineGetters(DWORD tlsSlot, const LPVOID * pLocations, int nLocations)
-{
- BYTE* pInlineGetter;
- DWORD dwOldProtect;
- for (int i=0; i<nLocations; i++)
- {
- pInlineGetter = (BYTE*)GetEEFuncEntryPoint((BYTE*)pLocations[i]);
-
- static const DWORD cbPatch = 9;
- if (!ClrVirtualProtect(pInlineGetter, cbPatch, PAGE_EXECUTE_READWRITE, &dwOldProtect))
- {
- ThrowLastError();
- }
-
- DWORD offset = (tlsSlot * sizeof(LPVOID) + offsetof(TEB, TlsSlots));
-
-#if defined(_TARGET_AMD64_)
- // mov r??, gs:[TLS offset]
- _ASSERTE_ALL_BUILDS("clr/src/VM/JITinterfaceGen.cpp",
- pInlineGetter[0] == 0x65 &&
- pInlineGetter[2] == 0x8B &&
- pInlineGetter[4] == 0x25 &&
- "Initialization failure while stomping instructions for the TLS slot offset: the instruction at the given offset did not match what we expect");
-
- *((DWORD*)(pInlineGetter + 5)) = offset;
-#else // _TARGET_AMD64_
- PORTABILITY_ASSERT("FixupInlineGetters");
-#endif //_TARGET_AMD64_
-
- FlushInstructionCache(GetCurrentProcess(), pInlineGetter, cbPatch);
- ClrVirtualProtect(pInlineGetter, cbPatch, dwOldProtect, &dwOldProtect);
- }
-}
-#endif // defined(_WIN64) && !defined(FEATURE_IMPLICIT_TLS)
-
void InitJITHelpers1()
{
STANDARD_VM_CONTRACT;
@@ -176,18 +69,6 @@ void InitJITHelpers1()
g_WriteBarrierManager.Initialize();
-#ifndef FEATURE_IMPLICIT_TLS
- if (gThreadTLSIndex < TLS_MINIMUM_AVAILABLE)
- {
- FixupInlineGetters(gThreadTLSIndex, InlineGetThreadLocations, COUNTOF(InlineGetThreadLocations));
- }
-
- if (gAppDomainTLSIndex < TLS_MINIMUM_AVAILABLE)
- {
- FixupInlineGetters(gAppDomainTLSIndex, InlineGetAppDomainLocations, COUNTOF(InlineGetAppDomainLocations));
- }
-#endif // !FEATURE_IMPLICIT_TLS
-
// Allocation helpers, faster but non-logging
if (!((TrackAllocationsEnabled()) ||
(LoggingOn(LF_GCALLOC, LL_INFO10))
@@ -196,43 +77,27 @@ void InitJITHelpers1()
#endif // _DEBUG
))
{
+#ifdef FEATURE_PAL
+ SetJitHelperFunction(CORINFO_HELP_NEWSFAST, JIT_NewS_MP_FastPortable);
+ SetJitHelperFunction(CORINFO_HELP_NEWSFAST_ALIGN8, 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(AllocateString_MP_FastPortable), ECall::FastAllocateString);
+#else // FEATURE_PAL
// if (multi-proc || server GC)
if (GCHeapUtilities::UseThreadAllocationContexts())
{
-#ifdef FEATURE_IMPLICIT_TLS
- SetJitHelperFunction(CORINFO_HELP_NEWSFAST, JIT_NewS_MP_FastPortable);
- SetJitHelperFunction(CORINFO_HELP_NEWSFAST_ALIGN8, 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(AllocateString_MP_FastPortable), ECall::FastAllocateString);
-#else // !FEATURE_IMPLICIT_TLS
- // 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_NEWSFAST_ALIGN8, 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_NEWSFAST_ALIGN8, 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_TrialAllocSFastMP_InlineGetThread);
+ SetJitHelperFunction(CORINFO_HELP_NEWSFAST_ALIGN8, 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), ECall::FastAllocateString);
- }
-#endif // FEATURE_IMPLICIT_TLS
+ ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateStringFastMP_InlineGetThread), ECall::FastAllocateString);
}
else
{
-#ifndef FEATURE_PAL
// Replace the 1p slow allocation helpers with faster version
//
// When we're running Workstation GC on a single proc box we don't have
@@ -244,27 +109,9 @@ void InitJITHelpers1()
SetJitHelperFunction(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1OBJ_UP);
ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateStringFastUP), ECall::FastAllocateString);
-#endif // !FEATURE_PAL
}
+#endif // FEATURE_PAL
}
-
- 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);
- }
-#ifndef FEATURE_IMPLICIT_TLS
- else
- if (gAppDomainTLSIndex >= TLS_MINIMUM_AVAILABLE)
- {
- SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE, JIT_GetSharedGCStaticBase_Slow);
- SetJitHelperFunction(CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE, JIT_GetSharedNonGCStaticBase_Slow);
- SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR, JIT_GetSharedGCStaticBaseNoCtor_Slow);
- SetJitHelperFunction(CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR,JIT_GetSharedNonGCStaticBaseNoCtor_Slow);
- }
-#endif // !FEATURE_IMPLICIT_TLS
#endif // _TARGET_AMD64_
}
diff --git a/src/vm/threads.cpp b/src/vm/threads.cpp
index 56bdffb1f1..941d3645be 100644
--- a/src/vm/threads.cpp
+++ b/src/vm/threads.cpp
@@ -71,10 +71,6 @@ static CrstStatic s_initializeYieldProcessorNormalizedCrst;
BOOL Thread::s_fCleanFinalizedThread = FALSE;
-#ifdef ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-BOOL Thread::s_fEnforceEEThreadNotRequiredContracts = FALSE;
-#endif
-
Volatile<LONG> Thread::s_threadPoolCompletionCountOverflow = 0;
CrstStatic g_DeadlockAwareCrst;
@@ -290,9 +286,6 @@ bool Thread::DetectHandleILStubsForDebugger()
return false;
}
-
-#ifdef FEATURE_IMPLICIT_TLS
-
extern "C" {
#ifndef __llvm__
__declspec(thread)
@@ -304,26 +297,15 @@ ThreadLocalInfo gCurrentThreadInfo =
NULL, // m_pThread
NULL, // m_pAppDomain
NULL, // m_EETlsData
-#if defined(FEATURE_MERGE_JIT_AND_ENGINE)
- NULL, // m_pCompiler
-#endif
};
} // extern "C"
// index into TLS Array. Definition added by compiler
EXTERN_C UINT32 _tls_index;
-#else // FEATURE_IMPLICIT_TLS
-extern "C" {
-GVAL_IMPL_INIT(DWORD, gThreadTLSIndex, TLS_OUT_OF_INDEXES); // index ( (-1) == uninitialized )
-GVAL_IMPL_INIT(DWORD, gAppDomainTLSIndex, TLS_OUT_OF_INDEXES); // index ( (-1) == uninitialized )
-}
-#endif // FEATURE_IMPLICIT_TLS
-
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_IMPLICIT_TLS
BOOL SetThread(Thread* t)
{
- LIMITED_METHOD_CONTRACT
+ LIMITED_METHOD_CONTRACT
gCurrentThreadInfo.m_pThread = t;
return TRUE;
@@ -331,52 +313,12 @@ BOOL SetThread(Thread* t)
BOOL SetAppDomain(AppDomain* ad)
{
- LIMITED_METHOD_CONTRACT
+ LIMITED_METHOD_CONTRACT
gCurrentThreadInfo.m_pAppDomain = ad;
return TRUE;
}
-#if defined(FEATURE_MERGE_JIT_AND_ENGINE)
-extern "C"
-{
-
-void* GetJitTls()
-{
- LIMITED_METHOD_CONTRACT
-
- return gCurrentThreadInfo.m_pJitTls;
-}
-
-void SetJitTls(void* v)
-{
- LIMITED_METHOD_CONTRACT
- gCurrentThreadInfo.m_pJitTls = v;
-}
-
-}
-#endif // defined(FEATURE_MERGE_JIT_AND_ENGINE)
-
-#define ThreadInited() (TRUE)
-
-#else // FEATURE_IMPLICIT_TLS
-BOOL SetThread(Thread* t)
-{
- WRAPPER_NO_CONTRACT
- return UnsafeTlsSetValue(GetThreadTLSIndex(), t);
-}
-
-BOOL SetAppDomain(AppDomain* ad)
-{
- WRAPPER_NO_CONTRACT
- return UnsafeTlsSetValue(GetAppDomainTLSIndex(), ad);
-}
-
-#define ThreadInited() (gThreadTLSIndex != TLS_OUT_OF_INDEXES)
-
-#endif // FEATURE_IMPLICIT_TLS
-
-
BOOL Thread::Alert ()
{
CONTRACTL {
@@ -681,7 +623,6 @@ Thread* SetupThread(BOOL fInternal)
}
CONTRACTL_END;
- _ASSERTE(ThreadInited());
Thread* pThread;
if ((pThread = GetThread()) != NULL)
return pThread;
@@ -782,18 +723,6 @@ Thread* SetupThread(BOOL fInternal)
!pThread->PrepareApartmentAndContext())
ThrowOutOfMemory();
-#ifndef FEATURE_IMPLICIT_TLS
- // make sure we will not fail when we store in TLS in the future.
- if (!UnsafeTlsSetValue(gThreadTLSIndex, NULL))
- {
- ThrowOutOfMemory();
- }
- if (!UnsafeTlsSetValue(GetAppDomainTLSIndex(), NULL))
- {
- ThrowOutOfMemory();
- }
-#endif
-
// reset any unstarted bits on the thread object
FastInterlockAnd((ULONG *) &pThread->m_State, ~Thread::TS_Unstarted);
FastInterlockOr((ULONG *) &pThread->m_State, Thread::TS_LegalToJoin);
@@ -915,7 +844,6 @@ Thread* SetupUnstartedThread(BOOL bRequiresTSL)
}
CONTRACTL_END;
- _ASSERTE(ThreadInited());
Thread* pThread = new Thread();
FastInterlockOr((ULONG *) &pThread->m_State,
@@ -1112,42 +1040,11 @@ HRESULT Thread::DetachThread(BOOL fDLLThreadDetach)
return S_OK;
}
-#ifndef FEATURE_IMPLICIT_TLS
-//---------------------------------------------------------------------------
-// Returns the TLS index for the Thread. This is strictly for the use of
-// our ASM stub generators that generate inline code to access the Thread.
-// Normally, you should use GetThread().
-//---------------------------------------------------------------------------
-DWORD GetThreadTLSIndex()
-{
- LIMITED_METHOD_CONTRACT;
-
- return gThreadTLSIndex;
-}
-
-//---------------------------------------------------------------------------
-// Returns the TLS index for the AppDomain. This is strictly for the use of
-// our ASM stub generators that generate inline code to access the AppDomain.
-// Normally, you should use GetAppDomain().
-//---------------------------------------------------------------------------
-DWORD GetAppDomainTLSIndex()
-{
- LIMITED_METHOD_CONTRACT;
-
- return gAppDomainTLSIndex;
-}
-#endif
-
DWORD GetRuntimeId()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_IMPLICIT_TLS
- _ASSERTE(GetThreadTLSIndex() != TLS_OUT_OF_INDEXES);
- return GetThreadTLSIndex() + 3;
-#else
return _tls_index;
-#endif
}
//---------------------------------------------------------------------------
@@ -1191,165 +1088,6 @@ Thread* WINAPI CreateThreadBlockThrow()
DWORD_PTR Thread::OBJREF_HASH = OBJREF_TABSIZE;
#endif
-#ifndef FEATURE_IMPLICIT_TLS
-
-#ifdef ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-
-// ----------------------------------------------------------------------------
-// GetThreadGenericFullCheck
-//
-// Description:
-// The non-PAL, x86 / x64 assembly versions of GetThreadGeneric call into this C
-// function to optionally do some verification before returning the EE Thread object
-// for the current thread. Currently the primary enforcement this function does is
-// around the EE_THREAD_(NOT)_REQUIRED contracts. For a definition of these
-// contracts, how they're used, and how temporary "safe" scopes may be created
-// using BEGIN_GETTHREAD_ALLOWED / END_GETTHREAD_ALLOWED, see the comments at the top
-// of contract.h.
-//
-// The EE_THREAD_(NOT)_REQUIRED contracts are enforced as follows:
-// * code:EEContract::DoChecks enforces the following:
-// * On entry to an EE_THREAD_REQUIRED function, GetThread() != NULL
-// * An EE_THREAD_REQUIRED function may not be called from an
-// EE_THREAD_NOT_REQUIRED function, unless there is an intervening
-// BEGIN/END_GETTHREAD_ALLOWED scope
-// * This function (GetThreadGenericFullCheck) enforces that an
-// EE_THREAD_NOT_REQUIRED function may not call GetThread(), unless there is
-// an intervening BEGIN/END_GETTHREAD_ALLOWED scope. While this enforcement
-// is straightforward below, the tricky part is getting
-// GetThreadGenericFullCheck() to actually be called when GetThread() is
-// called, given the optimizations around GetThread():
-// * code:InitThreadManager ensures that non-PAL, debug, x86/x64 builds that
-// run with COMPlus_EnforceEEThreadNotRequiredContracts set are forced to
-// use GetThreadGeneric instead of the dynamically generated optimized
-// TLS getter.
-// * The non-PAL, debug, x86/x64 GetThreadGeneric() (implemented in the
-// processor-specific assembly files) knows to call
-// GetThreadGenericFullCheck() to do the enforcement.
-//
-Thread * GetThreadGenericFullCheck()
-{
- // Can not have a dynamic contract here. Contract depends on GetThreadGeneric.
- // Contract here causes stack overflow.
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
-
- if (!ThreadInited())
- {
- // #GTInfiniteRecursion
- //
- // Normally, we'd want to assert here, but that could lead to infinite recursion.
- // Bringing up the assert dialog requires a string lookup, which requires getting
- // the Thread's UI culture ID, which, or course, requires getting the Thread. So
- // we'll just break instead.
- DebugBreak();
- }
-
- if (g_fEEStarted &&
-
- // Using ShouldEnforceEEThreadNotRequiredContracts() instead
- // of directly checking CLRConfig::GetConfigValue, as the latter contains a dynamic
- // contract and therefore calls GetThread(), which would cause infinite recursion.
- Thread::ShouldEnforceEEThreadNotRequiredContracts() &&
-
- // The following verifies that it's safe to call GetClrDebugState() below without
- // risk of its callees invoking extra error checking or fiber code that could
- // recursively call GetThread() and overflow the stack
- (CExecutionEngine::GetTlsData() != NULL))
- {
- // It's safe to peek into the debug state, so let's do so, to see if
- // our caller is really allowed to be calling GetThread(). This enforces
- // the EE_THREAD_NOT_REQUIRED contract.
- ClrDebugState * pDbg = GetClrDebugState(FALSE); // FALSE=don't allocate
- if ((pDbg != NULL) && (!pDbg->IsGetThreadAllowed()))
- {
- // We need to bracket the ASSERTE with BEGIN/END_GETTHREAD_ALLOWED to avoid
- // infinite recursion (see
- // code:GetThreadGenericFullCheck#GTInfiniteRecursion). The ASSERTE here will
- // cause us to reenter this function to get the thread (again). However,
- // BEGIN/END_GETTHREAD_ALLOWED at least stops the recursion right then and
- // there, as it prevents us from reentering this block yet again (since
- // BEGIN/END_GETTHREAD_ALLOWED causes pDbg->IsGetThreadAllowed() to be TRUE).
- // All such reentries to this function will quickly return the thread without
- // executing the code below, so the original ASSERTE can proceed.
- BEGIN_GETTHREAD_ALLOWED;
- _ASSERTE(!"GetThread() called in a EE_THREAD_NOT_REQUIRED scope. If the GetThread() call site has a clear code path for a return of NULL, then consider using GetThreadNULLOk() or BEGIN/END_GETTHREAD_ALLOWED");
- END_GETTHREAD_ALLOWED;
- }
- }
-
- Thread * pThread = (Thread *) UnsafeTlsGetValue(gThreadTLSIndex);
-
- // set bogus last error to help find places that fail to save it across GetThread calls
- ::SetLastError(LAST_ERROR_TRASH_VALUE);
-
- return pThread;
-}
-
-#endif // ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-
-#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
-//
-// Some platforms have this implemented in assembly
-//
-EXTERN_C Thread* STDCALL GetThreadGeneric(VOID);
-EXTERN_C AppDomain* STDCALL GetAppDomainGeneric(VOID);
-#else
-Thread* STDCALL GetThreadGeneric()
-{
- // Can not have contract here. Contract depends on GetThreadGeneric.
- // Contract here causes stack overflow.
- //CONTRACTL {
- // NOTHROW;
- // GC_NOTRIGGER;
- //}
- //CONTRACTL_END;
-
- // see code:GetThreadGenericFullCheck#GTInfiniteRecursion
- _ASSERTE(ThreadInited());
-
- Thread* pThread = (Thread*)UnsafeTlsGetValue(gThreadTLSIndex);
-
- TRASH_LASTERROR;
-
- return pThread;
-}
-
-AppDomain* STDCALL GetAppDomainGeneric()
-{
- // No contract. This function is called during ExitTask.
- //CONTRACTL {
- // NOTHROW;
- // GC_NOTRIGGER;
- //}
- //CONTRACTL_END;
-
- _ASSERTE(ThreadInited());
-
- AppDomain* pAppDomain = (AppDomain*)UnsafeTlsGetValue(GetAppDomainTLSIndex());
-
- TRASH_LASTERROR;
-
- return pAppDomain;
-}
-#endif // defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
-
-//
-// FLS getter to avoid unnecessary indirection via execution engine. It will be used if we get high TLS slot
-// from the OS where we cannot use the fast optimized assembly helpers. (It happens pretty often in hosted scenarios).
-//
-LPVOID* ClrFlsGetBlockDirect()
-{
- LIMITED_METHOD_CONTRACT;
-
- return (LPVOID*)UnsafeTlsGetValue(CExecutionEngine::GetTlsIndex());
-}
-
-extern "C" void * ClrFlsGetBlock();
-
-#endif // FEATURE_IMPLICIT_TLS
-
-
extern "C" void STDCALL JIT_PatchedCodeStart();
extern "C" void STDCALL JIT_PatchedCodeLast();
@@ -1387,98 +1125,24 @@ void InitThreadManager()
#ifndef FEATURE_PAL
-#ifdef FEATURE_IMPLICIT_TLS
_ASSERTE(GetThread() == NULL);
- // Mscordbi calculates the address of currentThread pointer using OFFSETOF__TLS__tls_CurrentThread. Ensure that
- // value is correct.
+ PTEB Teb = NtCurrentTeb();
+ BYTE** tlsArray = (BYTE**)Teb->ThreadLocalStoragePointer;
+ BYTE* tlsData = (BYTE*)tlsArray[_tls_index];
- PTEB Teb;
- BYTE* tlsData;
- BYTE** tlsArray;
+ size_t offsetOfCurrentThreadInfo = (BYTE*)&gCurrentThreadInfo - tlsData;
- Teb = NtCurrentTeb();
- tlsArray = (BYTE**)Teb->ThreadLocalStoragePointer;
- tlsData = (BYTE*)tlsArray[_tls_index];
+ _ASSERTE(offsetOfCurrentThreadInfo < 0x8000);
+ _ASSERTE(_tls_index < 0x10000);
- Thread **ppThread = (Thread**) (tlsData + OFFSETOF__TLS__tls_CurrentThread);
- _ASSERTE_ALL_BUILDS("clr/src/VM/Threads.cpp",
- (&(gCurrentThreadInfo.m_pThread) == ppThread) &&
- "Offset of m_pThread as specified by OFFSETOF__TLS__tls_CurrentThread is not correct. "
- "This can change due to addition/removal of declspec(Thread) thread local variables.");
+ // Save gCurrentThreadInfo location for debugger
+ g_TlsIndex = (DWORD)(_tls_index + (offsetOfCurrentThreadInfo << 16) + 0x80000000);
- _ASSERTE_ALL_BUILDS("clr/src/VM/Threads.cpp",
- ((BYTE*)&(gCurrentThreadInfo.m_EETlsData) == tlsData + OFFSETOF__TLS__tls_EETlsData) &&
- "Offset of m_EETlsData as specified by OFFSETOF__TLS__tls_EETlsData is not correct. "
- "This can change due to addition/removal of declspec(Thread) thread local variables.");
-#else
- _ASSERTE(gThreadTLSIndex == TLS_OUT_OF_INDEXES);
-#endif
_ASSERTE(g_TrapReturningThreads == 0);
#endif // !FEATURE_PAL
- // Consult run-time switches that choose whether to use generic or optimized
- // versions of GetThread and GetAppDomain
-
- BOOL fUseGenericTlsGetters = FALSE;
-
-#ifdef ENABLE_GET_THREAD_GENERIC_FULL_CHECK
- // Debug builds allow user to throw a switch to force use of the generic GetThread
- // for the sole purpose of enforcing EE_THREAD_NOT_REQUIRED contracts
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EnforceEEThreadNotRequiredContracts) != 0)
- {
- // Set this static on Thread so this value can be safely read later on by
- // code:GetThreadGenericFullCheck
- Thread::s_fEnforceEEThreadNotRequiredContracts = TRUE;
-
- fUseGenericTlsGetters = TRUE;
- }
-#endif
-
-#ifndef FEATURE_IMPLICIT_TLS
- // Now, we setup GetThread and GetAppDomain to point to their optimized or generic versions. Irrespective
- // of the version they call into, we write opcode sequence into the dummy GetThread/GetAppDomain
- // implementations (living in jithelp.s/.asm) via the MakeOptimizedTlsGetter calls below.
- //
- // For this to work, we must ensure that the dummy versions lie between the JIT_PatchedCodeStart
- // and JIT_PatchedCodeLast code range (which lies in the .text section) so that when we change the protection
- // above, we do so for GetThread and GetAppDomain as well.
-
- //---------------------------------------------------------------------------
- // INITIALIZE GetThread
- //---------------------------------------------------------------------------
-
- // No backout necessary - part of the one time global initialization
- gThreadTLSIndex = UnsafeTlsAlloc();
- if (gThreadTLSIndex == TLS_OUT_OF_INDEXES)
- COMPlusThrowWin32();
-
- MakeOptimizedTlsGetter(gThreadTLSIndex, (PVOID)GetThread, TLS_GETTER_MAX_SIZE, (POPTIMIZEDTLSGETTER)GetThreadGeneric, fUseGenericTlsGetters);
-
- //---------------------------------------------------------------------------
- // INITIALIZE GetAppDomain
- //---------------------------------------------------------------------------
-
- // No backout necessary - part of the one time global initialization
- gAppDomainTLSIndex = UnsafeTlsAlloc();
- if (gAppDomainTLSIndex == TLS_OUT_OF_INDEXES)
- COMPlusThrowWin32();
-
- MakeOptimizedTlsGetter(gAppDomainTLSIndex, (PVOID)GetAppDomain, TLS_GETTER_MAX_SIZE, (POPTIMIZEDTLSGETTER)GetAppDomainGeneric, fUseGenericTlsGetters);
-
- //---------------------------------------------------------------------------
- // Switch general purpose TLS getter to more efficient one if possible
- //---------------------------------------------------------------------------
-
- // Make sure that the TLS index is allocated
- CExecutionEngine::CheckThreadState(0, FALSE);
-
- DWORD masterSlotIndex = CExecutionEngine::GetTlsIndex();
- CLRFLSGETBLOCK pGetter = (CLRFLSGETBLOCK)MakeOptimizedTlsGetter(masterSlotIndex, (PVOID)ClrFlsGetBlock, TLS_GETTER_MAX_SIZE);
- __ClrFlsGetBlock = pGetter ? pGetter : ClrFlsGetBlockDirect;
-#else
__ClrFlsGetBlock = CExecutionEngine::GetTlsData;
-#endif // FEATURE_IMPLICIT_TLS
IfFailThrow(Thread::CLRSetThreadStackGuarantee(Thread::STSGuarantee_Force));
diff --git a/src/vm/threads.h b/src/vm/threads.h
index 17cc1f305d..05e01b3004 100644
--- a/src/vm/threads.h
+++ b/src/vm/threads.h
@@ -586,8 +586,6 @@ enum ThreadpoolThreadType
//
// Public functions for ASM code generators
//
-// int GetThreadTLSIndex() - returns TLS index used to point to Thread
-// int GetAppDomainTLSIndex() - returns TLS index used to point to AppDomain
// Thread* __stdcall CreateThreadBlockThrow() - creates new Thread on reverse p-invoke
//
// Public functions for one-time init/cleanup
@@ -629,14 +627,6 @@ Thread* SetupThreadNoThrow(HRESULT *phresult = NULL);
Thread* SetupUnstartedThread(BOOL bRequiresTSL=TRUE);
void DestroyThread(Thread *th);
-
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-#ifndef FEATURE_IMPLICIT_TLS
-DWORD GetThreadTLSIndex();
-DWORD GetAppDomainTLSIndex();
-#endif
-
DWORD GetRuntimeId();
EXTERN_C Thread* WINAPI CreateThreadBlockThrow();
@@ -3891,23 +3881,6 @@ private:
ULONG m_ulEnablePreemptiveGCCount;
#endif // _DEBUG
-#ifdef ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-
-private:
- // Set once on initialization, single-threaded, inside friend code:InitThreadManager,
- // based on whether the user has set COMPlus_EnforceEEThreadNotRequiredContracts.
- // This is then later accessed via public
- // code:Thread::ShouldEnforceEEThreadNotRequiredContracts. See
- // code:GetThreadGenericFullCheck for details.
- static BOOL s_fEnforceEEThreadNotRequiredContracts;
-
-public:
- static BOOL ShouldEnforceEEThreadNotRequiredContracts();
-
-#endif // ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-
-
-
private:
// For suspends:
CLREvent m_DebugSuspendEvent;
@@ -7386,7 +7359,6 @@ inline void SetTypeHandleOnThreadForAlloc(TypeHandle th)
#endif // CROSSGEN_COMPILE
-#ifdef FEATURE_IMPLICIT_TLS
class Compiler;
// users of OFFSETOF__TLS__tls_CurrentThread macro expect the offset of these variables wrt to _tls_start to be stable.
// Defining each of the following thread local variable separately without the struct causes the offsets to change in
@@ -7398,11 +7370,7 @@ struct ThreadLocalInfo
Thread* m_pThread;
AppDomain* m_pAppDomain;
void** m_EETlsData; // ClrTlsInfo::data
-#ifdef FEATURE_MERGE_JIT_AND_ENGINE
- void* m_pJitTls;
-#endif
};
-#endif // FEATURE_IMPLICIT_TLS
class ThreadStateHolder
{
diff --git a/src/vm/threads.inl b/src/vm/threads.inl
index ee2aaacf94..f5a439c350 100644
--- a/src/vm/threads.inl
+++ b/src/vm/threads.inl
@@ -22,7 +22,6 @@
#include "frames.h"
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_IMPLICIT_TLS
#ifndef __llvm__
EXTERN_C __declspec(thread) ThreadLocalInfo gCurrentThreadInfo;
@@ -40,18 +39,8 @@ EXTERN_C inline AppDomain* STDCALL GetAppDomain()
return gCurrentThreadInfo.m_pAppDomain;
}
-#endif // FEATURE_IMPLICIT_TLS
#endif // !DACCESS_COMPILE
-#ifdef ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-// See code:GetThreadGenericFullCheck
-inline /* static */ BOOL Thread::ShouldEnforceEEThreadNotRequiredContracts()
-{
- LIMITED_METHOD_CONTRACT;
- return s_fEnforceEEThreadNotRequiredContracts;
-}
-#endif // ENABLE_GET_THREAD_GENERIC_FULL_CHECK
-
inline void Thread::IncLockCount()
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/vm/vars.cpp b/src/vm/vars.cpp
index ff941d2101..464560c3a6 100644
--- a/src/vm/vars.cpp
+++ b/src/vm/vars.cpp
@@ -120,13 +120,10 @@ GPTR_IMPL_INIT(StressLog, g_pStressLog, &StressLog::theLog);
GPTR_IMPL(RCWCleanupList,g_pRCWCleanupList);
#endif // FEATURE_COMINTEROP
+GVAL_IMPL_INIT(DWORD, g_TlsIndex, TLS_OUT_OF_INDEXES);
#ifndef DACCESS_COMPILE
-// <TODO> @TODO Remove eventually - </TODO> determines whether the verifier throws an exception when something fails
-bool g_fVerifierOff;
-
-
// <TODO> @TODO - PROMOTE. </TODO>
OBJECTHANDLE g_pPreallocatedOutOfMemoryException;
OBJECTHANDLE g_pPreallocatedStackOverflowException;
diff --git a/src/vm/vars.hpp b/src/vm/vars.hpp
index c9f4848692..a7b6fb6173 100644
--- a/src/vm/vars.hpp
+++ b/src/vm/vars.hpp
@@ -406,9 +406,7 @@ GPTR_DECL(MethodDesc, g_pExecuteBackoutCodeHelperMethod);
GPTR_DECL(MethodDesc, g_pObjectFinalizerMD);
-//<TODO> @TODO Remove eventually - determines whether the verifier throws an exception when something fails</TODO>
-EXTERN bool g_fVerifierOff;
-
+GVAL_DECL(DWORD, g_TlsIndex);
// Global System Information
extern SYSTEM_INFO g_SystemInfo;