Skip to content

Commit 8ceca25

Browse files
authored
Properly handle byrefs in tailcall helper stubs (#41815)
* Properly handle byrefs in tailcall helper stubs Switch to using ByReference instead of using stind.i/ldind.i and relying on the JIT to report the locations being moved between. Fixes #41555 * Move NextCallReturnAddress call back
1 parent 09c9d10 commit 8ceca25

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

src/coreclr/src/vm/corelib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ DEFINE_FIELD(NULL, VALUE, Value)
589589
DEFINE_CLASS(NULLABLE, System, Nullable`1)
590590

591591
DEFINE_CLASS(BYREFERENCE, System, ByReference`1)
592+
DEFINE_METHOD(BYREFERENCE, CTOR, .ctor, NoSig)
593+
DEFINE_METHOD(BYREFERENCE, GET_VALUE, get_Value, NoSig)
592594
DEFINE_CLASS(SPAN, System, Span`1)
593595
DEFINE_METHOD(SPAN, GET_ITEM, get_Item, IM_Int_RetRefT)
594596
DEFINE_CLASS(READONLY_SPAN, System, ReadOnlySpan`1)

src/coreclr/src/vm/tailcallhelp.cpp

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,6 @@ MethodDesc* TailCallHelp::CreateStoreArgsStub(TailCallInfo& info)
372372
for (COUNT_T i = 0; i < info.ArgBufLayout.Values.GetCount(); i++)
373373
{
374374
const ArgBufferValue& arg = info.ArgBufLayout.Values[i];
375-
CorElementType ty = arg.TyHnd.GetSignatureCorElementType();
376375

377376
emitOffs(arg.Offset);
378377
pCode->EmitLDARG(i);
@@ -629,35 +628,63 @@ void TailCallHelp::CreateCallTargetStubSig(const TailCallInfo& info, SigBuilder*
629628
#endif // _DEBUG
630629
}
631630

631+
// Get TypeHandle for ByReference<System.Byte>
632+
static TypeHandle GetByReferenceOfByteType()
633+
{
634+
TypeHandle byteTH(CoreLibBinder::GetElementType(ELEMENT_TYPE_U1));
635+
Instantiation byteInst(&byteTH, 1);
636+
TypeHandle th = TypeHandle(CoreLibBinder::GetClass(CLASS__BYREFERENCE)).Instantiate(byteInst);
637+
return th;
638+
}
639+
640+
// Get MethodDesc* for ByReference<System.Byte>::get_Value
641+
static MethodDesc* GetByReferenceOfByteValueGetter()
642+
{
643+
MethodDesc* getter = CoreLibBinder::GetMethod(METHOD__BYREFERENCE__GET_VALUE);
644+
getter =
645+
MethodDesc::FindOrCreateAssociatedMethodDesc(
646+
getter,
647+
GetByReferenceOfByteType().GetMethodTable(),
648+
false,
649+
Instantiation(),
650+
TRUE);
651+
652+
return getter;
653+
}
654+
655+
// Get MethodDesc* for ByReference<System.Byte>::.ctor
656+
static MethodDesc* GetByReferenceOfByteCtor()
657+
{
658+
MethodDesc* ctor = CoreLibBinder::GetMethod(METHOD__BYREFERENCE__CTOR);
659+
ctor =
660+
MethodDesc::FindOrCreateAssociatedMethodDesc(
661+
ctor,
662+
GetByReferenceOfByteType().GetMethodTable(),
663+
false,
664+
Instantiation(),
665+
TRUE);
666+
667+
return ctor;
668+
}
669+
632670
void TailCallHelp::EmitLoadTyHnd(ILCodeStream* stream, TypeHandle tyHnd)
633671
{
634-
CorElementType ty = tyHnd.GetSignatureCorElementType();
635672
if (tyHnd.IsByRef())
636-
{
637-
// Note: we can use an "untracked" ldind.i here even with byrefs because
638-
// we are loading between two tracked positions.
639-
stream->EmitLDIND_I();
640-
}
673+
stream->EmitCALL(stream->GetToken(GetByReferenceOfByteValueGetter()), 1, 1);
641674
else
642-
{
643-
int token = stream->GetToken(tyHnd);
644-
stream->EmitLDOBJ(token);
645-
}
675+
stream->EmitLDOBJ(stream->GetToken(tyHnd));
646676
}
647677

648678
void TailCallHelp::EmitStoreTyHnd(ILCodeStream* stream, TypeHandle tyHnd)
649679
{
650-
CorElementType ty = tyHnd.GetSignatureCorElementType();
651680
if (tyHnd.IsByRef())
652681
{
653-
// Note: we can use an "untracked" stind.i here even with byrefs because
654-
// we are storing between two tracked positions.
655-
stream->EmitSTIND_I();
682+
stream->EmitNEWOBJ(stream->GetToken(GetByReferenceOfByteCtor()), 1);
683+
stream->EmitSTOBJ(stream->GetToken(GetByReferenceOfByteType()));
656684
}
657685
else
658686
{
659-
int token = stream->GetToken(tyHnd);
660-
stream->EmitSTOBJ(token);
687+
stream->EmitSTOBJ(stream->GetToken(tyHnd));
661688
}
662689
}
663690

0 commit comments

Comments
 (0)