summaryrefslogtreecommitdiff
path: root/src/vm/precode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/precode.cpp')
-rw-r--r--src/vm/precode.cpp126
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
-