summaryrefslogtreecommitdiff
path: root/src/vm/arm64/stubs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/arm64/stubs.cpp')
-rw-r--r--src/vm/arm64/stubs.cpp123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/vm/arm64/stubs.cpp b/src/vm/arm64/stubs.cpp
index 680557984a..b25dc4d531 100644
--- a/src/vm/arm64/stubs.cpp
+++ b/src/vm/arm64/stubs.cpp
@@ -565,6 +565,18 @@ TADDR FixupPrecode::GetMethodDesc()
return base + (m_MethodDescChunkIndex * MethodDesc::ALIGNMENT);
}
+TADDR RelativeFixupPrecode::GetMethodDesc()
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ // This lookup is also manually inlined in PrecodeFixupThunk assembly code
+ TADDR baseAddr = GetBase();
+ TADDR base = *PTR_TADDR(baseAddr);
+ if (base == NULL)
+ return NULL;
+ return baseAddr + base + (m_MethodDescChunkIndex * MethodDesc::ALIGNMENT);
+}
+
#ifdef DACCESS_COMPILE
void FixupPrecode::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
{
@@ -573,6 +585,14 @@ void FixupPrecode::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
DacEnumMemoryRegion(GetBase(), sizeof(TADDR));
}
+
+void RelativeFixupPrecode::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
+{
+ SUPPORTS_DAC;
+ DacEnumMemoryRegion(dac_cast<TADDR>(this), sizeof(RelativeFixupPrecode));
+
+ DacEnumMemoryRegion(GetBase(), sizeof(TADDR));
+}
#endif // DACCESS_COMPILE
#ifndef DACCESS_COMPILE
@@ -675,6 +695,39 @@ void FixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int
}
}
+void RelativeFixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int iMethodDescChunkIndex /*=0*/, int iPrecodeChunkIndex /*=0*/)
+{
+ WRAPPER_NO_CONTRACT;
+
+ InitCommon();
+
+ // Initialize chunk indices only if they are not initialized yet. This is necessary to make MethodDesc::Reset work.
+ if (m_PrecodeChunkIndex == 0)
+ {
+ _ASSERTE(FitsInU1(iPrecodeChunkIndex));
+ m_PrecodeChunkIndex = static_cast<BYTE>(iPrecodeChunkIndex);
+ }
+
+ if (iMethodDescChunkIndex != -1)
+ {
+ if (m_MethodDescChunkIndex == 0)
+ {
+ _ASSERTE(FitsInU1(iMethodDescChunkIndex));
+ m_MethodDescChunkIndex = static_cast<BYTE>(iMethodDescChunkIndex);
+ }
+
+ if (*(void**)GetBase() == NULL)
+ *(void**)GetBase() = (BYTE*)pMD - (iMethodDescChunkIndex * MethodDesc::ALIGNMENT) - GetBase();
+ }
+
+ _ASSERTE(GetMethodDesc() == (TADDR)pMD);
+
+ if (pLoaderAllocator != NULL)
+ {
+ m_pTargetOffset = GetEEFuncEntryPoint(PrecodeRelativeFixupThunk) - (TADDR)this - RelativeFixupPrecode::GetTargetOffset();
+ }
+}
+
#ifdef FEATURE_NATIVE_IMAGE_GENERATION
// Partial initialization. Used to save regrouped chunks.
void FixupPrecode::InitForSave(int iPrecodeChunkIndex)
@@ -688,10 +741,27 @@ void FixupPrecode::InitForSave(int iPrecodeChunkIndex)
// The rest is initialized in code:FixupPrecode::Fixup
}
+// Partial initialization. Used to save regrouped chunks.
+void RelativeFixupPrecode::InitForSave(int iPrecodeChunkIndex)
+{
+ STANDARD_VM_CONTRACT;
+
+ InitCommon();
+
+ _ASSERTE(FitsInU1(iPrecodeChunkIndex));
+ m_PrecodeChunkIndex = static_cast<BYTE>(iPrecodeChunkIndex);
+ // The rest is initialized in code:RelativeFixupPrecode::Fixup
+}
+
void FixupPrecode::Fixup(DataImage *image, MethodDesc * pMD)
{
STANDARD_VM_CONTRACT;
+#ifdef HAS_RELATIVE_FIXUP_PRECODE
+ // FixupPrecode is not saved to image in this case
+ _ASSERTE(!"FixupPrecode is not saved to NGENed image, RelativeFixupPrecode is instead");
+#else // HAS_RELATIVE_FIXUP_PRECODE
+
// Note that GetMethodDesc() does not return the correct value because of
// regrouping of MethodDescs into hot and cold blocks. That's why the caller
// has to supply the actual MethodDesc
@@ -716,6 +786,44 @@ void FixupPrecode::Fixup(DataImage *image, MethodDesc * pMD)
image->FixupFieldToNode(this, (BYTE *)GetBase() - (BYTE *)this,
pMDChunkNode, sizeof(MethodDescChunk));
}
+#endif // HAS_RELATIVE_FIXUP_PRECODE
+}
+
+void RelativeFixupPrecode::Fixup(DataImage *image, MethodDesc * pMD)
+{
+ STANDARD_VM_CONTRACT;
+
+ // Note that GetMethodDesc() does not return the correct value because of
+ // regrouping of MethodDescs into hot and cold blocks. That's why the caller
+ // has to supply the actual MethodDesc
+
+ SSIZE_T mdChunkOffset;
+ ZapNode * pMDChunkNode = image->GetNodeForStructure(pMD, &mdChunkOffset);
+ ZapNode * pHelperThunk = image->GetHelperThunk(CORINFO_HELP_EE_PRECODE_FIXUP);
+
+ image->FixupFieldToNode(this,
+ offsetof(RelativeFixupPrecode, m_pTargetOffset),
+ pHelperThunk,
+ offsetof(RelativeFixupPrecode, m_pTargetOffset) - RelativeFixupPrecode::GetTargetOffset(),
+ IMAGE_REL_BASED_RELPTR);
+
+ // Set the actual chunk index
+ RelativeFixupPrecode * pNewPrecode = (RelativeFixupPrecode *)image->GetImagePointer(this);
+
+ size_t mdOffset = mdChunkOffset - sizeof(MethodDescChunk);
+ size_t chunkIndex = mdOffset / MethodDesc::ALIGNMENT;
+ _ASSERTE(FitsInU1(chunkIndex));
+ pNewPrecode->m_MethodDescChunkIndex = (BYTE)chunkIndex;
+
+ // Fixup the base of MethodDescChunk
+ if (m_PrecodeChunkIndex == 0)
+ {
+ image->FixupFieldToNode(this,
+ (BYTE *)GetBase() - (BYTE *)this,
+ pMDChunkNode,
+ sizeof(MethodDescChunk),
+ IMAGE_REL_BASED_RELPTR);
+ }
}
#endif // FEATURE_NATIVE_IMAGE_GENERATION
@@ -762,6 +870,21 @@ BOOL DoesSlotCallPrestub(PCODE pCode)
}
#endif
+ //RelativeFixupPrecode
+#if defined(HAS_RELATIVE_FIXUP_PRECODE)
+ if (RelativeFixupPrecode::IsRelativeFixupPrecodeByASM(pCode))
+ {
+ PCODE pTarget = dac_cast<PTR_RelativeFixupPrecode>(pInstr)->GetTarget();
+
+ if (isJump(pTarget))
+ {
+ pTarget = decodeJump(pTarget);
+ }
+
+ return pTarget == (TADDR)PrecodeRelativeFixupThunk;
+ }
+#endif // HAS_RELATIVE_FIXUP_PRECODE
+
// StubPrecode
if (pInstr[0] == 0x10000089 && // adr x9, #16
pInstr[1] == 0xA940312A && // ldp x10,x12,[x9]