diff options
Diffstat (limited to 'src/vm/precode.cpp')
-rw-r--r-- | src/vm/precode.cpp | 126 |
1 files changed, 117 insertions, 9 deletions
diff --git a/src/vm/precode.cpp b/src/vm/precode.cpp index f0e005adb5..5ab4ca8637 100644 --- a/src/vm/precode.cpp +++ b/src/vm/precode.cpp @@ -35,6 +35,9 @@ BOOL Precode::IsValidType(PrecodeType t) #ifdef HAS_FIXUP_PRECODE case PRECODE_FIXUP: #endif // HAS_FIXUP_PRECODE +#ifdef HAS_RELATIVE_FIXUP_PRECODE + case PRECODE_RELATIVE_FIXUP: +#endif // HAS_RELATIVE_FIXUP_PRECODE #ifdef HAS_THISPTR_RETBUF_PRECODE case PRECODE_THISPTR_RETBUF: #endif // HAS_THISPTR_RETBUF_PRECODE @@ -61,6 +64,10 @@ SIZE_T Precode::SizeOf(PrecodeType t) case PRECODE_FIXUP: return sizeof(FixupPrecode); #endif // HAS_FIXUP_PRECODE +#ifdef HAS_RELATIVE_FIXUP_PRECODE + case PRECODE_RELATIVE_FIXUP: + return sizeof(RelativeFixupPrecode); +#endif // HAS_RELATIVE_FIXUP_PRECODE #ifdef HAS_THISPTR_RETBUF_PRECODE case PRECODE_THISPTR_RETBUF: return sizeof(ThisPtrRetBufPrecode); @@ -92,6 +99,11 @@ PCODE Precode::GetTarget() target = AsFixupPrecode()->GetTarget(); break; #endif // HAS_FIXUP_PRECODE +#ifdef HAS_RELATIVE_FIXUP_PRECODE + case PRECODE_RELATIVE_FIXUP: + target = AsRelativeFixupPrecode()->GetTarget(); + break; +#endif // HAS_RELATIVE_FIXUP_PRECODE #ifdef HAS_THISPTR_RETBUF_PRECODE case PRECODE_THISPTR_RETBUF: target = AsThisPtrRetBufPrecode()->GetTarget(); @@ -131,6 +143,11 @@ MethodDesc* Precode::GetMethodDesc(BOOL fSpeculative /*= FALSE*/) pMD = AsFixupPrecode()->GetMethodDesc(); break; #endif // HAS_FIXUP_PRECODE +#ifdef HAS_RELATIVE_FIXUP_PRECODE + case PRECODE_RELATIVE_FIXUP: + pMD = AsRelativeFixupPrecode()->GetMethodDesc(); + break; +#endif // HAS_RELATIVE_FIXUP_PRECODE #ifdef HAS_THISPTR_RETBUF_PRECODE case PRECODE_THISPTR_RETBUF: pMD = AsThisPtrRetBufPrecode()->GetMethodDesc(); @@ -149,6 +166,13 @@ MethodDesc* Precode::GetMethodDesc(BOOL fSpeculative /*= FALSE*/) UnexpectedPrecodeType("Precode::GetMethodDesc", precodeType); } +#ifdef HAS_RELATIVE_FIXUP_PRECODE + if (precodeType == PRECODE_RELATIVE_FIXUP) + { + _ASSERTE(dac_cast<PTR_MethodDesc>(pMD)->IsZapped()); + } +#endif // HAS_RELATIVE_FIXUP_PRECODE + // GetMethodDesc() on platform specific precode types returns TADDR. It should return // PTR_MethodDesc instead. It is a workaround to resolve cyclic dependency between headers. // Once we headers factoring of headers cleaned up, we should be able to get rid of it. @@ -179,11 +203,16 @@ BOOL Precode::IsCorrectMethodDesc(MethodDesc * pMD) { PrecodeType precodeType = GetType(); -#ifdef HAS_FIXUP_PRECODE_CHUNKS // We do not keep track of the MethodDesc in every kind of fixup precode if (precodeType == PRECODE_FIXUP) return TRUE; -#endif + +#ifdef HAS_RELATIVE_FIXUP_PRECODE + if (precodeType == PRECODE_RELATIVE_FIXUP) + { + return TRUE; + } +#endif // HAS_RELATIVE_FIXUP_PRECODE } #endif // HAS_FIXUP_PRECODE_CHUNKS @@ -208,6 +237,11 @@ BOOL Precode::IsPointingToPrestub(PCODE target) return TRUE; #endif +#ifdef HAS_RELATIVE_FIXUP_PRECODE + if (IsPointingTo(target, GetEEFuncEntryPoint(PrecodeRelativeFixupThunk))) + return TRUE; +#endif + #ifdef FEATURE_PREJIT Module *pZapModule = GetMethodDesc()->GetZapModule(); if (pZapModule != NULL) @@ -237,7 +271,11 @@ PCODE Precode::TryToSkipFixupPrecode(PCODE addr) #if defined(FEATURE_PREJIT) && defined(HAS_FIXUP_PRECODE) // Early out for common cases - if (!FixupPrecode::IsFixupPrecodeByASM(addr)) + if (!FixupPrecode::IsFixupPrecodeByASM(addr) +#ifdef HAS_RELATIVE_FIXUP_PRECODE + && !RelativeFixupPrecode::IsRelativeFixupPrecodeByASM(addr) +#endif // HAS_RELATIVE_FIXUP_PRECODE + ) return NULL; // This optimization makes sense in NGened code only. @@ -279,6 +317,11 @@ Precode* Precode::GetPrecodeForTemporaryEntryPoint(TADDR temporaryEntryPoints, i return PTR_Precode(temporaryEntryPoints + index * sizeof(FixupPrecode)); } #endif + +#ifdef HAS_RELATIVE_FIXUP_PRECODE + _ASSERTE(t != PRECODE_RELATIVE_FIXUP); +#endif + SIZE_T oneSize = SizeOfTemporaryEntryPoint(t); return PTR_Precode(temporaryEntryPoints + index * oneSize); } @@ -313,6 +356,11 @@ SIZE_T Precode::SizeOfTemporaryEntryPoints(PrecodeType t, bool preallocateJumpSt _ASSERTE(!preallocateJumpStubs); } #endif + +#ifdef HAS_RELATIVE_FIXUP_PRECODE + _ASSERTE(t != PRECODE_RELATIVE_FIXUP); +#endif + SIZE_T oneSize = SizeOfTemporaryEntryPoint(t); return count * oneSize; } @@ -349,6 +397,10 @@ Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, SIZE_T size; +#ifdef HAS_RELATIVE_FIXUP_PRECODE + _ASSERTE(t != PRECODE_RELATIVE_FIXUP); +#endif + #ifdef HAS_FIXUP_PRECODE_CHUNKS if (t == PRECODE_FIXUP) { @@ -388,6 +440,11 @@ void Precode::Init(PrecodeType t, MethodDesc* pMD, LoaderAllocator *pLoaderAlloc ((FixupPrecode*)this)->Init(pMD, pLoaderAllocator); break; #endif // HAS_FIXUP_PRECODE +#ifdef HAS_RELATIVE_FIXUP_PRECODE + case PRECODE_RELATIVE_FIXUP: + ((RelativeFixupPrecode*)this)->Init(pMD, pLoaderAllocator); + break; +#endif // HAS_RELATIVE_FIXUP_PRECODE #ifdef HAS_THISPTR_RETBUF_PRECODE case PRECODE_THISPTR_RETBUF: ((ThisPtrRetBufPrecode*)this)->Init(pMD, pLoaderAllocator); @@ -418,6 +475,12 @@ void Precode::ResetTargetInterlocked() break; #endif // HAS_FIXUP_PRECODE +#ifdef HAS_RELATIVE_FIXUP_PRECODE + case PRECODE_RELATIVE_FIXUP: + AsRelativeFixupPrecode()->ResetTargetInterlocked(); + break; +#endif // HAS_RELATIVE_FIXUP_PRECODE + default: UnexpectedPrecodeType("Precode::ResetTargetInterlocked", precodeType); break; @@ -453,6 +516,12 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) break; #endif // HAS_FIXUP_PRECODE +#ifdef HAS_RELATIVE_FIXUP_PRECODE + case PRECODE_RELATIVE_FIXUP: + ret = AsRelativeFixupPrecode()->SetTargetInterlocked(target, expected); + break; +#endif // HAS_RELATIVE_FIXUP_PRECODE + #ifdef HAS_THISPTR_RETBUF_PRECODE case PRECODE_THISPTR_RETBUF: ret = AsThisPtrRetBufPrecode()->SetTargetInterlocked(target, expected); @@ -672,6 +741,10 @@ void Precode::Save(DataImage *image) _ASSERTE(GetType() != PRECODE_FIXUP); #endif +#ifdef HAS_RELATIVE_FIXUP_PRECODE + _ASSERTE(GetType() != PRECODE_RELATIVE_FIXUP); +#endif // HAS_RELATIVE_FIXUP_PRECODE + #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) // StubPrecode may have straddlers (relocations crossing pages) on x86 and x64. We need // to insert padding to eliminate it. To do that, we need to save these using custom ZapNode that can only @@ -722,9 +795,15 @@ void Precode::Fixup(DataImage *image, MethodDesc * pMD) break; #endif // HAS_NDIRECT_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE +#ifdef HAS_RELATIVE_FIXUP_PRECODE + case PRECODE_RELATIVE_FIXUP: + AsRelativeFixupPrecode()->Fixup(image, pMD); + break; +#else // HAS_RELATIVE_FIXUP_PRECODE case PRECODE_FIXUP: AsFixupPrecode()->Fixup(image, pMD); break; +#endif // HAS_RELATIVE_FIXUP_PRECODE #endif // HAS_FIXUP_PRECODE default: UnexpectedPrecodeType("Precode::Save", precodeType); @@ -754,6 +833,10 @@ void Precode::SaveChunk::Save(DataImage* image, MethodDesc * pMD) } #endif // HAS_FIXUP_PRECODE_CHUNKS +#ifdef HAS_RELATIVE_FIXUP_PRECODE + _ASSERTE(precodeType != PRECODE_RELATIVE_FIXUP); +#endif // HAS_RELATIVE_FIXUP_PRECODE + SIZE_T size = Precode::SizeOf(precodeType); Precode* pPrecode = (Precode *)new (image->GetHeap()) BYTE[size]; pPrecode->Init(precodeType, pMD, NULL); @@ -768,20 +851,38 @@ static void SaveFixupPrecodeChunk(DataImage * image, MethodDesc ** rgMD, COUNT_T { STANDARD_VM_CONTRACT; - ULONG size = sizeof(FixupPrecode) * count + sizeof(PTR_MethodDesc); - FixupPrecode * pBase = (FixupPrecode *)new (image->GetHeap()) BYTE[size]; + ULONG sizeSinglePrecode; + PrecodeType type; + +#ifdef HAS_RELATIVE_FIXUP_PRECODE + sizeSinglePrecode = sizeof(RelativeFixupPrecode); + type = PRECODE_RELATIVE_FIXUP; +#else // HAS_RELATIVE_FIXUP_PRECODE + sizeSinglePrecode = sizeof(FixupPrecode); + type = PRECODE_FIXUP; +#endif // HAS_RELATIVE_FIXUP_PRECODE - ZapStoredStructure * pNode = image->StoreStructure(NULL, size, kind, - Precode::AlignOf(PRECODE_FIXUP)); + ULONG size = sizeSinglePrecode * count + sizeof(PTR_MethodDesc); + ZapStoredStructure * pNode = image->StoreStructure(NULL, size, kind, Precode::AlignOf(type)); + +#ifdef HAS_RELATIVE_FIXUP_PRECODE + RelativeFixupPrecode * pBase = (RelativeFixupPrecode *)new (image->GetHeap()) BYTE[size]; +#else // HAS_RELATIVE_FIXUP_PRECODE + FixupPrecode * pBase = (FixupPrecode *)new (image->GetHeap()) BYTE[size]; +#endif // HAS_RELATIVE_FIXUP_PRECODE for (COUNT_T i = 0; i < count; i++) { MethodDesc * pMD = rgMD[i]; +#ifdef HAS_RELATIVE_FIXUP_PRECODE + RelativeFixupPrecode * pPrecode = pBase + i; +#else // HAS_RELATIVE_FIXUP_PRECODE FixupPrecode * pPrecode = pBase + i; +#endif // HAS_RELATIVE_FIXUP_PRECODE pPrecode->InitForSave((count - 1) - i); - image->BindPointer(pPrecode, pNode, i * sizeof(FixupPrecode)); + image->BindPointer(pPrecode, pNode, i * sizeSinglePrecode); // Alias the temporary entrypoint image->RegisterSurrogate(pMD, pPrecode); @@ -871,7 +972,14 @@ void Precode::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) } #endif +#ifdef HAS_RELATIVE_FIXUP_PRECODE + if (t == PRECODE_RELATIVE_FIXUP) + { + AsRelativeFixupPrecode()->EnumMemoryRegions(flags); + return; + } +#endif // HAS_RELATIVE_FIXUP_PRECODE + DacEnumMemoryRegion(GetStart(), SizeOf(t)); } #endif - |