summaryrefslogtreecommitdiff
path: root/src/vm/method.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/vm/method.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/vm/method.cpp')
-rw-r--r--src/vm/method.cpp86
1 files changed, 74 insertions, 12 deletions
diff --git a/src/vm/method.cpp b/src/vm/method.cpp
index 815f9d217a..68f54233ed 100644
--- a/src/vm/method.cpp
+++ b/src/vm/method.cpp
@@ -563,7 +563,7 @@ PCODE MethodDesc::GetMethodEntryPoint()
return GetMethodTable_NoLogging()->GetSlot(GetSlot());
}
-PTR_PCODE MethodDesc::GetAddrOfSlot()
+TADDR MethodDesc::GetAddrOfSlot()
{
CONTRACTL
{
@@ -584,7 +584,7 @@ PTR_PCODE MethodDesc::GetAddrOfSlot()
SIZE_T size = GetBaseSize();
- return PTR_PCODE(dac_cast<TADDR>(this) + size);
+ return dac_cast<TADDR>(this) + size;
}
_ASSERTE(GetMethodTable()->IsCanonicalMethodTable());
@@ -2342,7 +2342,15 @@ void MethodDesc::Reset()
InterlockedUpdateFlags2(enum_flag2_HasStableEntryPoint | enum_flag2_HasPrecode, FALSE);
- *GetAddrOfSlot() = GetTemporaryEntryPoint();
+ TADDR slot = GetAddrOfSlot();
+ if (IsVtableSlot())
+ {
+ ((MethodTable::VTableIndir2_t *) slot)->SetValue(GetTemporaryEntryPoint());
+ }
+ else
+ {
+ *((PCODE *) slot) = GetTemporaryEntryPoint();
+ }
}
if (HasNativeCodeSlot())
@@ -4711,9 +4719,19 @@ void MethodDesc::SetTemporaryEntryPoint(LoaderAllocator *pLoaderAllocator, Alloc
GetMethodDescChunk()->EnsureTemporaryEntryPointsCreated(pLoaderAllocator, pamTracker);
- PTR_PCODE pSlot = GetAddrOfSlot();
- _ASSERTE(*pSlot == NULL);
- *pSlot = GetTemporaryEntryPoint();
+ TADDR slot = GetAddrOfSlot();
+ if (IsVtableSlot())
+ {
+ MethodTable::VTableIndir2_t *slotPtr = ((MethodTable::VTableIndir2_t *) slot);
+ _ASSERTE(slotPtr->IsNull());
+ slotPtr->SetValue(GetTemporaryEntryPoint());
+ }
+ else
+ {
+ PCODE *slotPtr = (PCODE *) slot;
+ _ASSERTE(*slotPtr == NULL);
+ *slotPtr = GetTemporaryEntryPoint();
+ }
if (RequiresStableEntryPoint())
{
@@ -4776,7 +4794,7 @@ Precode* MethodDesc::GetOrCreatePrecode()
return GetPrecode();
}
- PTR_PCODE pSlot = GetAddrOfSlot();
+ TADDR pSlot = GetAddrOfSlot();
PCODE tempEntry = GetTemporaryEntryPoint();
PrecodeType requiredType = GetPrecodeType();
@@ -4796,14 +4814,40 @@ Precode* MethodDesc::GetOrCreatePrecode()
AllocMemTracker amt;
Precode* pPrecode = Precode::Allocate(requiredType, this, GetLoaderAllocator(), &amt);
- if (FastInterlockCompareExchangePointer(EnsureWritablePages(pSlot), pPrecode->GetEntryPoint(), tempEntry) == tempEntry)
+ PCODE newVal;
+ PCODE oldVal;
+ TADDR *slotAddr;
+
+ if (IsVtableSlot())
+ {
+ newVal = MethodTable::VTableIndir2_t::GetRelative(pSlot, pPrecode->GetEntryPoint());
+ oldVal = MethodTable::VTableIndir2_t::GetRelative(pSlot, tempEntry);
+ slotAddr = (TADDR *) EnsureWritablePages((MethodTable::VTableIndir2_t *) pSlot);
+ }
+ else
+ {
+ newVal = pPrecode->GetEntryPoint();
+ oldVal = tempEntry;
+ slotAddr = (TADDR *) EnsureWritablePages((PCODE *) pSlot);
+ }
+
+ if (FastInterlockCompareExchangePointer(slotAddr, (TADDR) newVal, (TADDR) oldVal) == oldVal)
amt.SuppressRelease();
}
// Set the flags atomically
InterlockedUpdateFlags2(enum_flag2_HasStableEntryPoint | enum_flag2_HasPrecode, TRUE);
- return Precode::GetPrecodeFromEntryPoint(*pSlot);
+ PCODE addr;
+ if (IsVtableSlot())
+ {
+ addr = ((MethodTable::VTableIndir2_t *)pSlot)->GetValue();
+ }
+ else
+ {
+ addr = *((PCODE *)pSlot);
+ }
+ return Precode::GetPrecodeFromEntryPoint(addr);
}
//*******************************************************************************
@@ -4857,10 +4901,28 @@ BOOL MethodDesc::SetStableEntryPointInterlocked(PCODE addr)
_ASSERTE(!HasPrecode());
PCODE pExpected = GetTemporaryEntryPoint();
- PTR_PCODE pSlot = GetAddrOfSlot();
- EnsureWritablePages(pSlot);
+ TADDR pSlot = GetAddrOfSlot();
+
+ BOOL fResult;
+
+ TADDR *slotAddr;
+ PCODE newVal;
+ PCODE oldVal;
+
+ if (IsVtableSlot())
+ {
+ newVal = MethodTable::VTableIndir2_t::GetRelative(pSlot, addr);
+ oldVal = MethodTable::VTableIndir2_t::GetRelative(pSlot, pExpected);
+ slotAddr = (TADDR *) EnsureWritablePages((MethodTable::VTableIndir2_t *) pSlot);
+ }
+ else
+ {
+ newVal = addr;
+ oldVal = pExpected;
+ slotAddr = (TADDR *) EnsureWritablePages((PCODE *) pSlot);
+ }
- BOOL fResult = FastInterlockCompareExchangePointer(pSlot, addr, pExpected) == pExpected;
+ fResult = FastInterlockCompareExchangePointer(slotAddr, (TADDR) newVal, (TADDR) oldVal) == oldVal;
InterlockedUpdateFlags2(enum_flag2_HasStableEntryPoint, TRUE);