Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit a39f5c5

Browse files
committed
Remove relocations for second-level indirection of Vtable in case FEATURE_FNV_MEM_OPTIMIZATIONS is enabled.
Introduce FEATURE_FNV_MEM_OPTIMIZATIONS, under which FragileNonVersionable specific memory optimizations are enabled
1 parent 239da95 commit a39f5c5

35 files changed

+631
-139
lines changed

clrdefinitions.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ add_definitions(-DFEATURE_STRONGNAME_MIGRATION)
195195
if (CLR_CMAKE_PLATFORM_UNIX OR CLR_CMAKE_TARGET_ARCH_ARM64)
196196
add_definitions(-DFEATURE_STUBS_AS_IL)
197197
endif ()
198+
if (FEATURE_FNV_MEM_OPTIMIZATIONS)
199+
add_definitions(-DFEATURE_FNV_MEM_OPTIMIZATIONS)
200+
endif(FEATURE_FNV_MEM_OPTIMIZATIONS)
198201
add_definitions(-DFEATURE_SVR_GC)
199202
add_definitions(-DFEATURE_SYMDIFF)
200203
add_definitions(-DFEATURE_TIERED_COMPILATION)

src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,11 @@ CORINFO_MODULE_HANDLE getMethodModule(CORINFO_METHOD_HANDLE method);
109109

110110
// This function returns the offset of the specified method in the
111111
// vtable of it's owning class or interface.
112-
void getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
113-
unsigned* offsetOfIndirection, /* OUT */
114-
unsigned* offsetAfterIndirection,/* OUT */
115-
bool* isRelative /* OUT */
112+
void getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
113+
unsigned* offsetOfIndirection, /* OUT */
114+
unsigned* offsetAfterIndirection, /* OUT */
115+
bool* isRelative, /* OUT */
116+
bool* isRelativeAfterIndirection /* OUT */
116117
);
117118

118119
// Find the virtual method in implementingClass that overrides virtualMethod.

src/ToolBox/superpmi/superpmi-shared/lwmlist.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ LWM(GetMethodName, DLD, DD)
108108
LWM(GetMethodNameFromMetadata, DLDD, DDD)
109109
LWM(GetMethodSig, DLDL, Agnostic_CORINFO_SIG_INFO)
110110
LWM(GetMethodSync, DWORDLONG, DLDL)
111-
LWM(GetMethodVTableOffset, DWORDLONG, DDD)
111+
LWM(GetMethodVTableOffset, DWORDLONG, DDDD)
112112
LWM(GetNewArrHelper, DWORDLONG, DWORD)
113113
LWM(GetNewHelper, Agnostic_GetNewHelper, DWORD)
114114
LWM(GetParentType, DWORDLONG, DWORDLONG)

