-
Notifications
You must be signed in to change notification settings - Fork 5.1k
[clr-interp] Implement array support for reference and value types #116384
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
[clr-interp] Implement array support for reference and value types #116384
Conversation
Tagging subscribers to this area: @BrzVlad, @janvorli, @kg |
src/coreclr/interpreter/compiler.cpp
Outdated
break; | ||
} | ||
|
||
assert(!"Array constructor with <= 1 args is not allowed"); |
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.
It is not possible to call array constructor with 1 arg in C#, but it is valid in IL. I am sure we will have some test cases for it,
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.
Ok, removed the assert.
src/coreclr/vm/interpexec.cpp
Outdated
// TODO: Stack slot is 8 bytes aligned and | ||
// AllocateArrayEx expects the dimensions to be in int32_t array | ||
// so we need to convert the stack slots to int32_t | ||
int32_t* dims = (int32_t*)alloca(rank * sizeof(int32_t)); |
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.
alloca will overflow the stack when called in the loop. Is it what the TODO above is about? I think this should just be moved to a helper method, so that the alloca buffer gets de-allocated once the opcode executes.
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.
Thanks, I’ve moved it to a helper function. An alternative would be to pack argCalls into an int32_t* array, but that would require a series of mov and shift opcodes.
src/coreclr/vm/interpexec.cpp
Outdated
@@ -1252,6 +1252,31 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr | |||
|
|||
goto CALL_INTERP_SLOT; | |||
} | |||
case INTOP_NEWOBJ_ARR: |
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.
I would call the opcode INTOP_NEW_MDARR
to make it clear that it allocates multi-dimensional arrays.
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.
Updated to INTOP_NEWMDARR to match INTOP_NEWARR.
src/coreclr/vm/interpexec.cpp
Outdated
ip += 5; | ||
break; | ||
} | ||
case INTOP_LDELEMA1: |
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.
What is the 1
suffix trying to say? I think this should be INTOP_LDELEMA
.
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 might be a mono-ism, the mono interp has an opcode named this
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.
Mono has three different opcodes for different situations:
LDELEMA_TC
is the most generic one with type checks for reference types (see theLDELEMA_REF
suggestion in comments below)LDELEMA
andLDELEMA1
for arrays of value types,LDELEMA1
seems to be the specialized variant for SZARRAYs (0-based, 1-rank)
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.
I'd personally prefer to use an unified convention across opcodes like this. This could be LDELEMA
(for SZARRAY), LDELEMA_MD
(for all other arrays) and LDELEMA_REF
(for arrays of reference types).
We have some prior art in CoreCLR for treating SZARRAY
as just "array" and using a prefix/suffix for other arrays. I don't have any preference for a specific naming convention as long as it's consistent between the opcodes.
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.
Thanks, I agree with LDELEMA/LDELEMA_REF/LDELEMA_MD suggestion.
src/coreclr/vm/interpexec.cpp
Outdated
if (elemRef != NULL) | ||
{ | ||
MethodTable* arrayElemMT = (MethodTable*)pMethod->pDataItems[ip[4]]; | ||
if (arrayElemMT != NULL && !ObjIsInstanceOf(OBJECTREFToObject(elemRef), arrayElemMT)) |
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.
ObjIsInstanceOf
can trigger GC, so the object references have to be protected around the call; or re-fetched from the interpterer stack after the call. The latter is probably more efficient.
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.
LGTM, thank you!
…reclr-interp-array-ref
Description
This PR adds support for array operations in the interpreter, including both ref and value types.
Changes
LDELEM_REF
,LDELEM_VT
STELEM_REF
,STELEM_VT
,STELEM_VT_NOREF
LDELEMA
,LDELEMA_REF
Out-of-scope
LDELEMA_MD
and multi-dimensional array getters will be implemented as follow-up.