Bug 1454940 - Update assertions in JS_TransplantObject to allow the original object to be gray r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 19 Apr 2018 10:36:29 +0200
changeset 468060 677b77419dcb0a773fe72fd2164f3d8c97996f5a
parent 468059 dd2d50a70a7e972bb4a35a8895322b5a0ef6dd92
child 468061 f4f07a24b951dd9c94eb3775a7b58c534fb9d524
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1454940
milestone61.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 1454940 - Update assertions in JS_TransplantObject to allow the original object to be gray r=sfink
js/src/jsapi.cpp
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -868,33 +868,34 @@ JS_PUBLIC_API(JSObject*)
 JS_TransplantObject(JSContext* cx, HandleObject origobj, HandleObject target)
 {
     AssertHeapIsIdle();
     MOZ_ASSERT(origobj != target);
     MOZ_ASSERT(!origobj->is<CrossCompartmentWrapperObject>());
     MOZ_ASSERT(!target->is<CrossCompartmentWrapperObject>());
     MOZ_ASSERT(origobj->getClass() == target->getClass());
     ReleaseAssertObjectHasNoWrappers(cx, target);
+    MOZ_ASSERT(JS::CellIsNotGray(target));
 
     RootedValue origv(cx, ObjectValue(*origobj));
     RootedObject newIdentity(cx);
 
     // Don't allow a compacting GC to observe any intermediate state.
     AutoDisableCompactingGC nocgc(cx);
 
     AutoDisableProxyCheck adpc;
 
     JSCompartment* destination = target->compartment();
 
     if (origobj->compartment() == destination) {
         // If the original object is in the same compartment as the
         // destination, then we know that we won't find a wrapper in the
         // destination's cross compartment map and that the same
         // object will continue to work.
-        AutoCompartment ac(cx, origobj);
+        AutoCompartmentUnchecked ac(cx, origobj->compartment());
         if (!JSObject::swap(cx, origobj, target))
             MOZ_CRASH();
         newIdentity = origobj;
     } else if (WrapperMap::Ptr p = destination->lookupWrapper(origv)) {
         // There might already be a wrapper for the original object in
         // the new compartment. If there is, we use its identity and swap
         // in the contents of |target|.
         newIdentity = &p->value().get().toObject();
@@ -918,28 +919,29 @@ JS_TransplantObject(JSContext* cx, Handl
     // `newIdentity == origobj`, because this process also clears out any
     // cached wrapper state.
     if (!RemapAllWrappersForObject(cx, origobj, newIdentity))
         MOZ_CRASH();
 
     // Lastly, update the original object to point to the new one.
     if (origobj->compartment() != destination) {
         RootedObject newIdentityWrapper(cx, newIdentity);
-        AutoCompartment ac(cx, origobj);
+        AutoCompartmentUnchecked ac(cx, origobj->compartment());
         if (!JS_WrapObject(cx, &newIdentityWrapper))
             MOZ_CRASH();
         MOZ_ASSERT(Wrapper::wrappedObject(newIdentityWrapper) == newIdentity);
         if (!JSObject::swap(cx, origobj, newIdentityWrapper))
             MOZ_CRASH();
         if (!origobj->compartment()->putWrapper(cx, CrossCompartmentKey(newIdentity), origv))
             MOZ_CRASH();
     }
 
     // The new identity object might be one of several things. Return it to avoid
     // ambiguity.
+    MOZ_ASSERT(JS::CellIsNotGray(newIdentity));
     return newIdentity;
 }
 
 /*
  * Recompute all cross-compartment wrappers for an object, resetting state.
  * Gecko uses this to clear Xray wrappers when doing a navigation that reuses
  * the inner window and global object.
  */