src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,38 +2972,42 @@ void MethodContext::repGetEHinfo(CORINFO_METHOD_HANDLE ftn, unsigned EHnumber, C
29722972
void MethodContext::recGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
29732973
unsigned* offsetOfIndirection,
29742974
unsigned* offsetAfterIndirection,
2975-
bool* isRelative)
2975+
bool* isRelative,
2976+
bool* isRelativeAfterIndirection)
29762977
{
29772978
if (GetMethodVTableOffset == nullptr)
2978-
GetMethodVTableOffset = new LightWeightMap<DWORDLONG, DDD>();
2979+
GetMethodVTableOffset = new LightWeightMap<DWORDLONG, DDDD>();
29792980

2980-
DDD value;
2981+
DDDD value;
29812982
value.A = (DWORD)*offsetOfIndirection;
29822983
value.B = (DWORD)*offsetAfterIndirection;
29832984
value.C = *isRelative ? 1 : 0;
2985+
value.D = *isRelativeAfterIndirection ? 1 : 0;
29842986
GetMethodVTableOffset->Add((DWORDLONG)method, value);
29852987
DEBUG_REC(dmpGetMethodVTableOffset((DWORDLONG)method, value));
29862988
}
2987-
void MethodContext::dmpGetMethodVTableOffset(DWORDLONG key, DDD value)
2989+
void MethodContext::dmpGetMethodVTableOffset(DWORDLONG key, DDDD value)
29882990
{
2989-
printf("GetMethodVTableOffset key ftn-%016llX, value offi-%u, offa-%u. offr-%d", key, value.A, value.B, value.C);
2991+
printf("GetMethodVTableOffset key ftn-%016llX, value offi-%u, offa-%u. offr-%d. offr2-%d", key, value.A, value.B, value.C, value.D);
29902992
}
29912993
void MethodContext::repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
29922994
unsigned* offsetOfIndirection,
29932995
unsigned* offsetAfterIndirection,
2994-
bool* isRelative)
2996+
bool* isRelative,
2997+
bool* isRelativeAfterIndirection)
29952998
{
2996-
DDD value;
2999+
DDDD value;
29973000

29983001
AssertCodeMsg(GetMethodVTableOffset != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX",
29993002
(DWORDLONG)method);
30003003
AssertCodeMsg(GetMethodVTableOffset->GetIndex((DWORDLONG)method) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX",
30013004
(DWORDLONG)method);
30023005
value = GetMethodVTableOffset->Get((DWORDLONG)method);
30033006

3004-
*offsetOfIndirection = (unsigned)value.A;
3005-
*offsetAfterIndirection = (unsigned)value.B;
3006-
*isRelative = (value.C != 0);
3007+
*offsetOfIndirection = (unsigned)value.A;
3008+
*offsetAfterIndirection = (unsigned)value.B;
3009+
*isRelative = (value.C != 0);
3010+
*isRelativeAfterIndirection = (value.D != 0);
30073011
DEBUG_REP(dmpGetMethodVTableOffset((DWORDLONG)method, value));
30083012
}
30093013

src/ToolBox/superpmi/superpmi-shared/methodcontext.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,13 @@ class MethodContext
249249
DWORD B;
250250
DWORD C;
251251
};
252+
struct DDDD
253+
{
254+
DWORD A;
255+
DWORD B;
256+
DWORD C;
257+
DWORD D;
258+
};
252259
struct Agnostic_CanTailCall
253260
{
254261
DWORDLONG callerHnd;
@@ -865,12 +872,14 @@ class MethodContext
865872
void recGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
866873
unsigned* offsetOfIndirection,
867874
unsigned* offsetAfterIndirection,
868-
bool* isRelative);
869-
void dmpGetMethodVTableOffset(DWORDLONG key, DDD value);
875+
bool* isRelative,
876+
bool* isRelativeAfterIndirection);
877+
void dmpGetMethodVTableOffset(DWORDLONG key, DDDD value);
870878
void repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
871879
unsigned* offsetOfIndirection,
872880
unsigned* offsetAfterIndirection,
873-
bool* isRelative);
881+
bool* isRelative,
882+
bool* isRelativeAfterIndirection);
874883

875884
void recResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod,
876885
CORINFO_CLASS_HANDLE implClass,

src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,16 @@ CORINFO_MODULE_HANDLE interceptor_ICJI::getMethodModule(CORINFO_METHOD_HANDLE me
218218

219219
// This function returns the offset of the specified method in the
220220
// vtable of it's owning class or interface.
221-
void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
222-
unsigned* offsetOfIndirection, /* OUT */
223-
unsigned* offsetAfterIndirection, /* OUT */
224-
bool* isRelative /* OUT */
221+
void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
222+
unsigned* offsetOfIndirection, /* OUT */
223+
unsigned* offsetAfterIndirection, /* OUT */
224+
bool* isRelative, /* OUT */
225+
bool* isRelativeAfterIndirection /* OUT */
225226
)
226227
{
227228
mc->cr->AddCall("getMethodVTableOffset");
228-
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
229-
mc->recGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
229+
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative, isRelativeAfterIndirection);
230+
mc->recGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative, isRelativeAfterIndirection);
230231
}
231232

232233
// Find the virtual method in implementingClass that overrides virtualMethod.

