summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Balykov <g.balykov@samsung.com>2017-06-22 21:14:04 +0300
committerGleb Balykov <g.balykov@samsung.com>2017-07-10 16:37:05 +0300
commit7a107e9622ff5803987add587414610014eeca4e (patch)
treef712e897cb88d35eb07b5d910ffbceb496521d03
parent33e3886802d95e7d4b5bfde630c0067d07c6291a (diff)
downloadcoreclr-7a107e9622ff5803987add587414610014eeca4e.tar.gz
coreclr-7a107e9622ff5803987add587414610014eeca4e.tar.bz2
coreclr-7a107e9622ff5803987add587414610014eeca4e.zip
Remove relocations for MethodTable::m_pPerInstInfo for Linux ARM
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp1
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.h1
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h2
-rw-r--r--src/debug/daccess/nidump.cpp8
-rw-r--r--src/inc/corinfo.h7
-rw-r--r--src/jit/importer.cpp6
-rw-r--r--src/vm/ceeload.cpp11
-rw-r--r--src/vm/class.cpp7
-rw-r--r--src/vm/genericdict.cpp2
-rw-r--r--src/vm/generics.cpp5
-rw-r--r--src/vm/jitinterface.cpp13
-rw-r--r--src/vm/methodtable.cpp47
-rw-r--r--src/vm/methodtable.h29
-rw-r--r--src/vm/methodtable.inl2
-rw-r--r--src/vm/methodtablebuilder.cpp7
-rw-r--r--src/vm/prestub.cpp13
16 files changed, 127 insertions, 34 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
index f522265e11..ed5799f710 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
@@ -1504,6 +1504,7 @@ void MethodContext::repGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
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;
+ pResult->stubLookup.runtimeLookup.indirectSecondOffset = value.stubLookup.runtimeLookup.indirectSecondOffset != 0;
for (int i = 0; i < CORINFO_MAXINDIRECTIONS; i++)
pResult->stubLookup.runtimeLookup.offsets[i] = (SIZE_T)value.stubLookup.runtimeLookup.offsets[i];
}
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
index 4b42fa7be4..aa5cd85431 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
@@ -211,6 +211,7 @@ public:
DWORD testForFixup;
DWORDLONG offsets[CORINFO_MAXINDIRECTIONS];
DWORD indirectFirstOffset;
+ DWORD indirectSecondOffset;
};
struct Agnostic_CORINFO_LOOKUP
{
diff --git a/src/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h b/src/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h
index 0030a2bbd5..c3988f8487 100644
--- a/src/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h
+++ b/src/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h
@@ -297,6 +297,7 @@ inline MethodContext::Agnostic_CORINFO_RUNTIME_LOOKUP SpmiRecordsHelper::StoreAg
runtimeLookup.testForNull = (DWORD)pLookup->testForNull;
runtimeLookup.testForFixup = (DWORD)pLookup->testForFixup;
runtimeLookup.indirectFirstOffset = (DWORD)pLookup->indirectFirstOffset;
+ runtimeLookup.indirectSecondOffset = (DWORD)pLookup->indirectSecondOffset;
for (int i = 0; i < CORINFO_MAXINDIRECTIONS; i++)
runtimeLookup.offsets[i] = (DWORDLONG)pLookup->offsets[i];
return runtimeLookup;
@@ -312,6 +313,7 @@ inline CORINFO_RUNTIME_LOOKUP SpmiRecordsHelper::RestoreCORINFO_RUNTIME_LOOKUP(
runtimeLookup.testForNull = lookup.testForNull != 0;
runtimeLookup.testForFixup = lookup.testForFixup != 0;
runtimeLookup.indirectFirstOffset = lookup.indirectFirstOffset != 0;
+ runtimeLookup.indirectSecondOffset = lookup.indirectSecondOffset != 0;
for (int i = 0; i < CORINFO_MAXINDIRECTIONS; i++)
runtimeLookup.offsets[i] = (size_t)lookup.offsets[i];
return CORINFO_RUNTIME_LOOKUP();
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index e1cf16629c..eec4c43be6 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -5084,7 +5084,10 @@ void NativeImageDumper::MethodTableToString( PTR_MethodTable mt, SString& buf )
{
numDicts = (DWORD)CountDictionariesInClass(token, dependency->pImport);
}
- PTR_Dictionary dictionary( mt->GetPerInstInfo()[numDicts-1] );
+
+ TADDR base = dac_cast<TADDR>(&(mt->GetPerInstInfo()[numDicts-1]));
+
+ PTR_Dictionary dictionary( MethodTable::PerInstInfoElem_t::GetValueAtPtr(base) );
unsigned numArgs = mt->GetNumGenericArgs();
DictionaryToArgString( dictionary, numArgs, buf );
@@ -7049,8 +7052,7 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name,
GenericsDictInfo, METHODTABLES);
DisplayEndStructure( METHODTABLES ); //GenericsDictInfo
-
- DPTR(PTR_Dictionary) perInstInfo = mt->GetPerInstInfo();
+ DPTR(MethodTable::PerInstInfoElem_t) perInstInfo = mt->GetPerInstInfo();
DisplayStartStructure( "PerInstInfo",
DPtrToPreferredAddr(perInstInfo),
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index 4af22e53f4..9c2e08b373 100644
--- a/src/inc/corinfo.h
+++ b/src/inc/corinfo.h
@@ -1332,6 +1332,13 @@ struct CORINFO_RUNTIME_LOOKUP
// 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;
+
+ // If set, second offset is indirect.
+ // 0 means that value stored at second offset (offsets[1]) from pointer is next pointer, to which the next offset
+ // (offsets[2]) is added and so on.
+ // 1 means that value stored at second offset (offsets[1]) from pointer is offset2, and the next pointer is
+ // stored at pointer+offsets[1]+offset2.
+ bool indirectSecondOffset;
} ;
// Result of calling embedGenericHandle
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index b618478c66..c5e9b68042 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -1980,10 +1980,10 @@ GenTreePtr Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedTok
// Applied repeated indirections
for (WORD i = 0; i < pRuntimeLookup->indirections; i++)
{
- if (i == 1 && pRuntimeLookup->indirectFirstOffset)
+ if ((i == 1 && pRuntimeLookup->indirectFirstOffset) || (i == 2 && pRuntimeLookup->indirectSecondOffset))
{
indOffTree = impCloneExpr(slotPtrTree, &slotPtrTree, NO_CLASS_HANDLE, (unsigned)CHECK_SPILL_ALL,
- nullptr DEBUGARG("impRuntimeLookup indirectFirstOffset"));
+ nullptr DEBUGARG("impRuntimeLookup indirectOffset"));
}
if (i != 0)
@@ -1993,7 +1993,7 @@ GenTreePtr Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedTok
slotPtrTree->gtFlags |= GTF_IND_INVARIANT;
}
- if (i == 1 && pRuntimeLookup->indirectFirstOffset)
+ if ((i == 1 && pRuntimeLookup->indirectFirstOffset) || (i == 2 && pRuntimeLookup->indirectSecondOffset))
{
slotPtrTree = gtNewOperNode(GT_ADD, TYP_I_IMPL, indOffTree, slotPtrTree);
}
diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp
index ff8c17e06c..ea93e5ccf4 100644
--- a/src/vm/ceeload.cpp
+++ b/src/vm/ceeload.cpp
@@ -9289,13 +9289,20 @@ void Module::PlaceType(DataImage *image, TypeHandle th, DWORD profilingFlags)
{
if (pMT->HasPerInstInfo())
{
- Dictionary ** pPerInstInfo = pMT->GetPerInstInfo();
+ DPTR(MethodTable::PerInstInfoElem_t) pPerInstInfo = pMT->GetPerInstInfo();
BOOL fIsEagerBound = pMT->CanEagerBindToParentDictionaries(image, NULL);
if (fIsEagerBound)
{
- image->PlaceInternedStructureForAddress(pPerInstInfo, CORCOMPILE_SECTION_READONLY_SHARED_HOT, CORCOMPILE_SECTION_READONLY_HOT);
+ if (MethodTable::PerInstInfoElem_t::isRelative)
+ {
+ image->PlaceStructureForAddress(pPerInstInfo, CORCOMPILE_SECTION_READONLY_HOT);
+ }
+ else
+ {
+ image->PlaceInternedStructureForAddress(pPerInstInfo, CORCOMPILE_SECTION_READONLY_SHARED_HOT, CORCOMPILE_SECTION_READONLY_HOT);
+ }
}
else
{
diff --git a/src/vm/class.cpp b/src/vm/class.cpp
index 6697b23a9a..c1519a2bfe 100644
--- a/src/vm/class.cpp
+++ b/src/vm/class.cpp
@@ -908,8 +908,11 @@ ClassLoader::LoadExactParentAndInterfacesTransitively(MethodTable *pMT)
DWORD nDicts = pParentMT->GetNumDicts();
for (DWORD iDict = 0; iDict < nDicts; iDict++)
{
- if (pMT->GetPerInstInfo()[iDict] != pParentMT->GetPerInstInfo()[iDict])
- *EnsureWritablePages(&pMT->GetPerInstInfo()[iDict]) = pParentMT->GetPerInstInfo()[iDict];
+ if (pMT->GetPerInstInfo()[iDict].GetValueMaybeNull() != pParentMT->GetPerInstInfo()[iDict].GetValueMaybeNull())
+ {
+ EnsureWritablePages(&pMT->GetPerInstInfo()[iDict]);
+ pMT->GetPerInstInfo()[iDict].SetValueMaybeNull(pParentMT->GetPerInstInfo()[iDict].GetValueMaybeNull());
+ }
}
}
diff --git a/src/vm/genericdict.cpp b/src/vm/genericdict.cpp
index c93e583345..5fad30f4b8 100644
--- a/src/vm/genericdict.cpp
+++ b/src/vm/genericdict.cpp
@@ -742,7 +742,7 @@ Dictionary::PopulateEntry(
}
// MethodTable is expected to be normalized
- _ASSERTE(pDictionary == pMT->GetPerInstInfo()[dictionaryIndex]);
+ _ASSERTE(pDictionary == pMT->GetPerInstInfo()[dictionaryIndex].GetValueMaybeNull());
}
else
{
diff --git a/src/vm/generics.cpp b/src/vm/generics.cpp
index 51e6d7bbac..d1a511ffb7 100644
--- a/src/vm/generics.cpp
+++ b/src/vm/generics.cpp
@@ -499,7 +499,7 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation(
_ASSERTE(pOldMT->HasPerInstInfo());
// Fill in per-inst map pointer (which points to the array of generic dictionary pointers)
- pMT->SetPerInstInfo ((Dictionary**) (pMemory + cbMT + cbOptional + cbIMap + sizeof(GenericsDictInfo)));
+ pMT->SetPerInstInfo((MethodTable::PerInstInfoElem_t *) (pMemory + cbMT + cbOptional + cbIMap + sizeof(GenericsDictInfo)));
_ASSERTE(FitsIn<WORD>(pOldMT->GetNumDicts()));
_ASSERTE(FitsIn<WORD>(pOldMT->GetNumGenericArgs()));
pMT->SetDictInfo(static_cast<WORD>(pOldMT->GetNumDicts()), static_cast<WORD>(pOldMT->GetNumGenericArgs()));
@@ -508,7 +508,8 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation(
// The others are filled in by LoadExactParents which copied down any inherited generic
// dictionary pointers.
Dictionary * pDict = (Dictionary*) (pMemory + cbMT + cbOptional + cbIMap + cbPerInst);
- *(pMT->GetPerInstInfo() + (pOldMT->GetNumDicts()-1)) = pDict;
+ MethodTable::PerInstInfoElem_t *pPInstInfo = (MethodTable::PerInstInfoElem_t *) (pMT->GetPerInstInfo() + (pOldMT->GetNumDicts()-1));
+ pPInstInfo->SetValueMaybeNull(pDict);
// Fill in the instantiation section of the generic dictionary. The remainder of the
// generic dictionary will be zeroed, which is the correct initial state.
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 2fc5e09391..67e36560fd 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -3093,6 +3093,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr
pResult->signature = NULL;
pResult->indirectFirstOffset = 0;
+ pResult->indirectSecondOffset = 0;
// Unless we decide otherwise, just do the lookup via a helper function
pResult->indirections = CORINFO_USEHELPER;
@@ -3307,6 +3308,12 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr
IfFailThrow(sigptr.GetData(&data));
pResult->offsets[2] = sizeof(TypeHandle) * data;
+ if (MethodTable::IsPerInstInfoRelative())
+ {
+ pResult->indirectFirstOffset = 1;
+ pResult->indirectSecondOffset = 1;
+ }
+
return;
}
else if (type == ELEMENT_TYPE_GENERICINST &&
@@ -3554,6 +3561,12 @@ NoSpecialCase:
// Next indirect through the dictionary appropriate to this instantiated type
pResult->offsets[1] = sizeof(TypeHandle*) * (pContextMT->GetNumDicts() - 1);
+
+ if (MethodTable::IsPerInstInfoRelative())
+ {
+ pResult->indirectFirstOffset = 1;
+ pResult->indirectSecondOffset = 1;
+ }
}
}
}
diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp
index b26ff856a9..d60f565b08 100644
--- a/src/vm/methodtable.cpp
+++ b/src/vm/methodtable.cpp
@@ -4331,7 +4331,14 @@ void MethodTable::Save(DataImage *image, DWORD profilingFlags)
ZapStoredStructure * pPerInstInfoNode;
if (CanEagerBindToParentDictionaries(image, NULL))
{
- pPerInstInfoNode = image->StoreInternedStructure((BYTE *)GetPerInstInfo() - sizeof(GenericsDictInfo), GetPerInstInfoSize() + sizeof(GenericsDictInfo), DataImage::ITEM_DICTIONARY);
+ if (PerInstInfoElem_t::isRelative)
+ {
+ pPerInstInfoNode = image->StoreStructure((BYTE *)GetPerInstInfo() - sizeof(GenericsDictInfo), GetPerInstInfoSize() + sizeof(GenericsDictInfo), DataImage::ITEM_DICTIONARY);
+ }
+ else
+ {
+ pPerInstInfoNode = image->StoreInternedStructure((BYTE *)GetPerInstInfo() - sizeof(GenericsDictInfo), GetPerInstInfoSize() + sizeof(GenericsDictInfo), DataImage::ITEM_DICTIONARY);
+ }
}
else
{
@@ -4678,14 +4685,21 @@ BOOL MethodTable::IsWriteable()
// target module. Thus we want to call CanEagerBindToMethodTable
// to check we can hardbind to the containing structure.
static
-void HardBindOrClearDictionaryPointer(DataImage *image, MethodTable *pMT, void * p, SSIZE_T offset)
+void HardBindOrClearDictionaryPointer(DataImage *image, MethodTable *pMT, void * p, SSIZE_T offset, bool isRelative)
{
WRAPPER_NO_CONTRACT;
if (image->CanEagerBindToMethodTable(pMT) &&
image->CanHardBindToZapModule(pMT->GetLoaderModule()))
{
- image->FixupPointerField(p, offset);
+ if (isRelative)
+ {
+ image->FixupRelativePointerField(p, offset);
+ }
+ else
+ {
+ image->FixupPointerField(p, offset);
+ }
}
else
{
@@ -5020,7 +5034,7 @@ void MethodTable::Fixup(DataImage *image)
if (HasPerInstInfo())
{
// Fixup the pointer to the per-inst table
- image->FixupPointerField(this, offsetof(MethodTable, m_pPerInstInfo));
+ image->FixupPlainOrRelativePointerField(this, &MethodTable::m_pPerInstInfo);
for (MethodTable *pChain = this; pChain != NULL; pChain = pChain->GetParentMethodTable())
{
@@ -5033,10 +5047,23 @@ void MethodTable::Fixup(DataImage *image)
// We special-case the dictionary for this method table because we must always
// hard bind to it even if it's not in its preferred zap module
+ size_t sizeDict = sizeof(PerInstInfoElem_t);
+
if (pChain == this)
- image->FixupPointerField(GetPerInstInfo(), dictNum * sizeof(Dictionary *));
+ {
+ if (PerInstInfoElem_t::isRelative)
+ {
+ image->FixupRelativePointerField(GetPerInstInfo(), dictNum * sizeDict);
+ }
+ else
+ {
+ image->FixupPointerField(GetPerInstInfo(), dictNum * sizeDict);
+ }
+ }
else
- HardBindOrClearDictionaryPointer(image, pChain, GetPerInstInfo(), dictNum * sizeof(Dictionary *));
+ {
+ HardBindOrClearDictionaryPointer(image, pChain, GetPerInstInfo(), dictNum * sizeDict, PerInstInfoElem_t::isRelative);
+ }
}
}
}
@@ -6221,7 +6248,7 @@ BOOL MethodTable::IsWinRTObjectType()
//==========================================================================================
// Return a pointer to the dictionary for an instantiated type
// Return NULL if not instantiated
-Dictionary* MethodTable::GetDictionary()
+PTR_Dictionary MethodTable::GetDictionary()
{
LIMITED_METHOD_DAC_CONTRACT;
@@ -6229,7 +6256,8 @@ Dictionary* MethodTable::GetDictionary()
{
// The instantiation for this class is stored in the type slots table
// *after* any inherited slots
- return GetPerInstInfo()[GetNumDicts()-1];
+ TADDR base = dac_cast<TADDR>(&(GetPerInstInfo()[GetNumDicts()-1]));
+ return PerInstInfoElem_t::GetValueMaybeNullAtPtr(base);
}
else
{
@@ -6246,7 +6274,8 @@ Instantiation MethodTable::GetInstantiation()
if (HasInstantiation())
{
PTR_GenericsDictInfo pDictInfo = GetGenericsDictInfo();
- return Instantiation(GetPerInstInfo()[pDictInfo->m_wNumDicts-1]->GetInstantiation(), pDictInfo->m_wNumTyPars);
+ TADDR base = dac_cast<TADDR>(&(GetPerInstInfo()[pDictInfo->m_wNumDicts-1]));
+ return Instantiation(PerInstInfoElem_t::GetValueMaybeNullAtPtr(base)->GetInstantiation(), pDictInfo->m_wNumTyPars);
}
else
{
diff --git a/src/vm/methodtable.h b/src/vm/methodtable.h
index 7bf5432ebc..bf811aa409 100644
--- a/src/vm/methodtable.h
+++ b/src/vm/methodtable.h
@@ -3007,12 +3007,20 @@ public:
// must have a dictionary entry. On the other hand, for instantiations shared with Dict<string,double> the opposite holds.
//
+#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_)
+ typedef RelativePointer<PTR_Dictionary> PerInstInfoElem_t;
+ typedef RelativePointer<DPTR(PerInstInfoElem_t)> PerInstInfo_t;
+#else
+ typedef PlainPointer<PTR_Dictionary> PerInstInfoElem_t;
+ typedef PlainPointer<DPTR(PerInstInfoElem_t)> PerInstInfo_t;
+#endif
+
// Return a pointer to the per-instantiation information. See field itself for comments.
- DPTR(PTR_Dictionary) GetPerInstInfo()
+ DPTR(PerInstInfoElem_t) GetPerInstInfo()
{
LIMITED_METHOD_DAC_CONTRACT;
_ASSERTE(HasPerInstInfo());
- return dac_cast<DPTR(PTR_Dictionary)>(m_pMultipurposeSlot1);
+ return ReadPointer(this, &MethodTable::m_pPerInstInfo);
}
BOOL HasPerInstInfo()
{
@@ -3020,15 +3028,20 @@ public:
return GetFlag(enum_flag_HasPerInstInfo) && !IsArray();
}
#ifndef DACCESS_COMPILE
+ static inline bool IsPerInstInfoRelative()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return decltype(m_pPerInstInfo)::isRelative;
+ }
static inline DWORD GetOffsetOfPerInstInfo()
{
LIMITED_METHOD_CONTRACT;
return offsetof(MethodTable, m_pPerInstInfo);
}
- void SetPerInstInfo(Dictionary** pPerInstInfo)
+ void SetPerInstInfo(PerInstInfoElem_t *pPerInstInfo)
{
LIMITED_METHOD_CONTRACT;
- m_pPerInstInfo = pPerInstInfo;
+ m_pPerInstInfo.SetValue(pPerInstInfo);
}
void SetDictInfo(WORD numDicts, WORD numTyPars)
{
@@ -3048,7 +3061,7 @@ public:
// Get a pointer to the dictionary for this instantiated type
// (The instantiation is stored in the initial slots of the dictionary)
// If not instantiated, return NULL
- Dictionary* GetDictionary();
+ PTR_Dictionary GetDictionary();
#ifdef FEATURE_PREJIT
//
@@ -4108,9 +4121,9 @@ private:
union
{
- PTR_Dictionary * m_pPerInstInfo;
- TADDR m_ElementTypeHnd;
- TADDR m_pMultipurposeSlot1;
+ PerInstInfo_t m_pPerInstInfo;
+ TADDR m_ElementTypeHnd;
+ TADDR m_pMultipurposeSlot1;
};
public:
union
diff --git a/src/vm/methodtable.inl b/src/vm/methodtable.inl
index 4c808eee26..b69513d662 100644
--- a/src/vm/methodtable.inl
+++ b/src/vm/methodtable.inl
@@ -1256,7 +1256,7 @@ inline BOOL MethodTable::HasExplicitSize()
inline DWORD MethodTable::GetPerInstInfoSize()
{
LIMITED_METHOD_DAC_CONTRACT;
- return GetNumDicts() * sizeof(TypeHandle*);
+ return GetNumDicts() * sizeof(PerInstInfoElem_t);
}
//==========================================================================================
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index 87de930500..d7e9818888 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -9842,7 +9842,7 @@ MethodTable * MethodTableBuilder::AllocateNewMT(Module *pLoaderModule,
if (dwNumDicts != 0)
{
cbTotalSize += sizeof(GenericsDictInfo);
- cbTotalSize += S_SIZE_T(dwNumDicts) * S_SIZE_T(sizeof(TypeHandle*));
+ cbTotalSize += S_SIZE_T(dwNumDicts) * S_SIZE_T(sizeof(MethodTable::PerInstInfoElem_t));
cbTotalSize += cbInstAndDict;
}
@@ -9995,14 +9995,15 @@ MethodTable * MethodTableBuilder::AllocateNewMT(Module *pLoaderModule,
// the dictionary pointers follow the interface map
if (dwNumDicts)
{
- Dictionary** pPerInstInfo = (Dictionary**)(pData + offsetOfInstAndDict.Value() + sizeof(GenericsDictInfo));
+ MethodTable::PerInstInfoElem_t *pPerInstInfo = (MethodTable::PerInstInfoElem_t *)(pData + offsetOfInstAndDict.Value() + sizeof(GenericsDictInfo));
pMT->SetPerInstInfo ( pPerInstInfo);
// Fill in the dictionary for this type, if it's instantiated
if (cbInstAndDict)
{
- *(pPerInstInfo + (dwNumDicts-1)) = (Dictionary*) (pPerInstInfo + dwNumDicts);
+ MethodTable::PerInstInfoElem_t *pPInstInfo = (MethodTable::PerInstInfoElem_t *)(pPerInstInfo + (dwNumDicts-1));
+ pPInstInfo->SetValueMaybeNull((Dictionary*) (pPerInstInfo + dwNumDicts));
}
}
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index 31a5670e00..a2580b2619 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -2385,6 +2385,7 @@ void ProcessDynamicDictionaryLookup(TransitionBlock * pTransitionBlock
pResult->signature = NULL;
pResult->indirectFirstOffset = 0;
+ pResult->indirectSecondOffset = 0;
pResult->indirections = CORINFO_USEHELPER;
@@ -2457,6 +2458,12 @@ void ProcessDynamicDictionaryLookup(TransitionBlock * pTransitionBlock
IfFailThrow(sigptr.GetData(&data));
pResult->offsets[2] = sizeof(TypeHandle) * data;
+ if (MethodTable::IsPerInstInfoRelative())
+ {
+ pResult->indirectFirstOffset = 1;
+ pResult->indirectSecondOffset = 1;
+ }
+
return;
}
}
@@ -2502,6 +2509,12 @@ void ProcessDynamicDictionaryLookup(TransitionBlock * pTransitionBlock
// Next indirect through the dictionary appropriate to this instantiated type
pResult->offsets[1] = sizeof(TypeHandle*) * (pContextMT->GetNumDicts() - 1);
+ if (MethodTable::IsPerInstInfoRelative())
+ {
+ pResult->indirectFirstOffset = 1;
+ pResult->indirectSecondOffset = 1;
+ }
+
*pDictionaryIndexAndSlot |= dictionarySlot;
}
}