From a394e915916c4abbff08636884124c6e82f36a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Wed, 18 Jul 2018 12:24:56 +0200 Subject: 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`). --- .../Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs | 14 ++++++++++++++ .../Target_X64/X64ReadyToRunHelperNode.cs | 6 +++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'src/ILCompiler.Compiler') 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)); } } -- cgit v1.2.3