From b3bcab18be1bfced216b8f6db748b5522e716b5e Mon Sep 17 00:00:00 2001 From: aravind Date: Tue, 7 May 2013 17:44:15 -0700 Subject: [PATCH] Inline FPushCtor Similar to FPushCtorD --- hphp/doc/ir.specification | 11 +---- hphp/runtime/vm/translator/annotation.cpp | 9 +++- hphp/runtime/vm/translator/hopt/codegen.cpp | 43 +------------------ hphp/runtime/vm/translator/hopt/codegen.h | 5 --- .../vm/translator/hopt/hhbctranslator.cpp | 34 ++++++++------- .../vm/translator/hopt/hhbctranslator.h | 1 + hphp/runtime/vm/translator/hopt/ir.h | 4 -- .../runtime/vm/translator/hopt/linearscan.cpp | 1 - .../vm/translator/hopt/nativecalls.cpp | 4 +- .../runtime/vm/translator/hopt/simplifier.cpp | 11 ----- .../vm/translator/hopt/tracebuilder.cpp | 6 --- hphp/runtime/vm/translator/translator.cpp | 2 +- 12 files changed, 32 insertions(+), 99 deletions(-) diff --git a/hphp/doc/ir.specification b/hphp/doc/ir.specification index 2740f0a0f..ab290904f 100644 --- a/hphp/doc/ir.specification +++ b/hphp/doc/ir.specification @@ -817,18 +817,9 @@ D:BoxedCell = LdStaticLocCached S0:ConstCacheHandle -> L 8. Allocation -D:StkPtr = NewObj S0:ConstInt S1:Cls S2:StkPtr S3:FramePtr - - Allocate a new object. Push a Cell pointing to the object and an - ActRec for the constructor onto the stack and return the new SP. - S0 is the number of parameters for the constructor - S1 is the class of the object - S2 is the current stack pointer - S3 is the frame pointer of the current ActRec - D:Obj = AllocObj S1:Cls - Allocate a new object of class S1. + Allocates a new object of class S1. NewArray NewTuple diff --git a/hphp/runtime/vm/translator/annotation.cpp b/hphp/runtime/vm/translator/annotation.cpp index cf0e6c191..9a19e70a0 100644 --- a/hphp/runtime/vm/translator/annotation.cpp +++ b/hphp/runtime/vm/translator/annotation.cpp @@ -144,6 +144,7 @@ void annotate(NormalizedInstruction* i) { case OpFPushClsMethodD: case OpFPushClsMethodF: case OpFPushCtorD: + case OpFPushCtor: case OpFPushFuncD: { // When we push predictable action records, we can use a simpler // translation for their corresponding FCall. @@ -170,12 +171,16 @@ void annotate(NormalizedInstruction* i) { } else if (i->op() == OpFPushClsMethodD) { funcName = curUnit()->lookupLitstrId(i->imm[1].u_SA); className = curUnit()->lookupLitstrId(i->imm[2].u_SA); - } else { - assert(i->op() == OpFPushCtorD); + } else if (i->op() == OpFPushCtorD) { className = curUnit()->lookupLitstrId(i->imm[1].u_SA); const Class* cls = Unit::lookupUniqueClass(className); if (!cls) break; funcName = cls->getCtor()->name(); + } else { + assert(i->op() == OpFPushCtor); + const Class* cls = i->inputs[0]->rtt.valueClass(); + if (!cls) break; + funcName = cls->getCtor()->name(); } assert(funcName->isStatic()); recordActRecPush(*i, curUnit(), funcName, className, diff --git a/hphp/runtime/vm/translator/hopt/codegen.cpp b/hphp/runtime/vm/translator/hopt/codegen.cpp index 7d149c5d7..eab71bc43 100644 --- a/hphp/runtime/vm/translator/hopt/codegen.cpp +++ b/hphp/runtime/vm/translator/hopt/codegen.cpp @@ -351,7 +351,7 @@ CALL_OPCODE(CreateCont) CALL_OPCODE(FillContLocals) CALL_OPCODE(NewArray) CALL_OPCODE(NewTuple) -CALL_OPCODE(NewObj) +CALL_OPCODE(AllocObj) CALL_OPCODE(LdClsCtor); CALL_OPCODE(CreateCl) CALL_OPCODE(PrintStr) @@ -3253,53 +3253,12 @@ const Func* loadClassCtor(Class* cls) { return f; } -HOT_FUNC_VM ActRec* -irNewInstanceHelper(Class* cls, - int numArgs, - Cell* sp, - ActRec* prevAr) { - Cell* obj = sp - 1; // this is where the newly allocated object will go - ActRec* ar = (ActRec*)(uintptr_t(obj) - sizeof(ActRec)); - - Instance* newObj = newInstanceHelper(cls, numArgs, ar, prevAr); - // store obj into the stack - obj->m_data.pobj = newObj; - obj->m_type = KindOfObject; - return ar; -} - -static inline ALWAYS_INLINE Class* getKnownClass(Class** classCache, - const StringData* clsName) { - Class* cls = *classCache; - if (UNLIKELY(cls == nullptr)) { - // lookupKnownClass does its own VMRegAnchor'ing. - cls = TargetCache::lookupKnownClass(classCache, clsName, true); - assert(*classCache && *classCache == cls); - } - assert(cls); - return cls; -} - Instance* createClHelper(Class* cls, int numArgs, ActRec* ar, TypedValue* sp) { Instance* newObj = newInstance(cls); newObj->incRefCount(); return static_cast(newObj)->init(numArgs, ar, sp); } -void CodeGenerator::cgAllocObj(IRInstruction* inst) { - SSATmp* dst = inst->getDst(); - SSATmp* cls = inst->getSrc(0); - - Instance* (*helper)(Class*) = newInstance; - ArgGroup args; - args.ssa(cls); - cgCallHelper(m_as, - (TCA)helper, - dst, - kSyncPoint, - args); -} - void CodeGenerator::cgInlineCreateCont(IRInstruction* inst) { auto const& data = *inst->getExtra(); auto const helper = data.origFunc->isMethod() diff --git a/hphp/runtime/vm/translator/hopt/codegen.h b/hphp/runtime/vm/translator/hopt/codegen.h index 272515c94..909110cae 100644 --- a/hphp/runtime/vm/translator/hopt/codegen.h +++ b/hphp/runtime/vm/translator/hopt/codegen.h @@ -528,11 +528,6 @@ private: const Func* loadClassCtor(Class* cls); -ActRec* irNewInstanceHelper(Class* cls, - int numArgs, - Cell* sp, - ActRec* prevAr); - Instance* createClHelper(Class*, int, ActRec*, TypedValue*); void genCodeForTrace(Trace* trace, diff --git a/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp b/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp index 7ac8f696a..29b0b15ff 100644 --- a/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp +++ b/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp @@ -1487,11 +1487,27 @@ void HhbcTranslator::emitFPushActRec(SSATmp* func, assert(m_stackDeficit == 0); } +void HhbcTranslator::emitFPushCtorCommon(SSATmp* cls, + const Func* func, + int32_t numParams) { + SSATmp* obj = gen(IncRef, gen(AllocObj, cls)); + push(obj); + + SSATmp* fn = nullptr; + if (func) { + fn = cns(func); + } else { + fn = gen(LdClsCtor, cls); + } + SSATmp* obj2 = gen(IncRef, obj); + int32_t numArgsAndCtorFlag = numParams | (1 << 31); + emitFPushActRec(fn, obj2, numArgsAndCtorFlag, nullptr); +} + void HhbcTranslator::emitFPushCtor(int32_t numParams) { SSATmp* cls = popA(); exceptionBarrier(); - gen(NewObj, cls, cns(numParams), m_tb->getSp(), m_tb->getFp()); - m_fpiStack.emplace(nullptr, 0); + emitFPushCtorCommon(cls, nullptr, numParams); } void HhbcTranslator::emitFPushCtorD(int32_t numParams, int32_t classNameStrId) { @@ -1521,19 +1537,7 @@ void HhbcTranslator::emitFPushCtorD(int32_t numParams, int32_t classNameStrId) { } else { clss = gen(LdClsCached, cns(className)); } - SSATmp* obj = gen(IncRef, gen(AllocObj, clss)); - push(obj); - - SSATmp* fn = nullptr; - if (func) { - fn = cns(func); - } else { - fn = gen(LdClsCtor, clss); - } - - SSATmp* obj2 = gen(IncRef, obj); - int32_t numArgsAndCtorFlag = numParams | (1 << 31); - emitFPushActRec(fn, obj2, numArgsAndCtorFlag, nullptr); + emitFPushCtorCommon(clss, func, numParams); } /* diff --git a/hphp/runtime/vm/translator/hopt/hhbctranslator.h b/hphp/runtime/vm/translator/hopt/hhbctranslator.h index 0ce248bc2..92836a1f6 100644 --- a/hphp/runtime/vm/translator/hopt/hhbctranslator.h +++ b/hphp/runtime/vm/translator/hopt/hhbctranslator.h @@ -239,6 +239,7 @@ struct HhbcTranslator { const StringData* methName); void emitFPushCtorD(int32_t numParams, int32_t classNameStrId); void emitFPushCtor(int32_t numParams); + void emitFPushCtorCommon(SSATmp* cls, const Func* func, int32_t numParams); void emitCreateCl(int32_t numParams, int32_t classNameStrId); void emitFCallArray(const Offset pcOffset, const Offset after); void emitFCall(uint32_t numParams, diff --git a/hphp/runtime/vm/translator/hopt/ir.h b/hphp/runtime/vm/translator/hopt/ir.h index 7088b6bda..2eee9a559 100644 --- a/hphp/runtime/vm/translator/hopt/ir.h +++ b/hphp/runtime/vm/translator/hopt/ir.h @@ -311,10 +311,6 @@ O(LdSwitchDblIndex, D(Int), S(Dbl) S(Int) S(Int), N) \ O(LdSwitchStrIndex, D(Int), S(Str) S(Int) S(Int), CRc|N) \ O(LdSwitchObjIndex, D(Int), S(Obj) S(Int) S(Int), CRc|N|Er) \ O(JmpSwitchDest, ND, S(Int), T|E) \ -O(NewObj, D(StkPtr), S(Cls) \ - C(Int) \ - S(StkPtr) \ - S(FramePtr), E|Mem|N|Refs|PRc|Er) \ O(AllocObj, D(Obj), S(Cls), N) \ O(LdClsCtor, D(Func), S(Cls), C|Er|N) \ O(CreateCl, D(Obj), C(Cls) \ diff --git a/hphp/runtime/vm/translator/hopt/linearscan.cpp b/hphp/runtime/vm/translator/hopt/linearscan.cpp index 88e956a68..0afd17aa1 100644 --- a/hphp/runtime/vm/translator/hopt/linearscan.cpp +++ b/hphp/runtime/vm/translator/hopt/linearscan.cpp @@ -376,7 +376,6 @@ void LinearScan::allocRegToInstruction(InstructionList::iterator it) { opc == SpillFrame || opc == ExceptionBarrier || opc == RetAdjustStack || - opc == NewObj || opc == InterpOne || opc == GenericRetDecRefs || opc == GuardStk || diff --git a/hphp/runtime/vm/translator/hopt/nativecalls.cpp b/hphp/runtime/vm/translator/hopt/nativecalls.cpp index 60d6e9159..914b4eb3b 100644 --- a/hphp/runtime/vm/translator/hopt/nativecalls.cpp +++ b/hphp/runtime/vm/translator/hopt/nativecalls.cpp @@ -133,8 +133,8 @@ static CallMap s_callMap({ {NewArray, (TCA)new_array, DSSA, SNone, {{SSA, 0}}}, {NewTuple, (TCA)new_tuple, DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, - {NewObj, (TCA)irNewInstanceHelper, DSSA, SSync, - {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}}, + {AllocObj, (TCA)newInstance, DSSA, SSync, + {{SSA, 0}}}, {LdClsCtor, (TCA)loadClassCtor, DSSA, SSync, {{SSA, 0}}}, {PrintStr, (TCA)print_string, DNone, SNone, {{SSA, 0}}}, diff --git a/hphp/runtime/vm/translator/hopt/simplifier.cpp b/hphp/runtime/vm/translator/hopt/simplifier.cpp index 85086e6d0..00575e7aa 100644 --- a/hphp/runtime/vm/translator/hopt/simplifier.cpp +++ b/hphp/runtime/vm/translator/hopt/simplifier.cpp @@ -130,17 +130,6 @@ StackValueInfo getStackValue(SSATmp* sp, uint32_t index) { // pushes an ActRec index - kNumActRecCells); - case NewObj: - if (index == kNumActRecCells) { - // newly allocated object, which we unfortunately don't have any - // kind of handle to :-( - return StackValueInfo { Type::Obj }; - } - - return getStackValue(sp->inst()->getSrc(2), - // NewObj pushes an object and an ActRec - index - (1 + kNumActRecCells)); - default: { // Assume it's a vector instruction. This will assert in diff --git a/hphp/runtime/vm/translator/hopt/tracebuilder.cpp b/hphp/runtime/vm/translator/hopt/tracebuilder.cpp index 8af81298a..1613b252d 100644 --- a/hphp/runtime/vm/translator/hopt/tracebuilder.cpp +++ b/hphp/runtime/vm/translator/hopt/tracebuilder.cpp @@ -289,12 +289,6 @@ void TraceBuilder::updateTrackedState(IRInstruction* inst) { m_spOffset += kNumActRecCells; break; - case NewObj: - m_spValue = inst->getDst(); - // new obj leaves the new object and an actrec on the stack - m_spOffset += kNumActRecCells + 1; - break; - case InterpOne: { m_spValue = inst->getDst(); int64_t stackAdjustment = inst->getSrc(3)->getValInt(); diff --git a/hphp/runtime/vm/translator/translator.cpp b/hphp/runtime/vm/translator/translator.cpp index 8781c7605..280690552 100644 --- a/hphp/runtime/vm/translator/translator.cpp +++ b/hphp/runtime/vm/translator/translator.cpp @@ -3004,7 +3004,7 @@ static bool shouldAnalyzeCallee(const NormalizedInstruction* fcall) { // methods, which will need to be updated when we support // OpFPushClsMethod here. if (pushOp != OpFPushFuncD && pushOp != OpFPushObjMethodD - && pushOp != OpFPushCtorD) { + && pushOp != OpFPushCtorD && pushOp != OpFPushCtor) { FTRACE(1, "analyzeCallee: push op ({}) was not supported\n", opcodeToName(pushOp)); return false;