@@ -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