diff options
Diffstat (limited to 'src/jit/morph.cpp')
-rw-r--r-- | src/jit/morph.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 4b76e804bf..91b92064fd 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -7231,14 +7231,30 @@ void Compiler::fgMorphTailCall(GenTreeCall* call) unsigned vtabOffsOfIndirection; unsigned vtabOffsAfterIndirection; - info.compCompHnd->getMethodVTableOffset(call->gtCallMethHnd, &vtabOffsOfIndirection, &vtabOffsAfterIndirection); + bool isRelative; + info.compCompHnd->getMethodVTableOffset(call->gtCallMethHnd, &vtabOffsOfIndirection, &vtabOffsAfterIndirection, + &isRelative); /* Get the appropriate vtable chunk */ if (vtabOffsOfIndirection != CORINFO_VIRTUALCALL_NO_CHUNK) { - add = gtNewOperNode(GT_ADD, TYP_I_IMPL, vtbl, gtNewIconNode(vtabOffsOfIndirection, TYP_I_IMPL)); + add = gtNewOperNode(GT_ADD, TYP_I_IMPL, vtbl, gtNewIconNode(vtabOffsOfIndirection, TYP_I_IMPL)); + + GenTreePtr indOffTree; + + if (isRelative) + { + indOffTree = impCloneExpr(add, &add, NO_CLASS_HANDLE, (unsigned)CHECK_SPILL_ALL, + nullptr DEBUGARG("virtual table call")); + } + vtbl = gtNewOperNode(GT_IND, TYP_I_IMPL, add); + + if (isRelative) + { + vtbl = gtNewOperNode(GT_ADD, TYP_I_IMPL, vtbl, indOffTree); + } } /* Now the appropriate vtable slot */ |