Changed lookupIR in targetcache.cpp to not require a VMRegAnchor

Updated lookupIR functions in StaticMethodCache and StaticMethodFCache
to accept the FP as an argument.
Esse commit está contido em:
Paul Bissonnette
2013-06-10 12:52:54 -07:00
commit de Sara Golemon
commit c6ca429a5e
9 arquivos alterados com 52 adições e 50 exclusões
+6 -2
Ver Arquivo
@@ -782,14 +782,15 @@ D:T = LookupClsCns<T,className,constName>
undefined constant error if autoload cannot define the constant.
D:FuncCtx = LdClsMethodFCache S0:ConstStr S1:ConstStr
S2:{Obj|Cls|Ctx} L:Label
S2:{Obj|Cls|Ctx} S3:FramePtr L:Label
Loads from the MethodFCache a pointer to the callee function and the
context (ActRec's m_this/m_cls slot) into D. S0 and S1 hold the
names of the callee's class and method, respectively. S2 is the
current context. This instruction loads the corresponding entry in
the MethodFCache if needed. In case the given method is not found,
control is transferred to label L.
control is transferred to label L. The current frame pointer is
passed in S3.
D:Ctx = GetCtxFwdCall S0:Ctx S1:Func
@@ -798,6 +799,7 @@ D:Ctx = GetCtxFwdCall S0:Ctx S1:Func
S0 and returns it. If S0 is a Cctx, this opcode returns S0.
D:FuncCls = LdClsMethodCache S0:ConstStr S1:ConstStr S2:ConstNamedEntity*
S3:FramePtr S4:StkPtr
Lookup a function and class in the class method targetcache. The
sources to this instruction are:
@@ -805,6 +807,8 @@ D:FuncCls = LdClsMethodCache S0:ConstStr S1:ConstStr S2:ConstNamedEntity*
S0 - class name
S1 - method name
S2 - the NamedEntity* for the class
S3 - the current frame pointer
S4 - the current stack pointer
D:Func = LdClsMethod S0:Cls S1:ConstInt
+1
Ver Arquivo
@@ -530,6 +530,7 @@ public:
const HPHP::Class* cls,
const StringData* methodName,
ObjectData* this_,
ActRec* vmfp,
bool raise = false);
MethodLookup::LookupResult lookupCtorMethod(const HPHP::Func*& f,
const HPHP::Class* cls,
+3 -2
Ver Arquivo
@@ -1108,8 +1108,9 @@ VMExecutionContext::lookupClsMethod(const Func*& f,
const Class* cls,
const StringData* methodName,
ObjectData* obj,
ActRec* vmfp,
bool raise /* = false */) {
Class* ctx = arGetContextClass(getFP());
Class* ctx = arGetContextClass(vmfp);
f = lookupMethodCtx(cls, methodName, ctx, ClsMethod, false);
if (!f) {
if (obj && obj->instanceof(cls)) {
@@ -5347,7 +5348,7 @@ void VMExecutionContext::pushClsMethodImpl(Class* cls,
ObjectData* obj,
int numArgs) {
const Func* f;
LookupResult res = lookupClsMethod(f, cls, name, obj, true);
LookupResult res = lookupClsMethod(f, cls, name, obj, getFP(), true);
if (res == MethodFoundNoThis || res == MagicCallStaticFound) {
obj = nullptr;
} else {
+17 -8
Ver Arquivo
@@ -4367,6 +4367,8 @@ void CodeGenerator::cgLdClsMethodCache(IRInstruction* inst) {
SSATmp* className = inst->src(0);
SSATmp* methodName = inst->src(1);
SSATmp* baseClass = inst->src(2);
SSATmp* fp = inst->src(3);
SSATmp* sp = inst->src(4);
Block* label = inst->taken();
// Stats::emitInc(a, Stats::TgtCache_StaticMethodHit);
@@ -4391,17 +4393,22 @@ void CodeGenerator::cgLdClsMethodCache(IRInstruction* inst) {
// handle case where method is not entered in the cache
unlikelyIfBlock(CC_E, [&] (Asm& a) {
if (false) { // typecheck
const UNUSED Func* f = StaticMethodCache::lookupIR(ch, ne, cls, method);
UNUSED TypedValue* fake_fp = nullptr;
UNUSED TypedValue* fake_sp = nullptr;
const UNUSED Func* f = StaticMethodCache::lookupIR(ch, ne, cls, method,
fake_fp, fake_sp);
}
// can raise an error if class is undefined
cgCallHelper(a,
(TCA)StaticMethodCache::lookupIR,
funcDestReg,
kSyncPoint,
ArgGroup(m_regs).imm(ch) // Handle ch
.immPtr(ne) // NamedEntity* np.second
.immPtr(cls) // className
.immPtr(method) // methodName
ArgGroup(m_regs).imm(ch) // Handle ch
.immPtr(ne) // NamedEntity* np.second
.immPtr(cls) // className
.immPtr(method) // methodName
.reg(m_regs[fp].reg()) // frame pointer
.reg(m_regs[sp].reg()) // stack pointer
);
// recordInstrCall is done in cgCallHelper
a.testq(funcDestReg, funcDestReg);
@@ -4487,6 +4494,7 @@ void CodeGenerator::cgLdClsMethodFCache(IRInstruction* inst) {
const Class* cls = inst->src(0)->getValClass();
const StringData* methName = inst->src(1)->getValStr();
SSATmp* srcCtxTmp = inst->src(2);
SSATmp* fp = inst->src(3);
PhysReg srcCtxReg = m_regs[srcCtxTmp].reg(0);
Block* exitLabel = inst->taken();
const StringData* clsName = cls->name();
@@ -4502,8 +4510,8 @@ void CodeGenerator::cgLdClsMethodFCache(IRInstruction* inst) {
// Handle case where method is not entered in the cache
unlikelyIfBlock(CC_E, [&] (Asm& a) {
const Func* (*lookup)(CacheHandle, const Class*, const StringData*) =
StaticMethodFCache::lookupIR;
const Func* (*lookup)(CacheHandle, const Class*,
const StringData*, TypedValue*) = StaticMethodFCache::lookupIR;
// preserve destCtxReg across the call since it wouldn't be otherwise
RegSet toSave = m_state.liveRegs[inst] | RegSet(destCtxReg);
cgCallHelper(a, Transl::CppCall((TCA)lookup),
@@ -4511,7 +4519,8 @@ void CodeGenerator::cgLdClsMethodFCache(IRInstruction* inst) {
kSyncPoint,
ArgGroup(m_regs).imm(ch)
.immPtr(cls)
.immPtr(methName),
.immPtr(methName)
.reg(m_regs[fp].reg()),
toSave);
// If entry found in target cache, jump back to m_as.
// Otherwise, bail to exit label
+6 -2
Ver Arquivo
@@ -1947,13 +1947,16 @@ void HhbcTranslator::emitFPushClsMethodD(int32_t numParams,
func && magicCall ? methodName : nullptr);
} else {
// lookup static method & class in the target cache
SSATmp* stack = spillStack();
IRTrace* exitTrace = getExitSlowTrace();
SSATmp* funcClassTmp =
gen(LdClsMethodCache,
exitTrace,
cns(className),
cns(methodName),
cns(np.second));
cns(np.second),
m_tb->fp(),
stack);
emitFPushActRec(funcClassTmp,
m_tb->genDefInitNull(),
numParams,
@@ -1988,7 +1991,8 @@ void HhbcTranslator::emitFPushClsMethodF(int32_t numParams,
SSATmp* funcCtxTmp = gen(LdClsMethodFCache, exitBlock,
cns(cls),
cns(methName),
curCtxTmp);
curCtxTmp,
m_tb->fp());
emitFPushActRec(funcCtxTmp,
m_tb->genDefInitNull(),
numParams,
+7 -2
Ver Arquivo
@@ -308,8 +308,13 @@ O(LdCns, DParam, CStr, NF) \
O(LookupCns, DParam, CStr, E|Refs|Er|N|Mem) \
O(LdClsMethodCache, D(FuncCls), C(Str) \
C(Str) \
C(NamedEntity), N|C|E|Refs|Er|Mem) \
O(LdClsMethodFCache, D(FuncCtx), C(Cls) CStr S(Obj,Cls,Ctx), N|C|E|Er) \
C(NamedEntity) \
S(FramePtr) \
S(StkPtr), N|C|E|Refs|Er|Mem) \
O(LdClsMethodFCache, D(FuncCtx), C(Cls) \
CStr \
S(Obj,Cls,Ctx) \
S(FramePtr), N|C|E|Er) \
O(GetCtxFwdCall, D(Ctx), S(Ctx) S(Func), C) \
O(LdClsMethod, D(Func), S(Cls) C(Int), C) \
O(LdPropAddr, D(PtrToGen), S(Obj) C(Int), C) \
+7 -29
Ver Arquivo
@@ -1008,16 +1008,16 @@ StaticMethodFCache::alloc(const StringData* clsName,
const Func*
StaticMethodCache::lookupIR(Handle handle, const NamedEntity *ne,
const StringData* clsName,
const StringData* methName) {
const StringData* methName, TypedValue* vmfp,
TypedValue* vmsp) {
StaticMethodCache* thiz = static_cast<StaticMethodCache*>
(handleToPtr(handle));
Stats::inc(Stats::TgtCache_StaticMethodMiss);
Stats::inc(Stats::TgtCache_StaticMethodHit, -1);
TRACE(1, "miss %s :: %s caller %p\n",
clsName->data(), methName->data(), __builtin_return_address(0));
VMRegAnchor _; // needed for lookupClsMethod.
ActRec* ar = reinterpret_cast<ActRec*>(vmsp() - kNumActRecCells);
ActRec* ar = reinterpret_cast<ActRec*>(vmsp - kNumActRecCells);
const Func* f;
VMExecutionContext* ec = g_vmContext;
const Class* cls = Unit::loadClass(ne, clsName);
@@ -1028,6 +1028,7 @@ StaticMethodCache::lookupIR(Handle handle, const NamedEntity *ne,
nullptr, // there may be an active this,
// but we can just fall through
// in that case.
(ActRec*)vmfp,
false /*raise*/);
if (LIKELY(res == MethodFoundNoThis &&
!f->isAbstract() &&
@@ -1042,9 +1043,6 @@ StaticMethodCache::lookupIR(Handle handle, const NamedEntity *ne,
return f;
}
assert(res != MethodFoundWithThis); // Not possible: no this supplied.
// We've already sync'ed regs; this is some hard case, we might as well
// just let the interpreter handle this entirely.
assert(*vmpc() == OpFPushClsMethodD);
// Indicate to the IR that it should take even slower path
return nullptr;
@@ -1073,6 +1071,7 @@ StaticMethodCache::lookup(Handle handle, const NamedEntity *ne,
nullptr, // there may be an active this,
// but we can just fall through
// in that case.
ec->getFP(),
false /*raise*/);
if (LIKELY(res == MethodFoundNoThis &&
!f->isAbstract() &&
@@ -1106,18 +1105,18 @@ StaticMethodCache::lookup(Handle handle, const NamedEntity *ne,
const Func*
StaticMethodFCache::lookupIR(Handle handle, const Class* cls,
const StringData* methName) {
const StringData* methName, TypedValue* vmfp) {
assert(cls);
StaticMethodFCache* thiz = static_cast<StaticMethodFCache*>
(handleToPtr(handle));
Stats::inc(Stats::TgtCache_StaticMethodFMiss);
Stats::inc(Stats::TgtCache_StaticMethodFHit, -1);
VMRegAnchor _; // needed for lookupClsMethod.
const Func* f;
VMExecutionContext* ec = g_vmContext;
LookupResult res = ec->lookupClsMethod(f, cls, methName,
nullptr,
(ActRec*)vmfp,
false /*raise*/);
assert(res != MethodFoundWithThis); // Not possible: no this supplied.
if (LIKELY(res == MethodFoundNoThis && !f->isAbstract())) {
@@ -1143,25 +1142,4 @@ StaticMethodFCache::lookupIR(Handle handle, const Class* cls,
return nullptr;
}
const Func*
StaticMethodFCache::lookup(Handle handle, const Class* cls,
const StringData* methName) {
const Func* f = lookupIR(handle, cls, methName);
if (f) return f;
VMRegAnchor _; // needed for opFPushClsMethodF
// We've already sync'ed regs; this is some hard case, we might as well
// just let the interpreter handle this entirely.
assert(*vmpc() == OpFPushClsMethodF);
Stats::inc(Stats::Instr_TC, -1);
Stats::inc(Stats::Instr_InterpOneFPushClsMethodF);
g_vmContext->opFPushClsMethodF();
// We already did all the work so tell our caller to do nothing.
TRACE(1, "miss staticfcache %s :: %s -> intractable null\n",
cls->name()->data(), methName->data());
return nullptr;
}
} } } // HPHP::Transl::TargetCache
+3 -4
Ver Arquivo
@@ -243,7 +243,8 @@ struct StaticMethodCache {
const char* ctxName);
static const Func* lookupIR(CacheHandle chand,
const NamedEntity* ne, const StringData* cls,
const StringData* meth);
const StringData* meth, TypedValue* vmfp,
TypedValue* vmsp);
static const Func* lookup(CacheHandle chand,
const NamedEntity* ne, const StringData* cls,
const StringData* meth);
@@ -255,10 +256,8 @@ struct StaticMethodFCache {
static CacheHandle alloc(const StringData* cls, const StringData* meth,
const char* ctxName);
static const Func* lookup(CacheHandle chand, const Class* cls,
const StringData* meth);
static const Func* lookupIR(CacheHandle chand, const Class* cls,
const StringData* meth);
const StringData* meth, TypedValue* vmfp);
};
typedef Cache<const StringData*, const Func*, StringData*, NSDynFunction>
+2 -1
Ver Arquivo
@@ -4077,7 +4077,8 @@ const Func* lookupImmutableMethod(const Class* cls, const StringData* name,
const Func* func;
MethodLookup::LookupResult res = staticLookup ?
g_vmContext->lookupClsMethod(func, cls, name, 0, false) :
g_vmContext->lookupClsMethod(func, cls, name, 0,
g_vmContext->getFP(), false) :
g_vmContext->lookupObjMethod(func, cls, name, false);
if (res == MethodLookup::MethodNotFound) return nullptr;