src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,15 @@ CORINFO_MODULE_HANDLE interceptor_ICJI::getMethodModule(CORINFO_METHOD_HANDLE me
143143

144144
// This function returns the offset of the specified method in the
145145
// vtable of it's owning class or interface.
146-
void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
147-
unsigned* offsetOfIndirection, /* OUT */
148-
unsigned* offsetAfterIndirection, /* OUT */
149-
bool* isRelative /* OUT */
146+
void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
147+
unsigned* offsetOfIndirection, /* OUT */
148+
unsigned* offsetAfterIndirection, /* OUT */
149+
bool* isRelative, /* OUT */
150+
bool* isRelativeAfterIndirection /* OUT */
150151
)
151152
{
152153
mcs->AddCall("getMethodVTableOffset");
153-
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
154+
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative, isRelativeAfterIndirection);
154155
}
155156

156157
// Find the virtual method in implementingClass that overrides virtualMethod.

src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,14 @@ CORINFO_MODULE_HANDLE interceptor_ICJI::getMethodModule(CORINFO_METHOD_HANDLE me
132132

133133
// This function returns the offset of the specified method in the
134134
// vtable of it's owning class or interface.
135-
void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
136-
unsigned* offsetOfIndirection, /* OUT */
137-
unsigned* offsetAfterIndirection, /* OUT */
138-
bool* isRelative /* OUT */
135+
void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
136+
unsigned* offsetOfIndirection, /* OUT */
137+
unsigned* offsetAfterIndirection, /* OUT */
138+
bool* isRelative, /* OUT */
139+
bool* isRelativeAfterIndirection /* OUT */
139140
)
140141
{
141-
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
142+
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative, isRelativeAfterIndirection);
142143
}
143144

144145
// Get the unboxed entry point for a method, if possible.

src/ToolBox/superpmi/superpmi/icorjitinfo.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,15 @@ CORINFO_MODULE_HANDLE MyICJI::getMethodModule(CORINFO_METHOD_HANDLE method)
163163

164164
// This function returns the offset of the specified method in the
165165
// vtable of it's owning class or interface.
166-
void MyICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
167-
unsigned* offsetOfIndirection, /* OUT */
168-
unsigned* offsetAfterIndirection, /* OUT */
169-
bool* isRelative /* OUT */
166+
void MyICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
167+
unsigned* offsetOfIndirection, /* OUT */
168+
unsigned* offsetAfterIndirection, /* OUT */
169+
bool* isRelative, /* OUT */
170+
bool* isRelativeAfterIndirection /* OUT */
170171
)
171172
{
172173
jitInstance->mc->cr->AddCall("getMethodVTableOffset");
173-
jitInstance->mc->repGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
174+
jitInstance->mc->repGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative, isRelativeAfterIndirection);
174175
}
175176

176177
// Find the virtual method in implementingClass that overrides virtualMethod.

src/debug/daccess/nidump.cpp

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5907,7 +5907,9 @@ void NativeImageDumper::DumpTypes(PTR_Module module)
59075907

59085908
for (COUNT_T i = 0; i < slotChunkCount; ++i)
59095909
{
5910-
DumpMethodTableSlotChunk(m_discoveredSlotChunks[i].addr, m_discoveredSlotChunks[i].nSlots);
5910+
DumpMethodTableSlotChunk(m_discoveredSlotChunks[i].addr,
5911+
m_discoveredSlotChunks[i].nSlots,
5912+
m_discoveredSlotChunks[i].isRelative);
59115913
}
59125914
}
59135915
DisplayEndArray( "Total MethodTableSlotChunks", METHODTABLES );
@@ -7172,8 +7174,9 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name,
71727174
while (itIndirect.Next())
71737175
{
71747176
SlotChunk sc;
7175-
sc.addr = itIndirect.GetIndirectionSlot();
7177+
sc.addr = dac_cast<TADDR>(itIndirect.GetIndirectionSlot());
71767178
sc.nSlots = (WORD)itIndirect.GetNumSlots();
7179+
sc.isRelative = MethodTable::VTableIndir2_t::isRelative;
71777180
m_discoveredSlotChunks.AppendEx(sc);
71787181
}
71797182

