Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>2018-07-18 13:24:56 +0300
committerGitHub <noreply@github.com>2018-07-18 13:24:56 +0300
commita394e915916c4abbff08636884124c6e82f36a8f (patch)
treee297ec7a720296cd7f54f60aa5943088d4d88d82 /src
parente2c4bc3d7889f951c231d7f131d6a7e20c034fb6 (diff)
Make thread statics faster (#6108)
* Fix the TODO to inline `.cctor` check into the R2R helper. This avoids some method calls and stack frame setup. * Remove array cast from the hot path. The runtime doesn't care what type the storage is, as long as it's a managed reference - in fact, it seems to be treated as an `Object` in `pCurrentThread->GetThreadStaticStorageForModule` anyway. I considered replacing the cast with an `Unsafe.As`, but just redeclaring the signatures as returning `object[]` seemed better (because now we actually guarantee the classlib won't pass anything but `object[]` to `RhSetThreadStaticStorageForModule`).
Diffstat (limited to 'src')
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs14
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs6
-rw-r--r--src/Native/Runtime/thread.cpp4
-rw-r--r--src/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs4
5 files changed, 24 insertions, 6 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs
index 09ebadeaa..662867f99 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs
@@ -88,6 +88,20 @@ namespace ILCompiler.DependencyAnalysis.X64
}
}
+ public void EmitJE(ISymbolNode symbol)
+ {
+ if (symbol.RepresentsIndirectionCell)
+ {
+ throw new NotImplementedException();
+ }
+ else
+ {
+ Builder.EmitByte(0x0f);
+ Builder.EmitByte(0x84);
+ Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32);
+ }
+ }
+
public void EmitINT3()
{
Builder.EmitByte(0xCC);
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs
index 026367d85..dbe8319c8 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs
@@ -127,7 +127,11 @@ namespace ILCompiler.DependencyAnalysis
else
{
encoder.EmitLEAQ(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target), - NonGCStaticsNode.GetClassConstructorContextStorageSize(factory.Target, target));
- // TODO: performance optimization - inline the check verifying whether we need to trigger the cctor
+
+ AddrMode initialized = new AddrMode(encoder.TargetRegister.Arg2, null, factory.Target.PointerSize, 0, AddrModeSize.Int32);
+ encoder.EmitCMP(ref initialized, 1);
+ encoder.EmitJE(factory.HelperEntrypoint(HelperEntrypoint.GetThreadStaticBaseForType));
+
encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnThreadStaticBase));
}
}
diff --git a/src/Native/Runtime/thread.cpp b/src/Native/Runtime/thread.cpp
index 570581143..77cfc1904 100644
--- a/src/Native/Runtime/thread.cpp
+++ b/src/Native/Runtime/thread.cpp
@@ -1336,10 +1336,10 @@ Boolean Thread::SetThreadStaticStorageForModule(Object * pStorage, UInt32 module
return TRUE;
}
-COOP_PINVOKE_HELPER(Array*, RhGetThreadStaticStorageForModule, (UInt32 moduleIndex))
+COOP_PINVOKE_HELPER(Object*, RhGetThreadStaticStorageForModule, (UInt32 moduleIndex))
{
Thread * pCurrentThread = ThreadStore::RawGetCurrentThread();
- return (Array*)pCurrentThread->GetThreadStaticStorageForModule(moduleIndex);
+ return pCurrentThread->GetThreadStaticStorageForModule(moduleIndex);
}
COOP_PINVOKE_HELPER(Boolean, RhSetThreadStaticStorageForModule, (Array * pStorage, UInt32 moduleIndex))
diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs b/src/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs
index fc8e142cd..b125d8fa2 100644
--- a/src/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs
+++ b/src/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs
@@ -22,7 +22,7 @@ namespace Internal.Runtime
{
// Get the array that holds thread static memory blocks for each type in the given module
int moduleIndex = pModuleData->ModuleIndex;
- object[] storage = (object[])RuntimeImports.RhGetThreadStaticStorageForModule(moduleIndex);
+ object[] storage = RuntimeImports.RhGetThreadStaticStorageForModule(moduleIndex);
// Check whether thread static storage has already been allocated for this module and type.
if ((storage != null) && (typeTlsIndex < storage.Length) && (storage[typeTlsIndex] != null))
diff --git a/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
index 49ed62a79..acc2fd324 100644
--- a/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
+++ b/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
@@ -561,11 +561,11 @@ namespace System.Runtime
#if !PROJECTN
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhGetThreadStaticStorageForModule")]
- internal static unsafe extern Array RhGetThreadStaticStorageForModule(int moduleIndex);
+ internal static unsafe extern object[] RhGetThreadStaticStorageForModule(int moduleIndex);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhSetThreadStaticStorageForModule")]
- internal static unsafe extern bool RhSetThreadStaticStorageForModule(Array storage, int moduleIndex);
+ internal static unsafe extern bool RhSetThreadStaticStorageForModule(object[] storage, int moduleIndex);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhCurrentNativeThreadId")]