From 9b1330b3b007c737d9de49ea1c75f1254ddd57c0 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 11 Dec 2013 14:03:24 +0000 Subject: [PATCH] Bug 945453 - Postbarrier JIT-code writes to arguments objects r=terrence r=djvj --- js/src/gc/StoreBuffer.cpp | 7 ++++++- js/src/jit/BaselineCompiler.cpp | 20 ++++++++++++++++++++ js/src/jit/IonBuilder.cpp | 5 ++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index 010dacb1c031..625e265bce5e 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -10,6 +10,7 @@ #include "mozilla/Assertions.h" +#include "vm/ArgumentsObject.h" #include "vm/ForkJoin.h" #include "jsgcinlines.h" @@ -64,7 +65,11 @@ StoreBuffer::WholeCellEdges::mark(JSTracer *trc) JS_ASSERT(tenured->isTenured()); JSGCTraceKind kind = GetGCThingTraceKind(tenured); if (kind <= JSTRACE_OBJECT) { - MarkChildren(trc, static_cast(tenured)); + JSObject *object = static_cast(tenured); + if (object->is()) + ArgumentsObject::trace(trc, object); + else + MarkChildren(trc, object); return; } #ifdef JS_ION diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 6f5f03f21ece..febad931dae9 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -2343,6 +2343,26 @@ BaselineCompiler::emitFormalArgAccess(uint32_t arg, bool get) } else { masm.patchableCallPreBarrier(argAddr, MIRType_Value); storeValue(frame.peek(-1), argAddr, R0); + +#ifdef JSGC_GENERATIONAL + // Fully sync the stack if post-barrier is needed. + frame.syncStack(0); + + // Reload the arguments object + Register reg = R2.scratchReg(); + masm.loadPtr(Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfArgsObj()), reg); + + Nursery &nursery = cx->runtime()->gcNursery; + Label skipBarrier; + Label isTenured; + masm.branchPtr(Assembler::Below, reg, ImmWord(nursery.start()), &isTenured); + masm.branchPtr(Assembler::Below, reg, ImmWord(nursery.heapEnd()), &skipBarrier); + + masm.bind(&isTenured); + masm.call(&postBarrierSlot_); + + masm.bind(&skipBarrier); +#endif } masm.bind(&done); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 62da7dd8e304..28b2285a8fdc 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -9111,7 +9111,10 @@ IonBuilder::jsop_setarg(uint32_t arg) // If an arguments object is in use, and it aliases formals, then all SETARGs // must go through the arguments object. if (info().argsObjAliasesFormals()) { - current->add(MSetArgumentsObjectArg::New(alloc(), current->argumentsObject(), GET_SLOTNO(pc), val)); + if (NeedsPostBarrier(info(), val)) + current->add(MPostWriteBarrier::New(alloc(), current->argumentsObject(), val)); + current->add(MSetArgumentsObjectArg::New(alloc(), current->argumentsObject(), + GET_SLOTNO(pc), val)); return true; }