From f3f3e0b48e89016274f3173922bfe551da93a200 Mon Sep 17 00:00:00 2001 From: Guilherme Ottoni Date: Sun, 19 May 2013 13:37:02 -0700 Subject: [PATCH] Optimize ContSend, ContRaise, and ContNext for m_received being null Make sure m_received is always null at ContSend, ContRaise, and ContNext, and this information to generate better code for these bytecode instructions. --- hphp/doc/ir.specification | 4 ++++ hphp/runtime/ext/ext_continuation.cpp | 4 +++- hphp/runtime/vm/bytecode.cpp | 2 +- hphp/runtime/vm/translator/hopt/codegen.cpp | 6 +++++ .../vm/translator/hopt/hhbctranslator.cpp | 23 ++++++++++--------- hphp/runtime/vm/translator/hopt/ir.h | 1 + 6 files changed, 27 insertions(+), 13 deletions(-) diff --git a/hphp/doc/ir.specification b/hphp/doc/ir.specification index 39a9a13a5..19f43414e 100644 --- a/hphp/doc/ir.specification +++ b/hphp/doc/ir.specification @@ -1389,6 +1389,10 @@ DbgAssertPtr S0:PtrToGen the same logic as DbgAssertRefCount. Internally this uses always_assert(); failures cause an abort (whatever always_assert does). +DbgAssertType S0:Cell + + Assert that S0 is of type T at runtime. If the assertion fails, + execution is aborted via a hardware exception. 18. Iterators diff --git a/hphp/runtime/ext/ext_continuation.cpp b/hphp/runtime/ext/ext_continuation.cpp index 8d562a529..a99b0ec79 100644 --- a/hphp/runtime/ext/ext_continuation.cpp +++ b/hphp/runtime/ext/ext_continuation.cpp @@ -141,7 +141,9 @@ void c_Continuation::t_raise(CVarRef v) { void c_Continuation::t_raised() { if (m_should_throw) { m_should_throw = false; - throw_exception(m_received); + Variant e(Variant::nullInit); + m_received.swap(e); + throw_exception(e); } } diff --git a/hphp/runtime/vm/bytecode.cpp b/hphp/runtime/vm/bytecode.cpp index a3e9ecbc8..29346937f 100644 --- a/hphp/runtime/vm/bytecode.cpp +++ b/hphp/runtime/vm/bytecode.cpp @@ -7128,7 +7128,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopContReceive(PC& pc) { TypedValue* fr = cont->m_received.asTypedValue(); TypedValue* to = m_stack.allocTV(); memcpy(to, fr, sizeof(TypedValue)); - tvWriteUninit(fr); + tvWriteNull(fr); } inline void OPTBLD_INLINE VMExecutionContext::iopContRetC(PC& pc) { diff --git a/hphp/runtime/vm/translator/hopt/codegen.cpp b/hphp/runtime/vm/translator/hopt/codegen.cpp index 1f88a72f4..be5a503b4 100644 --- a/hphp/runtime/vm/translator/hopt/codegen.cpp +++ b/hphp/runtime/vm/translator/hopt/codegen.cpp @@ -5059,6 +5059,12 @@ void traceCallback(ActRec* fp, Cell* sp, int64_t pcOff, void* rip) { checkFrame(fp, sp, /*checkLocals*/true); } +void CodeGenerator::cgDbgAssertType(IRInstruction* inst) { + ConditionCode cc = emitTypeTest(inst->getTypeParam(), + m_regs[inst->getSrc(0)].getReg(1), true); + ifThen(m_as, cc, [&] { m_as.ud2(); }); +} + void CodeGenerator::cgVerifyParamCls(IRInstruction* inst) { SSATmp* objClass = inst->getSrc(0); assert(!objClass->isConst()); diff --git a/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp b/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp index 089428cf3..867dc3470 100644 --- a/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp +++ b/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp @@ -1003,7 +1003,7 @@ void HhbcTranslator::emitContReceive() { gen(ContRaiseCheck, getExitSlowTrace(), cont); auto const valOffset = cns(CONTOFF(m_received)); push(gen(LdProp, Type::Cell, cont, valOffset)); - gen(StProp, cont, valOffset, m_tb->genDefUninit()); + gen(StProp, cont, valOffset, m_tb->genDefNull()); } void HhbcTranslator::emitContRetC() { @@ -1026,10 +1026,11 @@ void HhbcTranslator::emitContNext() { assert(getCurClass()); SSATmp* cont = gen(LdThis, m_tb->getFp()); gen(ContPreNext, getExitSlowTrace(), cont); - - auto const oldVal = gen(LdProp, Type::Cell, cont, cns(CONTOFF(m_received))); - gen(StProp, cont, cns(CONTOFF(m_received)), m_tb->genDefInitNull()); - gen(DecRef, oldVal); + if (RuntimeOption::EvalHHIRGenerateAsserts) { + // We're guaranteed to have a Null in m_received at this point + auto const oldVal = gen(LdProp, Type::Cell, cont, cns(CONTOFF(m_received))); + gen(DbgAssertType, Type::InitNull, oldVal); + } } void HhbcTranslator::emitContSendImpl(bool raise) { @@ -1037,16 +1038,16 @@ void HhbcTranslator::emitContSendImpl(bool raise) { SSATmp* cont = gen(LdThis, m_tb->getFp()); gen(ContStartedCheck, getExitSlowTrace(), cont); gen(ContPreNext, getExitSlowTrace(), cont); - gen(AssertLoc, Type::Cell, LocalId(0), m_tb->getFp()); auto const newVal = gen(IncRef, ldLoc(0)); - auto const oldVal = gen(LdProp, Type::Cell, cont, cns(CONTOFF(m_received))); + if (RuntimeOption::EvalHHIRGenerateAsserts) { + // We're guaranteed to have a Null in m_received at this point + auto const oldVal = gen(LdProp, Type::Cell, cont, cns(CONTOFF(m_received))); + gen(DbgAssertType, Type::InitNull, oldVal); + } gen(StProp, cont, cns(CONTOFF(m_received)), newVal); - gen(DecRef, oldVal); if (raise) { - gen( - StRaw, cont, cns(RawMemSlot::ContShouldThrow), cns(true) - ); + gen(StRaw, cont, cns(RawMemSlot::ContShouldThrow), cns(true)); } } diff --git a/hphp/runtime/vm/translator/hopt/ir.h b/hphp/runtime/vm/translator/hopt/ir.h index 3467e96f2..3d386c26f 100644 --- a/hphp/runtime/vm/translator/hopt/ir.h +++ b/hphp/runtime/vm/translator/hopt/ir.h @@ -587,6 +587,7 @@ O(ArrayIdx, D(Cell), C(TCA) S(Arr) S(Int,Str) S(Cell), \ E|N|CRc|PRc|Refs|Mem) \ O(DbgAssertRefCount, ND, SUnk, N|E) \ O(DbgAssertPtr, ND, S(PtrToGen), N|E) \ +O(DbgAssertType, ND, S(Cell), E) \ O(Nop, ND, NA, NF) \ /* */