summaryrefslogtreecommitdiff
path: root/src/vm/jitinterfacegen.cpp
diff options
context:
space:
mode:
authordotnet-bot <dotnet-bot@microsoft.com>2015-01-30 14:14:42 -0800
committerdotnet-bot <dotnet-bot@microsoft.com>2015-01-30 14:14:42 -0800
commitef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch)
treedee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/vm/jitinterfacegen.cpp
downloadcoreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.gz
coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.bz2
coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.zip
Initial commit to populate CoreCLR repo
[tfs-changeset: 1407945]
Diffstat (limited to 'src/vm/jitinterfacegen.cpp')
-rw-r--r--src/vm/jitinterfacegen.cpp291
1 files changed, 291 insertions, 0 deletions
diff --git a/src/vm/jitinterfacegen.cpp b/src/vm/jitinterfacegen.cpp
new file mode 100644
index 0000000000..7ef145316a
--- /dev/null
+++ b/src/vm/jitinterfacegen.cpp
@@ -0,0 +1,291 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+// ===========================================================================
+// File: JITinterfaceGen.CPP
+//
+
+// ===========================================================================
+
+// This contains generic C versions of some of the routines
+// required by JITinterface.cpp. They are modeled after
+// X86 specific routines found in JIThelp.asm or JITinterfaceX86.cpp
+// More and more we're making AMD64 and IA64 specific versions of
+// the helpers as well, JitInterfaceGen.cpp sticks around for rotor...
+
+
+#include "common.h"
+#include "clrtypes.h"
+#include "jitinterface.h"
+#include "eeconfig.h"
+#include "excep.h"
+#include "comdelegate.h"
+#ifdef FEATURE_REMOTING
+#include "remoting.h" // create context bound and remote class instances
+#endif
+#include "field.h"
+#include "ecall.h"
+
+#ifdef _WIN64
+
+// These are the fastest(?) versions of JIT helpers as they have the code to GetThread patched into them
+// that does not make a call.
+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);
+
+// This next set is the fast version that invoke GetThread but is still faster than the VM implementation (i.e.
+// the "slow" versions).
+EXTERN_C Object* JIT_TrialAllocSFastMP(CORINFO_CLASS_HANDLE typeHnd_);
+EXTERN_C Object* JIT_TrialAllocSFastSP(CORINFO_CLASS_HANDLE typeHnd_);
+EXTERN_C Object* JIT_BoxFastMP (CORINFO_CLASS_HANDLE type, void* unboxedData);
+EXTERN_C Object* JIT_BoxFastUP (CORINFO_CLASS_HANDLE type, void* unboxedData);
+EXTERN_C Object* AllocateStringFastMP (CLR_I4 cch);
+EXTERN_C Object* AllocateStringFastUP (CLR_I4 cch);
+
+EXTERN_C Object* JIT_NewArr1OBJ_MP (CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size);
+EXTERN_C Object* JIT_NewArr1OBJ_UP (CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size);
+EXTERN_C Object* JIT_NewArr1VC_MP (CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size);
+EXTERN_C Object* JIT_NewArr1VC_UP (CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size);
+
+//For the optimized JIT_Mon helpers
+#if defined(_TARGET_AMD64_)
+EXTERN_C void JIT_MonEnterWorker_Slow(Object* obj, BYTE* pbLockTaken);
+EXTERN_C void JIT_MonExitWorker_Slow(Object* obj, BYTE* pbLockTaken);
+EXTERN_C void JIT_MonTryEnter_Slow(Object* obj, INT32 timeOut, BYTE* pbLockTaken);
+EXTERN_C void JIT_MonEnterStatic_Slow(AwareLock* lock, BYTE* pbLockTaken);
+EXTERN_C void JIT_MonExitStatic_Slow(AwareLock* lock, BYTE* pbLockTaken);
+#endif // _TARGET_AMD64_
+
+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);
+
+#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
+
+/*********************************************************************/
+// Initialize the part of the JIT helpers that require very little of
+// EE infrastructure to be in place.
+/*********************************************************************/
+#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();
+EXTERN_C void JIT_MonEnterWorker_InlineGetThread_GetThread_PatchLabel();
+EXTERN_C void JIT_MonExitWorker_InlineGetThread_GetThread_PatchLabel();
+EXTERN_C void JIT_MonTryEnter_GetThread_PatchLabel();
+EXTERN_C void JIT_MonEnterStaticWorker_InlineGetThread_GetThread_PatchLabel_1();
+EXTERN_C void JIT_MonEnterStaticWorker_InlineGetThread_GetThread_PatchLabel_2();
+EXTERN_C void JIT_MonExitStaticWorker_InlineGetThread_GetThread_PatchLabel();
+
+
+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,
+ (PVOID)JIT_MonEnterWorker_InlineGetThread_GetThread_PatchLabel,
+ (PVOID)JIT_MonExitWorker_InlineGetThread_GetThread_PatchLabel,
+ (PVOID)JIT_MonTryEnter_GetThread_PatchLabel,
+ (PVOID)JIT_MonEnterStaticWorker_InlineGetThread_GetThread_PatchLabel_1,
+ (PVOID)JIT_MonEnterStaticWorker_InlineGetThread_GetThread_PatchLabel_2,
+ (PVOID)JIT_MonExitStaticWorker_InlineGetThread_GetThread_PatchLabel,
+};
+
+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)
+
+#if defined(_TARGET_AMD64_)
+EXTERN_C void JIT_MonEnterStaticWorker();
+EXTERN_C void JIT_MonExitStaticWorker();
+#endif
+
+void InitJITHelpers1()
+{
+ STANDARD_VM_CONTRACT;
+
+ _ASSERTE(g_SystemInfo.dwNumberOfProcessors != 0);
+
+#if defined(_TARGET_AMD64_)
+
+ 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));
+ }
+
+ // Allocation helpers, faster but non-logging
+ if (!((TrackAllocationsEnabled()) ||
+ (LoggingOn(LF_GCALLOC, LL_INFO10))
+#ifdef _DEBUG
+ || (g_pConfig->ShouldInjectFault(INJECTFAULT_GCHEAP) != 0)
+#endif // _DEBUG
+ ))
+ {
+
+ // if (multi-proc || server GC)
+ if (GCHeap::UseAllocationContexts())
+ {
+ // 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);
+
+ ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateStringFastMP), ECall::FastAllocateString);
+ }
+ }
+ else
+ {
+ // Replace the 1p slow allocation helpers with faster version
+ //
+ // When we're running Workstation GC on a single proc box we don't have
+ // InlineGetThread versions because there is no need to call GetThread
+ SetJitHelperFunction(CORINFO_HELP_NEWSFAST, JIT_TrialAllocSFastSP);
+ SetJitHelperFunction(CORINFO_HELP_NEWSFAST_ALIGN8, JIT_TrialAllocSFastSP);
+ SetJitHelperFunction(CORINFO_HELP_BOX, JIT_BoxFastUP);
+ SetJitHelperFunction(CORINFO_HELP_NEWARR_1_VC, JIT_NewArr1VC_UP);
+ SetJitHelperFunction(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1OBJ_UP);
+
+ ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateStringFastUP), ECall::FastAllocateString);
+ }
+ }
+
+ if (gThreadTLSIndex >= TLS_MINIMUM_AVAILABLE)
+ {
+ // We need to patch the helpers for FCalls
+ MakeIntoJumpStub(JIT_MonEnterWorker_InlineGetThread, JIT_MonEnterWorker_Slow);
+ MakeIntoJumpStub(JIT_MonExitWorker_InlineGetThread, JIT_MonExitWorker_Slow);
+ MakeIntoJumpStub(JIT_MonTryEnter_InlineGetThread, JIT_MonTryEnter_Slow);
+
+ SetJitHelperFunction(CORINFO_HELP_MON_ENTER, JIT_MonEnterWorker_Slow);
+ SetJitHelperFunction(CORINFO_HELP_MON_EXIT, JIT_MonExitWorker_Slow);
+
+ SetJitHelperFunction(CORINFO_HELP_MON_ENTER_STATIC, JIT_MonEnterStatic_Slow);
+ SetJitHelperFunction(CORINFO_HELP_MON_EXIT_STATIC, JIT_MonExitStatic_Slow);
+ }
+
+ 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_
+}
+
+#endif // !_TARGET_X86_