Bug 1301301, part 1 - Unify NoteJSObject and NoteJSScript into NoteJSChild. r=smaug draft
authorAndrew McCreight <continuation@gmail.com>
Tue, 20 Sep 2016 13:51:04 -0700
changeset 416237 2a517e4fb9308bd15bea53c452b8c116c4368865
parent 416236 53c0918d84309956d8a99cbe0e7d80e3ee04e8cf
child 416238 ecb426227bc148ffd85ecdde08e3099757cbf350
push id30069
push userbmo:continuation@gmail.com
push dateWed, 21 Sep 2016 18:14:08 +0000
reviewerssmaug
bugs1301301
milestone52.0a1
Bug 1301301, part 1 - Unify NoteJSObject and NoteJSScript into NoteJSChild. r=smaug This will let my next patch pass in other GC things. This should not change behavior in any important way. MozReview-Commit-ID: FykviKKvQzI
dom/base/nsWrapperCache.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJS.cpp
js/xpconnect/src/XPCWrappedNative.cpp
xpcom/base/CycleCollectedJSContext.cpp
xpcom/base/nsCycleCollector.cpp
xpcom/base/nsCycleCollectorTraceJSHelpers.cpp
xpcom/glue/nsCycleCollectionTraversalCallback.h
--- a/dom/base/nsWrapperCache.cpp
+++ b/dom/base/nsWrapperCache.cpp
@@ -64,65 +64,62 @@ nsWrapperCache::ReleaseWrapper(void* aSc
 
 #ifdef DEBUG
 
 class DebugWrapperTraversalCallback : public nsCycleCollectionTraversalCallback
 {
 public:
   explicit DebugWrapperTraversalCallback(JSObject* aWrapper)
     : mFound(false)
-    , mWrapper(aWrapper)
+    , mWrapper(JS::GCCellPtr(aWrapper))
   {
     mFlags = WANT_ALL_TRACES;
   }
 
   NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt aRefCount,
                                            const char* aObjName)
   {
   }
   NS_IMETHOD_(void) DescribeGCedNode(bool aIsMarked,
                                      const char* aObjName,
                                      uint64_t aCompartmentAddress)
   {
   }
 
-  NS_IMETHOD_(void) NoteJSObject(JSObject* aChild)
+  NS_IMETHOD_(void) NoteJSChild(const JS::GCCellPtr& aChild)
   {
     if (aChild == mWrapper) {
       mFound = true;
     }
   }
-  NS_IMETHOD_(void) NoteJSScript(JSScript* aChild)
-  {
-  }
   NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild)
   {
   }
   NS_IMETHOD_(void) NoteNativeChild(void* aChild,
                                     nsCycleCollectionParticipant* aHelper)
   {
   }
 
   NS_IMETHOD_(void) NoteNextEdgeName(const char* aName)
   {
   }
 
   bool mFound;
 
 private:
-  JSObject* mWrapper;
+  JS::GCCellPtr mWrapper;
 };
 
 static void
 DebugWrapperTraceCallback(JS::GCCellPtr aPtr, const char* aName, void* aClosure)
 {
   DebugWrapperTraversalCallback* callback =
     static_cast<DebugWrapperTraversalCallback*>(aClosure);
   if (aPtr.is<JSObject>()) {
-    callback->NoteJSObject(&aPtr.as<JSObject>());
+    callback->NoteJSChild(aPtr);
   }
 }
 
 void
 nsWrapperCache::CheckCCWrapperTraversal(void* aScriptObjectHolder,
                                         nsScriptObjectTracer* aTracer)
 {
   JSObject* wrapper = GetWrapper();
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -70,17 +70,17 @@ void XPCTraceableVariant::TraceJS(JSTrac
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(XPCVariant)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPCVariant)
     JS::Value val = tmp->GetJSValPreserveColor();
     if (val.isObject()) {
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mJSVal");
-        cb.NoteJSObject(&val.toObject());
+        cb.NoteJSChild(JS::GCCellPtr(val));
     }
 
     tmp->mData.Traverse(cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPCVariant)
     JS::Value val = tmp->GetJSValPreserveColor();
 
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -118,17 +118,17 @@ NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrapp
     // Don't let the extra reference for nsSupportsWeakReference keep a wrapper that is
     // not subject to finalization alive.
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "self");
     cb.NoteXPCOMChild(s);
 
     if (tmp->IsValid()) {
         MOZ_ASSERT(refcnt > 1);
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mJSObj");
-        cb.NoteJSObject(tmp->GetJSObjectPreserveColor());
+        cb.NoteJSChild(JS::GCCellPtr(tmp->GetJSObjectPreserveColor()));
     }
 
     if (tmp->IsRootWrapper()) {
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "aggregated native");
         cb.NoteXPCOMChild(tmp->GetAggregatedNativeObject());
     } else {
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "root");
         cb.NoteXPCOMChild(ToSupports(tmp->GetRootWrapper()));
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -69,17 +69,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
         // considered "weak", and we're *not* going to traverse it.
         //
         // This reasoning is in line with the slightly confusing lifecycle rules
         // for XPCWrappedNatives, described in a larger comment below and also
         // on our wiki at http://wiki.mozilla.org/XPConnect_object_wrapping
 
         JSObject* obj = tmp->GetFlatJSObjectPreserveColor();
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFlatJSObject");
-        cb.NoteJSObject(obj);
+        cb.NoteJSChild(JS::GCCellPtr(obj));
     }
 
     // XPCWrappedNative keeps its native object alive.
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mIdentity");
     cb.NoteXPCOMChild(tmp->GetIdentityObject());
 
     tmp->NoteTearoffs(cb);
 
