summaryrefslogtreecommitdiff
path: root/src/jit/lower.cpp
diff options
context:
space:
mode:
authorGleb Balykov <g.balykov@samsung.com>2018-06-29 17:25:17 +0300
committerJan Kotas <jkotas@microsoft.com>2018-06-29 07:25:17 -0700
commit61146b5c5851698e113e936d4e4b51b628095f27 (patch)
tree7b9d9eec971076fe30fa47244bff066b75ac0b09 /src/jit/lower.cpp
parent1ad9c94ef5e541e9c8ac29606515d6f54e0e445c (diff)
downloadcoreclr-61146b5c5851698e113e936d4e4b51b628095f27.tar.gz
coreclr-61146b5c5851698e113e936d4e4b51b628095f27.tar.bz2
coreclr-61146b5c5851698e113e936d4e4b51b628095f27.zip
Remove relocations for vtable chunks (#17147)
* Separate sections READONLY_VCHUNKS and READONLY_DICTIONARY * Remove relocations for second-level indirection of Vtable in case FEATURE_NGEN_RELOCS_OPTIMIZATIONS is enabled. Introduce FEATURE_NGEN_RELOCS_OPTIMIZATIONS, under which NGEN specific relocations optimizations are enabled * Replace push/pop of R11 in stubs with - str/ldr of R4 in space reserved in epilog for non-tail calls - usage of R4 with hybrid-tail calls (same as for EmitShuffleThunk) * Replace push/pop of R11 for function epilog with usage of LR as helper register right before its restore from stack
Diffstat (limited to 'src/jit/lower.cpp')
-rw-r--r--src/jit/lower.cpp51
1 files changed, 42 insertions, 9 deletions
diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp
index ce04c28500..093c2f9611 100644
--- a/src/jit/lower.cpp
+++ b/src/jit/lower.cpp
@@ -3085,6 +3085,16 @@ GenTree* Lowering::LowerDirectCall(GenTreeCall* call)
result = Ind(Ind(result));
break;
+ case IAT_RELPVALUE:
+ {
+ // Non-virtual direct calls to addresses accessed by
+ // a single relative indirection.
+ GenTree* cellAddr = AddrGen(addr);
+ GenTree* indir = Ind(cellAddr);
+ result = comp->gtNewOperNode(GT_ADD, TYP_I_IMPL, indir, AddrGen(addr));
+ break;
+ }
+
default:
noway_assert(!"Bad accessType");
break;
@@ -3874,6 +3884,9 @@ GenTree* Lowering::LowerNonvirtPinvokeCall(GenTreeCall* call)
case IAT_PPVALUE:
result = Ind(Ind(AddrGen(addr)));
break;
+
+ case IAT_RELPVALUE:
+ unreached();
}
}
@@ -3970,19 +3983,24 @@ GenTree* Lowering::LowerVirtualVtableCall(GenTreeCall* call)
//
// Save relative offset to tmp (vtab is virtual table pointer, vtabOffsOfIndirection is offset of
// vtable-1st-level-indirection):
- // tmp = [vtab + vtabOffsOfIndirection]
+ // tmp = vtab
//
// Save address of method to result (vtabOffsAfterIndirection is offset of vtable-2nd-level-indirection):
- // result = [vtab + vtabOffsOfIndirection + vtabOffsAfterIndirection + tmp]
+ // result = [tmp + vtabOffsOfIndirection + vtabOffsAfterIndirection + [tmp + vtabOffsOfIndirection]]
+ //
+ //
+ // If relative pointers are also in second level indirection, additional temporary is used:
+ // tmp1 = vtab
+ // tmp2 = tmp1 + vtabOffsOfIndirection + vtabOffsAfterIndirection + [tmp1 + vtabOffsOfIndirection]
+ // result = tmp2 + [tmp2]
+ //
unsigned lclNumTmp = comp->lvaGrabTemp(true DEBUGARG("lclNumTmp"));
-
comp->lvaTable[lclNumTmp].incRefCnts(comp->compCurBB->getBBWeight(comp), comp);
- GenTree* lclvNodeStore = comp->gtNewTempAssign(lclNumTmp, result);
- LIR::Range range = LIR::SeqTree(comp, lclvNodeStore);
- JITDUMP("result of obtaining pointer to virtual table:\n");
- DISPRANGE(range);
- BlockRange().InsertBefore(call, std::move(range));
+ unsigned lclNumTmp2 = comp->lvaGrabTemp(true DEBUGARG("lclNumTmp2"));
+ comp->lvaTable[lclNumTmp2].incRefCnts(comp->compCurBB->getBBWeight(comp), comp);
+
+ GenTree* lclvNodeStore = comp->gtNewTempAssign(lclNumTmp, result);
GenTree* tmpTree = comp->gtNewLclvNode(lclNumTmp, result->TypeGet());
tmpTree = Offset(tmpTree, vtabOffsOfIndirection);
@@ -3991,7 +4009,22 @@ GenTree* Lowering::LowerVirtualVtableCall(GenTreeCall* call)
GenTree* offs = comp->gtNewIconNode(vtabOffsOfIndirection + vtabOffsAfterIndirection, TYP_INT);
result = comp->gtNewOperNode(GT_ADD, TYP_I_IMPL, comp->gtNewLclvNode(lclNumTmp, result->TypeGet()), offs);
- result = Ind(OffsetByIndex(result, tmpTree));
+ GenTree* base = OffsetByIndexWithScale(result, tmpTree, 1);
+ GenTree* lclvNodeStore2 = comp->gtNewTempAssign(lclNumTmp2, base);
+
+ LIR::Range range = LIR::SeqTree(comp, lclvNodeStore);
+ JITDUMP("result of obtaining pointer to virtual table:\n");
+ DISPRANGE(range);
+ BlockRange().InsertBefore(call, std::move(range));
+
+ LIR::Range range2 = LIR::SeqTree(comp, lclvNodeStore2);
+ JITDUMP("result of obtaining pointer to virtual table 2nd level indirection:\n");
+ DISPRANGE(range2);
+ BlockRange().InsertAfter(lclvNodeStore, std::move(range2));
+
+ result = Ind(comp->gtNewLclvNode(lclNumTmp2, result->TypeGet()));
+ result =
+ comp->gtNewOperNode(GT_ADD, TYP_I_IMPL, result, comp->gtNewLclvNode(lclNumTmp2, result->TypeGet()));
}
else
{