@@ -7185,7 +7188,7 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name,
71857188
DisplayStartElement( "Slot", ALWAYS );
71867189
DisplayWriteElementInt( "Index", i, ALWAYS );
71877190
TADDR base = dac_cast<TADDR>(&(mt->GetVtableIndirections()[i]));
7188-
PTR_PCODE tgt = MethodTable::VTableIndir_t::GetValueMaybeNullAtPtr(base);
7191+
DPTR(MethodTable::VTableIndir2_t) tgt = MethodTable::VTableIndir_t::GetValueMaybeNullAtPtr(base);
71897192
DisplayWriteElementPointer( "Pointer",
71907193
DataPtrToDisplay(dac_cast<TADDR>(tgt)),
71917194
ALWAYS );
@@ -7207,8 +7210,9 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name,
72077210
DisplayEndElement( ALWAYS ); //Slot
72087211

72097212
SlotChunk sc;
7210-
sc.addr = tgt;
7213+
sc.addr = dac_cast<TADDR>(tgt);
72117214
sc.nSlots = (mt->GetNumVtableSlots() - mt->GetNumVirtuals());
7215+
sc.isRelative = false;
72127216
m_discoveredSlotChunks.AppendEx(sc);
72137217
}
72147218
else if (mt->HasSingleNonVirtualSlot())
@@ -7344,25 +7348,42 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name,
73447348
#endif
73457349

73467350
void
7347-
NativeImageDumper::DumpMethodTableSlotChunk( PTR_PCODE slotChunk, COUNT_T numSlots )
7351+
NativeImageDumper::DumpMethodTableSlotChunk( TADDR slotChunk, COUNT_T numSlots, bool isRelative )
73487352
{
73497353
IF_OPT( METHODTABLES )
73507354
{
7351-
DisplayStartStructure( "MethodTableSlotChunk", DPtrToPreferredAddr(slotChunk), numSlots * sizeof(PCODE),
7352-
METHODTABLES );
7355+
COUNT_T slotsSize;
7356+
if (isRelative)
7357+
{
7358+
slotsSize = numSlots * sizeof(RelativePointer<PCODE>);
7359+
}
7360+
else
7361+
{
7362+
slotsSize = numSlots * sizeof(PCODE);
7363+
}
7364+
DisplayStartStructure( "MethodTableSlotChunk", DataPtrToDisplay(slotChunk), slotsSize, METHODTABLES );
73537365

73547366
IF_OPT(VERBOSE_TYPES)
73557367
{
73567368
DisplayStartList( W("[%-4s]: %s (%s)"), ALWAYS );
73577369
for( unsigned i = 0; i < numSlots; ++i )
73587370
{
7359-
DumpSlot(i, slotChunk[i]);
7371+
PCODE target;
7372+
if (isRelative)
7373+
{
7374+
target = RelativePointer<PCODE>::GetValueMaybeNullAtPtr(slotChunk + i * sizeof(RelativePointer<PCODE>));
7375+
}
7376+
else
7377+
{
7378+
target = dac_cast<PTR_PCODE>(slotChunk)[i];
7379+
}
7380+
7381+
DumpSlot(i, target);
73607382
}
73617383
DisplayEndList( ALWAYS ); //Slot list
73627384
}
73637385
else
7364-
CoverageRead( PTR_TO_TADDR(slotChunk),
7365-
numSlots * sizeof(PCODE) );
7386+
CoverageRead( slotChunk, slotsSize );
73667387
DisplayEndStructure(ALWAYS); //Slot chunk
73677388
}
73687389
}
@@ -7735,7 +7756,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
77357756
}
77367757
if ( md->HasNonVtableSlot() )
77377758
{
7738-
DisplayWriteElementInt( "Slot", (DWORD)(PTR_TO_TADDR(md->GetAddrOfSlot()) - PTR_TO_TADDR(md)), ALWAYS);
7759+
DisplayWriteElementInt( "Slot", (DWORD)(md->GetAddrOfSlot() - PTR_TO_TADDR(md)), ALWAYS);
77397760
}
77407761
if (md->HasNativeCodeSlot())
77417762
{

0 commit comments

Comments
 (0)