Early release of m_received value

Continuation::send() uses m_received field to transfer the value inside
the continuation. This field remains set until the continuation is
iterated the next time.

Unset this field early by ContReceive so that the memory can be
reclaimed.
Esse commit está contido em:
jan
2013-03-27 15:22:04 -07:00
commit de Sara Golemon
commit 6822bc55cc
5 arquivos alterados com 18 adições e 13 exclusões
+2 -1
Ver Arquivo
@@ -3647,7 +3647,8 @@ ContReceive [] -> [C]
Receive continuation value. If the continuation in local 0 has a pending
exception, this instruction will throw that exception. Otherwise, the value
sent to the continuation will be pushed on the stack.
sent to the continuation will be pushed on the stack. The value will be no
longer referenced by the Continuation object.
ContDone [] -> []
+4 -2
Ver Arquivo
@@ -6887,8 +6887,10 @@ inline void OPTBLD_INLINE VMExecutionContext::iopContReceive(PC& pc) {
NEXT();
c_Continuation* cont = frame_continuation(m_fp);
cont->t_raised();
TypedValue* tv = m_stack.allocTV();
tvDup(cont->m_received.asTypedValue(), tv);
TypedValue* fr = cont->m_received.asTypedValue();
TypedValue* to = m_stack.allocTV();
memcpy(to, fr, sizeof(TypedValue));
tvWriteUninit(fr);
}
inline void OPTBLD_INLINE VMExecutionContext::iopContDone(PC& pc) {
@@ -752,9 +752,8 @@ void HhbcTranslator::emitContReceive() {
SSATmp* cont = m_tb->genLdAssertedLoc(0, Type::Obj);
m_tb->genContRaiseCheck(cont, getExitSlowTrace());
SSATmp* valOffset = m_tb->genDefConst<int64_t>(CONTOFF(m_received));
SSATmp* value = m_tb->genLdProp(cont, valOffset, Type::Cell, nullptr);
value = m_tb->genIncRef(value);
push(value);
push(m_tb->genLdProp(cont, valOffset, Type::Cell, nullptr));
m_tb->genStProp(cont, valOffset, m_tb->genDefUninit(), true);
}
void HhbcTranslator::emitContDone() {
+3 -3
Ver Arquivo
@@ -7538,11 +7538,11 @@ void TranslatorX64::translateContReceive(const Tracelet& t,
const NormalizedInstruction& i) {
const int contIdx = 0;
emitContRaiseCheck(a, i);
PhysReg rCont = getReg(i.inputs[contIdx]->location);
ScratchReg rScratch(m_regMap);
emitLea(a, getReg(i.inputs[contIdx]->location), CONTOFF(m_received),
r(rScratch));
emitIncRefGeneric(r(rScratch), 0);
emitLea(a, rCont, CONTOFF(m_received), r(rScratch));
emitCopyToStack(a, i, r(rScratch), -1 * (int)sizeof(Cell));
emitStoreUninitNull(a, CONTOFF(m_received), rCont);
}
void TranslatorX64::translateContEnter(const Tracelet& t,
+7 -4
Ver Arquivo
@@ -25827,8 +25827,8 @@ bool TestCodeRun::TestYield() {
"function gen() {\n"
" yield new Evil;\n"
" yield null;\n"
" yield null;\n"
" yield null;\n"
" yield new Evil;\n"
" yield new Evil;\n"
"}\n"
"function main() {\n"
" $GLOBALS['cont'] = $c = gen();\n"
@@ -25837,7 +25837,7 @@ bool TestCodeRun::TestYield() {
" $c->send(new Evil);\n"
" $GLOBALS['gonext'] = true;\n"
" $c->next();\n"
" $c->send(new Evil);\n"
" $c->send(null);\n"
" $c->send(null);\n"
" echo \"Finished!\\n\";\n"
"}\n"
@@ -25848,10 +25848,13 @@ bool TestCodeRun::TestYield() {
"NULL\n"
"in __destruct()\n"
"NULL\n"
"in __destruct()\n"
"object(Evil)#4 (0) {\n"
"}\n"
"Caught: Continuation is already running\n"
"in __destruct()\n"
"NULL\n"
"Caught: Continuation is already running\n"
"Caught: Continuation is already finished\n"
"Finished!\n"
"Returned from main safely\n");