Backed out 2 changesets (bug 1335751) for mochitest devtools failures
authorJon Coppeard <jcoppeard@mozilla.com>
Sun, 05 Mar 2017 12:37:31 +0000
changeset 375059 71f7cd1d842f054d2d8b6ebc4dc06b7c4ba0bc54
parent 375058 376d3e4d4a750adf58e011f65b530ecf65726652
child 375060 3f78543493a2b14aaa43db417fa2085d457c94df
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1335751
milestone54.0a1
Backed out 2 changesets (bug 1335751) for mochitest devtools failures
js/public/TracingAPI.h
js/src/gc/Marking.cpp
js/src/gc/Verifier.cpp
js/src/jsfriendapi.h
xpcom/base/CycleCollectedJSContext.cpp
xpcom/base/CycleCollectedJSContext.h
xpcom/base/nsCycleCollector.cpp
--- a/js/public/TracingAPI.h
+++ b/js/public/TracingAPI.h
@@ -81,31 +81,29 @@ class JS_PUBLIC_API(JSTracer)
         // Traversing children is the responsibility of the callback.
         Callback
     };
     bool isMarkingTracer() const { return tag_ == TracerKindTag::Marking || tag_ == TracerKindTag::WeakMarking; }
     bool isWeakMarkingTracer() const { return tag_ == TracerKindTag::WeakMarking; }
     bool isTenuringTracer() const { return tag_ == TracerKindTag::Tenuring; }
     bool isCallbackTracer() const { return tag_ == TracerKindTag::Callback; }
     inline JS::CallbackTracer* asCallbackTracer();
-    bool traceWeakEdges() const { return traceWeakEdges_; }
 #ifdef DEBUG
     bool checkEdges() { return checkEdges_; }
 #endif
 
   protected:
     JSTracer(JSRuntime* rt, TracerKindTag tag,
              WeakMapTraceKind weakTraceKind = TraceWeakMapValues)
       : runtime_(rt)
       , weakMapAction_(weakTraceKind)
 #ifdef DEBUG
       , checkEdges_(true)
 #endif
       , tag_(tag)
-      , traceWeakEdges_(true)
     {}
 
 #ifdef DEBUG
     // Set whether to check edges are valid in debug builds.
     void setCheckEdges(bool check) {
         checkEdges_ = check;
     }
 #endif
@@ -114,17 +112,16 @@ class JS_PUBLIC_API(JSTracer)
     JSRuntime* runtime_;
     WeakMapTraceKind weakMapAction_;
 #ifdef DEBUG
     bool checkEdges_;
 #endif
 
   protected:
     TracerKindTag tag_;
