Move Continuation state check to ContCheck opcode

Add ContCheck opcode that moves away responsibility of checking
Continuation status from Cont{Next,Send,Raise} opcodes.

This check needs to run outside of try/catch in next()/send()/raise()
methods and moving it to a separate opcode lets us merge
Cont{Next,Send,Raise} with ContEnter.
Esse commit está contido em:
Jan Oravec
2013-06-25 16:52:41 -07:00
commit de Sara Golemon
commit 2a1d59c286
10 arquivos alterados com 51 adições e 30 exclusões
+5 -1
Ver Arquivo
@@ -7010,13 +7010,17 @@ static void emitContinuationMethod(UnitEmitter& ue, FuncEmitter* fe,
// translations
fe->setAttrs(Attr(fe->attrs() | AttrClone));
// check continuation status; send()/raise() also checks started
ue.emitOp(OpContCheck);
ue.emitIVA(m == METH_SEND || m == METH_RAISE);
const Offset ehStart = ue.bcPos();
static Op mOps[] = {
OpContNext,
OpContSend,
OpContRaise,
};
ue.emitOp(mOps[m]);
const Offset ehStart = ue.bcPos();
ue.emitOp(OpContEnter);
ue.emitOp(OpContStopped);
ue.emitOp(OpNull);
+13 -9
Ver Arquivo
@@ -3720,24 +3720,28 @@ ContRetC [C] -> []
which must be a non-static method of the Continuation class. Further attempts
to iterate it will fail.
ContCheck <check started> [] -> []
Check whether continuation can be iterated. $this must be a Continuation
object. If the continuation is finished, already running, or not yet started
and <check started> is enabled, an exception will be thrown.
ContNext [] -> []
Prepare continuation for iteration. $this must be a Continuation
object. If the continuation is finished or already running, an exception
will be thrown.
Prepare continuation for iteration. $this must be a Continuation object
that passed ContCheck<false> check.
ContSend [] -> []
Prepare continuation to receive a value. $this must be a Continuation
object. If the continuation is finished or already running, an exception will
be thrown. Otherwise, the value in local 0 is stored in the continuation.
Prepare continuation to receive a value. $this must be a Continuation object
that passed ContCheck<true> check. The value in local 0 is stored in the
continuation.
ContRaise [] -> []
Prepare continuation to receive a thrown exception. $this must be a
Continuation object. If the continuation is finished or already running, an
exception will be thrown. Otherwise, the exception in local 0 is stored in
the continuation.
Continuation object that passed ContCheck<true> check. The exception in
local 0 is stored in the continuation.
ContValid [] -> [C:Bool]
-2
Ver Arquivo
@@ -492,8 +492,6 @@ private:
OPCODES
#undef O
template<bool raise>
void contSendImpl();
void classExistsImpl(PC& pc, Attr typeAttr);
void fPushObjMethodImpl(
Class* cls, StringData* name, ObjectData* obj, int numArgs);
+16 -15
Ver Arquivo
@@ -6853,33 +6853,34 @@ inline void OPTBLD_INLINE VMExecutionContext::iopContRetC(PC& pc) {
m_fp = prevFp;
}
inline void OPTBLD_INLINE VMExecutionContext::iopContCheck(PC& pc) {
NEXT();
DECODE_IVA(check_started);
c_Continuation* cont = this_continuation(m_fp);
if (check_started) {
cont->startedCheck();
}
cont->preNext();
}
inline void OPTBLD_INLINE VMExecutionContext::iopContNext(PC& pc) {
NEXT();
c_Continuation* cont = this_continuation(m_fp);
cont->preNext();
cont->m_received.setNull();
}
template<bool raise>
inline void VMExecutionContext::contSendImpl() {
c_Continuation* cont = this_continuation(m_fp);
cont->startedCheck();
cont->preNext();
cont->m_received.assignVal(tvAsVariant(frame_local(m_fp, 0)));
if (raise) {
assert(cont->m_label);
--cont->m_label;
}
}
inline void OPTBLD_INLINE VMExecutionContext::iopContSend(PC& pc) {
NEXT();
contSendImpl<false>();
c_Continuation* cont = this_continuation(m_fp);
cont->m_received.assignVal(tvAsVariant(frame_local(m_fp, 0)));
}
inline void OPTBLD_INLINE VMExecutionContext::iopContRaise(PC& pc) {
NEXT();
contSendImpl<true>();
c_Continuation* cont = this_continuation(m_fp);
cont->m_received.assignVal(tvAsVariant(frame_local(m_fp, 0)));
assert(cont->m_label);
--cont->m_label;
}
inline void OPTBLD_INLINE VMExecutionContext::iopContValid(PC& pc) {
+1
Ver Arquivo
@@ -552,6 +552,7 @@ enum SetOpOp {
O(UnpackCont, NA, NOV, TWO(CV,CV), NF) \
O(PackCont, ONE(IVA), ONE(CV), NOV, NF) \
O(ContRetC, NA, ONE(CV), NOV, CF_TF) \
O(ContCheck, ONE(IVA), NOV, NOV, NF) \
O(ContNext, NA, NOV, NOV, NF) \
O(ContSend, NA, NOV, NOV, NF) \
O(ContRaise, NA, NOV, NOV, NF) \
+9 -3
Ver Arquivo
@@ -1155,10 +1155,18 @@ void HhbcTranslator::emitContRetC() {
emitContExitImpl();
}
void HhbcTranslator::emitContCheck(bool checkStarted) {
assert(curClass());
SSATmp* cont = gen(LdThis, m_tb->fp());
if (checkStarted) {
gen(ContStartedCheck, getExitSlowTrace(), cont);
}
gen(ContPreNext, getExitSlowTrace(), cont);
}
void HhbcTranslator::emitContNext() {
assert(curClass());
SSATmp* cont = gen(LdThis, m_tb->fp());
gen(ContPreNext, getExitSlowTrace(), cont);
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)));
@@ -1169,8 +1177,6 @@ void HhbcTranslator::emitContNext() {
void HhbcTranslator::emitContSendImpl(bool raise) {
assert(curClass());
SSATmp* cont = gen(LdThis, m_tb->fp());
gen(ContStartedCheck, getExitSlowTrace(), cont);
gen(ContPreNext, getExitSlowTrace(), cont);
gen(AssertLoc, Type::Cell, LocalId(0), m_tb->fp());
auto const newVal = gen(IncRef, ldLoc(0));
if (RuntimeOption::EvalHHIRGenerateAsserts) {
+1
Ver Arquivo
@@ -380,6 +380,7 @@ struct HhbcTranslator {
void emitUnpackCont();
void emitPackCont(int64_t labelId);
void emitContRetC();
void emitContCheck(bool checkStarted);
void emitContNext();
void emitContSendImpl(bool raise);
void emitContSend();
+4
Ver Arquivo
@@ -564,6 +564,10 @@ void Translator::translateContRetC(const NormalizedInstruction& i) {
HHIR_EMIT(ContRetC);
}
void Translator::translateContCheck(const NormalizedInstruction& i) {
HHIR_EMIT(ContCheck, i.imm[0].u_IVA);
}
void Translator::translateContNext(const NormalizedInstruction& i) {
HHIR_EMIT(ContNext);
}
+1
Ver Arquivo
@@ -133,6 +133,7 @@
CASE(UnpackCont) \
CASE(PackCont) \
CASE(ContRetC) \
CASE(ContCheck) \
CASE(ContNext) \
CASE(ContSend) \
CASE(ContRaise) \
+1
Ver Arquivo
@@ -1269,6 +1269,7 @@ static const struct {
{ OpUnpackCont, {Local, StackTop2, OutInt64, 2 }},
{ OpPackCont, {Local|Stack1, None, OutNone, -1 }},
{ OpContRetC, {Local|Stack1, None, OutNone, -1 }},
{ OpContCheck, {None, None, OutNone, 0 }},
{ OpContNext, {None, None, OutNone, 0 }},
{ OpContSend, {Local, None, OutNone, 0 }},
{ OpContRaise, {Local, None, OutNone, 0 }},