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)
{
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
}
}
+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)
// 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
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
}
#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]