--- a/xpcom/base/CycleCollectedJSContext.cpp
+++ b/xpcom/base/CycleCollectedJSContext.cpp
@@ -350,21 +350,17 @@ TraversalTracer::onChild(const JS::GCCel
    * use special APIs to handle such chains iteratively.
    */
   if (AddToCCKind(aThing.kind())) {
     if (MOZ_UNLIKELY(mCb.WantDebugInfo())) {
       char buffer[200];
       getTracingEdgeName(buffer, sizeof(buffer));
       mCb.NoteNextEdgeName(buffer);
     }
-    if (aThing.is<JSObject>()) {
-      mCb.NoteJSObject(&aThing.as<JSObject>());
-    } else {
-      mCb.NoteJSScript(&aThing.as<JSScript>());
-    }
+    mCb.NoteJSChild(aThing);
   } else if (aThing.is<js::Shape>()) {
     // The maximum depth of traversal when tracing a Shape is unbounded, due to
     // the parent pointers on the shape.
     JS_TraceShapeCycleCollectorChildren(this, aThing);
   } else if (aThing.is<js::ObjectGroup>()) {
     // The maximum depth of traversal when tracing an ObjectGroup is unbounded,
     // due to information attached to the groups which can lead other groups to
     // be traced.
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -2117,18 +2117,17 @@ public:
 
   // nsCycleCollectionTraversalCallback methods.
   NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt aRefCount,
                                            const char* aObjName);
   NS_IMETHOD_(void) DescribeGCedNode(bool aIsMarked, const char* aObjName,
                                      uint64_t aCompartmentAddress);
 
   NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild);
-  NS_IMETHOD_(void) NoteJSObject(JSObject* aChild);
-  NS_IMETHOD_(void) NoteJSScript(JSScript* aChild);
+  NS_IMETHOD_(void) NoteJSChild(const JS::GCCellPtr& aThing);
   NS_IMETHOD_(void) NoteNativeChild(void* aChild,
                                     nsCycleCollectionParticipant* aParticipant);
   NS_IMETHOD_(void) NoteNextEdgeName(const char* aName);
 
 private:
   void NoteJSChild(JS::GCCellPtr aChild);
 
   NS_IMETHOD_(void) NoteRoot(void* aRoot,
@@ -2396,29 +2395,17 @@ CCGraphBuilder::NoteNativeChild(void* aC
 
   MOZ_ASSERT(aParticipant, "Need a nsCycleCollectionParticipant!");
   if (!aParticipant->CanSkipThis(aChild) || WantAllTraces()) {
     NoteChild(aChild, aParticipant, edgeName);
   }
 }
 
 NS_IMETHODIMP_(void)
-CCGraphBuilder::NoteJSObject(JSObject* aChild)
-{
-  return NoteJSChild(JS::GCCellPtr(aChild));
-}
-
-NS_IMETHODIMP_(void)
-CCGraphBuilder::NoteJSScript(JSScript* aChild)
-{
-  return NoteJSChild(JS::GCCellPtr(aChild));
-}
-
-void
-CCGraphBuilder::NoteJSChild(JS::GCCellPtr aChild)
+CCGraphBuilder::NoteJSChild(const JS::GCCellPtr& aChild)
 {
   if (!aChild) {
     return;
   }
 
   nsCString edgeName;
   if (MOZ_UNLIKELY(WantDebugInfo())) {
     edgeName.Assign(mNextEdgeName);
@@ -2498,18 +2485,17 @@ public:
   {
   }
 
   // The logic of the Note*Child functions must mirror that of their
   // respective functions in CCGraphBuilder.
   NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild);
   NS_IMETHOD_(void) NoteNativeChild(void* aChild,
                                     nsCycleCollectionParticipant* aHelper);
-  NS_IMETHOD_(void) NoteJSObject(JSObject* aChild);
-  NS_IMETHOD_(void) NoteJSScript(JSScript* aChild);
+  NS_IMETHOD_(void) NoteJSChild(const JS::GCCellPtr& aThing);
 
   NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt aRefcount,
                                            const char* aObjname)
   {
   }
   NS_IMETHOD_(void) DescribeGCedNode(bool aIsMarked,
                                      const char* aObjname,
                                      uint64_t aCompartmentAddress)
@@ -2548,27 +2534,19 @@ ChildFinder::NoteNativeChild(void* aChil
   }
   MOZ_ASSERT(aHelper, "Native child must have a participant");
   if (!aHelper->CanSkip(aChild, true)) {
     mMayHaveChild = true;
   }
 }
 
 NS_IMETHODIMP_(void)
