Bug 831733 - GC: Transplant jsapi test (testBug604087) fails with rooting analysis r=billm
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 17 Jan 2013 10:09:14 +0000
changeset 119262 e5f0630bccc324e4976acb25578b66a1769c7f6d
parent 119261 2c517fcf3c690a9088a3a778701fab3a0c52abeb
child 119263 8a7a3de45a947fbe1cec3c3bc82c079f7ab6e614
push id24195
push userMs2ger@gmail.com
push dateSat, 19 Jan 2013 16:10:11 +0000
treeherdermozilla-central@02e12a80aef9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs831733, 604087
milestone21.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 831733 - GC: Transplant jsapi test (testBug604087) fails with rooting analysis r=billm
js/src/jscompartment.cpp
js/src/jswrapper.cpp
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -15,16 +15,17 @@
 #include "jsmath.h"
 #include "jsproxy.h"
 #include "jsscope.h"
 #include "jswatchpoint.h"
 #include "jswrapper.h"
 
 #include "assembler/wtf/Platform.h"
 #include "gc/Marking.h"
+#include "gc/Root.h"
 #include "js/MemoryMetrics.h"
 #include "methodjit/MethodJIT.h"
 #include "methodjit/PolyIC.h"
 #include "methodjit/MonoIC.h"
 #include "methodjit/Retcon.h"
 #include "vm/Debugger.h"
 #include "yarr/BumpPointerAllocator.h"
 
@@ -238,26 +239,30 @@ WrapForSameCompartment(JSContext *cx, Ha
     vp->setObject(*wrapped);
     return true;
 }
 
 bool
 JSCompartment::putWrapper(const CrossCompartmentKey &wrapped, const js::Value &wrapper)
 {
     JS_ASSERT(wrapped.wrapped);
+    JS_ASSERT(!IsPoisonedPtr(wrapped.wrapped));
+    JS_ASSERT(!IsPoisonedPtr(wrapped.debugger));
+    JS_ASSERT(!IsPoisonedPtr(wrapper.toGCThing()));
     JS_ASSERT_IF(wrapped.kind == CrossCompartmentKey::StringWrapper, wrapper.isString());
     JS_ASSERT_IF(wrapped.kind != CrossCompartmentKey::StringWrapper, wrapper.isObject());
     // todo: uncomment when bug 815999 is fixed:
     // JS_ASSERT(!wrapped.wrapped->isMarked(gc::GRAY));
     return crossCompartmentWrappers.put(wrapped, wrapper);
 }
 
 bool
-JSCompartment::wrap(JSContext *cx, Value *vp, JSObject *existing)
+JSCompartment::wrap(JSContext *cx, Value *vp, JSObject *existingArg)
 {
+    RootedObject existing(cx, existingArg);
     JS_ASSERT(cx->compartment == this);
     JS_ASSERT_IF(existing, existing->compartment() == cx->compartment);
     JS_ASSERT_IF(existing, vp->isObject());
     JS_ASSERT_IF(existing, IsDeadProxyObject(existing));
 
     unsigned flags = 0;
 
     JS_CHECK_CHROME_RECURSION(cx, return false);
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -1044,18 +1044,20 @@ js::NukeCrossCompartmentWrappers(JSConte
 
     return JS_TRUE;
 }
 
 // Given a cross-compartment wrapper |wobj|, update it to point to
 // |newTarget|. This recomputes the wrapper with JS_WrapValue, and thus can be
 // useful even if wrapper already points to newTarget.
 bool
-js::RemapWrapper(JSContext *cx, JSObject *wobj, JSObject *newTarget)
+js::RemapWrapper(JSContext *cx, JSObject *wobjArg, JSObject *newTargetArg)
 {
+    RootedObject wobj(cx, wobjArg);
+    RootedObject newTarget(cx, newTargetArg);
     JS_ASSERT(IsCrossCompartmentWrapper(wobj));
     JS_ASSERT(!IsCrossCompartmentWrapper(newTarget));
     JSObject *origTarget = Wrapper::wrappedObject(wobj);
     JS_ASSERT(origTarget);
     Value origv = ObjectValue(*origTarget);
     JSCompartment *wcompartment = wobj->compartment();
 
     // If we're mapping to a different target (as opposed to just recomputing
@@ -1072,19 +1074,19 @@ js::RemapWrapper(JSContext *cx, JSObject
 
     // When we remove origv from the wrapper map, its wrapper, wobj, must
     // immediately cease to be a cross-compartment wrapper. Neuter it.
     NukeCrossCompartmentWrapper(cx, wobj);
 
     // First, we wrap it in the new compartment. We try to use the existing
     // wrapper, |wobj|, since it's been nuked anyway. The wrap() function has
     // the choice to reuse |wobj| or not.
-    JSObject *tobj = newTarget;
+    RootedObject tobj(cx, newTarget);
     AutoCompartment ac(cx, wobj);
-    if (!wcompartment->wrap(cx, &tobj, wobj))
+    if (!wcompartment->wrap(cx, tobj.address(), wobj))
         MOZ_CRASH();
 
     // If wrap() reused |wobj|, it will have overwritten it and returned with
     // |tobj == wobj|. Otherwise, |tobj| will point to a new wrapper and |wobj|
     // will still be nuked. In the latter case, we replace |wobj| with the
     // contents of the new wrapper in |tobj|.
     if (tobj != wobj) {
         // Now, because we need to maintain object identity, we do a brain
@@ -1102,20 +1104,21 @@ js::RemapWrapper(JSContext *cx, JSObject
     // wrapper, which has now been updated (via reuse or swap).
     wcompartment->putWrapper(ObjectValue(*newTarget), ObjectValue(*wobj));
     return true;
 }
 
 // Remap all cross-compartment wrappers pointing to |oldTarget| to point to
 // |newTarget|. All wrappers are recomputed.
 JS_FRIEND_API(bool)
-js::RemapAllWrappersForObject(JSContext *cx, JSObject *oldTarget,
-                              JSObject *newTarget)
+js::RemapAllWrappersForObject(JSContext *cx, JSObject *oldTargetArg,
+                              JSObject *newTargetArg)
 {
-    Value origv = ObjectValue(*oldTarget);
+    RootedValue origv(cx, ObjectValue(*oldTargetArg));
+    RootedObject newTarget(cx, newTargetArg);
 
     AutoWrapperVector toTransplant(cx);
     if (!toTransplant.reserve(cx->runtime->compartments.length()))
         return false;
 
     for (CompartmentsIter c(cx->runtime); !c.done(); c.next()) {
         if (WrapperMap::Ptr wp = c->lookupWrapper(origv)) {
             // We found a wrapper. Remember and root it.