-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Add support for statics access from shared generic code, as well as precise-init static class construction #117110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
davidwrighton
commented
Jun 27, 2025
- There is another renaming of the helpers call opcodes to allow distinguishing between whether or not the arg is supplied via svar or dataindex.
- More tests to cover these scenarios
- This should finish up the support for shared generics
…recise-init static class construction - There is another renaming of the helpers call opcodes to allow distinguishing between whether or not the arg is supplied via svar or dataindex. - More tests to cover these scenarios - This should finish up the support for shared generics
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR extends the interpreter to distinguish helper call opcodes based on how arguments are supplied (via static var vs. data index) and adds support for precise static constructor initialization in shared generic code.
- Introduces new opcodes (
INTOP_CALL_HELPER_P_S
,_PS
,_SP
,_GS
,_APS
,_AGS
) in both the opcode definitions and interpreter execution. - Updates the compiler to emit the new opcodes and to insert precise-init calls for
initClass
at method start and on static field access. - Adds
TestPreciseInitCctors
in the interpreter tests to verify that static constructors run exactly when expected.
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
src/tests/JIT/interpreter/Interpreter.cs | Added TestPreciseInitCctors ; hooked it into RunInterpreterTests |
src/coreclr/vm/interpexec.cpp | Expanded switch to handle new helper‐call opcodes |
src/coreclr/interpreter/intops.h | Declared InterpOpHelperFtnNoArgs for no-argument helpers |
src/coreclr/interpreter/intops.def | Defined new opcodes (_S , _PS , _SP , _GS , _APS , _AGS ) |
src/coreclr/interpreter/compiler.cpp | Emit new opcodes in EmitPushHelperCall_* , insert precise-init logic, update PrintInsData |
Comments suppressed due to low confidence (5)
src/coreclr/interpreter/compiler.cpp:3318
- New code paths for method‐start
initClass
and the subsequent runtime‐lookup branches (CORINFO_LOOKUP_THISOBJ
,METHODPARAM
, etc.) aren't covered by existing interpreter tests. Add tests inInterpreter.cs
to exercise these branches and validate that the correct helper opcodes are emitted and executed.
CorInfoInitClassResult initOnFunctionStart = m_compHnd->initClass(NULL, NULL, METHOD_BEING_COMPILED_CONTEXT());
src/tests/JIT/interpreter/Interpreter.cs:1996
- The error message references
TriggerCctorClass
even though this branch testsTriggerCctorMethod
. Also it doesn't show the actualpreciseInitCctorsRun
value. Consider usingConsole.WriteLine("preciseInitCctorsRun should be 2, but is {0}", preciseInitCctorsRun);
for clarity.
Console.WriteLine("TriggerCctorClass should return 2, but did not");
src/tests/JIT/interpreter/Interpreter.cs:2003
- Same issue as above: this branch follows
new MyPreciseInitClass<double>()
but prints the wrong helper name and omits the actual counter value. Update to referencepreciseInitCctorsRun
with the expected versus actual value.
Console.WriteLine("TriggerCctorClass should return 3, but did not");
src/tests/JIT/interpreter/Interpreter.cs:2016
- This message is in the branch testing
TriggerCctorMethod<object>()
but again calls out the wrong helper name and hides the counter. Use a consistent message likepreciseInitCctorsRun should be 5, but is {0}
.
Console.WriteLine("TriggerCctorClass should return 5, but did not");
src/tests/JIT/interpreter/Interpreter.cs:2023
- Similarly, this branch tests the constructor on
MyPreciseInitClass<Type>()
but the message refers toTriggerCctorClass
and omits the run count. Consider using the actualpreciseInitCctorsRun
in the output for easy debugging.
Console.WriteLine("TriggerCctorClass should return 6, but did not");
@@ -3079,6 +3079,13 @@ void InterpCompiler::EmitStaticFieldAddress(CORINFO_FIELD_INFO *pFieldInfo, CORI | |||
case CORINFO_FIELD_STATIC_ADDRESS: | |||
case CORINFO_FIELD_STATIC_RVA_ADDRESS: | |||
{ | |||
if (pFieldInfo->fieldFlags |= CORINFO_FLG_FIELD_INITCLASS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This uses |=
(assignment) instead of &
to test the CORINFO_FLG_FIELD_INITCLASS
flag, which both mutates fieldFlags
and always evaluates true. Change it to if ((pFieldInfo->fieldFlags & CORINFO_FLG_FIELD_INITCLASS) != 0)
.
if (pFieldInfo->fieldFlags |= CORINFO_FLG_FIELD_INITCLASS) | |
if ((pFieldInfo->fieldFlags & CORINFO_FLG_FIELD_INITCLASS) != 0) |
Copilot uses AI. Check for mistakes.
Tagging subscribers to this area: @BrzVlad, @janvorli, @kg |
{ | ||
Console.WriteLine("TriggerCctorClass should return 2, but did not"); | ||
return false; | ||
} | ||
|
||
object o = new MyPreciseInitClass<double>(); | ||
if (preciseInitCctorsRun != 3) | ||
{ | ||
Console.WriteLine("TriggerCctorClass should return 3, but did not"); | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two writelines are wrong