Skip to content

Commit c124174

Browse files
committed
workaround for "live" byrefs in minopts.
1 parent 12ca088 commit c124174

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

src/coreclr/jit/async.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -958,18 +958,25 @@ ContinuationLayout AsyncTransformation::LayOutContinuation(BasicBlock*
958958
if (dsc->TypeIs(TYP_STRUCT) || dsc->IsImplicitByRef())
959959
{
960960
ClassLayout* layout = dsc->GetLayout();
961-
assert(!layout->HasGCByRef());
962961

963-
if (layout->IsCustomLayout())
962+
// TODO: (async) we do not need to save ByRef-containing locals
963+
// as by the spec an await turns them into zero-inited state.
964+
// For now just store/restore as if there are no gc refs.
965+
// This is mostly to handle the "fake" live-across-await byrefs
966+
// in min-opts, since C#-compiled code by itself does not let
967+
// byrefs be live across awaits.
968+
unsigned objCount = layout->HasGCByRef() ? 0 : layout->GetGCPtrCount();
969+
970+
if (layout->IsCustomLayout())
964971
{
965972
inf.Alignment = 1;
966973
inf.DataSize = layout->GetSize();
967-
inf.GCDataCount = layout->GetGCPtrCount();
974+
inf.GCDataCount = objCount;
968975
}
969976
else
970977
{
971978
inf.Alignment = m_comp->info.compCompHnd->getClassAlignmentRequirement(layout->GetClassHandle());
972-
if ((layout->GetGCPtrCount() * TARGET_POINTER_SIZE) == layout->GetSize())
979+
if ((objCount * TARGET_POINTER_SIZE) == layout->GetSize())
973980
{
974981
inf.DataSize = 0;
975982
}
@@ -978,7 +985,7 @@ ContinuationLayout AsyncTransformation::LayOutContinuation(BasicBlock*
978985
inf.DataSize = layout->GetSize();
979986
}
980987

981-
inf.GCDataCount = layout->GetGCPtrCount();
988+
inf.GCDataCount = objCount;
982989
}
983990
}
984991
else if (dsc->TypeIs(TYP_REF))
@@ -987,10 +994,17 @@ ContinuationLayout AsyncTransformation::LayOutContinuation(BasicBlock*
987994
inf.DataSize = 0;
988995
inf.GCDataCount = 1;
989996
}
997+
else if (dsc->TypeIs(TYP_BYREF))
998+
{
999+
// TODO: (async) ByRefs do not need to be saved at all.
1000+
// For now pretend they are unmanaged data.
1001+
// See the note on `layout->HasGCByRef()` case for justification.
1002+
inf.Alignment = TARGET_POINTER_SIZE;
1003+
inf.DataSize = TARGET_POINTER_SIZE;
1004+
inf.GCDataCount = 0;
1005+
}
9901006
else
9911007
{
992-
assert(!dsc->TypeIs(TYP_BYREF));
993-
9941008
inf.Alignment = genTypeAlignments[dsc->TypeGet()];
9951009
inf.DataSize = genTypeSize(dsc);
9961010
inf.GCDataCount = 0;

0 commit comments

Comments
 (0)