diff options
author | Gleb Balykov <g.balykov@samsung.com> | 2018-06-29 17:25:17 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2018-06-29 07:25:17 -0700 |
commit | 61146b5c5851698e113e936d4e4b51b628095f27 (patch) | |
tree | 7b9d9eec971076fe30fa47244bff066b75ac0b09 /src/jit/lower.cpp | |
parent | 1ad9c94ef5e541e9c8ac29606515d6f54e0e445c (diff) | |
download | coreclr-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.cpp | 51 |
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 { |