-ChildFinder::NoteJSObject(JSObject* aChild)
+ChildFinder::NoteJSChild(const JS::GCCellPtr& aChild)
 {
-  if (aChild && JS::ObjectIsMarkedGray(aChild)) {
-    mMayHaveChild = true;
-  }
-}
-
-NS_IMETHODIMP_(void)
-ChildFinder::NoteJSScript(JSScript* aChild)
-{
-  if (aChild && JS::ScriptIsMarkedGray(aChild)) {
+  if (aChild && JS::GCThingIsMarkedGray(aChild)) {
     mMayHaveChild = true;
   }
 }
 
 static bool
 MayHaveChild(void* aObj, nsCycleCollectionParticipant* aCp)
 {
   ChildFinder cf;
--- a/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp
+++ b/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp
@@ -22,22 +22,18 @@ CycleCollectionNoteEdgeNameImpl(nsCycleC
 
 void
 nsScriptObjectTracer::NoteJSChild(JS::GCCellPtr aGCThing, const char* aName,
                                   void* aClosure)
 {
   nsCycleCollectionTraversalCallback* cb =
     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, aName);
-  if (aGCThing.is<JSObject>()) {
-    cb->NoteJSObject(&aGCThing.as<JSObject>());
-  } else if (aGCThing.is<JSScript>()) {
-    cb->NoteJSScript(&aGCThing.as<JSScript>());
-  } else {
-    MOZ_ASSERT(!mozilla::AddToCCKind(aGCThing.kind()));
+  if (mozilla::AddToCCKind(aGCThing.kind())) {
+    cb->NoteJSChild(aGCThing);
   }
 }
 
 void
 TraceCallbackFunc::Trace(JS::Heap<JS::Value>* aPtr, const char* aName,
                          void* aClosure) const
 {
   if (aPtr->isMarkable()) {
--- a/xpcom/glue/nsCycleCollectionTraversalCallback.h
+++ b/xpcom/glue/nsCycleCollectionTraversalCallback.h
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCycleCollectionTraversalCallback_h__
 #define nsCycleCollectionTraversalCallback_h__
 
 #include "jspubtd.h"
+#include "js/HeapAPI.h"
 #include "nsISupports.h"
 
 class nsCycleCollectionParticipant;
 
 class NS_NO_VTABLE nsCycleCollectionTraversalCallback
 {
 public:
   // You must call DescribeRefCountedNode() with an accurate
@@ -22,18 +23,17 @@ public:
   NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt aRefcount,
                                            const char* aObjName) = 0;
   // Note, aCompartmentAddress is 0 if it is unknown.
   NS_IMETHOD_(void) DescribeGCedNode(bool aIsMarked,
                                      const char* aObjName,
                                      uint64_t aCompartmentAddress = 0) = 0;
 
   NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild) = 0;
-  NS_IMETHOD_(void) NoteJSObject(JSObject* aChild) = 0;
-  NS_IMETHOD_(void) NoteJSScript(JSScript* aChild) = 0;
+  NS_IMETHOD_(void) NoteJSChild(const JS::GCCellPtr& aThing) = 0;
   NS_IMETHOD_(void) NoteNativeChild(void* aChild,
                                     nsCycleCollectionParticipant* aHelper) = 0;
 
   // Give a name to the edge associated with the next call to
   // NoteXPCOMChild, NoteJSObject, NoteJSScript, or NoteNativeChild.
   // Callbacks who care about this should set WANT_DEBUG_INFO in the
   // flags.
   NS_IMETHOD_(void) NoteNextEdgeName(const char* aName) = 0;