@@ -70,39 +70,61 @@ protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bo
7070
7171 case ReadyToRunHelperId . GetThreadStaticBase :
7272 {
73- bool isMultiFile = ! factory . CompilationModuleGroup . IsSingleFileCompilation ;
74-
7573 MetadataType target = ( MetadataType ) Target ;
74+ encoder . EmitLEAQ ( encoder . TargetRegister . Arg1 , factory . TypeThreadStaticIndex ( target ) ) ;
7675
77- encoder . EmitLEAQ ( encoder . TargetRegister . Arg2 , factory . TypeThreadStaticIndex ( target ) ) ;
78-
79- // First arg: address of the TypeManager slot that provides the helper with
80- // information about module index and the type manager instance (which is used
81- // for initialization on first access).
82- AddrMode loadFromArg2 = new AddrMode ( encoder . TargetRegister . Arg2 , null , 0 , 0 , AddrModeSize . Int64 ) ;
83- encoder . EmitMOV ( encoder . TargetRegister . Arg0 , ref loadFromArg2 ) ;
84-
85- // Second arg: index of the type in the ThreadStatic section of the modules
86- AddrMode loadFromArg2AndDelta = new AddrMode ( encoder . TargetRegister . Arg2 , null , factory . Target . PointerSize , 0 , AddrModeSize . Int32 ) ;
87- encoder . EmitMOV ( encoder . TargetRegister . Arg1 , ref loadFromArg2AndDelta ) ;
88-
89- ISymbolNode helper = isMultiFile ?
90- factory . HelperEntrypoint ( HelperEntrypoint . GetThreadStaticBaseForType ) :
91- factory . ExternSymbol ( "RhpGetThreadStaticBaseForType" ) ;
76+ // Arg0: index of the type in the ThreadStatic section of the modules
77+ AddrMode loadFromArg1AndDelta = new AddrMode ( encoder . TargetRegister . Arg1 , null , factory . Target . PointerSize , 0 , AddrModeSize . Int32 ) ;
78+ encoder . EmitMOV ( encoder . TargetRegister . Arg0 , ref loadFromArg1AndDelta ) ;
9279
93- if ( ! factory . PreinitializationManager . HasLazyStaticConstructor ( target ) )
80+ bool isSingleFile = factory . CompilationModuleGroup . IsSingleFileCompilation ;
81+ if ( isSingleFile )
9482 {
95- encoder . EmitJMP ( helper ) ;
83+ ISymbolNode helper = factory . ExternSymbol ( "RhpGetThreadStaticBaseForType" ) ;
84+ if ( ! factory . PreinitializationManager . HasLazyStaticConstructor ( target ) )
85+ {
86+ encoder . EmitJMP ( helper ) ;
87+ }
88+ else
89+ {
90+ // check if class is initialized
91+ encoder . EmitLEAQ ( encoder . TargetRegister . Arg2 , factory . TypeNonGCStaticsSymbol ( target ) , - NonGCStaticsNode . GetClassConstructorContextSize ( factory . Target ) ) ;
92+ AddrMode initialized = new AddrMode ( encoder . TargetRegister . Arg2 , null , 0 , 0 , AddrModeSize . Int64 ) ;
93+ encoder . EmitCMP ( ref initialized , 0 ) ;
94+ encoder . EmitJE ( helper ) ;
95+
96+ // Arg1: address of the TypeManager slot that provides the helper with
97+ // information about module index and the type manager instance (which is used for initialization on first access).
98+ AddrMode loadFromArg1 = new AddrMode ( encoder . TargetRegister . Arg1 , null , 0 , 0 , AddrModeSize . Int64 ) ;
99+ encoder . EmitMOV ( encoder . TargetRegister . Arg1 , ref loadFromArg1 ) ;
100+ encoder . EmitJMP ( factory . HelperEntrypoint ( HelperEntrypoint . EnsureClassConstructorRunAndReturnThreadStaticBase ) ) ;
101+ }
96102 }
97103 else
98104 {
99- encoder . EmitLEAQ ( encoder . TargetRegister . Arg2 , factory . TypeNonGCStaticsSymbol ( target ) , - NonGCStaticsNode . GetClassConstructorContextSize ( factory . Target ) ) ;
100-
101- AddrMode initialized = new AddrMode ( encoder . TargetRegister . Arg2 , null , 0 , 0 , AddrModeSize . Int64 ) ;
102- encoder . EmitCMP ( ref initialized , 0 ) ;
103- encoder . EmitJE ( helper ) ;
104-
105- encoder . EmitJMP ( factory . HelperEntrypoint ( HelperEntrypoint . EnsureClassConstructorRunAndReturnThreadStaticBase ) ) ;
105+ ISymbolNode helper = factory . HelperEntrypoint ( HelperEntrypoint . GetThreadStaticBaseForType ) ;
106+
107+ // Arg1: address of the TypeManager slot that provides the helper with
108+ // information about module index and the type manager instance (which is used for initialization on first access).
109+ AddrMode loadFromArg1 = new AddrMode ( encoder . TargetRegister . Arg1 , null , 0 , 0 , AddrModeSize . Int64 ) ;
110+ encoder . EmitMOV ( encoder . TargetRegister . Arg1 , ref loadFromArg1 ) ;
111+
112+ if ( ! factory . PreinitializationManager . HasLazyStaticConstructor ( target ) )
113+ {
114+ encoder . EmitJMP ( helper ) ;
115+ }
116+ else
117+ {
118+ // check if class is initialized
119+ encoder . EmitLEAQ ( encoder . TargetRegister . Arg2 , factory . TypeNonGCStaticsSymbol ( target ) , - NonGCStaticsNode . GetClassConstructorContextSize ( factory . Target ) ) ;
120+
121+ AddrMode initialized = new AddrMode ( encoder . TargetRegister . Arg2 , null , 0 , 0 , AddrModeSize . Int64 ) ;
122+ encoder . EmitCMP ( ref initialized , 0 ) ;
123+ encoder . EmitJE ( helper ) ;
124+
125+ // call another helper (same arguments)
126+ encoder . EmitJMP ( factory . HelperEntrypoint ( HelperEntrypoint . EnsureClassConstructorRunAndReturnThreadStaticBase ) ) ;
127+ }
106128 }
107129 }
108130 break ;
0 commit comments