-    bool traceWeakEdges_;
 };
 
 namespace JS {
 
 class AutoTracingName;
 class AutoTracingIndex;
 class AutoTracingCallback;
 
@@ -230,21 +227,16 @@ class JS_PUBLIC_API(CallbackTracer) : pu
     void dispatchToOnEdge(JSScript** scriptp) { onScriptEdge(scriptp); }
     void dispatchToOnEdge(js::Shape** shapep) { onShapeEdge(shapep); }
     void dispatchToOnEdge(js::ObjectGroup** groupp) { onObjectGroupEdge(groupp); }
     void dispatchToOnEdge(js::BaseShape** basep) { onBaseShapeEdge(basep); }
     void dispatchToOnEdge(js::jit::JitCode** codep) { onJitCodeEdge(codep); }
     void dispatchToOnEdge(js::LazyScript** lazyp) { onLazyScriptEdge(lazyp); }
     void dispatchToOnEdge(js::Scope** scopep) { onScopeEdge(scopep); }
 
-  protected:
-    void setTraceWeakEdges(bool value) {
-        traceWeakEdges_ = value;
-    }
-
   private:
     friend class AutoTracingName;
     const char* contextName_;
 
     friend class AutoTracingIndex;
     size_t contextIndex_;
 
     friend class AutoTracingDetails;
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -474,22 +474,19 @@ js::UnsafeTraceManuallyBarrieredEdge(JST
 {
     DispatchToTracer(trc, ConvertToBase(thingp), name);
 }
 
 template <typename T>
 void
 js::TraceWeakEdge(JSTracer* trc, WeakRef<T>* thingp, const char* name)
 {
-    if (!trc->isMarkingTracer()) {
-        // Non-marking tracers can select whether or not they see weak edges.
-        if (trc->traceWeakEdges())
-            DispatchToTracer(trc, ConvertToBase(thingp->unsafeUnbarrieredForTracing()), name);
-        return;
-    }
+    // Non-marking tracers treat the edge strongly.
+    if (!trc->isMarkingTracer())
+        return DispatchToTracer(trc, ConvertToBase(thingp->unsafeUnbarrieredForTracing()), name);
 
     NoteWeakEdge(GCMarker::fromTracer(trc),
                  ConvertToBase(thingp->unsafeUnbarrieredForTracing()));
 }
 
 template <typename T>
 void
 js::TraceRoot(JSTracer* trc, T* thingp, const char* name)
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -444,34 +444,24 @@ js::gc::GCRuntime::finishVerifier()
     if (verifyPreData) {
         js_delete(verifyPreData.ref());
         verifyPreData = nullptr;
     }
 }
 
 #endif /* JS_GC_ZEAL */
 
-#if defined(JSGC_HASH_TABLE_CHECKS) || defined(DEBUG)
+#ifdef JSGC_HASH_TABLE_CHECKS
 
-class HeapCheckTracerBase : public JS::CallbackTracer
+class CheckHeapTracer : public JS::CallbackTracer
 {
   public:
-    explicit HeapCheckTracerBase(JSRuntime* rt, WeakMapTraceKind weakTraceKind);
+    explicit CheckHeapTracer(JSRuntime* rt);
     bool init();
-    bool traceHeap(AutoLockForExclusiveAccess& lock);
-    virtual void checkCell(Cell* cell) = 0;
-
-  protected:
-    void dumpCellPath();
-
-    Cell* parentCell() {
-        return parentIndex == -1 ? nullptr : stack[parentIndex].thing.asCell();
-    }
-
-    size_t failures;
+    void check(AutoLockForExclusiveAccess& lock);
 
   private:
     void onChild(const JS::GCCellPtr& thing) override;
 
     struct WorkItem {
         WorkItem(JS::GCCellPtr thing, const char* name, int parentIndex)
           : thing(thing), name(name), parentIndex(parentIndex), processed(false)
         {}
@@ -479,216 +469,114 @@ class HeapCheckTracerBase : public JS::C
         JS::GCCellPtr thing;
         const char* name;
         int parentIndex;
         bool processed;
     };
 
     JSRuntime* rt;
     bool oom;
+    size_t failures;
     HashSet<Cell*, DefaultHasher<Cell*>, SystemAllocPolicy> visited;
     Vector<WorkItem, 0, SystemAllocPolicy> stack;
     int parentIndex;
 };
 
-HeapCheckTracerBase::HeapCheckTracerBase(JSRuntime* rt, WeakMapTraceKind weakTraceKind)
-  : CallbackTracer(rt, weakTraceKind),
-    failures(0),
+CheckHeapTracer::CheckHeapTracer(JSRuntime* rt)
+  : CallbackTracer(rt, TraceWeakMapKeysValues),
     rt(rt),
     oom(false),
+    failures(0),
     parentIndex(-1)
 {
 #ifdef DEBUG
     setCheckEdges(false);
 #endif
 }
 
 bool
-HeapCheckTracerBase::init()
+CheckHeapTracer::init()
 {
     return visited.init();
 }
 
+inline static bool
+IsValidGCThingPointer(Cell* cell)
+{
+    return (uintptr_t(cell) & CellMask) == 0;
+}
+
 void
-HeapCheckTracerBase::onChild(const JS::GCCellPtr& thing)
+CheckHeapTracer::onChild(const JS::GCCellPtr& thing)
 {
     Cell* cell = thing.asCell();
-    checkCell(cell);
-
     if (visited.lookup(cell))
         return;
 
     if (!visited.put(cell)) {
         oom = true;
         return;
     }
 
+    if (!IsValidGCThingPointer(cell) || !IsGCThingValidAfterMovingGC(cell))
+    {
+        failures++;
+        fprintf(stderr, "Bad pointer %p\n", cell);
+        const char* name = contextName();
+        for (int index = parentIndex; index != -1; index = stack[index].parentIndex) {
+            const WorkItem& parent = stack[index];
+            cell = parent.thing.asCell();
+            fprintf(stderr, "  from %s %p %s edge\n",
+                    GCTraceKindToAscii(cell->getTraceKind()), cell, name);
+            name = parent.name;
+        }
+        fprintf(stderr, "  from root %s\n", name);
+        return;
+    }
+
     // Don't trace into GC things owned by another runtime.
     if (cell->runtimeFromAnyThread() != rt)
         return;
 
-    // Don't trace into GC in zones being used by helper threads.
-    Zone* zone = thing.is<JSObject>() ? thing.as<JSObject>().zone() : cell->asTenured().zone();
-    if (zone->group() && zone->group()->usedByHelperThread)
-        return;
-
     WorkItem item(thing, contextName(), parentIndex);
     if (!stack.append(item))
         oom = true;
 }
 
-bool
-HeapCheckTracerBase::traceHeap(AutoLockForExclusiveAccess& lock)
+void
+CheckHeapTracer::check(AutoLockForExclusiveAccess& lock)
 {
     // The analysis thinks that traceRuntime might GC by calling a GC callback.
     JS::AutoSuppressGCAnalysis nogc;
     if (!rt->isBeingDestroyed())
         rt->gc.traceRuntime(this, lock);
 
-    while (!stack.empty() && !oom) {
+    while (!stack.empty()) {
         WorkItem item = stack.back();
         if (item.processed) {
             stack.popBack();
         } else {
             parentIndex = stack.length() - 1;
+            TraceChildren(this, item.thing);
             stack.back().processed = true;
-            TraceChildren(this, item.thing);
         }
     }
 
-    return !oom;
-}
-
-void
-HeapCheckTracerBase::dumpCellPath()
-{
-    const char* name = contextName();
-    for (int index = parentIndex; index != -1; index = stack[index].parentIndex) {
-        const WorkItem& parent = stack[index];
-        Cell* cell = parent.thing.asCell();
-        fprintf(stderr, "  from %s %p %s edge\n",
-                GCTraceKindToAscii(cell->getTraceKind()), cell, name);
-        name = parent.name;
-    }
-    fprintf(stderr, "  from root %s\n", name);
-}
-
-#endif // defined(JSGC_HASH_TABLE_CHECKS) || defined(DEBUG)
-
-#ifdef JSGC_HASH_TABLE_CHECKS
-
-class CheckHeapTracer final : public HeapCheckTracerBase
-{
-  public:
-    explicit CheckHeapTracer(JSRuntime* rt);
-    void check(AutoLockForExclusiveAccess& lock);
-
-  private:
-    void checkCell(Cell* cell) override;
-};
-
-CheckHeapTracer::CheckHeapTracer(JSRuntime* rt)
-  : HeapCheckTracerBase(rt, TraceWeakMapKeysValues)
-{}
-
-inline static bool
-IsValidGCThingPointer(Cell* cell)
-{
-    return (uintptr_t(cell) & CellMask) == 0;
-}
-
-void
-CheckHeapTracer::checkCell(Cell* cell)
-{
-    if (!IsValidGCThingPointer(cell) || !IsGCThingValidAfterMovingGC(cell)) {
-        failures++;
-        fprintf(stderr, "Bad pointer %p\n", cell);
-        dumpCellPath();
-    }
-}
-
-void
-CheckHeapTracer::check(AutoLockForExclusiveAccess& lock)
-{
-    if (!traceHeap(lock))
+    if (oom)
         return;
 
-    if (failures)
-        fprintf(stderr, "Heap check: %" PRIuSIZE " failure(s)\n", failures);
+    if (failures) {
+        fprintf(stderr, "Heap check: %" PRIuSIZE " failure(s) out of %" PRIu32 " pointers checked\n",
+                failures, visited.count());
+    }
     MOZ_RELEASE_ASSERT(failures == 0);
 }
 
 void
 js::gc::CheckHeapAfterGC(JSRuntime* rt)
 {
     AutoTraceSession session(rt, JS::HeapState::Tracing);
     CheckHeapTracer tracer(rt);
     if (tracer.init())
         tracer.check(session.lock);
 }
 
 #endif /* JSGC_HASH_TABLE_CHECKS */
-
-#ifdef DEBUG
-
-class CheckGrayMarkingTracer final : public HeapCheckTracerBase
-{
-  public:
-    explicit CheckGrayMarkingTracer(JSRuntime* rt);
-    bool check(AutoLockForExclusiveAccess& lock);
-
-  private:
-    void checkCell(Cell* cell) override;
-};
-
-CheckGrayMarkingTracer::CheckGrayMarkingTracer(JSRuntime* rt)
-  : HeapCheckTracerBase(rt, DoNotTraceWeakMaps)
-{
-    // Weak gray->black edges are allowed.
-    setTraceWeakEdges(false);
-}
-
-void
-CheckGrayMarkingTracer::checkCell(Cell* cell)
-{
-    Cell* parent = parentCell();
-    if (!cell->isTenured() || !parent || !parent->isTenured())
-        return;
-
-    TenuredCell* tenuredCell = &cell->asTenured();
-    TenuredCell* tenuredParent = &parent->asTenured();
-    if (tenuredParent->isMarked(BLACK) && !tenuredParent->isMarked(GRAY) &&
-        tenuredCell->isMarked(GRAY))
-    {
-        failures++;
-        fprintf(stderr, "Found black to gray edge %p\n", cell);
-        dumpCellPath();
-    }
-}
-
-bool
-CheckGrayMarkingTracer::check(AutoLockForExclusiveAccess& lock)
-{
-    if (!traceHeap(lock))
-        return true; // Ignore failure.
-
-    return failures == 0;
-}
-
-JS_FRIEND_API(bool)
-js::CheckGrayMarkingState(JSContext* cx)
-{
-    JSRuntime* rt = cx->runtime();
-    MOZ_ASSERT(!JS::CurrentThreadIsHeapCollecting());
-    MOZ_ASSERT(!rt->gc.isIncrementalGCInProgress());
-    if (!rt->gc.areGrayBitsValid())
-        return true;
-
-    gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PHASE_TRACE_HEAP);
-    AutoTraceSession session(rt, JS::HeapState::Tracing);
-    CheckGrayMarkingTracer tracer(rt);
-    if (!tracer.init())
-        return true; // Ignore failure
-
-    return tracer.check(session.lock);
-}
-
-#endif // DEBUG
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -487,26 +487,16 @@ IterateGrayObjects(JS::Zone* zone, GCThi
 
 /**
  * Invoke cellCallback on every gray JSObject in the given zone while cycle
  * collection is in progress.
  */
 extern JS_FRIEND_API(void)
 IterateGrayObjectsUnderCC(JS::Zone* zone, GCThingCallback cellCallback, void* data);
 
-#ifdef DEBUG
-// Trace the heap and check there are no black to gray edges. These are
-// not allowed since the cycle collector could throw away the gray thing and
-// leave a dangling pointer.
-//
-// This doesn't trace weak maps as these are handled separately.
-extern JS_FRIEND_API(bool)
-CheckGrayMarkingState(JSContext* cx);
-#endif
-
 #ifdef JS_HAS_CTYPES
 extern JS_FRIEND_API(size_t)
 SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject* obj);
 #endif
 
 extern JS_FRIEND_API(JSCompartment*)
 GetAnyCompartmentInZone(JS::Zone* zone);
 
--- a/xpcom/base/CycleCollectedJSContext.cpp
+++ b/xpcom/base/CycleCollectedJSContext.cpp
@@ -222,54 +222,17 @@ NoteWeakMapsTracer::trace(JSObject* aMap
     // if we haven't already.
     if (!mChildTracer.mTracedAny &&
         aKey && JS::GCThingIsMarkedGray(aKey) && kdelegate) {
       mCb.NoteWeakMapping(aMap, aKey, kdelegate, nullptr);
     }
   }
 }
 
