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.
Esse commit está contido em:
Guilherme Ottoni
2013-05-19 13:37:02 -07:00
commit de sgolemon
commit f3f3e0b48e
6 arquivos alterados com 27 adições e 13 exclusões
+4
Ver Arquivo
@@ -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<T> S0:Cell
Assert that S0 is of type T at runtime. If the assertion fails,
execution is aborted via a hardware exception.
18. Iterators
+3 -1
Ver Arquivo
@@ -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);
}
}
+1 -1
Ver Arquivo
@@ -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) {
@@ -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());
+12 -11
Ver Arquivo
@@ -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));
}
}
+1
Ver Arquivo
@@ -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) \
/* */