未验证 提交 125253b7 编写于 作者: A Andy Ayers 提交者: GitHub

JIT: fix osr gc info this reporting (#51057)

With the advent of #38229 an optimized method may need to report generics
context via `this` while the un-optimzed version did not need to report.

This impacts OSR, which previously was always trying to use the unoptimized
root method frame reporting. Now under OSR we must sometimes add a slot to
the OSR frame instead.

Addresses one of the failure cases in #43534.
上级 624a8349
......@@ -3931,13 +3931,24 @@ void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSiz
int offset = 0;
// OSR can report the root method's frame slot, if that method reported context.
//
bool isOsrAndUsingRootFrameSlot = false;
if (compiler->opts.IsOSR())
{
PatchpointInfo* ppInfo = compiler->info.compPatchpointInfo;
offset = ppInfo->GenericContextArgOffset();
assert(offset != -1);
PatchpointInfo* const ppInfo = compiler->info.compPatchpointInfo;
if (ppInfo->HasKeptAliveThis())
{
offset = ppInfo->GenericContextArgOffset();
assert(offset != -1);
isOsrAndUsingRootFrameSlot = true;
}
}
else
// If not OSR, or OSR but newly reporting context, use the current frame offset.
//
if (!isOsrAndUsingRootFrameSlot)
{
offset = compiler->lvaToCallerSPRelativeOffset(compiler->lvaCachedGenericContextArgOffset(),
compiler->isFramePointerUsed());
......
......@@ -6267,19 +6267,15 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
}
#endif // JIT32_GCENCODER
// OSR methods use the original method slot for the cached kept alive this,
// so don't need to allocate a slot on the new frame.
if (opts.IsOSR())
{
if (lvaKeepAliveAndReportThis())
{
PatchpointInfo* ppInfo = info.compPatchpointInfo;
assert(ppInfo->HasKeptAliveThis());
int originalOffset = ppInfo->KeptAliveThisOffset();
lvaCachedGenericContextArgOffs = originalFrameStkOffs + originalOffset;
}
}
else if (lvaReportParamTypeArg())
// For OSR methods, param type args are always reportable via the root method frame slot.
// (see gcInfoBlockHdrSave) and so do not need a new slot on the frame.
//
// OSR methods may also be able to use the root frame kept alive this, if the root
// method needed to report this.
//
// Inlining done under OSR may introduce new reporting, in which case the OSR frame
// must allocate a slot.
if (!opts.IsOSR() && lvaReportParamTypeArg())
{
#ifdef JIT32_GCENCODER
noway_assert(codeGen->isFramePointerUsed());
......@@ -6292,10 +6288,25 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
#ifndef JIT32_GCENCODER
else if (lvaKeepAliveAndReportThis())
{
// When "this" is also used as generic context arg.
lvaIncrementFrameSize(TARGET_POINTER_SIZE);
stkOffs -= TARGET_POINTER_SIZE;
lvaCachedGenericContextArgOffs = stkOffs;
bool canUseExistingSlot = false;
if (opts.IsOSR())
{
PatchpointInfo* ppInfo = info.compPatchpointInfo;
if (ppInfo->HasKeptAliveThis())
{
int originalOffset = ppInfo->KeptAliveThisOffset();
lvaCachedGenericContextArgOffs = originalFrameStkOffs + originalOffset;
canUseExistingSlot = true;
}
}
if (!canUseExistingSlot)
{
// When "this" is also used as generic context arg.
lvaIncrementFrameSize(TARGET_POINTER_SIZE);
stkOffs -= TARGET_POINTER_SIZE;
lvaCachedGenericContextArgOffs = stkOffs;
}
}
#endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册