diff options
Diffstat (limited to 'src/vm/arm64/stubs.cpp')
-rw-r--r-- | src/vm/arm64/stubs.cpp | 123 |
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] |