-// Report whether the key or value of a weak mapping entry are gray but need to
-// be marked black.
-static void
-ShouldWeakMappingEntryBeBlack(JSObject* aMap, JS::GCCellPtr aKey, JS::GCCellPtr aValue,
-                              bool* aKeyShouldBeBlack, bool* aValueShouldBeBlack)
-{
-  *aKeyShouldBeBlack = false;
-  *aValueShouldBeBlack = false;
-
-  // If nothing that could be held alive by this entry is marked gray, return.
-  bool keyMightNeedMarking = aKey && JS::GCThingIsMarkedGray(aKey);
-  bool valueMightNeedMarking = aValue && JS::GCThingIsMarkedGray(aValue) &&
-    aValue.kind() != JS::TraceKind::String;
-  if (!keyMightNeedMarking && !valueMightNeedMarking) {
-    return;
-  }
-
-  if (!AddToCCKind(aKey.kind())) {
-    aKey = nullptr;
-  }
-
-  if (keyMightNeedMarking && aKey.is<JSObject>()) {
-    JSObject* kdelegate = js::GetWeakmapKeyDelegate(&aKey.as<JSObject>());
-    if (kdelegate && !JS::ObjectIsMarkedGray(kdelegate) &&
-        (!aMap || !JS::ObjectIsMarkedGray(aMap)))
-    {
-      *aKeyShouldBeBlack = true;
-    }
-  }
-
-  if (aValue && JS::GCThingIsMarkedGray(aValue) &&
-      (!aKey || !JS::GCThingIsMarkedGray(aKey)) &&
-      (!aMap || !JS::ObjectIsMarkedGray(aMap)) &&
-      aValue.kind() != JS::TraceKind::Shape) {
-    *aValueShouldBeBlack = true;
-  }
-}
-
+// This is based on the logic in FixWeakMappingGrayBitsTracer::trace.
 struct FixWeakMappingGrayBitsTracer : public js::WeakMapTracer
 {
   explicit FixWeakMappingGrayBitsTracer(JSContext* aCx)
     : js::WeakMapTracer(aCx)
   {
   }
 
   void
@@ -278,73 +241,52 @@ struct FixWeakMappingGrayBitsTracer : pu
     do {
       mAnyMarked = false;
       js::TraceWeakMaps(this);
     } while (mAnyMarked);
   }
 
   void trace(JSObject* aMap, JS::GCCellPtr aKey, JS::GCCellPtr aValue) override
   {
-    bool keyShouldBeBlack;
-    bool valueShouldBeBlack;
-    ShouldWeakMappingEntryBeBlack(aMap, aKey, aValue,
-                                  &keyShouldBeBlack, &valueShouldBeBlack);
-    if (keyShouldBeBlack && JS::UnmarkGrayGCThingRecursively(aKey)) {
-      mAnyMarked = true;
+    // If nothing that could be held alive by this entry is marked gray, return.
+    bool keyMightNeedMarking = aKey && JS::GCThingIsMarkedGray(aKey);
+    bool valueMightNeedMarking = aValue && JS::GCThingIsMarkedGray(aValue) &&
+                                 aValue.kind() != JS::TraceKind::String;
+    if (!keyMightNeedMarking && !valueMightNeedMarking) {
+      return;
+    }
+
+    if (!AddToCCKind(aKey.kind())) {
+      aKey = nullptr;
     }
 
-    if (valueShouldBeBlack && JS::UnmarkGrayGCThingRecursively(aValue)) {
-      mAnyMarked = true;
+    if (keyMightNeedMarking && aKey.is<JSObject>()) {
+      JSObject* kdelegate = js::GetWeakmapKeyDelegate(&aKey.as<JSObject>());
+      if (kdelegate && !JS::ObjectIsMarkedGray(kdelegate) &&
+          (!aMap || !JS::ObjectIsMarkedGray(aMap)))
+      {
+        if (JS::UnmarkGrayGCThingRecursively(aKey)) {
+          mAnyMarked = true;
+        }
+      }
+    }
+
+    if (aValue && JS::GCThingIsMarkedGray(aValue) &&
+        (!aKey || !JS::GCThingIsMarkedGray(aKey)) &&
+        (!aMap || !JS::ObjectIsMarkedGray(aMap)) &&
+        aValue.kind() != JS::TraceKind::Shape) {
+      if (JS::UnmarkGrayGCThingRecursively(aValue)) {
+        mAnyMarked = true;
+      }
     }
   }
 
   MOZ_INIT_OUTSIDE_CTOR bool mAnyMarked;
 };
 
-#ifdef DEBUG
-// Check whether weak maps are marked correctly according to the logic above.
-struct CheckWeakMappingGrayBitsTracer : public js::WeakMapTracer
-{
-  explicit CheckWeakMappingGrayBitsTracer(JSContext* aCx)
-    : js::WeakMapTracer(aCx), mFailed(false)
-  {
-  }
-
-  static bool
-  Check(JSContext* aCx)
-  {
-    CheckWeakMappingGrayBitsTracer tracer(aCx);
-    js::TraceWeakMaps(&tracer);
-    return !tracer.mFailed;
-  }
-
-  void trace(JSObject* aMap, JS::GCCellPtr aKey, JS::GCCellPtr aValue) override
-  {
-    bool keyShouldBeBlack;
-    bool valueShouldBeBlack;
-    ShouldWeakMappingEntryBeBlack(aMap, aKey, aValue,
-                                  &keyShouldBeBlack, &valueShouldBeBlack);
-
-    if (keyShouldBeBlack) {
-      fprintf(stderr, "Weak mapping key %p of map %p should be black\n",
-              aKey.asCell(), aMap);
-      mFailed = true;
-    }
-
-    if (valueShouldBeBlack) {
-      fprintf(stderr, "Weak mapping value %p of map %p should be black\n",
-              aValue.asCell(), aMap);
-      mFailed = true;
-    }
-  }
-
-  bool mFailed;
-};
-#endif // DEBUG
-
 static void
 CheckParticipatesInCycleCollection(JS::GCCellPtr aThing, const char* aName,
                                    void* aClosure)
 {
   bool* cycleCollectionEnabled = static_cast<bool*>(aClosure);
 
   if (*cycleCollectionEnabled) {
     return;
@@ -1308,26 +1250,16 @@ CycleCollectedJSContext::FixWeakMappingG
 {
   MOZ_ASSERT(mJSContext);
   MOZ_ASSERT(!JS::IsIncrementalGCInProgress(mJSContext),
              "Don't call FixWeakMappingGrayBits during a GC.");
   FixWeakMappingGrayBitsTracer fixer(mJSContext);
   fixer.FixAll();
 }
 
-void
-CycleCollectedJSContext::CheckGrayBits() const
-{
-  MOZ_ASSERT(mJSContext);
-  MOZ_ASSERT(!JS::IsIncrementalGCInProgress(mJSContext),
-             "Don't call CheckGrayBits during a GC.");
-  MOZ_ASSERT(js::CheckGrayMarkingState(mJSContext));
-  MOZ_ASSERT(CheckWeakMappingGrayBitsTracer::Check(mJSContext));
-}
-
 bool
 CycleCollectedJSContext::AreGCGrayBitsValid() const
 {
   MOZ_ASSERT(mJSContext);
   return js::AreGCGrayBitsValid(mJSContext);
 }
 
 void
--- a/xpcom/base/CycleCollectedJSContext.h
+++ b/xpcom/base/CycleCollectedJSContext.h
@@ -308,17 +308,16 @@ public:
   std::queue<nsCOMPtr<nsIRunnable>>& GetDebuggerPromiseMicroTaskQueue();
 
   nsCycleCollectionParticipant* GCThingParticipant();
   nsCycleCollectionParticipant* ZoneParticipant();
 
   nsresult TraverseRoots(nsCycleCollectionNoteRootCallback& aCb);
   virtual bool UsefulToMergeZones() const;
   void FixWeakMappingGrayBits() const;
-  void CheckGrayBits() const;
   bool AreGCGrayBitsValid() const;
   void GarbageCollect(uint32_t aReason) const;
 
   void NurseryWrapperAdded(nsWrapperCache* aCache);
   void NurseryWrapperPreserved(JSObject* aWrapper);
   void JSObjectsTenured();
 
   void DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc,
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -3827,19 +3827,16 @@ nsCycleCollector::BeginCollection(ccType
   bool forceGC = isShutdown || (mLogger && mLogger->IsAllTraces());
 
   // BeginCycleCollectionCallback() might have started an IGC, and we need
   // to finish it before we run FixGrayBits.
   FinishAnyIncrementalGCInProgress();
   timeLog.Checkpoint("Pre-FixGrayBits finish IGC");
 
   FixGrayBits(forceGC, timeLog);
-  if (mJSContext) {
-    mJSContext->CheckGrayBits();
-  }
 
   FreeSnowWhite(true);
   timeLog.Checkpoint("BeginCollection FreeSnowWhite");
 
   if (mLogger && NS_FAILED(mLogger->Begin())) {
     mLogger = nullptr;
   }