Add incremental GC barrier for generator frames associated with args/call objects, bug 716013. r=billm
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 23 Jan 2012 13:59:04 -0800
changeset 86368 1b5b7d538230afd714174f78d918ada69c960c93
parent 86367 850ce7c81121f7731719449c974da81ee333a11f
child 86369 80da2e1c26b60ac1f56d9b14dd5ddd38f43b9195
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs716013
milestone12.0a1
Add incremental GC barrier for generator frames associated with args/call objects, bug 716013. r=billm
js/src/jit-test/tests/basic/bug716013.js
js/src/vm/Stack.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug716013.js
@@ -0,0 +1,4 @@
+f = (function() {
+    for (x in [arguments, arguments]) yield(gczeal(4, function(){}))
+})
+for (i in f()) {}
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -789,16 +789,27 @@ ContextStack::pushGeneratorFrame(JSConte
 
     StackFrame *stackfp = reinterpret_cast<StackFrame *>(firstUnused + vplen);
     Value *stackvp = (Value *)stackfp - vplen;
 
     /* Save this for popGeneratorFrame. */
     gfg->gen_ = gen;
     gfg->stackvp_ = stackvp;
 
+    /*
+     * Trigger incremental barrier on the floating frame's generator object.
+     * This is normally traced through only by associated arguments/call
+     * objects, but only when the generator is not actually on the stack.
+     * We don't need to worry about generational barriers as the generator
+     * object has a trace hook and cannot be nursery allocated.
+     */
+    JSObject *genobj = js_FloatingFrameToGenerator(genfp)->obj;
+    JS_ASSERT(genobj->getClass()->trace);
+    JSObject::writeBarrierPre(genobj);
+
     /* Copy from the generator's floating frame to the stack. */
     stackfp->stealFrameAndSlots(stackvp, genfp, genvp, gen->regs.sp);
     stackfp->resetGeneratorPrev(cx);
     stackfp->unsetFloatingGenerator();
     gfg->regs_.rebaseFromTo(gen->regs, *stackfp);
 
     gfg->prevRegs_ = seg_->pushRegs(gfg->regs_);
     JS_ASSERT(space().firstUnused() == gfg->regs_.sp);