From c4c08e2e2de1d9ddafc34041ef2babc168caa176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Thu, 13 Sep 2018 14:01:09 +0200 Subject: [PATCH] Restore JIT prototype The JIT prototype was originally brought up on the closed source ".NET Native for UWP apps" compiler/runtime, so this is mostly to adapt it for CoreRT. Surprisingly, this hasn't bit rotten much over time and some of the bitrot has been cleaned up by @tonerdo in his interpreter work (#6182). Both an interpreter and a JIT are a great addition to a fully AOT compiled runtime and they complement each other nicely. With this, I'm making the JIT prototype work on CoreRT: * Adjust the hacks that were used by JIT code manager to talk to the runtime (in CoreRT, runtime is linked into the executable and the hacks didn't work). This will need further cleanup at some point. * Rename ReaderWriterLock because it was conflicting with a type of the same name in the runtime. * Add an experimental flavor of the stack trace decoder. This needs to use the experimental type loader. * Expose the JIT component from MSBuild - compile JIT support into the executable, use the experimental flavor of the reflection stack (shared with the interpreter), add the extra native library with JIT support. This is to allow enabling JIT support as part of `dotnet publish`. You can try this out pretty much the same way as @tonerdo's interpreter: see instructions in #6182. Instead of passing `/p:ExperimentalInterpreterSupport=true`, pass `/p:ExperimentalJitSupport=true`. You'll need to manually copy clrjitilc.dll from the compiler to the publish directory (we use the same codegen that is used to compile the AOT parts of the application to also JIT compile at runtime). --- .../Microsoft.NETCore.Native.Windows.props | 1 + .../Microsoft.NETCore.Native.targets | 14 +++++++++----- src/JitInterface/src/CorInfoImpl.cs | 18 ++++++++++++------ src/Native/jitinterface/CMakeLists.txt | 19 ++++++++++++++----- src/Native/jitinterface/CodeHeap.cpp | 10 ++++++++++ src/Native/jitinterface/JITCodeManager.cpp | 18 ++++++++++++++---- src/Native/jitinterface/JITCodeManager.h | 14 +++++++------- .../JitSupport/RyuJitExecutionStrategy.cs | 12 +++++++----- ...ate.StackTraceMetadata.Experimental.csproj | 8 ++++++++ .../System.Private.StackTraceMetadata.csproj | 8 +++++--- 10 files changed, 87 insertions(+), 35 deletions(-) create mode 100644 src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.Experimental.csproj diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props b/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props index 22392cd256f..b06165b8a84 100644 --- a/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props +++ b/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props @@ -40,6 +40,7 @@ See the LICENSE file in the project root for more information. + diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.targets b/src/BuildIntegration/Microsoft.NETCore.Native.targets index 79f3a61b735..99e6ffea19d 100644 --- a/src/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/BuildIntegration/Microsoft.NETCore.Native.targets @@ -67,6 +67,8 @@ See the LICENSE file in the project root for more information. $(NativeOutputPath) $(NativeIntermediateOutputPath) + true + $(FrameworkLibPath)\Framework$(LibFileExt) $(FrameworkLibPath)\libframework$(LibFileExt) SetupProperties @@ -81,17 +83,19 @@ See the LICENSE file in the project root for more information. - + + - + + - - + + @@ -180,7 +184,7 @@ See the LICENSE file in the project root for more information. - + diff --git a/src/JitInterface/src/CorInfoImpl.cs b/src/JitInterface/src/CorInfoImpl.cs index 13d2ccac485..b02092b30e2 100644 --- a/src/JitInterface/src/CorInfoImpl.cs +++ b/src/JitInterface/src/CorInfoImpl.cs @@ -42,6 +42,12 @@ private enum ImageFileMachine ARM = 0x01c4, } +#if SUPPORT_JIT + private const string JitSupportLibrary = "*"; +#else + private const string JitSupportLibrary = "jitinterface"; +#endif + private IntPtr _jit; private IntPtr _unmanagedCallbacks; // array of pointers to JIT-EE interface callbacks @@ -55,7 +61,7 @@ private enum ImageFileMachine [DllImport("clrjitilc", CallingConvention=CallingConvention.StdCall)] private extern static IntPtr getJit(); - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static IntPtr GetJitHost(IntPtr configProvider); // @@ -68,15 +74,15 @@ private static CorInfoImpl GetThis(IntPtr thisHandle) return _this; } - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static CorJitResult JitCompileMethod(out IntPtr exception, IntPtr jit, IntPtr thisHandle, IntPtr callbacks, ref CORINFO_METHOD_INFO info, uint flags, out IntPtr nativeEntry, out uint codeSize); - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static uint GetMaxIntrinsicSIMDVectorLength(IntPtr jit, CORJIT_FLAGS* flags); - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static IntPtr AllocException([MarshalAs(UnmanagedType.LPWStr)]string message, int messageLength); private IntPtr AllocException(Exception ex) @@ -93,10 +99,10 @@ private IntPtr AllocException(Exception ex) return nativeException; } - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static void FreeException(IntPtr obj); - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static char* GetExceptionMessage(IntPtr obj); private Compilation _compilation; diff --git a/src/Native/jitinterface/CMakeLists.txt b/src/Native/jitinterface/CMakeLists.txt index 46c071c8ad6..5262e0d8cbc 100644 --- a/src/Native/jitinterface/CMakeLists.txt +++ b/src/Native/jitinterface/CMakeLists.txt @@ -7,15 +7,23 @@ set(NATIVE_SOURCES corinfoexception.cpp ) +set (JIT_SOURCES + CodeHeap.cpp + JITCodeManager.cpp + ../Runtime/coreclr/GCInfoDecoder.cpp +) + if(WIN32 AND CLR_CMAKE_PLATFORM_ARCH_AMD64) - set(NATIVE_SOURCES ${NATIVE_SOURCES} - CodeHeap.cpp - JITCodeManager.cpp - ../Runtime/coreclr/GCInfoDecoder.cpp - ) add_definitions(-DGCINFODECODER_NO_EE) add_definitions(-DFEATURE_REDHAWK) + add_definitions(-DFEATURE_SINGLE_MODULE_RUNTIME) + + add_library(System.Private.Jit.Native + STATIC + ${NATIVE_SOURCES} + ${JIT_SOURCES} + ) endif(WIN32 AND CLR_CMAKE_PLATFORM_ARCH_AMD64) add_library(jitinterface @@ -27,4 +35,5 @@ install (TARGETS jitinterface DESTINATION tools) if(WIN32) target_link_libraries(jitinterface ntdll.lib) install (FILES ${CMAKE_CURRENT_BINARY_DIR}/$/jitinterface.pdb DESTINATION tools) + install (TARGETS System.Private.Jit.Native DESTINATION sdk) endif(WIN32) diff --git a/src/Native/jitinterface/CodeHeap.cpp b/src/Native/jitinterface/CodeHeap.cpp index 1adc206ea26..468bd258852 100644 --- a/src/Native/jitinterface/CodeHeap.cpp +++ b/src/Native/jitinterface/CodeHeap.cpp @@ -18,13 +18,23 @@ static void *s_topAddress = nullptr; static DWORD s_pageSize = 0; extern HMODULE s_hRuntime; +#if FEATURE_SINGLE_MODULE_RUNTIME +extern "C" void RhpNewArray(); +#endif + void InitMemoryStatics() { std::call_once(s_staticInit, []() { HMODULE module = s_hRuntime; if (module != NULL) + { +#if FEATURE_SINGLE_MODULE_RUNTIME + s_mrtAddr = &RhpNewArray; +#else s_mrtAddr = GetProcAddress(module, "RhpNewArray"); +#endif + } assert(s_mrtAddr != nullptr); diff --git a/src/Native/jitinterface/JITCodeManager.cpp b/src/Native/jitinterface/JITCodeManager.cpp index 198671f14ee..11a1088be06 100644 --- a/src/Native/jitinterface/JITCodeManager.cpp +++ b/src/Native/jitinterface/JITCodeManager.cpp @@ -46,14 +46,24 @@ HMODULE s_hRuntime = NULL; pfnRegisterCodeManager s_pfnRegisterCodeManager; pfnUnregisterCodeManager s_pfnUnregisterCodeManager; +#if FEATURE_SINGLE_MODULE_RUNTIME +extern "C" bool RegisterCodeManager(ICodeManager * pCodeManager, PTR_VOID pvStartRange, UInt32 cbRange); +extern "C" void UnregisterCodeManager(ICodeManager * pCodeManager); +#endif + bool InitializeCodeManagerRuntime() { std::call_once(s_RuntimeInit, []() { if (s_hRuntime != NULL) { +#if FEATURE_SINGLE_MODULE_RUNTIME + s_pfnRegisterCodeManager = &RegisterCodeManager; + s_pfnUnregisterCodeManager = &UnregisterCodeManager; +#else s_pfnRegisterCodeManager = (pfnRegisterCodeManager)GetProcAddress(s_hRuntime, "RegisterCodeManager"); s_pfnUnregisterCodeManager = (pfnUnregisterCodeManager)GetProcAddress(s_hRuntime, "UnregisterCodeManager"); +#endif } }); @@ -259,7 +269,7 @@ bool JITCodeManager::Initialize() // Note that main method bodies will not have an entry in the map. PTR_RUNTIME_FUNCTION JITCodeManager::AllocRuntimeFunction(PTR_RUNTIME_FUNCTION mainMethod, DWORD beginAddr, DWORD endAddr, DWORD unwindData) { - ReaderWriterLock::WriteHolder lh(&m_lock); + SlimReaderWriterLock::WriteHolder lh(&m_lock); m_runtimeFunctions.push_back(RUNTIME_FUNCTION()); PTR_RUNTIME_FUNCTION method = &m_runtimeFunctions.back(); @@ -278,7 +288,7 @@ PTR_RUNTIME_FUNCTION JITCodeManager::AllocRuntimeFunction(PTR_RUNTIME_FUNCTION m void JITCodeManager::UpdateRuntimeFunctionTable() { - ReaderWriterLock::WriteHolder lh(&m_lock); + SlimReaderWriterLock::WriteHolder lh(&m_lock); PTR_RUNTIME_FUNCTION pFunctionTable = &m_runtimeFunctions[0]; DWORD nEntryCount = (DWORD)m_runtimeFunctions.size(); @@ -381,7 +391,7 @@ bool JITCodeManager::FindMethodInfo(PTR_VOID ControlPC, if (RelativePC >= m_cbRange) return false; - ReaderWriterLock::ReadHolder lh(&m_lock); + SlimReaderWriterLock::ReadHolder lh(&m_lock); int MethodIndex = LookupUnwindInfoForMethod((UInt32)RelativePC, m_pRuntimeFunctionTable, 0, m_nRuntimeFunctionTable - 1); @@ -420,7 +430,7 @@ bool JITCodeManager::IsFunclet(MethodInfo * pMethInfo) JITMethodInfo * pMethodInfo = (JITMethodInfo *)pMethInfo; // A funclet will have an entry in funclet to main method map - ReaderWriterLock::ReadHolder lh(&m_lock); + SlimReaderWriterLock::ReadHolder lh(&m_lock); return m_FuncletToMainMethodMap.find(pMethodInfo->runtimeFunction.BeginAddress) != m_FuncletToMainMethodMap.end(); } diff --git a/src/Native/jitinterface/JITCodeManager.h b/src/Native/jitinterface/JITCodeManager.h index aeff8bc8991..991cb0d65d9 100644 --- a/src/Native/jitinterface/JITCodeManager.h +++ b/src/Native/jitinterface/JITCodeManager.h @@ -51,19 +51,19 @@ typedef DPTR(struct _UNWIND_INFO) PTR_UNWIND_INFO; typedef DPTR(union _UNWIND_CODE) PTR_UNWIND_CODE; #endif // target_amd64 -class ReaderWriterLock : private SRWLOCK +class SlimReaderWriterLock : private SRWLOCK { public: - ReaderWriterLock() + SlimReaderWriterLock() { ::InitializeSRWLock(this); } class ReadHolder { - ReaderWriterLock * m_pLock; + SlimReaderWriterLock * m_pLock; public: - ReadHolder(ReaderWriterLock * pLock) + ReadHolder(SlimReaderWriterLock * pLock) : m_pLock(pLock) { ::AcquireSRWLockShared(m_pLock); @@ -77,10 +77,10 @@ class ReaderWriterLock : private SRWLOCK class WriteHolder { - ReaderWriterLock * m_pLock; + SlimReaderWriterLock * m_pLock; public: - WriteHolder(ReaderWriterLock * pLock) + WriteHolder(SlimReaderWriterLock * pLock) : m_pLock(pLock) { ::AcquireSRWLockExclusive(m_pLock); @@ -167,7 +167,7 @@ class JITCodeManager : ICodeManager UInt32 m_cbRange; // lock to protect m_runtimeFunctions and m_FuncletToMainMethodMap - ReaderWriterLock m_lock; + SlimReaderWriterLock m_lock; std::vector m_runtimeFunctions; PTR_RUNTIME_FUNCTION m_pRuntimeFunctionTable; diff --git a/src/System.Private.Jit/src/Internal/Runtime/JitSupport/RyuJitExecutionStrategy.cs b/src/System.Private.Jit/src/Internal/Runtime/JitSupport/RyuJitExecutionStrategy.cs index e67b3b8c4a0..9548f2f08c4 100644 --- a/src/System.Private.Jit/src/Internal/Runtime/JitSupport/RyuJitExecutionStrategy.cs +++ b/src/System.Private.Jit/src/Internal/Runtime/JitSupport/RyuJitExecutionStrategy.cs @@ -22,6 +22,8 @@ namespace Internal.Runtime.JitSupport { public class RyuJitExecutionStrategy : MethodExecutionStrategy { + private const string NativeJitSupportLibrary = "*"; + private CorInfoImpl _corInfoImpl; private TypeSystemContext _context; private NodeFactory _nodeFactory; @@ -33,13 +35,13 @@ private void UpdateBytesUsed(ObjectNode.ObjectData nodeData, ref int bytesUsed) return; } - [DllImport("jitinterface")] + [DllImport(NativeJitSupportLibrary)] static extern IntPtr AllocJittedCode(UInt32 cbCode, UInt32 align, out IntPtr pCodeManager); - [DllImport("jitinterface")] + [DllImport(NativeJitSupportLibrary)] static extern void SetEHInfoPtr(IntPtr pCodeManager, IntPtr pbCode, IntPtr ehInfo); - [DllImport("jitinterface")] + [DllImport(NativeJitSupportLibrary)] static extern unsafe IntPtr PublishRuntimeFunction( IntPtr pCodeManager, IntPtr pbCode, @@ -51,10 +53,10 @@ static extern unsafe IntPtr PublishRuntimeFunction( byte[] pGCData, UInt32 cbGCData); - [DllImport("jitinterface")] + [DllImport(NativeJitSupportLibrary)] static extern void UpdateRuntimeFunctionTable(IntPtr pCodeManager); - [DllImport("jitinterface")] + [DllImport(NativeJitSupportLibrary)] static extern void InitJitCodeManager(IntPtr mrtModule); public override IntPtr OnEntryPoint(MethodEntrypointPtr methodEntrypoint, IntPtr callerArgs) diff --git a/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.Experimental.csproj b/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.Experimental.csproj new file mode 100644 index 00000000000..637480fcb78 --- /dev/null +++ b/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.Experimental.csproj @@ -0,0 +1,8 @@ + + + System.Private.StackTraceMetadata.Experimental + true + + + + diff --git a/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj b/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj index 799bc65e032..22c4b488c9d 100644 --- a/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj +++ b/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj @@ -1,7 +1,7 @@ - System.Private.StackTraceMetadata + System.Private.StackTraceMetadata 4.0.0.0 Library true @@ -11,8 +11,10 @@ - - + + + +