void getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
unsigned* offsetOfIndirection, /* OUT */
unsigned* offsetAfterIndirection,/* OUT */
- unsigned* isRelative /* OUT */
+ bool* isRelative /* OUT */
);
// Find the virtual method in implementingClass that overrides virtualMethod.
void MethodContext::recGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
unsigned* offsetOfIndirection,
unsigned* offsetAfterIndirection,
- unsigned* isRelative)
+ bool* isRelative)
{
if (GetMethodVTableOffset == nullptr)
GetMethodVTableOffset = new LightWeightMap<DWORDLONG, DDD>();
DDD value;
value.A = (DWORD)*offsetOfIndirection;
value.B = (DWORD)*offsetAfterIndirection;
- value.C = (DWORD)*isRelative;
+ value.C = *isRelative;
GetMethodVTableOffset->Add((DWORDLONG)method, value);
DEBUG_REC(dmpGetMethodVTableOffset((DWORDLONG)method, value));
}
void MethodContext::dmpGetMethodVTableOffset(DWORDLONG key, DDD value)
{
- printf("GetMethodVTableOffset key ftn-%016llX, value offi-%u, offa-%u", key, value.A, value.B);
+ printf("GetMethodVTableOffset key ftn-%016llX, value offi-%u, offa-%u. offr-%d", key, value.A, value.B, value.C);
}
void MethodContext::repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
unsigned* offsetOfIndirection,
unsigned* offsetAfterIndirection,
- unsigned* isRelative)
+ bool* isRelative)
{
DDD value;
*offsetOfIndirection = (unsigned)value.A;
*offsetAfterIndirection = (unsigned)value.B;
- *isRelative = (unsigned)value.C;
+ *isRelative = value.C;
DEBUG_REP(dmpGetMethodVTableOffset((DWORDLONG)method, value));
}
{
DWORD A;
DWORD B;
- DWORD C;
+ bool C;
};
struct Agnostic_CanTailCall
{
void recGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
unsigned* offsetOfIndirection,
unsigned* offsetAfterIndirection,
- unsigned* isRelative);
+ bool* isRelative);
void dmpGetMethodVTableOffset(DWORDLONG key, DDD value);
void repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
unsigned* offsetOfIndirection,
unsigned* offsetAfterIndirection,
- unsigned* isRelative);
+ bool* isRelative);
void recResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod,
CORINFO_CLASS_HANDLE implClass,
void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
unsigned* offsetOfIndirection, /* OUT */
unsigned* offsetAfterIndirection,/* OUT */
- unsigned* isRelative /* OUT */
+ bool* isRelative /* OUT */
)
{
mc->cr->AddCall("getMethodVTableOffset");
void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
unsigned* offsetOfIndirection, /* OUT */
unsigned* offsetAfterIndirection,/* OUT */
- unsigned* isRelative /* OUT */
+ bool* isRelative /* OUT */
)
{
mcs->AddCall("getMethodVTableOffset");
void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
unsigned* offsetOfIndirection, /* OUT */
unsigned* offsetAfterIndirection,/* OUT */
- unsigned* isRelative /* OUT */
+ bool* isRelative /* OUT */
)
{
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
void MyICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
unsigned* offsetOfIndirection, /* OUT */
unsigned* offsetAfterIndirection,/* OUT */
- unsigned* isRelative /* OUT */
+ bool* isRelative /* OUT */
)
{
jitInstance->mc->cr->AddCall("getMethodVTableOffset");
CORINFO_METHOD_HANDLE method, /* IN */
unsigned* offsetOfIndirection, /* OUT */
unsigned* offsetAfterIndirection, /* OUT */
- unsigned* isRelative /* OUT */
+ bool* isRelative /* OUT */
) = 0;
// Find the virtual method in implementingClass that overrides virtualMethod,
CORINFO_METHOD_HANDLE method, /* IN */
unsigned* offsetOfIndirection, /* OUT */
unsigned* offsetAfterIndirection, /* OUT */
- unsigned* isRelative /* OUT */)
+ bool* isRelative /* OUT */)
{
API_ENTER(getMethodVTableOffset);
wrapHnd->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
regMaskTP vptrMask1;
unsigned vtabOffsOfIndirection;
unsigned vtabOffsAfterIndirection;
- unsigned isRelative;
+ bool isRelative;
noway_assert(callType == CT_USER_FUNC);
// ADD vptrReg1, REG_CALL_IND_SCRATCH, vtabOffsOfIndirection + vtabOffsAfterIndirection
getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, vptrReg1, vptrReg, offset);
#else
- _ASSERTE(false);
+ unreached();
#endif
}
}
else
{
- _ASSERTE(!isRelative);
+ assert(!isRelative);
}
/* Call through the appropriate vtable slot */
getEmitter()->emitIns_R_ARR(ins_Load(TYP_I_IMPL), EA_PTRSIZE, REG_TAILCALL_ADDR, vptrReg1,
vptrReg, 0);
#else
- _ASSERTE(false);
+ unreached();
#endif
}
else
gcInfo.gcRegByrefSetCur, ilOffset,
vptrReg); // ireg
#else
- _ASSERTE(!isRelative);
+ assert(!isRelative);
getEmitter()->emitIns_Call(emitter::EC_FUNC_VIRTUAL, call->gtCallMethHnd,
INDEBUG_LDISASM_COMMA(sigInfo) NULL, // addr
args, retSize, gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
fmt = IF_T2_M0;
sf = INS_FLAGS_NOT_SET;
}
- else if (insDoesNotSetFlags(flags) && reg1 != REG_SP && reg1 != REG_PC)
+ else if (insDoesNotSetFlags(flags) && (reg1 != REG_SP) && (reg1 != REG_PC))
{
// movw,movt reg1, imm
- codeGen->instGen_Set_Reg_To_Imm(attr, reg1, imm);
+ codeGen->instGen_Set_Reg_To_Imm(attr, reg1, (ins == INS_sub ? -1 : 1) * imm);
// ins reg1, reg2
- emitIns_R_R(ins, attr, reg1, reg2);
+ emitIns_R_R(INS_add, attr, reg1, reg2);
return;
}
// Get hold of the vtable offset (note: this might be expensive)
unsigned vtabOffsOfIndirection;
unsigned vtabOffsAfterIndirection;
- unsigned isRelative;
+ bool isRelative;
comp->info.compCompHnd->getMethodVTableOffset(call->gtCallMethHnd, &vtabOffsOfIndirection,
&vtabOffsAfterIndirection, &isRelative);
{
if (isRelative)
{
+ // MethodTable offset is a relative pointer.
+ //
+ // Additional temporary variable is used to store virtual table pointer.
+ // Address of method is obtained by the next computations:
+ //
+ // Save relative offset to tmp (vtab is virtual table pointer, vtabOffsOfIndirection is offset of
+ // vtable-1st-level-indirection):
+ // tmp = [vtab + vtabOffsOfIndirection]
+ //
+ // Save address of method to result (vtabOffsAfterIndirection is offset of vtable-2nd-level-indirection):
+ // result = [vtab + vtabOffsOfIndirection + vtabOffsAfterIndirection + tmp]
unsigned lclNumTmp = comp->lvaGrabTemp(true DEBUGARG("lclNumTmp"));
comp->lvaTable[lclNumTmp].incRefCnts(comp->compCurBB->getBBWeight(comp), comp);
GenTree* lclvNodeStore = comp->gtNewTempAssign(lclNumTmp, result);
LIR::Range range = LIR::SeqTree(comp, lclvNodeStore);
- JITDUMP("results of lowering call interm:\n");
+ JITDUMP("result of obtaining pointer to virtual table:\n");
DISPRANGE(range);
BlockRange().InsertBefore(call, std::move(range));
}
else
{
- _ASSERTE(!isRelative);
+ assert(!isRelative);
}
// Load the function address
unsigned vtabOffsOfIndirection;
unsigned vtabOffsAfterIndirection;
- unsigned isRelative;
+ bool isRelative;
info.compCompHnd->getMethodVTableOffset(call->gtCallMethHnd, &vtabOffsOfIndirection, &vtabOffsAfterIndirection,
&isRelative);
void CEEInfo::getMethodVTableOffset (CORINFO_METHOD_HANDLE methodHnd,
unsigned * pOffsetOfIndirection,
unsigned * pOffsetAfterIndirection,
- unsigned * isRelative)
+ bool * isRelative)
{
CONTRACTL {
SO_TOLERANT;
CORINFO_METHOD_HANDLE methodHnd,
unsigned * pOffsetOfIndirection,
unsigned * pOffsetAfterIndirection,
- unsigned * isRelative);
+ bool * isRelative);
CORINFO_METHOD_HANDLE resolveVirtualMethod(
CORINFO_METHOD_HANDLE virtualMethod,
void ZapInfo::getMethodVTableOffset(CORINFO_METHOD_HANDLE method,
unsigned * pOffsetOfIndirection,
unsigned * pOffsetAfterIndirection,
- unsigned * isRelative)
+ bool * isRelative)
{
m_pEEJitInfo->getMethodVTableOffset(method, pOffsetOfIndirection, pOffsetAfterIndirection, isRelative);
}
void getMethodVTableOffset(CORINFO_METHOD_HANDLE method,
unsigned * pOffsetOfIndirection,
unsigned * pOffsetAfterIndirection,
- unsigned * isRelative);
+ bool * isRelative);
CORINFO_METHOD_HANDLE resolveVirtualMethod(
CORINFO_METHOD_HANDLE virtualMethod,