summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgbalykov <g.balykov@samsung.com>2017-06-03 06:31:28 +0300
committerJan Kotas <jkotas@microsoft.com>2017-06-02 20:31:28 -0700
commitfd3668c7c9b9f5d64b5e6d1edf8c55a307cd3c2d (patch)
tree4dfd969b9979a2e4794e0cff4c46a378343b993e
parentb47b138d595267315008885e6ac7e2f4322cc5a9 (diff)
downloadcoreclr-fd3668c7c9b9f5d64b5e6d1edf8c55a307cd3c2d.tar.gz
coreclr-fd3668c7c9b9f5d64b5e6d1edf8c55a307cd3c2d.tar.bz2
coreclr-fd3668c7c9b9f5d64b5e6d1edf8c55a307cd3c2d.zip
Remove relocations from SECTION_MethodDesc for ngened images for fields accessed from jit code for Linux ARM (#11963)
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp6
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.h1
-rw-r--r--src/debug/daccess/nidump.cpp4
-rw-r--r--src/inc/corinfo.h7
-rw-r--r--src/inc/fixuppointer.h99
-rw-r--r--src/jit/importer.cpp14
-rw-r--r--src/vm/dllimport.cpp12
-rw-r--r--src/vm/genmeth.cpp10
-rw-r--r--src/vm/jitinterface.cpp12
-rw-r--r--src/vm/method.cpp18
-rw-r--r--src/vm/method.hpp32
-rw-r--r--src/vm/methodtablebuilder.cpp4
-rw-r--r--src/vm/prestub.cpp13
13 files changed, 211 insertions, 21 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
index e60ef83fc9..4c5fb61595 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
@@ -1573,6 +1573,7 @@ void MethodContext::recGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
value.stubLookup.runtimeLookup.indirections = (DWORD)pResult->stubLookup.runtimeLookup.indirections;
value.stubLookup.runtimeLookup.testForNull = (DWORD)pResult->stubLookup.runtimeLookup.testForNull;
value.stubLookup.runtimeLookup.testForFixup = (DWORD)pResult->stubLookup.runtimeLookup.testForFixup;
+ value.stubLookup.runtimeLookup.indirectFirstOffset = (DWORD)pResult->stubLookup.runtimeLookup.indirectFirstOffset;
for (int i = 0; i < CORINFO_MAXINDIRECTIONS; i++)
value.stubLookup.runtimeLookup.offsets[i] = (DWORDLONG)pResult->stubLookup.runtimeLookup.offsets[i];
}
@@ -1583,6 +1584,7 @@ void MethodContext::recGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
value.stubLookup.runtimeLookup.indirections = (DWORD)0;
value.stubLookup.runtimeLookup.testForNull = (DWORD)0;
value.stubLookup.runtimeLookup.testForFixup = (DWORD)0;
+ value.stubLookup.runtimeLookup.indirectFirstOffset = (DWORD)0;
for (int i = 0; i < CORINFO_MAXINDIRECTIONS; i++)
value.stubLookup.runtimeLookup.offsets[i] = (DWORDLONG)0;
@@ -1761,6 +1763,7 @@ void MethodContext::repGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
pResult->stubLookup.runtimeLookup.indirections = (WORD)value.stubLookup.runtimeLookup.indirections;
pResult->stubLookup.runtimeLookup.testForNull = value.stubLookup.runtimeLookup.testForNull != 0;
pResult->stubLookup.runtimeLookup.testForFixup = value.stubLookup.runtimeLookup.testForFixup != 0;
+ pResult->stubLookup.runtimeLookup.indirectFirstOffset = value.stubLookup.runtimeLookup.indirectFirstOffset != 0;
for (int i = 0; i < CORINFO_MAXINDIRECTIONS; i++)
pResult->stubLookup.runtimeLookup.offsets[i] = (SIZE_T)value.stubLookup.runtimeLookup.offsets[i];
}
@@ -3218,6 +3221,7 @@ void MethodContext::recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolve
value.lookup.runtimeLookup.indirections = (DWORD)pResult->lookup.runtimeLookup.indirections;
value.lookup.runtimeLookup.testForNull = (DWORD)pResult->lookup.runtimeLookup.testForNull;
value.lookup.runtimeLookup.testForFixup = (DWORD)pResult->lookup.runtimeLookup.testForFixup;
+ value.lookup.runtimeLookup.indirectFirstOffset = (DWORD)pResult->lookup.runtimeLookup.indirectFirstOffset;
for (int i = 0; i < CORINFO_MAXINDIRECTIONS; i++)
value.lookup.runtimeLookup.offsets[i] = (DWORDLONG)pResult->lookup.runtimeLookup.offsets[i];
}
@@ -3228,6 +3232,7 @@ void MethodContext::recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolve
value.lookup.runtimeLookup.indirections = (DWORD)0;
value.lookup.runtimeLookup.testForNull = (DWORD)0;
value.lookup.runtimeLookup.testForFixup = (DWORD)0;
+ value.lookup.runtimeLookup.indirectFirstOffset = (DWORD)0;
for (int i = 0; i < CORINFO_MAXINDIRECTIONS; i++)
value.lookup.runtimeLookup.offsets[i] = (DWORDLONG)0;
// copy the constLookup view of the union
@@ -3305,6 +3310,7 @@ void MethodContext::repEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolve
pResult->lookup.runtimeLookup.indirections = (WORD)value.lookup.runtimeLookup.indirections;
pResult->lookup.runtimeLookup.testForNull = value.lookup.runtimeLookup.testForNull != 0;
pResult->lookup.runtimeLookup.testForFixup = value.lookup.runtimeLookup.testForFixup != 0;
+ pResult->lookup.runtimeLookup.indirectFirstOffset = value.lookup.runtimeLookup.indirectFirstOffset != 0;
for (int i = 0; i < CORINFO_MAXINDIRECTIONS; i++)
pResult->lookup.runtimeLookup.offsets[i] = (size_t)value.lookup.runtimeLookup.offsets[i];
}
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
index f7c0e164ca..4887522da3 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
@@ -240,6 +240,7 @@ public:
DWORD testForNull;
DWORD testForFixup;
DWORDLONG offsets[CORINFO_MAXINDIRECTIONS];
+ DWORD indirectFirstOffset;
};
struct Agnostic_CORINFO_CONST_LOOKUP
{
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index 6e7370834b..62b68ef89d 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -7905,7 +7905,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
if( !CHECK_OPT(METHODDESCS) )
CoverageReadString( dac_cast<TADDR>(ndmd->GetLibNameRaw()) );
- PTR_NDirectWriteableData wnd( nd->m_pWriteableData );
+ PTR_NDirectWriteableData wnd( ndmd->GetWriteableData() );
DisplayStartStructureWithOffset( m_pWriteableData,
DPtrToPreferredAddr(wnd),
sizeof(*wnd),
@@ -8061,7 +8061,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
}
//now handle the contents of the m_pMethInst/m_pPerInstInfo union.
unsigned numSlots = imd->m_wNumGenericArgs;
- PTR_Dictionary inst(imd->m_pPerInstInfo);
+ PTR_Dictionary inst(imd->IMD_GetMethodDictionary());
unsigned dictSize;
if( kind == InstantiatedMethodDesc::SharedMethodInstantiation )
{
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index 2117d4e18f..0620994f65 100644
--- a/src/inc/corinfo.h
+++ b/src/inc/corinfo.h
@@ -1323,6 +1323,13 @@ struct CORINFO_RUNTIME_LOOKUP
bool testForFixup;
SIZE_T offsets[CORINFO_MAXINDIRECTIONS];
+
+ // If set, first offset is indirect.
+ // 0 means that value stored at first offset (offsets[0]) from pointer is next pointer, to which the next offset
+ // (offsets[1]) is added and so on.
+ // 1 means that value stored at first offset (offsets[0]) from pointer is offset1, and the next pointer is
+ // stored at pointer+offsets[0]+offset1.
+ bool indirectFirstOffset;
} ;
// Result of calling embedGenericHandle
diff --git a/src/inc/fixuppointer.h b/src/inc/fixuppointer.h
index 549023ad6e..38ae348e1e 100644
--- a/src/inc/fixuppointer.h
+++ b/src/inc/fixuppointer.h
@@ -30,6 +30,10 @@ template<typename PTR_TYPE>
class RelativePointer
{
public:
+
+ static constexpr bool isRelative = true;
+ typedef PTR_TYPE type;
+
#ifndef DACCESS_COMPILE
RelativePointer()
{
@@ -173,6 +177,10 @@ template<typename PTR_TYPE>
class FixupPointer
{
public:
+
+ static constexpr bool isRelative = false;
+ typedef PTR_TYPE type;
+
// Returns whether the encoded pointer is NULL.
BOOL IsNull() const
{
@@ -237,6 +245,10 @@ template<typename PTR_TYPE>
class RelativeFixupPointer
{
public:
+
+ static constexpr bool isRelative = true;
+ typedef PTR_TYPE type;
+
// Implicit copy/move is not allowed
RelativeFixupPointer<PTR_TYPE>(const RelativeFixupPointer<PTR_TYPE> &) =delete;
RelativeFixupPointer<PTR_TYPE>(RelativeFixupPointer<PTR_TYPE> &&) =delete;
@@ -384,7 +396,7 @@ private:
// Fixup used for RelativePointer
#define IMAGE_REL_BASED_RelativePointer IMAGE_REL_BASED_RELPTR
-#else // FEATURE_PREJIT
+#endif // FEATURE_PREJIT
//----------------------------------------------------------------------------
// PlainPointer is simple pointer wrapper to support compilation without indirections
@@ -393,6 +405,10 @@ template<typename PTR_TYPE>
class PlainPointer
{
public:
+
+ static constexpr bool isRelative = false;
+ typedef PTR_TYPE type;
+
// Returns whether the encoded pointer is NULL.
BOOL IsNull() const
{
@@ -499,11 +515,13 @@ private:
TADDR m_ptr;
};
+#ifndef FEATURE_PREJIT
+
#define FixupPointer PlainPointer
#define RelativePointer PlainPointer
#define RelativeFixupPointer PlainPointer
-#endif // FEATURE_PREJIT
+#endif // !FEATURE_PREJIT
//----------------------------------------------------------------------------
// RelativePointer32 is pointer encoded as relative 32-bit offset. It is used
@@ -513,6 +531,10 @@ template<typename PTR_TYPE>
class RelativePointer32
{
public:
+
+ static constexpr bool isRelative = true;
+ typedef PTR_TYPE type;
+
// Returns whether the encoded pointer is NULL.
BOOL IsNull() const
{
@@ -581,4 +603,77 @@ private:
INT32 m_delta;
};
+template<bool isMaybeNull, typename T, typename PT>
+typename PT::type
+ReadPointer(const T *base, const PT T::* pPointerFieldMember)
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ uintptr_t offset = (uintptr_t) &(base->*pPointerFieldMember) - (uintptr_t) base;
+
+ if (isMaybeNull)
+ {
+ return PT::GetValueMaybeNullAtPtr(dac_cast<TADDR>(base) + offset);
+ }
+ else
+ {
+ return PT::GetValueAtPtr(dac_cast<TADDR>(base) + offset);
+ }
+}
+
+template<typename T, typename PT>
+typename PT::type
+ReadPointerMaybeNull(const T *base, const PT T::* pPointerFieldMember)
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ return ReadPointer<true>(base, pPointerFieldMember);
+}
+
+template<typename T, typename PT>
+typename PT::type
+ReadPointer(const T *base, const PT T::* pPointerFieldMember)
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ return ReadPointer<false>(base, pPointerFieldMember);
+}
+
+template<bool isMaybeNull, typename T, typename C, typename PT>
+typename PT::type
+ReadPointer(const T *base, const C T::* pFirstPointerFieldMember, const PT C::* pSecondPointerFieldMember)
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ const PT *ptr = &(base->*pFirstPointerFieldMember.*pSecondPointerFieldMember);
+ uintptr_t offset = (uintptr_t) ptr - (uintptr_t) base;
+
+ if (isMaybeNull)
+ {
+ return PT::GetValueMaybeNullAtPtr(dac_cast<TADDR>(base) + offset);
+ }
+ else
+ {
+ return PT::GetValueAtPtr(dac_cast<TADDR>(base) + offset);
+ }
+}
+
+template<typename T, typename C, typename PT>
+typename PT::type
+ReadPointerMaybeNull(const T *base, const C T::* pFirstPointerFieldMember, const PT C::* pSecondPointerFieldMember)
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ return ReadPointer<true>(base, pFirstPointerFieldMember, pSecondPointerFieldMember);
+}
+
+template<typename T, typename C, typename PT>
+typename PT::type
+ReadPointer(const T *base, const C T::* pFirstPointerFieldMember, const PT C::* pSecondPointerFieldMember)
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ return ReadPointer<false>(base, pFirstPointerFieldMember, pSecondPointerFieldMember);
+}
+
#endif //_FIXUPPOINTER_H
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index 361d102fed..5cc5e4efb9 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -1975,15 +1975,29 @@ GenTreePtr Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedTok
nullptr DEBUGARG("impRuntimeLookup slot"));
}
+ GenTreePtr indOffTree = nullptr;
+
// Applied repeated indirections
for (WORD i = 0; i < pRuntimeLookup->indirections; i++)
{
+ if (i == 1 && pRuntimeLookup->indirectFirstOffset)
+ {
+ indOffTree = impCloneExpr(slotPtrTree, &slotPtrTree, NO_CLASS_HANDLE, (unsigned)CHECK_SPILL_ALL,
+ nullptr DEBUGARG("impRuntimeLookup indirectFirstOffset"));
+ }
+
if (i != 0)
{
slotPtrTree = gtNewOperNode(GT_IND, TYP_I_IMPL, slotPtrTree);
slotPtrTree->gtFlags |= GTF_IND_NONFAULTING;
slotPtrTree->gtFlags |= GTF_IND_INVARIANT;
}
+
+ if (i == 1 && pRuntimeLookup->indirectFirstOffset)
+ {
+ slotPtrTree = gtNewOperNode(GT_ADD, TYP_I_IMPL, indOffTree, slotPtrTree);
+ }
+
if (pRuntimeLookup->offsets[i] != 0)
{
slotPtrTree =
diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp
index b7807119c0..49c7d7a8b8 100644
--- a/src/vm/dllimport.cpp
+++ b/src/vm/dllimport.cpp
@@ -2294,7 +2294,19 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth
//pcsEmit->EmitCALL(METHOD__STUBHELPERS__GET_NDIRECT_TARGET, 1, 1);
pcsEmit->EmitLDC(offsetof(NDirectMethodDesc, ndirect.m_pWriteableData));
pcsEmit->EmitADD();
+
+ if (decltype(NDirectMethodDesc::ndirect.m_pWriteableData)::isRelative)
+ {
+ pcsEmit->EmitDUP();
+ }
+
pcsEmit->EmitLDIND_I();
+
+ if (decltype(NDirectMethodDesc::ndirect.m_pWriteableData)::isRelative)
+ {
+ pcsEmit->EmitADD();
+ }
+
pcsEmit->EmitLDIND_I();
}
}
diff --git a/src/vm/genmeth.cpp b/src/vm/genmeth.cpp
index d5b435bb42..dc55221308 100644
--- a/src/vm/genmeth.cpp
+++ b/src/vm/genmeth.cpp
@@ -1518,9 +1518,9 @@ void InstantiatedMethodDesc::SetupGenericMethodDefinition(IMDInternalImport *pIM
S_SIZE_T dwAllocSize = S_SIZE_T(numTyPars) * S_SIZE_T(sizeof(TypeHandle));
// the memory allocated for m_pMethInst will be freed if the declaring type fails to load
- m_pPerInstInfo = (Dictionary *) pamTracker->Track(pAllocator->GetLowFrequencyHeap()->AllocMem(dwAllocSize));
+ m_pPerInstInfo.SetValue((Dictionary *) pamTracker->Track(pAllocator->GetLowFrequencyHeap()->AllocMem(dwAllocSize)));
- TypeHandle * pInstDest = (TypeHandle *)m_pPerInstInfo;
+ TypeHandle * pInstDest = (TypeHandle *) IMD_GetMethodDictionaryNonNull();
for(unsigned int i = 0; i < numTyPars; i++)
{
hEnumTyPars.EnumNext(&tkTyPar);
@@ -1553,7 +1553,7 @@ void InstantiatedMethodDesc::SetupWrapperStubWithInstantiations(MethodDesc* wrap
m_pWrappedMethodDesc.SetValue(wrappedMD);
m_wFlags2 = WrapperStubWithInstantiations | (m_wFlags2 & ~KindMask);
- m_pPerInstInfo = (Dictionary*)pInst;
+ m_pPerInstInfo.SetValueMaybeNull((Dictionary*)pInst);
_ASSERTE(FitsIn<WORD>(numGenericArgs));
m_wNumGenericArgs = static_cast<WORD>(numGenericArgs);
@@ -1571,7 +1571,7 @@ void InstantiatedMethodDesc::SetupSharedMethodInstantiation(DWORD numGenericArgs
_ASSERTE(numGenericArgs != 0);
// Initially the dictionary layout is empty
m_wFlags2 = SharedMethodInstantiation | (m_wFlags2 & ~KindMask);
- m_pPerInstInfo = (Dictionary *)pPerInstInfo;
+ m_pPerInstInfo.SetValueMaybeNull((Dictionary *)pPerInstInfo);
_ASSERTE(FitsIn<WORD>(numGenericArgs));
m_wNumGenericArgs = static_cast<WORD>(numGenericArgs);
@@ -1589,7 +1589,7 @@ void InstantiatedMethodDesc::SetupUnsharedMethodInstantiation(DWORD numGenericAr
// The first field is never used
m_wFlags2 = UnsharedMethodInstantiation | (m_wFlags2 & ~KindMask);
- m_pPerInstInfo = (Dictionary *)pInst;
+ m_pPerInstInfo.SetValueMaybeNull((Dictionary *)pInst);
_ASSERTE(FitsIn<WORD>(numGenericArgs));
m_wNumGenericArgs = static_cast<WORD>(numGenericArgs);
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index ef0e87fb3a..c28d6e12bd 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -3085,6 +3085,8 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr
CORINFO_RUNTIME_LOOKUP *pResult = &pResultLookup->runtimeLookup;
pResult->signature = NULL;
+ pResult->indirectFirstOffset = 0;
+
// Unless we decide otherwise, just do the lookup via a helper function
pResult->indirections = CORINFO_USEHELPER;
@@ -3208,6 +3210,11 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr
#endif
pResult->offsets[0] = offsetof(InstantiatedMethodDesc, m_pPerInstInfo);
+ if (decltype(InstantiatedMethodDesc::m_pPerInstInfo)::isRelative)
+ {
+ pResult->indirectFirstOffset = 1;
+ }
+
ULONG data;
IfFailThrow(sigptr.GetData(&data));
pResult->offsets[1] = sizeof(TypeHandle) * data;
@@ -3512,6 +3519,11 @@ NoSpecialCase:
// Indirect through dictionary table pointer in InstantiatedMethodDesc
pResult->offsets[0] = offsetof(InstantiatedMethodDesc, m_pPerInstInfo);
+
+ if (decltype(InstantiatedMethodDesc::m_pPerInstInfo)::isRelative)
+ {
+ pResult->indirectFirstOffset = 1;
+ }
}
}
diff --git a/src/vm/method.cpp b/src/vm/method.cpp
index ca0ecc178d..241a0ccee0 100644
--- a/src/vm/method.cpp
+++ b/src/vm/method.cpp
@@ -3496,7 +3496,14 @@ MethodDesc::Fixup(
}
}
- image->FixupPointerField(this, offsetof(InstantiatedMethodDesc, m_pPerInstInfo));
+ if (decltype(InstantiatedMethodDesc::m_pPerInstInfo)::isRelative)
+ {
+ image->FixupRelativePointerField(this, offsetof(InstantiatedMethodDesc, m_pPerInstInfo));
+ }
+ else
+ {
+ image->FixupPointerField(this, offsetof(InstantiatedMethodDesc, m_pPerInstInfo));
+ }
// Generic methods are dealt with specially to avoid encoding the formal method type parameters
if (IsTypicalMethodDefinition())
@@ -3575,7 +3582,14 @@ MethodDesc::Fixup(
NDirectMethodDesc *pNMD = (NDirectMethodDesc *)this;
- image->FixupPointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pWriteableData));
+ if (decltype(NDirectMethodDesc::ndirect.m_pWriteableData)::isRelative)
+ {
+ image->FixupRelativePointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pWriteableData));
+ }
+ else
+ {
+ image->FixupPointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pWriteableData));
+ }
NDirectWriteableData *pWriteableData = pNMD->GetWriteableData();
NDirectImportThunkGlue *pImportThunkGlue = pNMD->GetNDirectImportThunkGlue();
diff --git a/src/vm/method.hpp b/src/vm/method.hpp
index 4b85357d43..71e838a94a 100644
--- a/src/vm/method.hpp
+++ b/src/vm/method.hpp
@@ -2586,7 +2586,11 @@ public:
};
// The writeable part of the methoddesc.
- PTR_NDirectWriteableData m_pWriteableData;
+#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_)
+ RelativePointer<PTR_NDirectWriteableData> m_pWriteableData;
+#else
+ PlainPointer<PTR_NDirectWriteableData> m_pWriteableData;
+#endif
#ifdef HAS_NDIRECT_IMPORT_PRECODE
RelativePointer<PTR_NDirectImportThunkGlue> m_pImportThunkGlue;
@@ -2808,11 +2812,11 @@ public:
return (ndirect.m_wFlags & kStdCallWithRetBuf) != 0;
}
- NDirectWriteableData* GetWriteableData() const
+ PTR_NDirectWriteableData GetWriteableData() const
{
- LIMITED_METHOD_CONTRACT;
+ LIMITED_METHOD_DAC_CONTRACT;
- return ndirect.m_pWriteableData;
+ return ReadPointer(this, &NDirectMethodDesc::ndirect, &decltype(NDirectMethodDesc::ndirect)::m_pWriteableData);
}
PTR_NDirectImportThunkGlue GetNDirectImportThunkGlue()
@@ -3217,7 +3221,7 @@ public:
if (IMD_IsGenericMethodDefinition())
return TRUE;
else
- return m_pPerInstInfo != NULL;
+ return !m_pPerInstInfo.IsNull();
}
// All varieties of InstantiatedMethodDesc's support this method.
@@ -3225,13 +3229,21 @@ public:
{
LIMITED_METHOD_DAC_CONTRACT;
- return Instantiation(m_pPerInstInfo->GetInstantiation(), m_wNumGenericArgs);
+ return Instantiation(IMD_GetMethodDictionary()->GetInstantiation(), m_wNumGenericArgs);
}
PTR_Dictionary IMD_GetMethodDictionary()
{
LIMITED_METHOD_DAC_CONTRACT;
- return m_pPerInstInfo;
+
+ return ReadPointerMaybeNull(this, &InstantiatedMethodDesc::m_pPerInstInfo);
+ }
+
+ PTR_Dictionary IMD_GetMethodDictionaryNonNull()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ return ReadPointer(this, &InstantiatedMethodDesc::m_pPerInstInfo);
}
BOOL IMD_IsGenericMethodDefinition()
@@ -3390,7 +3402,11 @@ public: // <TODO>make private: JITinterface.cpp accesses through this </TODO>
//
// For generic method definitions that are not the typical method definition (e.g. C<int>.m<U>)
// this field is null; to obtain the instantiation use LoadMethodInstantiation
- PTR_Dictionary m_pPerInstInfo; //SHARED
+#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_)
+ RelativePointer<PTR_Dictionary> m_pPerInstInfo; //SHARED
+#else
+ PlainPointer<PTR_Dictionary> m_pPerInstInfo; //SHARED
+#endif
private:
WORD m_wFlags2;
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index 01c7ce97ab..1b3d775e59 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -5913,8 +5913,8 @@ MethodTableBuilder::InitMethodDesc(
NDirectMethodDesc *pNewNMD = (NDirectMethodDesc*)pNewMD;
// Allocate writeable data
- pNewNMD->ndirect.m_pWriteableData = (NDirectWriteableData*)
- AllocateFromHighFrequencyHeap(S_SIZE_T(sizeof(NDirectWriteableData)));
+ pNewNMD->ndirect.m_pWriteableData.SetValue((NDirectWriteableData*)
+ AllocateFromHighFrequencyHeap(S_SIZE_T(sizeof(NDirectWriteableData))));
#ifdef HAS_NDIRECT_IMPORT_PRECODE
pNewNMD->ndirect.m_pImportThunkGlue.SetValue(Precode::Allocate(PRECODE_NDIRECT_IMPORT, pNewMD,
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index 921d376978..1ebcdc4b4d 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -2383,6 +2383,9 @@ void ProcessDynamicDictionaryLookup(TransitionBlock * pTransitionBlock
pResult->testForFixup = pResult->testForNull = false;
pResult->signature = NULL;
+
+ pResult->indirectFirstOffset = 0;
+
pResult->indirections = CORINFO_USEHELPER;
DWORD numGenericArgs = 0;
@@ -2433,6 +2436,11 @@ void ProcessDynamicDictionaryLookup(TransitionBlock * pTransitionBlock
pResult->indirections = 2;
pResult->offsets[0] = offsetof(InstantiatedMethodDesc, m_pPerInstInfo);
+ if (decltype(InstantiatedMethodDesc::m_pPerInstInfo)::isRelative)
+ {
+ pResult->indirectFirstOffset = 1;
+ }
+
ULONG data;
IfFailThrow(sigptr.GetData(&data));
pResult->offsets[1] = sizeof(TypeHandle) * data;
@@ -2472,6 +2480,11 @@ void ProcessDynamicDictionaryLookup(TransitionBlock * pTransitionBlock
// Indirect through dictionary table pointer in InstantiatedMethodDesc
pResult->offsets[0] = offsetof(InstantiatedMethodDesc, m_pPerInstInfo);
+ if (decltype(InstantiatedMethodDesc::m_pPerInstInfo)::isRelative)
+ {
+ pResult->indirectFirstOffset = 1;
+ }
+
*pDictionaryIndexAndSlot |= dictionarySlot;
}
}