diff --git a/hphp/doc/ir.specification b/hphp/doc/ir.specification index ca9251510..b698cdfb1 100755 --- a/hphp/doc/ir.specification +++ b/hphp/doc/ir.specification @@ -747,11 +747,12 @@ D:Obj = LdThis S0:FramePtr [ -> L ] in S0 is not, this instruction does not load it into D and transfers control to the exit label L. -D:Ctx = LdCtx S0:FramePtr S1:Func +D:Ctx = LdCtx S0:FramePtr Loads into D the value of the m_this/m_cls field out of the frame - pointer S0 in the function given by S1. The result could be either - an object representing the this pointer or a class context. + pointer S0, which must be a frame of the function in the function + parameter. The result could be either an object representing the + this pointer or a class context. D:Cctx = LdCctx S0:FramePtr diff --git a/hphp/runtime/vm/jit/code-gen.cpp b/hphp/runtime/vm/jit/code-gen.cpp index fdc83df53..1d6a54992 100755 --- a/hphp/runtime/vm/jit/code-gen.cpp +++ b/hphp/runtime/vm/jit/code-gen.cpp @@ -4029,8 +4029,8 @@ void CodeGenerator::cgLdClsCctx(IRInstruction* inst) { } void CodeGenerator::cgLdCtx(IRInstruction* inst) { - PhysReg dstReg = m_regs[inst->dst()].reg(); - PhysReg srcReg = m_regs[inst->src(0)].reg(); + auto const dstReg = m_regs[inst->dst()].reg(); + auto const srcReg = m_regs[inst->src(0)].reg(); if (dstReg != InvalidReg) { m_as.loadq(srcReg[AROFF(m_this)], dstReg); } diff --git a/hphp/runtime/vm/jit/extra-data.h b/hphp/runtime/vm/jit/extra-data.h index ef56d413a..f46cc5f75 100644 --- a/hphp/runtime/vm/jit/extra-data.h +++ b/hphp/runtime/vm/jit/extra-data.h @@ -140,6 +140,18 @@ struct ClassData : IRExtraData { const Class* cls; }; +struct FuncData : IRExtraData { + explicit FuncData(const Func* func) : func(func) {} + + bool cseEquals(FuncData o) const { return func == o.func; } + size_t cseHash() const { return std::hash()(func); } + std::string show() const { + return folly::to(func->fullName()->data()); + } + + const Func* func; +}; + struct FPushCufData : IRExtraData { FPushCufData(uint32_t a, int32_t id) : args(a), iterId(id) @@ -368,6 +380,7 @@ X(MIterFree, IterId); X(CIterFree, IterId); X(DecodeCufIter, IterId); X(AllocObjFast, ClassData); +X(LdCtx, FuncData); X(CufIterSpillFrame, FPushCufData); X(DefConst, ConstData); X(LdConst, ConstData); diff --git a/hphp/runtime/vm/jit/hhbc-translator.cpp b/hphp/runtime/vm/jit/hhbc-translator.cpp index a896389b0..58050c72c 100755 --- a/hphp/runtime/vm/jit/hhbc-translator.cpp +++ b/hphp/runtime/vm/jit/hhbc-translator.cpp @@ -601,7 +601,7 @@ void HhbcTranslator::emitLateBoundCls() { emitInterpOne(Type::Cls, 0); return; } - auto const ctx = gen(LdCtx, m_tb->fp(), cns(curFunc())); + auto const ctx = gen(LdCtx, FuncData(curFunc()), m_tb->fp()); push(gen(LdClsCtx, ctx)); } @@ -1153,7 +1153,7 @@ void HhbcTranslator::emitCreateCont(Id funNameStrId) { ? gen( CreateContMeth, CreateContData { origFunc, genFunc }, - gen(LdCtx, m_tb->fp(), cns(curFunc())) + gen(LdCtx, FuncData(curFunc()), m_tb->fp()) ) : gen( CreateContFunc, @@ -1755,7 +1755,6 @@ void HhbcTranslator::emitFPushCufIter(int32_t numParams, void HhbcTranslator::emitFPushCufOp(Op op, Class* cls, StringData* invName, const Func* callee, int numArgs) { - const Func* curFunc = this->curFunc(); const bool safe = op == OpFPushCufSafe; const bool forward = op == OpFPushCufF; @@ -1775,7 +1774,7 @@ void HhbcTranslator::emitFPushCufOp(Op op, Class* cls, StringData* invName, SSATmp* func = cns(callee); if (cls) { if (forward) { - ctx = gen(LdCtx, m_tb->fp(), cns(curFunc)); + ctx = gen(LdCtx, FuncData(curFunc()), m_tb->fp()); ctx = gen(GetCtxFwdCall, ctx, cns(callee)); } else { ctx = genClsMethodCtx(callee, cls); @@ -2175,7 +2174,7 @@ void HhbcTranslator::emitFPushClsMethodF(int32_t numParams, bool magicCall = false; const Func* func = lookupImmutableMethod(cls, methName, magicCall, true /* staticLookup */); - SSATmp* curCtxTmp = gen(LdCtx, m_tb->fp(), cns(curFunc())); + SSATmp* curCtxTmp = gen(LdCtx, FuncData(curFunc()), m_tb->fp()); if (func) { SSATmp* funcTmp = cns(func); SSATmp* newCtxTmp = gen(GetCtxFwdCall, curCtxTmp, funcTmp); diff --git a/hphp/runtime/vm/jit/ir.h b/hphp/runtime/vm/jit/ir.h index 1f55f8295..345074e33 100755 --- a/hphp/runtime/vm/jit/ir.h +++ b/hphp/runtime/vm/jit/ir.h @@ -332,7 +332,7 @@ O(LdThis, D(Obj), S(FramePtr), C) \ O(LdRetAddr, D(RetAddr), S(FramePtr), NF) \ O(LdConst, DParam, NA, C) \ O(DefConst, DParam, NA, C) \ -O(LdCtx, D(Ctx), S(FramePtr) S(Func), C) \ +O(LdCtx, D(Ctx), S(FramePtr), C) \ O(LdCctx, D(Cctx), S(FramePtr), C) \ O(LdCls, D(Cls), S(Str) C(Cls), C|E|N|Refs|Er|Mem) \ O(LdClsCached, D(Cls), CStr, C|E|N|Refs|Er|Mem) \ diff --git a/hphp/runtime/vm/jit/simplifier.cpp b/hphp/runtime/vm/jit/simplifier.cpp index 788d25634..b8884f1ad 100644 --- a/hphp/runtime/vm/jit/simplifier.cpp +++ b/hphp/runtime/vm/jit/simplifier.cpp @@ -473,7 +473,7 @@ SSATmp* Simplifier::simplifyExitOnVarEnv(IRInstruction* inst) { } SSATmp* Simplifier::simplifyLdCtx(IRInstruction* inst) { - const Func* func = inst->src(1)->getValFunc(); + auto const func = inst->extra()->func; if (func->isStatic()) { // ActRec->m_cls of a static function is always a valid class pointer with // the bottom bit set