Skip to content
This repository was archived by the owner on Nov 1, 2020. It is now read-only.

Commit

Permalink
Restore JIT prototype (#6327)
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
MichalStrehovsky authored Sep 13, 2018
1 parent 44ebd78 commit 3ca0b10
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ See the LICENSE file in the project root for more information.
<NativeLibrary Condition="$(NativeCodeGen) == '' and $(NativeLib) != ''" Include="$(IlcPath)\sdk\bootstrapperdll.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)\sdk\$(FullRuntimeName).lib" />
<NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)\sdk\System.Private.TypeLoader.Native.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == '' and '$(ExperimentalJitSupport)' == 'true'" Include="$(IlcPath)\sdk\System.Private.Jit.Native.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == 'cpp'" Include="$(IlcPath)\sdk\bootstrappercpp.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == 'cpp'" Include="$(IlcPath)\sdk\PortableRuntime.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == 'wasm'" Include="$(IlcPath)\sdk\bootstrappercpp.lib" />
Expand Down
14 changes: 9 additions & 5 deletions src/BuildIntegration/Microsoft.NETCore.Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ See the LICENSE file in the project root for more information.
<FrameworkLibPath Condition="'$(FrameworkLibPath)' == ''">$(NativeOutputPath)</FrameworkLibPath>
<FrameworkObjPath Condition="'$(FrameworkObjPath)' == ''">$(NativeIntermediateOutputPath)</FrameworkObjPath>

<ExperimentalDynamicCodeSupport Condition="'$(ExperimentalInterpreterSupport)' == 'true' or '$(ExperimentalJitSupport)' == 'true'">true</ExperimentalDynamicCodeSupport>

<SharedLibrary Condition="'$(OS)' == 'Windows_NT'">$(FrameworkLibPath)\Framework$(LibFileExt)</SharedLibrary>
<SharedLibrary Condition="'$(OS)' != 'Windows_NT'">$(FrameworkLibPath)\libframework$(LibFileExt)</SharedLibrary>
<IlcDynamicBuildPropertyDependencies Condition="'$(IlcCalledViaPackage)' == 'true'">SetupProperties</IlcDynamicBuildPropertyDependencies>
Expand All @@ -81,17 +83,19 @@ See the LICENSE file in the project root for more information.
<ItemGroup>
<AutoInitializedAssemblies Include="System.Private.CoreLib" />
<AutoInitializedAssemblies Include="System.Private.DeveloperExperience.Console" />
<AutoInitializedAssemblies Include="System.Private.StackTraceMetadata" />
<AutoInitializedAssemblies Condition="'$(ExperimentalInterpreterSupport)' == 'true'" Include="System.Private.Interpreter" />
<AutoInitializedAssemblies Condition="'$(ExperimentalJitSupport)' == 'true'" Include="System.Private.Jit" />
</ItemGroup>

<ItemGroup Condition="'$(ExperimentalInterpreterSupport)' != 'true'">
<ItemGroup Condition="'$(ExperimentalDynamicCodeSupport)' != 'true'">
<AutoInitializedAssemblies Include="System.Private.StackTraceMetadata" />
<AutoInitializedAssemblies Include="System.Private.TypeLoader" />
<AutoInitializedAssemblies Include="System.Private.Reflection.Execution" />
<AutoInitializedAssemblies Include="System.Private.Interop" />
</ItemGroup>

