Bug 1443468 - Suppress gray marking assertion during maniupulation of internal GC state r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 20 Apr 2018 10:09:52 +0200
changeset 414650 104deeaf58dc7d20fe34fd226be4687467bd2713
parent 414649 57b9d3888456559d6b15c8282b240178fb6e05f0
child 414651 8adb1d0460486e306740661f950d87bc77df54ee
push id102396
push userjcoppeard@mozilla.com
push dateFri, 20 Apr 2018 08:10:55 +0000
treeherdermozilla-inbound@104deeaf58dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1443468
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 1443468 - Suppress gray marking assertion during maniupulation of internal GC state r=sfink
js/public/Proxy.h
js/src/gc/GC.cpp
js/src/vm/ProxyObject.cpp
--- a/js/public/Proxy.h
+++ b/js/public/Proxy.h
@@ -458,16 +458,34 @@ GetProxyDataLayout(JSObject* obj)
 
 inline const ProxyDataLayout*
 GetProxyDataLayout(const JSObject* obj)
 {
     MOZ_ASSERT(IsProxy(obj));
     return reinterpret_cast<const ProxyDataLayout*>(reinterpret_cast<const uint8_t*>(obj) +
                                                     ProxyDataOffset);
 }
+
+JS_FRIEND_API(void)
+SetValueInProxy(Value* slot, const Value& value);
+
+inline void
+SetProxyReservedSlotUnchecked(JSObject* obj, size_t n, const Value& extra)
+{
+    MOZ_ASSERT(n < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)));
+
+    Value* vp = &GetProxyDataLayout(obj)->reservedSlots->slots[n];
+
+    // Trigger a barrier before writing the slot.
+    if (vp->isGCThing() || extra.isGCThing())
+        SetValueInProxy(vp, extra);
+    else
+        *vp = extra;
+}
+
 } // namespace detail
 
 inline const BaseProxyHandler*
 GetProxyHandler(const JSObject* obj)
 {
     return detail::GetProxyDataLayout(obj)->handler;
 }
 
@@ -491,44 +509,33 @@ GetProxyReservedSlot(const JSObject* obj
 }
 
 inline void
 SetProxyHandler(JSObject* obj, const BaseProxyHandler* handler)
 {
     detail::GetProxyDataLayout(obj)->handler = handler;
 }
 
-JS_FRIEND_API(void)
-SetValueInProxy(Value* slot, const Value& value);
-
 inline void
 SetProxyReservedSlot(JSObject* obj, size_t n, const Value& extra)
 {
-    MOZ_ASSERT(n < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)));
     MOZ_ASSERT_IF(gc::detail::ObjectIsMarkedBlack(obj), JS::ValueIsNotGray(extra));
-
-    Value* vp = &detail::GetProxyDataLayout(obj)->reservedSlots->slots[n];
-
-    // Trigger a barrier before writing the slot.
-    if (vp->isGCThing() || extra.isGCThing())
-        SetValueInProxy(vp, extra);
-    else
-        *vp = extra;
+    detail::SetProxyReservedSlotUnchecked(obj, n, extra);
 }
 
 inline void
 SetProxyPrivate(JSObject* obj, const Value& value)
 {
     MOZ_ASSERT_IF(gc::detail::ObjectIsMarkedBlack(obj), JS::ValueIsNotGray(value));
 
     Value* vp = &detail::GetProxyDataLayout(obj)->values()->privateSlot;
 
     // Trigger a barrier before writing the slot.
     if (vp->isGCThing() || value.isGCThing())
-        SetValueInProxy(vp, value);
+        detail::SetValueInProxy(vp, value);
     else
         *vp = value;
 }
 
 inline bool
 IsScriptedProxy(const JSObject* obj)
 {
     return IsProxy(obj) && GetProxyHandler(obj)->isScripted();
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -5163,16 +5163,17 @@ NextIncomingCrossCompartmentPointer(JSOb
 
     return next;
 }
 
 void
 js::gc::DelayCrossCompartmentGrayMarking(JSObject* src)
 {
     MOZ_ASSERT(IsGrayListObject(src));
+    MOZ_ASSERT(src->isMarkedGray());
 
     AutoTouchingGrayThings tgt;
 
     /* Called from MarkCrossCompartmentXXX functions. */
     unsigned slot = ProxyObject::grayLinkReservedSlot(src);
     JSObject* dest = CrossCompartmentPointerReferent(src);
     JSCompartment* comp = dest->compartment();
 
@@ -5264,17 +5265,17 @@ RemoveFromGrayList(JSObject* wrapper)
         comp->gcIncomingGrayPointers = tail;
         return true;
     }
 
     while (obj) {
         unsigned slot = ProxyObject::grayLinkReservedSlot(obj);
         JSObject* next = GetProxyReservedSlot(obj, slot).toObjectOrNull();
         if (next == wrapper) {
-            SetProxyReservedSlot(obj, slot, ObjectOrNullValue(tail));
+            js::detail::SetProxyReservedSlotUnchecked(obj, slot, ObjectOrNullValue(tail));
             return true;
         }
         obj = next;
     }
 
     MOZ_CRASH("object not found in gray link list");
 }
 
--- a/js/src/vm/ProxyObject.cpp
+++ b/js/src/vm/ProxyObject.cpp
@@ -199,14 +199,14 @@ ProxyObject::create(JSContext* cx, const
             return cx->alreadyReportedOOM();
         pobj = pobjRoot;
     }
 
     return pobj;
 }
 
 JS_FRIEND_API(void)
-js::SetValueInProxy(Value* slot, const Value& value)
+js::detail::SetValueInProxy(Value* slot, const Value& value)
 {
     // Slots in proxies are not GCPtrValues, so do a cast whenever assigning
     // values to them which might trigger a barrier.
     *reinterpret_cast<GCPtrValue*>(slot) = value;
 }