summaryrefslogtreecommitdiff
path: root/packaging/0044-Replace-push-pop-of-R11-in-stubs-with.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/0044-Replace-push-pop-of-R11-in-stubs-with.patch')
-rw-r--r--packaging/0044-Replace-push-pop-of-R11-in-stubs-with.patch182
1 files changed, 182 insertions, 0 deletions
diff --git a/packaging/0044-Replace-push-pop-of-R11-in-stubs-with.patch b/packaging/0044-Replace-push-pop-of-R11-in-stubs-with.patch
new file mode 100644
index 0000000000..6c37a505cf
--- /dev/null
+++ b/packaging/0044-Replace-push-pop-of-R11-in-stubs-with.patch
@@ -0,0 +1,182 @@
+From 1c31fc93e3a1acc7c0671837e0c25fe389a8415f Mon Sep 17 00:00:00 2001
+From: Gleb Balykov <g.balykov@samsung.com>
+Date: Thu, 7 Jun 2018 17:51:53 +0300
+Subject: [PATCH 44/47] 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)
+
+---
+ src/vm/arm/stubs.cpp | 98 +++++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 77 insertions(+), 21 deletions(-)
+
+diff --git a/src/vm/arm/stubs.cpp b/src/vm/arm/stubs.cpp
+index ec0a1e7..950dc7d 100644
+--- a/src/vm/arm/stubs.cpp
++++ b/src/vm/arm/stubs.cpp
+@@ -1721,6 +1721,13 @@ VOID StubLinkerCPU::EmitShuffleThunk(ShuffleEntry *pShuffleEntryArray)
+
+ void StubLinkerCPU::ThumbEmitCallManagedMethod(MethodDesc *pMD, bool fTailcall)
+ {
++ bool isRelative = MethodTable::VTableIndir2_t::isRelative
++ && pMD->IsVtableSlot();
++
++#ifndef FEATURE_NGEN_RELOCS_OPTIMIZATIONS
++ _ASSERTE(!isRelative);
++#endif
++
+ // Use direct call if possible.
+ if (pMD->HasStableEntryPoint())
+ {
+@@ -1732,18 +1739,16 @@ void StubLinkerCPU::ThumbEmitCallManagedMethod(MethodDesc *pMD, bool fTailcall)
+ // mov r12, #slotaddress
+ ThumbEmitMovConstant(ThumbReg(12), (TADDR)pMD->GetAddrOfSlot());
+
+- bool isRelative = MethodTable::VTableIndir2_t::isRelative
+- && pMD->IsVtableSlot();
+ if (isRelative)
+ {
+-#if defined(FEATURE_NGEN_RELOCS_OPTIMIZATIONS)
+- // push r11
+- ThumbEmitPush(ThumbReg(11).Mask());
+- // mov r11, r12
+- ThumbEmitMovRegReg(ThumbReg(11), ThumbReg(12));
+-#else
+- _ASSERTE(false);
+-#endif
++ if (!fTailcall)
++ {
++ // str r4, [sp, 0]
++ ThumbEmitStoreRegIndirect(ThumbReg(4), thumbRegSp, 0);
++ }
++
++ // mov r4, r12
++ ThumbEmitMovRegReg(ThumbReg(4), ThumbReg(12));
+ }
+
+ // ldr r12, [r12]
+@@ -1751,21 +1756,30 @@ void StubLinkerCPU::ThumbEmitCallManagedMethod(MethodDesc *pMD, bool fTailcall)
+
+ if (isRelative)
+ {
+-#if defined(FEATURE_NGEN_RELOCS_OPTIMIZATIONS)
+- // add r12, r11
+- ThumbEmitAddReg(ThumbReg(12), ThumbReg(11));
+- // pop r11
+- ThumbEmitPop(ThumbReg(11).Mask());
+-#else
+- _ASSERTE(false);
+-#endif
++ // add r12, r4
++ ThumbEmitAddReg(ThumbReg(12), ThumbReg(4));
++
++ if (!fTailcall)
++ {
++ // ldr r4, [sp, 0]
++ ThumbEmitLoadRegIndirect(ThumbReg(4), thumbRegSp, 0);
++ }
+ }
+ }
+
+ if (fTailcall)
+ {
+- // bx r12
+- ThumbEmitJumpRegister(ThumbReg(12));
++ if (!isRelative)
++ {
++ // bx r12
++ ThumbEmitJumpRegister(ThumbReg(12));
++ }
++ else
++ {
++ // Replace LR with R12 on stack: hybrid-tail call, same as for EmitShuffleThunk
++ // str r12, [sp, 4]
++ ThumbEmitStoreRegIndirect(ThumbReg(12), thumbRegSp, 4);
++ }
+ }
+ else
+ {
+@@ -1902,6 +1916,13 @@ void StubLinkerCPU::ThumbEmitCallWithGenericInstantiationParameter(MethodDesc *p
+ }
+ }
+
++ bool isRelative = MethodTable::VTableIndir2_t::isRelative
++ && pMD->IsVtableSlot();
++
++#ifndef FEATURE_NGEN_RELOCS_OPTIMIZATIONS
++ _ASSERTE(!isRelative);
++#endif
++
+ // Update descriptor count to the actual number used.
+ cArgDescriptors = idxCurrentDesc;
+
+@@ -1994,7 +2015,17 @@ void StubLinkerCPU::ThumbEmitCallWithGenericInstantiationParameter(MethodDesc *p
+ }
+
+ // Emit a tail call to the target method.
++ if (isRelative)
++ {
++ ThumbEmitProlog(1, 0, FALSE);
++ }
++
+ ThumbEmitCallManagedMethod(pMD, true);
++
++ if (isRelative)
++ {
++ ThumbEmitEpilog();
++ }
+ }
+ else
+ {
+@@ -2003,7 +2034,9 @@ void StubLinkerCPU::ThumbEmitCallWithGenericInstantiationParameter(MethodDesc *p
+ // Calculate the size of the new stack frame:
+ //
+ // +------------+
+- // SP -> | | <-+
++ // SP -> | | <-- Space for helper arg, if isRelative is true
++ // +------------+
++ // | | <-+
+ // : : | Outgoing arguments
+ // | | <-+
+ // +------------+
+@@ -2034,6 +2067,12 @@ void StubLinkerCPU::ThumbEmitCallWithGenericInstantiationParameter(MethodDesc *p
+ DWORD cbStackArgs = (pLastArg->m_idxDst + 1) * 4;
+ DWORD cbStackFrame = cbStackArgs + sizeof(GSCookie) + sizeof(StubHelperFrame);
+ cbStackFrame = ALIGN_UP(cbStackFrame, 8);
++
++ if (isRelative)
++ {
++ cbStackFrame += 4;
++ }
++
+ DWORD cbStackFrameWithoutSavedRegs = cbStackFrame - (13 * 4); // r0-r11,lr
+
+ // Prolog:
+@@ -2242,8 +2281,25 @@ void StubLinkerCPU::EmitUnboxMethodStub(MethodDesc *pMD)
+ // add r0, #4
+ ThumbEmitIncrement(ThumbReg(0), 4);
+
++ bool isRelative = MethodTable::VTableIndir2_t::isRelative
++ && pMD->IsVtableSlot();
++
++#ifndef FEATURE_NGEN_RELOCS_OPTIMIZATIONS
++ _ASSERTE(!isRelative);
++#endif
++
++ if (isRelative)
++ {
++ ThumbEmitProlog(1, 0, FALSE);
++ }
++
+ // Tail call the real target.
+ ThumbEmitCallManagedMethod(pMD, true /* tail call */);
++
++ if (isRelative)
++ {
++ ThumbEmitEpilog();
++ }
+ }
+ }
+
+--
+2.7.4
+