diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2018-07-18 13:24:56 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-18 13:24:56 +0300 |
commit | a394e915916c4abbff08636884124c6e82f36a8f (patch) | |
tree | e297ec7a720296cd7f54f60aa5943088d4d88d82 /src/ILCompiler.Compiler | |
parent | e2c4bc3d7889f951c231d7f131d6a7e20c034fb6 (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/ILCompiler.Compiler')
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs | 14 | ||||
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs | 6 |
2 files changed, 19 insertions, 1 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)); } } |