bool Compiler::lvaIsOSRLocal(unsigned varNum)
{
- if (!opts.IsOSR())
- {
- return false;
- }
+ LclVarDsc* const varDsc = lvaGetDesc(varNum);
- if (varNum < info.compLocalsCount)
- {
- return true;
- }
-
- LclVarDsc* varDsc = lvaGetDesc(varNum);
-
- if (varDsc->lvIsStructField)
+#ifdef DEBUG
+ if (!opts.IsOSR())
{
- return (varDsc->lvParentLcl < info.compLocalsCount);
+ assert(!varDsc->lvIsOSRLocal);
}
+#endif
- return false;
+ return varDsc->lvIsOSRLocal;
}
//------------------------------------------------------------------------------
// the prolog. If the local has gc pointers, there are no gc-safe points
// between the prolog and the explicit initialization.
+ unsigned char lvIsOSRLocal : 1; // Root method local in an OSR method. Any stack home will be on the Tier0 frame.
+ // Initial value will be defined by Tier0. Requires special handing in prolog.
+
union {
unsigned lvFieldLclStart; // The index of the local var representing the first field in the promoted struct
// local. For implicit byref parameters, this gets hijacked between
CORINFO_CLASS_HANDLE clsHnd = info.compCompHnd->getArgClass(&info.compMethodInfo->locals, localsSig);
lvaSetClass(varNum, clsHnd);
}
-
- if (opts.IsOSR() && info.compPatchpointInfo->IsExposed(varNum))
- {
- JITDUMP("-- V%02u is OSR exposed\n", varNum);
- varDsc->lvHasLdAddrOp = 1;
-
- // todo: Why does it apply only to non-structs?
- //
- if (!varTypeIsStruct(varDsc) && !varTypeIsSIMD(varDsc))
- {
- lvaSetVarAddrExposed(varNum DEBUGARG(AddressExposedReason::OSR_EXPOSED));
- }
- }
}
if ( // If there already exist unsafe buffers, don't mark more structs as unsafe
}
}
+ // If this is an OSR method, mark all the OSR locals and model OSR exposure.
+ //
+ // Do this before we add the GS Cookie Dummy or Outgoing args to the locals
+ // so we don't have to do special checks to exclude them.
+ //
+ if (opts.IsOSR())
+ {
+ for (unsigned lclNum = 0; lclNum < lvaCount; lclNum++)
+ {
+ LclVarDsc* const varDsc = lvaGetDesc(lclNum);
+ varDsc->lvIsOSRLocal = true;
+
+ if (info.compPatchpointInfo->IsExposed(lclNum))
+ {
+ JITDUMP("-- V%02u is OSR exposed\n", lclNum);
+ varDsc->lvHasLdAddrOp = 1;
+
+ // todo: Why does it apply only to non-structs?
+ //
+ if (!varTypeIsStruct(varDsc) && !varTypeIsSIMD(varDsc))
+ {
+ lvaSetVarAddrExposed(lclNum DEBUGARG(AddressExposedReason::OSR_EXPOSED));
+ }
+ }
+ }
+ }
+
if (getNeedsGSSecurityCookie())
{
// Ensure that there will be at least one stack variable since
lvaSetVarAddrExposed(varDscInfo->varNum DEBUGARG(AddressExposedReason::TOO_CONSERVATIVE));
#endif // !TARGET_X86
}
-
- if (opts.IsOSR() && info.compPatchpointInfo->IsExposed(varDscInfo->varNum))
- {
- JITDUMP("-- V%02u is OSR exposed\n", varDscInfo->varNum);
- varDsc->lvHasLdAddrOp = 1;
- lvaSetVarAddrExposed(varDscInfo->varNum DEBUGARG(AddressExposedReason::OSR_EXPOSED));
- }
}
compArgSize = GetOutgoingArgByteSize(compArgSize);
fieldVarDsc->lvFldOrdinal = pFieldInfo->fldOrdinal;
fieldVarDsc->lvParentLcl = lclNum;
fieldVarDsc->lvIsParam = varDsc->lvIsParam;
+ fieldVarDsc->lvIsOSRLocal = varDsc->lvIsOSRLocal;
// This new local may be the first time we've seen a long typed local.
if (fieldVarDsc->lvType == TYP_LONG)