From e6bd76e3fdf36d7137b07723d20c689fbd503f69 Mon Sep 17 00:00:00 2001 From: Jan Oravec Date: Mon, 3 Jun 2013 11:34:40 -0700 Subject: [PATCH] Kill m_should_throw Do not check for m_should_throw from ContReceive. Add a label used by ContRaise pointing to Throw emitted by the Yield instead. --- hphp/compiler/analysis/emitter.cpp | 31 +++++++++++---------- hphp/compiler/expression/yield_expression.h | 2 +- hphp/runtime/ext/ext_continuation.cpp | 11 +------- hphp/runtime/ext/ext_continuation.h | 2 -- hphp/runtime/vm/bytecode.cpp | 4 +-- hphp/runtime/vm/jit/codegen.cpp | 7 ----- hphp/runtime/vm/jit/hhbctranslator.cpp | 5 ++-- hphp/runtime/vm/jit/ir.h | 8 +----- 8 files changed, 25 insertions(+), 45 deletions(-) diff --git a/hphp/compiler/analysis/emitter.cpp b/hphp/compiler/analysis/emitter.cpp index 85eddfdd9..bd490d92c 100644 --- a/hphp/compiler/analysis/emitter.cpp +++ b/hphp/compiler/analysis/emitter.cpp @@ -3906,16 +3906,26 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) { assert(m_evalStack.size() == 1); m_metaInfo.addKnownDataType( KindOfObject, false, m_ue.bcPos(), false, 1); - e.PackCont(y->getLabel()); + e.PackCont(2 * y->getLabel()); // transfer control assert(m_evalStack.size() == 0); e.ContExit(); - // emit return label - m_yieldLabels[y->getLabel()].set(e); + // emit return label for ContRaise + m_yieldLabels[2 * y->getLabel() - 1].set(e); - // check for exception and retrieve result + // retrieve and throw exception + assert(m_evalStack.size() == 0); + m_metaInfo.addKnownDataType( + KindOfObject, false, m_ue.bcPos(), false, 0); + e.ContReceive(); + e.Throw(); + + // emit return label for ContNext/ContSend + m_yieldLabels[2 * y->getLabel()].set(e); + + // retrieve result assert(m_evalStack.size() == 0); m_metaInfo.addKnownDataType( KindOfObject, false, m_ue.bcPos(), false, 0); @@ -4904,17 +4914,10 @@ void EmitterVisitor::emitContinuationSwitch(Emitter& e, int ncase) { } // make sure the labels are available - m_yieldLabels.resize(ncase + 1); + m_yieldLabels.resize(2 * ncase + 1); - if (ncase == 1) { - // Don't bother with the jump table when there are only two targets - e.UnpackCont(); - e.JmpNZ(m_yieldLabels[1]); - return; - } - - std::vector targets(ncase + 1); - for (int i = 0; i <= ncase; ++i) { + std::vector targets(2 * ncase + 1); + for (int i = 0; i <= 2 * ncase; ++i) { targets[i] = &m_yieldLabels[i]; } e.UnpackCont(); diff --git a/hphp/compiler/expression/yield_expression.h b/hphp/compiler/expression/yield_expression.h index 4b51fcb98..c54177553 100644 --- a/hphp/compiler/expression/yield_expression.h +++ b/hphp/compiler/expression/yield_expression.h @@ -32,7 +32,7 @@ public: DECLARE_EXPRESSION_VIRTUAL_FUNCTIONS; ExpressionPtr getExpression() { return m_exp; } - int getLabel() { assert(m_label >= 0); return m_label; } + int getLabel() { assert(m_label >= 1); return m_label; } void setLabel(int label) { assert(m_label == -1); m_label = label; } private: diff --git a/hphp/runtime/ext/ext_continuation.cpp b/hphp/runtime/ext/ext_continuation.cpp index ce207cc7e..3d319e135 100644 --- a/hphp/runtime/ext/ext_continuation.cpp +++ b/hphp/runtime/ext/ext_continuation.cpp @@ -49,7 +49,7 @@ c_Continuation::c_Continuation(Class* cb) : m_index(-1LL), m_value(Variant::NullInit()), m_received(Variant::NullInit()), - m_done(false), m_running(false), m_should_throw(false), + m_done(false), m_running(false), m_vmFunc(nullptr), m_label(0ll) { } @@ -139,15 +139,6 @@ void c_Continuation::t_raise(CVarRef v) { const_assert(false); } -void c_Continuation::t_raised() { - if (m_should_throw) { - m_should_throw = false; - Variant e((Variant::NullInit())); - m_received.swap(e); - throw_exception(e); - } -} - String c_Continuation::t_getorigfuncname() { return String(const_cast(m_origFuncName)); } diff --git a/hphp/runtime/ext/ext_continuation.h b/hphp/runtime/ext/ext_continuation.h index 7be79919d..6cc57ffa9 100644 --- a/hphp/runtime/ext/ext_continuation.h +++ b/hphp/runtime/ext/ext_continuation.h @@ -78,7 +78,6 @@ public: bool t_valid(); void t_send(CVarRef v); void t_raise(CVarRef v); - void t_raised(); String t_getorigfuncname(); String t_getcalledclass(); Variant t___clone(); @@ -130,7 +129,6 @@ public: const StringData* m_origFuncName; bool m_done; bool m_running; - bool m_should_throw; int m_localsOffset; Func *m_vmFunc; diff --git a/hphp/runtime/vm/bytecode.cpp b/hphp/runtime/vm/bytecode.cpp index d1ac2cb8a..24de47be0 100644 --- a/hphp/runtime/vm/bytecode.cpp +++ b/hphp/runtime/vm/bytecode.cpp @@ -7281,7 +7281,6 @@ inline void OPTBLD_INLINE VMExecutionContext::iopPackCont(PC& pc) { inline void OPTBLD_INLINE VMExecutionContext::iopContReceive(PC& pc) { NEXT(); c_Continuation* cont = frame_continuation(m_fp); - cont->t_raised(); TypedValue* fr = cont->m_received.asTypedValue(); TypedValue* to = m_stack.allocTV(); memcpy(to, fr, sizeof(TypedValue)); @@ -7315,7 +7314,8 @@ inline void VMExecutionContext::contSendImpl() { cont->preNext(); cont->m_received.assignVal(tvAsVariant(frame_local(m_fp, 0))); if (raise) { - cont->m_should_throw = true; + assert(cont->m_label); + --cont->m_label; } } diff --git a/hphp/runtime/vm/jit/codegen.cpp b/hphp/runtime/vm/jit/codegen.cpp index d8dd373ff..4152b3b76 100644 --- a/hphp/runtime/vm/jit/codegen.cpp +++ b/hphp/runtime/vm/jit/codegen.cpp @@ -5132,13 +5132,6 @@ void CodeGenerator::cgLinkContVarEnv(IRInstruction* inst) { (TCA)VMExecutionContext::unpackContVarEnvLinkage); } -void CodeGenerator::cgContRaiseCheck(IRInstruction* inst) { - SSATmp* cont = inst->src(0); - m_as.test_imm32_disp_reg32(0x1, CONTOFF(m_should_throw), - m_regs[cont].reg()); - emitFwdJcc(CC_NZ, inst->taken()); -} - void CodeGenerator::cgContPreNext(IRInstruction* inst) { auto contReg = m_regs[inst->src(0)].reg(); diff --git a/hphp/runtime/vm/jit/hhbctranslator.cpp b/hphp/runtime/vm/jit/hhbctranslator.cpp index 8d819428a..83c49e25e 100644 --- a/hphp/runtime/vm/jit/hhbctranslator.cpp +++ b/hphp/runtime/vm/jit/hhbctranslator.cpp @@ -1120,7 +1120,6 @@ void HhbcTranslator::emitPackCont(int64_t labelId) { void HhbcTranslator::emitContReceive() { gen(AssertLoc, Type::Obj, LocalId(0), m_tb->fp()); auto const cont = ldLoc(0); - gen(ContRaiseCheck, getExitSlowTrace(), cont); auto const valOffset = cns(CONTOFF(m_received)); push(gen(LdProp, Type::Cell, cont, valOffset)); gen(StProp, cont, valOffset, m_tb->genDefNull()); @@ -1167,7 +1166,9 @@ void HhbcTranslator::emitContSendImpl(bool raise) { } gen(StProp, cont, cns(CONTOFF(m_received)), newVal); if (raise) { - gen(StRaw, cont, cns(RawMemSlot::ContShouldThrow), cns(true)); + SSATmp* label = gen(LdRaw, Type::Int, cont, cns(RawMemSlot::ContLabel)); + label = gen(OpSub, label, cns(1)); + gen(StRaw, cont, cns(RawMemSlot::ContLabel), label); } } diff --git a/hphp/runtime/vm/jit/ir.h b/hphp/runtime/vm/jit/ir.h index 6eb7e1787..4284096cc 100644 --- a/hphp/runtime/vm/jit/ir.h +++ b/hphp/runtime/vm/jit/ir.h @@ -451,7 +451,6 @@ O(ContEnter, ND, S(FramePtr) \ S(TCA) C(Int) S(FramePtr), E|Mem) \ O(UnlinkContVarEnv, ND, S(FramePtr), E|N|Mem) \ O(LinkContVarEnv, ND, S(FramePtr), E|N|Mem) \ -O(ContRaiseCheck, ND, S(Obj), E) \ O(ContPreNext, ND, S(Obj), E|Mem) \ O(ContStartedCheck, ND, S(Obj), E) \ O(IterInit, D(Bool), S(Arr,Obj) \ @@ -759,7 +758,7 @@ class RawMemSlot { public: enum Kind { - ContLabel, ContDone, ContShouldThrow, ContRunning, ContARPtr, + ContLabel, ContDone, ContRunning, ContARPtr, StrLen, FuncNumParams, FuncRefBitVec, ContEntry, MisCtx, MaxKind }; @@ -768,7 +767,6 @@ class RawMemSlot { switch (k) { case ContLabel: return GetContLabel(); case ContDone: return GetContDone(); - case ContShouldThrow: return GetContShouldThrow(); case ContRunning: return GetContRunning(); case ContARPtr: return GetContARPtr(); case StrLen: return GetStrLen(); @@ -797,10 +795,6 @@ class RawMemSlot { static RawMemSlot m(CONTOFF(m_done), Transl::sz::byte, Type::Bool); return m; } - static RawMemSlot& GetContShouldThrow() { - static RawMemSlot m(CONTOFF(m_should_throw), Transl::sz::byte, Type::Bool); - return m; - } static RawMemSlot& GetContRunning() { static RawMemSlot m(CONTOFF(m_running), Transl::sz::byte, Type::Bool); return m;