Bug 853461 - GC: A couple more rooting hazards r=terrence
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 22 Mar 2013 14:05:10 +0000
changeset 125925 e6d92226bac221bf65543960b8d7100353345a17
parent 125924 d50dbae0b5388d40907ef5328668be697f34ad7e
child 125926 a614c0fa8f761ba127f025a2ea015ddd50a4798e
push id25172
push userjcoppeard@mozilla.com
push dateFri, 22 Mar 2013 14:16:18 +0000
treeherdermozilla-inbound@e6d92226bac2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs853461
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 853461 - GC: A couple more rooting hazards r=terrence
js/src/gc/RootMarking.cpp
js/src/vm/Debugger.cpp
js/src/vm/ParallelDo.cpp
js/src/vm/ScopeObject.cpp
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -487,18 +487,17 @@ AutoGCRooter::trace(JSTracer *trc)
       case VALARRAY: {
         AutoValueArray *array = static_cast<AutoValueArray *>(this);
         MarkValueRootRange(trc, array->length(), array->start(), "js::AutoValueArray");
         return;
       }
 
       case SCRIPTVECTOR: {
         AutoScriptVector::VectorImpl &vector = static_cast<AutoScriptVector *>(this)->vector;
-        for (size_t i = 0; i < vector.length(); i++)
-            MarkScriptRoot(trc, &vector[i], "AutoScriptVector element");
+        MarkScriptRootRange(trc, vector.length(), vector.begin(), "js::AutoScriptVector.vector");
         return;
       }
 
       case OBJOBJHASHMAP: {
         AutoObjectObjectHashMap::HashMapImpl &map = static_cast<AutoObjectObjectHashMap *>(this)->map;
         for (AutoObjectObjectHashMap::Enum e(map); !e.empty(); e.popFront()) {
             mozilla::DebugOnly<RawObject> key = e.front().key;
             MarkObjectRoot(trc, (RawObject *) &e.front().key, "AutoObjectObjectHashMap key");
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -873,17 +873,17 @@ Debugger::parseResumptionValue(Maybe<Aut
         ac.destroy();
         return JSTRAP_ERROR;
     }
 
     /* Check that rv is {return: val} or {throw: val}. */
     JSContext *cx = ac.ref().context();
     Rooted<JSObject*> obj(cx);
     RootedShape shape(cx);
-    jsid returnId = NameToId(cx->names().return_);
+    RootedId returnId(cx, NameToId(cx->names().return_));
     jsid throwId = NameToId(cx->names().throw_);
     bool okResumption = rv.isObject();
     if (okResumption) {
         obj = &rv.toObject();
         okResumption = obj->isObject();
     }
     if (okResumption) {
         shape = obj->lastProperty();
@@ -4430,20 +4430,22 @@ DebuggerObject_defineProperties(JSContex
     }
 
     {
         AutoIdVector rewrappedIds(cx);
         AutoPropDescArrayRooter rewrappedDescs(cx);
 
         Maybe<AutoCompartment> ac;
         ac.construct(cx, obj);
+        RootedId id(cx);
         for (size_t i = 0; i < n; i++) {
             if (!rewrappedIds.append(jsid()) || !rewrappedDescs.append())
                 return false;
-            if (!unwrappedDescs[i].wrapInto(cx, obj, ids[i], &rewrappedIds[i], &rewrappedDescs[i]))
+            id = ids[i];
+            if (!unwrappedDescs[i].wrapInto(cx, obj, id, &rewrappedIds[i], &rewrappedDescs[i]))
                 return false;
         }
 
         ErrorCopier ec(ac, dbg->toJSObject());
         for (size_t i = 0; i < n; i++) {
             bool dummy;
             if (!DefineProperty(cx, obj, rewrappedIds.handleAt(i),
                                 rewrappedDescs[i], true, &dummy))
@@ -4965,24 +4967,25 @@ DebuggerEnv_names(JSContext *cx, unsigne
         ErrorCopier ec(ac, dbg->toJSObject());
         if (!GetPropertyNames(cx, env, JSITER_HIDDEN, &keys))
             return false;
     }
 
     RootedObject arr(cx, NewDenseEmptyArray(cx));
     if (!arr)
         return false;
+    RootedId id(cx);
     for (size_t i = 0, len = keys.length(); i < len; i++) {
-         jsid id = keys[i];
-         if (JSID_IS_ATOM(id) && IsIdentifier(JSID_TO_ATOM(id))) {
-             if (!cx->compartment->wrapId(cx, &id))
-                 return false;
-             if (!js_NewbornArrayPush(cx, arr, StringValue(JSID_TO_STRING(id))))
-                 return false;
-         }
+        id = keys[i];
+        if (JSID_IS_ATOM(id) && IsIdentifier(JSID_TO_ATOM(id))) {
+            if (!cx->compartment->wrapId(cx, id.address()))
+                return false;
+            if (!js_NewbornArrayPush(cx, arr, StringValue(JSID_TO_STRING(id))))
+                return false;
+        }
     }
     args.rval().setObject(*arr);
     return true;
 }
 
 static JSBool
 DebuggerEnv_find(JSContext *cx, unsigned argc, Value *vp)
 {
--- a/js/src/vm/ParallelDo.cpp
+++ b/js/src/vm/ParallelDo.cpp
@@ -398,38 +398,38 @@ class ParallelIonInvoke
         // Find JIT code pointer.
         IonScript *ion = callee->nonLazyScript()->parallelIonScript();
         IonCode *code = ion->method();
         jitcode_ = code->raw();
         enter_ = cx->compartment->ionCompartment()->enterJIT();
         calleeToken_ = CalleeToToken(callee);
     }
 
-    bool invoke() {
-        Value result;
-        enter_(jitcode_, argc_ + 1, argv_ + 1, NULL, calleeToken_, &result);
+    bool invoke(JSContext *cx) {
+        RootedValue result(cx);
+        enter_(jitcode_, argc_ + 1, argv_ + 1, NULL, calleeToken_, result.address());
         return !result.isMagic();
     }
 };
 #endif // JS_ION
 
 class ParallelDo : public ForkJoinOp
 {
     JSContext *cx_;
-    HeapPtrObject fun_;
+    RootedObject fun_;
 
   public:
     // For tests, make sure to keep this in sync with minItemsTestingThreshold.
     const static uint32_t MAX_BAILOUTS = 3;
     uint32_t bailouts;
-    Vector<JSScript *> pendingInvalidations;
+    AutoScriptVector pendingInvalidations;
 
     ParallelDo(JSContext *cx, HandleObject fun)
       : cx_(cx),
-        fun_(fun),
+        fun_(cx, fun),
         bailouts(0),
         pendingInvalidations(cx)
     { }
 
 #ifndef JS_ION
     ExecutionStatus apply() {
         if (!executeSequentially())
             return ExecutionFatal;
@@ -588,36 +588,34 @@ class ParallelDo : public ForkJoinOp
         Spew(SpewOps, "Up");
 
         // Make a new IonContext for the slice, which is needed if we need to
         // re-enter the VM.
         IonContext icx(cx_, NULL);
 
         JS_ASSERT(pendingInvalidations[slice.sliceId] == NULL);
 
-        js::PerThreadData *pt = slice.perThreadData;
-        RootedObject fun(pt, fun_);
-        JS_ASSERT(fun->isFunction());
-        RootedFunction callee(cx_, fun->toFunction());
+        JS_ASSERT(fun_->isFunction());
+        RootedFunction callee(cx_, fun_->toFunction());
         if (!callee->nonLazyScript()->hasParallelIonScript()) {
             // Sometimes, particularly with GCZeal, the parallel ion
             // script can be collected between starting the parallel
             // op and reaching this point.  In that case, we just fail
             // and fallback.
             Spew(SpewOps, "Down (Script no longer present)");
             return false;
         }
 
         ParallelIonInvoke<3> fii(cx_, callee, 3);
 
         fii.args[0] = Int32Value(slice.sliceId);
         fii.args[1] = Int32Value(slice.numSlices);
         fii.args[2] = BooleanValue(false);
 
-        bool ok = fii.invoke();
+        bool ok = fii.invoke(cx_);
         JS_ASSERT(ok == !slice.abortedScript);
         if (!ok) {
             JSScript *script = slice.abortedScript;
             JS_ASSERT(script->hasParallelIonScript());
             pendingInvalidations[slice.sliceId] = script;
         }
 
         Spew(SpewOps, "Down");
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -16,16 +16,18 @@
 #include "jsatominlines.h"
 #include "jsobjinlines.h"
 
 #include "ScopeObject-inl.h"
 
 using namespace js;
 using namespace js::types;
 
+typedef Rooted<ArgumentsObject *> RootedArgumentsObject;
+
 /*****************************************************************************/
 
 StaticScopeIter::StaticScopeIter(JSContext *cx, HandleObject objArg)
   : obj(cx, objArg), onNamedLambda(false)
 {
     JS_ASSERT_IF(obj, obj->isStaticBlock() || obj->isFunction());
 }
 
@@ -1312,18 +1314,18 @@ class DebugScopeProxy : public BaseProxy
     }
 
     bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                   PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE
     {
         Rooted<DebugScopeObject*> debugScope(cx, &proxy->asDebugScope());
         Rooted<ScopeObject*> scope(cx, &debugScope->scope());
 
-        ArgumentsObject *maybeArgsObj;
-        if (!checkForMissingArguments(cx, id, *scope, &maybeArgsObj))
+        RootedArgumentsObject maybeArgsObj(cx);
+        if (!checkForMissingArguments(cx, id, *scope, maybeArgsObj.address()))
             return false;
 
         if (maybeArgsObj) {
             PodZero(desc);
             desc->obj = debugScope;
             desc->attrs = JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT;
             desc->value = ObjectValue(*maybeArgsObj);
             return true;
@@ -1342,18 +1344,18 @@ class DebugScopeProxy : public BaseProxy
     }
 
     bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,  HandleId id,
              MutableHandleValue vp) MOZ_OVERRIDE
     {
         Rooted<DebugScopeObject*> debugScope(cx, &proxy->asDebugScope());
         Rooted<ScopeObject*> scope(cx, &proxy->asDebugScope().scope());
 
-        ArgumentsObject *maybeArgsObj;
-        if (!checkForMissingArguments(cx, id, *scope, &maybeArgsObj))
+        RootedArgumentsObject maybeArgsObj(cx);
+        if (!checkForMissingArguments(cx, id, *scope, maybeArgsObj.address()))
             return false;
 
         if (maybeArgsObj) {
             vp.set(ObjectValue(*maybeArgsObj));
             return true;
         }
 
         if (handleUnaliasedAccess(cx, debugScope, scope, id, GET, vp))
@@ -1420,18 +1422,19 @@ class DebugScopeProxy : public BaseProxy
         return getScopePropertyNames(cx, proxy, props, JSITER_OWNONLY);
     }
 
     bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) MOZ_OVERRIDE
     {
         return getScopePropertyNames(cx, proxy, props, 0);
     }
 
-    bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) MOZ_OVERRIDE
+    bool has(JSContext *cx, HandleObject proxy, HandleId id_, bool *bp) MOZ_OVERRIDE
     {
+        RootedId id(cx, id_);
         ScopeObject &scopeObj = proxy->asDebugScope().scope();
 
         if (isArguments(cx, id) && isFunctionScope(scopeObj)) {
             *bp = true;
             return true;
         }
 
         JSBool found;