<ItemGroup Condition="'$(ExperimentalInterpreterSupport)' == 'true'">
<AutoInitializedAssemblies Include="System.Private.Interpreter" />
<ItemGroup Condition="'$(ExperimentalDynamicCodeSupport)' == 'true'">
<AutoInitializedAssemblies Include="System.Private.StackTraceMetadata.Experimental" />
<AutoInitializedAssemblies Include="System.Private.TypeLoader.Experimental" />
<AutoInitializedAssemblies Include="System.Private.Reflection.Execution.Experimental" />
<AutoInitializedAssemblies Include="System.Private.Interop.Experimental" />
Expand Down Expand Up @@ -180,7 +184,7 @@ See the LICENSE file in the project root for more information.
<IlcArg Condition="$(OutputType) == 'Library' and $(NativeLib) != ''" Include="--nativelib" />
<IlcArg Condition="$(ExportsFile) != ''" Include="--exportsfile:$(ExportsFile)" />
<ILcArg Condition="'$(Platform)' == 'wasm'" Include="--wasm" />
<ILcArg Condition="'$(ExperimentalInterpreterSupport)' == 'true'" Include="--nometadatablocking" />
<ILcArg Condition="'$(ExperimentalDynamicCodeSupport)' == 'true'" Include="--nometadatablocking" />
<IlcArg Include="@(AutoInitializedAssemblies->'--initassembly:%(Identity)')" />
<IlcArg Include="@(AppContextSwitchOverrides->'--appcontextswitch:%(Identity)')" />
<IlcArg Condition="$(ServerGarbageCollection) != ''" Include="--runtimeopt:RH_UseServerGC=1" />
Expand Down
18 changes: 12 additions & 6 deletions src/JitInterface/src/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);

//
Expand All @@ -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)
Expand All @@ -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;
Expand Down
19 changes: 14 additions & 5 deletions src/Native/jitinterface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -27,4 +35,5 @@ install (TARGETS jitinterface DESTINATION tools)
if(WIN32)
target_link_libraries(jitinterface ntdll.lib)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/jitinterface.pdb DESTINATION tools)
install (TARGETS System.Private.Jit.Native DESTINATION sdk)
endif(WIN32)
10 changes: 10 additions & 0 deletions src/Native/jitinterface/CodeHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
18 changes: 14 additions & 4 deletions src/Native/jitinterface/JITCodeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
});

Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
}

Expand Down
14 changes: 7 additions & 7 deletions src/Native/jitinterface/JITCodeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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<RUNTIME_FUNCTION> m_runtimeFunctions;
PTR_RUNTIME_FUNCTION m_pRuntimeFunctionTable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<AssemblyName>System.Private.StackTraceMetadata.Experimental</AssemblyName>
<DynamicCodeSupport>true</DynamicCodeSupport>
</PropertyGroup>

<Import Project="System.Private.StackTraceMetadata.csproj" />
</Project>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<AssemblyName>System.Private.StackTraceMetadata</AssemblyName>
<AssemblyName Condition="'$(AssemblyName)' == ''">System.Private.StackTraceMetadata</AssemblyName>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<OutputType>Library</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Expand All @@ -11,8 +11,10 @@
<ItemGroup Condition="'$(IsProjectNLibrary)' != 'true'">
<ProjectReference Include="..\..\System.Private.CoreLib\src\System.Private.CoreLib.csproj" />
<ProjectReference Include="..\..\System.Private.Reflection.Metadata\src\System.Private.Reflection.Metadata.csproj" />
<ProjectReference Include="..\..\System.Private.TypeLoader\src\System.Private.TypeLoader.csproj" />
<ProjectReference Include="..\..\System.Private.Reflection.Execution\src\System.Private.Reflection.Execution.csproj" />
<ProjectReference Condition="'$(DynamicCodeSupport)' != 'true'" Include="..\..\System.Private.TypeLoader\src\System.Private.TypeLoader.csproj" />
<ProjectReference Condition="'$(DynamicCodeSupport)' != 'true'" Include="..\..\System.Private.Reflection.Execution\src\System.Private.Reflection.Execution.csproj" />
<ProjectReference Condition="'$(DynamicCodeSupport)' == 'true'" Include="..\..\System.Private.TypeLoader\src\System.Private.TypeLoader.Experimental.csproj" />
<ProjectReference Condition="'$(DynamicCodeSupport)' == 'true'" Include="..\..\System.Private.Reflection.Execution\src\System.Private.Reflection.Execution.Experimental.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit 3ca0b10

Please sign in to comment.