Backed out 2 changesets (bug 1235598) for linux reftest bustage
authorWes Kocher <wkocher@mozilla.com>
Thu, 31 Dec 2015 15:51:13 -0800
changeset 315208 4bbe608d70f0934642031662a228364d0ef3feb3
parent 315207 01d9397026b136cc1eeaafc65e2f99fbd624e444
child 315209 471e252b7b301c81051efb6f16e1d1c964711408
push id1079
push userjlund@mozilla.com
push dateFri, 15 Apr 2016 21:02:33 +0000
treeherdermozilla-release@575fbf6786d5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1235598
milestone46.0a1
backs out3bcd3c276785b20eaa1b3ffac83149ae1d3a8b18
80cd10a8b3d7a2e249a7632dd442306e7f0b8890
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
Backed out 2 changesets (bug 1235598) for linux reftest bustage Backed out changeset 3bcd3c276785 (bug 1235598) Backed out changeset 80cd10a8b3d7 (bug 1235598)
dom/bindings/BindingUtils.h
dom/plugins/base/nsJSNPRuntime.cpp
dom/workers/XMLHttpRequest.cpp
dom/xul/nsXULElement.h
dom/xul/nsXULPrototypeCache.cpp
js/ipc/JavaScriptShared.cpp
js/public/TracingAPI.h
js/src/ctypes/CTypes.cpp
js/src/ctypes/CTypes.h
js/src/gc/Marking.cpp
js/src/gc/Tracer.cpp
js/src/jsfriendapi.cpp
js/src/jsgc.h
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJS.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
xpcom/base/CycleCollectedJSRuntime.cpp
xpcom/glue/tests/gtest/TestGCPostBarriers.cpp
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -329,17 +329,19 @@ class ProtoAndIfaceCache
     }
 
     JS::Heap<JSObject*>& EntrySlotMustExist(size_t i) {
       return (*this)[i];
     }
 
     void Trace(JSTracer* aTracer) {
       for (size_t i = 0; i < ArrayLength(*this); ++i) {
-        JS::TraceNullableEdge(aTracer, &(*this)[i], "protoAndIfaceCache[i]");
+        if ((*this)[i]) {
+          JS_CallObjectTracer(aTracer, &(*this)[i], "protoAndIfaceCache[i]");
+        }
       }
     }
 
     size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) {
       return aMallocSizeOf(this);
     }
   };
 
@@ -388,17 +390,19 @@ class ProtoAndIfaceCache
       return (*p)[leafIndex];
     }
 
     void Trace(JSTracer* trc) {
       for (size_t i = 0; i < ArrayLength(mPages); ++i) {
         Page* p = mPages[i];
         if (p) {
           for (size_t j = 0; j < ArrayLength(*p); ++j) {
-            JS::TraceNullableEdge(trc, &(*p)[j], "protoAndIfaceCache[i]");
+            if ((*p)[j]) {
+              JS_CallObjectTracer(trc, &(*p)[j], "protoAndIfaceCache[i]");
+            }
           }
         }
       }
     }
 
     size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) {
       size_t n = aMallocSizeOf(this);
       for (size_t i = 0; i < ArrayLength(mPages); ++i) {
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -283,17 +283,19 @@ TraceJSObjWrappers(JSTracer *trc, void *
   }
 
   // Trace all JSObjects in the sJSObjWrappers table and rekey the entries if
   // any of them moved.
   for (JSObjWrapperTable::Enum e(sJSObjWrappers); !e.empty(); e.popFront()) {
     nsJSObjWrapperKey key = e.front().key();
     JS_CallUnbarrieredObjectTracer(trc, &key.mJSObj, "sJSObjWrappers key object");
     nsJSObjWrapper *wrapper = e.front().value();
-    JS::TraceNullableEdge(trc, &wrapper->mJSObj, "sJSObjWrappers wrapper object");
+    if (wrapper->mJSObj) {
+      JS_CallObjectTracer(trc, &wrapper->mJSObj, "sJSObjWrappers wrapper object");
+    }
     if (key != e.front().key()) {
       e.rekeyFront(key);
     }
   }
 }
 
 static void
 DelayedReleaseGCCallback(JSGCStatus status)
@@ -2253,26 +2255,31 @@ NPObjectMember_Call(JSContext *cx, unsig
 static void
 NPObjectMember_Trace(JSTracer *trc, JSObject *obj)
 {
   NPObjectMemberPrivate *memberPrivate =
     (NPObjectMemberPrivate *)::JS_GetPrivate(obj);
   if (!memberPrivate)
     return;
 
-  // Our NPIdentifier is not always interned, so we must trace it.
-  JS::TraceEdge(trc, &memberPrivate->methodName, "NPObjectMemberPrivate.methodName");
-
-  JS::TraceEdge(trc, &memberPrivate->fieldValue, "NPObject Member => fieldValue");
+  // Our NPIdentifier is not always interned, so we must root it explicitly.
+  JS_CallIdTracer(trc, &memberPrivate->methodName, "NPObjectMemberPrivate.methodName");
+
+  if (!memberPrivate->fieldValue.isPrimitive()) {
+    JS_CallValueTracer(trc, &memberPrivate->fieldValue,
+                       "NPObject Member => fieldValue");
+  }
 
   // There's no strong reference from our private data to the
   // NPObject, so make sure to mark the NPObject wrapper to keep the
   // NPObject alive as long as this NPObjectMember is alive.
-  JS::TraceNullableEdge(trc, &memberPrivate->npobjWrapper,
+  if (memberPrivate->npobjWrapper) {
+    JS_CallObjectTracer(trc, &memberPrivate->npobjWrapper,
                         "NPObject Member => npobjWrapper");
+  }
 }
 
 static bool
 NPObjectMember_toPrimitive(JSContext *cx, unsigned argc, JS::Value *vp)
 {
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   JS::RootedValue thisv(cx, args.thisv());
   if (thisv.isPrimitive()) {
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -554,18 +554,18 @@ public:
     : CustomAutoRooter(aCx), mStateData(aData)
     {
       MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     }
 
   private:
     virtual void trace(JSTracer* aTrc)
     {
-      JS::TraceEdge(aTrc, &mStateData->mResponse,
-                    "XMLHttpRequest::StateData::mResponse");
+      JS_CallValueTracer(aTrc, &mStateData->mResponse,
+                         "XMLHttpRequest::StateData::mResponse");
     }
   };
 
   EventRunnable(Proxy* aProxy, bool aUploadEvent, const nsString& aType,
                 bool aLengthComputable, uint64_t aLoaded, uint64_t aTotal)
   : MainThreadProxyRunnable(aProxy->mWorkerPrivate, aProxy),
     StructuredCloneHolder(CloningSupported, TransferringNotSupported,
                           SameProcessDifferentThread),
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -244,17 +244,19 @@ public:
         // Calling fromMarkedLocation() is safe because we trace mScriptObject in
         // TraceScriptObject() and because its value is never changed after it has
         // been set.
         return JS::Handle<JSScript*>::fromMarkedLocation(mScriptObject.address());
     }
 
     void TraceScriptObject(JSTracer* aTrc)
     {
-        JS::TraceNullableEdge(aTrc, &mScriptObject, "active window XUL prototype script");
+        if (mScriptObject) {
+            JS_CallScriptTracer(aTrc, &mScriptObject, "active window XUL prototype script");
+        }
     }
 
     void Trace(const TraceCallbacks& aCallbacks, void* aClosure)
     {
         if (mScriptObject) {
             aCallbacks.Trace(&mScriptObject, "mScriptObject", aClosure);
         }
     }
--- a/dom/xul/nsXULPrototypeCache.cpp
+++ b/dom/xul/nsXULPrototypeCache.cpp
@@ -625,17 +625,17 @@ nsXULPrototypeCache::MarkInCCGeneration(
     mXBLDocTable.Enumerate(MarkXBLInCCGeneration, &aGeneration);
     mPrototypeTable.Enumerate(MarkXULInCCGeneration, &aGeneration);
 }
 
 static PLDHashOperator
 MarkScriptsInGC(nsIURI* aKey, JS::Heap<JSScript*>& aScript, void* aClosure)
 {
     JSTracer* trc = static_cast<JSTracer*>(aClosure);
-    JS::TraceEdge(trc, &aScript, "nsXULPrototypeCache script");
+    JS_CallScriptTracer(trc, &aScript, "nsXULPrototypeCache script");
     return PL_DHASH_NEXT;
 }
 
 void
 nsXULPrototypeCache::MarkInGC(JSTracer* aTrc)
 {
     mScriptTable.Enumerate(MarkScriptsInGC, aTrc);
 }
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -30,18 +30,20 @@ IdToObjectMap::init()
     if (table_.initialized())
         return true;
     return table_.init(32);
 }
 
 void
 IdToObjectMap::trace(JSTracer* trc)
 {
-    for (Table::Range r(table_.all()); !r.empty(); r.popFront())
-        JS::TraceEdge(trc, &r.front().value(), "ipc-object");
+    for (Table::Range r(table_.all()); !r.empty(); r.popFront()) {
+        DebugOnly<JSObject*> prior = r.front().value().get();
+        JS_CallObjectTracer(trc, &r.front().value(), "ipc-object");
+    }
 }
 
 void
 IdToObjectMap::sweep()
 {
     for (Table::Enum e(table_); !e.empty(); e.popFront()) {
         JS::Heap<JSObject*>* objp = &e.front().value();
         JS_UpdateWeakPointerAfterGC(objp);
--- a/js/public/TracingAPI.h
+++ b/js/public/TracingAPI.h
@@ -276,39 +276,50 @@ class MOZ_RAII AutoTracingDetails
 
 JS::CallbackTracer*
 JSTracer::asCallbackTracer()
 {
     MOZ_ASSERT(isCallbackTracer());
     return static_cast<JS::CallbackTracer*>(this);
 }
 
-namespace JS {
-
-// The JS::TraceEdge family of functions traces the given GC thing reference.
-// This performs the tracing action configured on the given JSTracer: typically
-// calling the JSTracer::callback or marking the thing as live.
+// The JS_Call*Tracer family of functions traces the given GC thing reference.
+// This performs the tracing action configured on the given JSTracer:
+// typically calling the JSTracer::callback or marking the thing as live.
+//
+// The argument to JS_Call*Tracer is an in-out param: when the function
+// returns, the garbage collector might have moved the GC thing. In this case,
+// the reference passed to JS_Call*Tracer will be updated to the object's new
+// location. Callers of this method are responsible for updating any state
+// that is dependent on the object's address. For example, if the object's
+// address is used as a key in a hashtable, then the object must be removed
+// and re-inserted with the correct hash.
 //
-// The argument to JS::TraceEdge is an in-out param: when the function returns,
-// the garbage collector might have moved the GC thing. In this case, the
-// reference passed to JS::TraceEdge will be updated to the thing's new
-// location. Callers of this method are responsible for updating any state that
-// is dependent on the object's address. For example, if the object's address
-// is used as a key in a hashtable, then the object must be removed and
-// re-inserted with the correct hash.
+extern JS_PUBLIC_API(void)
+JS_CallValueTracer(JSTracer* trc, JS::Heap<JS::Value>* valuep, const char* name);
+
+extern JS_PUBLIC_API(void)
+JS_CallIdTracer(JSTracer* trc, JS::Heap<jsid>* idp, const char* name);
+
+extern JS_PUBLIC_API(void)
+JS_CallObjectTracer(JSTracer* trc, JS::Heap<JSObject*>* objp, const char* name);
+
+extern JS_PUBLIC_API(void)
+JS_CallStringTracer(JSTracer* trc, JS::Heap<JSString*>* strp, const char* name);
+
+extern JS_PUBLIC_API(void)
+JS_CallScriptTracer(JSTracer* trc, JS::Heap<JSScript*>* scriptp, const char* name);
+
+extern JS_PUBLIC_API(void)
+JS_CallFunctionTracer(JSTracer* trc, JS::Heap<JSFunction*>* funp, const char* name);
+
+namespace JS {
 template <typename T>
 extern JS_PUBLIC_API(void)
 TraceEdge(JSTracer* trc, JS::Heap<T>* edgep, const char* name);
-
-// As with JS::TraceEdge, but checks if *edgep is a nullptr before proceeding.
-// Note that edgep itself must always be non-null.
-template <typename T>
-extern JS_PUBLIC_API(void)
-TraceNullableEdge(JSTracer* trc, JS::Heap<T>* edgep, const char* name);
-
 } // namespace JS
 
 // The following JS_CallUnbarriered*Tracer functions should only be called where
 // you know for sure that a heap post barrier is not required.  Use with extreme
 // caution!
 extern JS_PUBLIC_API(void)
 JS_CallUnbarrieredValueTracer(JSTracer* trc, JS::Value* valuep, const char* name);
 
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -4101,20 +4101,20 @@ CType::Trace(JSTracer* trc, JSObject* ob
     slot = obj->as<NativeObject>().getReservedSlot(SLOT_FNINFO);
     if (slot.isUndefined())
       return;
 
     FunctionInfo* fninfo = static_cast<FunctionInfo*>(slot.toPrivate());
     MOZ_ASSERT(fninfo);
 
     // Identify our objects to the tracer.
-    JS::TraceEdge(trc, &fninfo->mABI, "abi");
-    JS::TraceEdge(trc, &fninfo->mReturnType, "returnType");
+    JS_CallObjectTracer(trc, &fninfo->mABI, "abi");
+    JS_CallObjectTracer(trc, &fninfo->mReturnType, "returnType");
     for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i)
-      JS::TraceEdge(trc, &fninfo->mArgTypes[i], "argType");
+      JS_CallObjectTracer(trc, &fninfo->mArgTypes[i], "argType");
 
     break;
   }
   default:
     // Nothing to do here.
     break;
   }
 }
@@ -6899,20 +6899,20 @@ CClosure::Trace(JSTracer* trc, JSObject*
   Value slot = JS_GetReservedSlot(obj, SLOT_CLOSUREINFO);
   if (slot.isUndefined())
     return;
 
   ClosureInfo* cinfo = static_cast<ClosureInfo*>(slot.toPrivate());
 
   // Identify our objects to the tracer. (There's no need to identify
   // 'closureObj', since that's us.)
-  JS::TraceEdge(trc, &cinfo->typeObj, "typeObj");
-  JS::TraceEdge(trc, &cinfo->jsfnObj, "jsfnObj");
+  JS_CallObjectTracer(trc, &cinfo->typeObj, "typeObj");
+  JS_CallObjectTracer(trc, &cinfo->jsfnObj, "jsfnObj");
   if (cinfo->thisObj)
-    JS::TraceEdge(trc, &cinfo->thisObj, "thisObj");
+    JS_CallObjectTracer(trc, &cinfo->thisObj, "thisObj");
 }
 
 void
 CClosure::Finalize(JSFreeOp* fop, JSObject* obj)
 {
   // Make sure our ClosureInfo slot is legit. If it's not, bail.
   Value slot = JS_GetReservedSlot(obj, SLOT_CLOSUREINFO);
   if (slot.isUndefined())
--- a/js/src/ctypes/CTypes.h
+++ b/js/src/ctypes/CTypes.h
@@ -226,17 +226,17 @@ enum TypeCode {
 // as the key to the hash entry.
 struct FieldInfo
 {
   JS::Heap<JSObject*> mType;    // CType of the field
   size_t              mIndex;   // index of the field in the struct (first is 0)
   size_t              mOffset;  // offset of the field in the struct, in bytes
 
   void trace(JSTracer* trc) {
-      JS::TraceEdge(trc, &mType, "fieldType");
+    JS_CallObjectTracer(trc, &mType, "fieldType");
   }
 };
 
 struct UnbarrieredFieldInfo
 {
   JSObject*           mType;    // CType of the field
   size_t              mIndex;   // index of the field in the struct (first is 0)
   size_t              mOffset;  // offset of the field in the struct, in bytes
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -401,25 +401,16 @@ js::TraceEdge(JSTracer* trc, WriteBarrie
 template <typename T>
 JS_PUBLIC_API(void)
 JS::TraceEdge(JSTracer* trc, JS::Heap<T>* thingp, const char* name)
 {
     DispatchToTracer(trc, ConvertToBase(thingp->unsafeGet()), name);
 }
 
 template <typename T>
-JS_PUBLIC_API(void)
-JS::TraceNullableEdge(JSTracer* trc, JS::Heap<T>* thingp, const char* name)
-{
-    MOZ_ASSERT(thingp);
-    if (InternalGCMethods<T>::isMarkable(thingp->get()))
-        DispatchToTracer(trc, ConvertToBase(thingp->unsafeGet()), name);
-}
-
-template <typename T>
 void
 js::TraceManuallyBarrieredEdge(JSTracer* trc, T* thingp, const char* name)
 {
     DispatchToTracer(trc, ConvertToBase(thingp), name);
 }
 
 template <typename T>
 void
@@ -487,34 +478,28 @@ js::TraceRootRange(JSTracer* trc, size_t
             DispatchToTracer(trc, ConvertToBase(&vec[i]), name);
         ++index;
     }
 }
 
 // Instantiate a copy of the Tracing templates for each derived type.
 #define INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS(type) \
     template void js::TraceEdge<type>(JSTracer*, WriteBarrieredBase<type>*, const char*); \
+    template JS_PUBLIC_API(void) JS::TraceEdge<type>(JSTracer*, JS::Heap<type>*, const char*); \
     template void js::TraceManuallyBarrieredEdge<type>(JSTracer*, type*, const char*); \
     template void js::TraceWeakEdge<type>(JSTracer*, WeakRef<type>*, const char*); \
     template void js::TraceRoot<type>(JSTracer*, type*, const char*); \
     template void js::TraceRoot<type>(JSTracer*, ReadBarriered<type>*, const char*); \
     template void js::TraceNullableRoot<type>(JSTracer*, type*, const char*); \
     template void js::TraceNullableRoot<type>(JSTracer*, ReadBarriered<type>*, const char*); \
     template void js::TraceRange<type>(JSTracer*, size_t, WriteBarrieredBase<type>*, const char*); \
     template void js::TraceRootRange<type>(JSTracer*, size_t, type*, const char*);
 FOR_EACH_GC_POINTER_TYPE(INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS)
 #undef INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS
 
-#define INSTANTIATE_PUBLIC_TRACE_FUNCTIONS(type) \
-    template JS_PUBLIC_API(void) JS::TraceEdge<type>(JSTracer*, JS::Heap<type>*, const char*); \
-    template JS_PUBLIC_API(void) JS::TraceNullableEdge<type>(JSTracer*, JS::Heap<type>*, \
-                                                             const char*);
-FOR_EACH_PUBLIC_GC_POINTER_TYPE(INSTANTIATE_PUBLIC_TRACE_FUNCTIONS)
-#undef INSTANTIATE_PUBLIC_TRACE_FUNCTIONS
-
 template <typename T>
 void
 js::TraceManuallyBarrieredCrossCompartmentEdge(JSTracer* trc, JSObject* src, T* dst,
                                                const char* name)
 {
     if (ShouldMarkCrossCompartment(trc, src, *dst))
         DispatchToTracer(trc, dst, name);
 }
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -131,16 +131,52 @@ JS_CallUnbarrieredStringTracer(JSTracer*
 
 JS_PUBLIC_API(void)
 JS_CallUnbarrieredScriptTracer(JSTracer* trc, JSScript** scriptp, const char* name)
 {
     TraceManuallyBarrieredEdge(trc, scriptp, name);
 }
 
 JS_PUBLIC_API(void)
+JS_CallValueTracer(JSTracer* trc, JS::Heap<JS::Value>* valuep, const char* name)
+{
+    TraceManuallyBarrieredEdge(trc, valuep->unsafeGet(), name);
+}
+
+JS_PUBLIC_API(void)
+JS_CallIdTracer(JSTracer* trc, JS::Heap<jsid>* idp, const char* name)
+{
+    TraceManuallyBarrieredEdge(trc, idp->unsafeGet(), name);
+}
+
+JS_PUBLIC_API(void)
+JS_CallObjectTracer(JSTracer* trc, JS::Heap<JSObject*>* objp, const char* name)
+{
+    TraceManuallyBarrieredEdge(trc, objp->unsafeGet(), name);
+}
+
+JS_PUBLIC_API(void)
+JS_CallStringTracer(JSTracer* trc, JS::Heap<JSString*>* strp, const char* name)
+{
+    TraceManuallyBarrieredEdge(trc, strp->unsafeGet(), name);
+}
+
+JS_PUBLIC_API(void)
+JS_CallScriptTracer(JSTracer* trc, JS::Heap<JSScript*>* scriptp, const char* name)
+{
+    TraceManuallyBarrieredEdge(trc, scriptp->unsafeGet(), name);
+}
+
+JS_PUBLIC_API(void)
+JS_CallFunctionTracer(JSTracer* trc, JS::Heap<JSFunction*>* funp, const char* name)
+{
+    TraceManuallyBarrieredEdge(trc, funp->unsafeGet(), name);
+}
+
+JS_PUBLIC_API(void)
 JS_CallTenuredObjectTracer(JSTracer* trc, JS::TenuredHeap<JSObject*>* objp, const char* name)
 {
     JSObject* obj = objp->getPtr();
     if (!obj)
         return;
 
     TraceManuallyBarrieredEdge(trc, &obj, name);
 
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -1067,17 +1067,17 @@ JS::ObjectPtr::updateWeakPointerAfterGC(
 {
     if (js::gc::IsAboutToBeFinalizedUnbarriered(value.unsafeGet()))
         value = nullptr;
 }
 
 void
 JS::ObjectPtr::trace(JSTracer* trc, const char* name)
 {
-    JS::TraceEdge(trc, &value, name);
+    JS_CallObjectTracer(trc, &value, name);
 }
 
 JS_FRIEND_API(JSObject*)
 js::GetTestingFunctions(JSContext* cx)
 {
     RootedObject obj(cx, JS_NewPlainObject(cx));
     if (!obj)
         return nullptr;
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -46,59 +46,55 @@ struct FinalizePhase;
 enum State {
     NO_INCREMENTAL,
     MARK_ROOTS,
     MARK,
     SWEEP,
     COMPACT
 };
 
-// Expand the given macro D for each publicly exposed GC reference type.
-#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \
-    D(JS::Symbol*) \
-    D(JSAtom*) \
-    D(JSFunction*) \
-    D(JSObject*) \
-    D(JSScript*) \
-    D(JSString*) \
-    D(JS::Value) \
-    D(jsid)
-
 // Expand the given macro D for each valid GC reference type.
 #define FOR_EACH_GC_POINTER_TYPE(D) \
-    FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \
     D(AccessorShape*) \
     D(BaseShape*) \
     D(UnownedBaseShape*) \
     D(jit::JitCode*) \
     D(NativeObject*) \
     D(ArrayObject*) \
     D(ArgumentsObject*) \
     D(ArrayBufferObject*) \
     D(ArrayBufferObjectMaybeShared*) \
     D(ArrayBufferViewObject*) \
     D(DebugScopeObject*) \
     D(GlobalObject*) \
+    D(JSObject*) \
+    D(JSFunction*) \
     D(ModuleObject*) \
     D(ModuleEnvironmentObject*) \
     D(ModuleNamespaceObject*) \
     D(NestedScopeObject*) \
     D(PlainObject*) \
     D(SavedFrame*) \
     D(ScopeObject*) \
     D(ScriptSourceObject*) \
     D(SharedArrayBufferObject*) \
     D(ImportEntryObject*) \
     D(ExportEntryObject*) \
+    D(JSScript*) \
     D(LazyScript*) \
     D(Shape*) \
+    D(JSAtom*) \
+    D(JSString*) \
     D(JSFlatString*) \
     D(JSLinearString*) \
     D(PropertyName*) \
+    D(JS::Symbol*) \
     D(js::ObjectGroup*) \
+    D(Value) \
+    D(jsid) \
     D(TaggedProto)
 
 /* Map from C++ type to alloc kind. JSObject does not have a 1:1 mapping, so must use Arena::thingSize. */
 template <typename T> struct MapTypeToFinalizeKind {};
 template <> struct MapTypeToFinalizeKind<JSScript>          { static const AllocKind kind = AllocKind::SCRIPT; };
 template <> struct MapTypeToFinalizeKind<LazyScript>        { static const AllocKind kind = AllocKind::LAZY_SCRIPT; };
 template <> struct MapTypeToFinalizeKind<Shape>             { static const AllocKind kind = AllocKind::SHAPE; };
 template <> struct MapTypeToFinalizeKind<AccessorShape>     { static const AllocKind kind = AllocKind::ACCESSOR_SHAPE; };
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -61,17 +61,17 @@ XPCTraceableVariant::~XPCTraceableVarian
 
     if (!val.isNull())
         RemoveFromRootSet();
 }
 
 void XPCTraceableVariant::TraceJS(JSTracer* trc)
 {
     MOZ_ASSERT(mJSVal.isMarkable());
-    JS::TraceEdge(trc, &mJSVal, "XPCTraceableVariant::mJSVal");
+    JS_CallValueTracer(trc, &mJSVal, "XPCTraceableVariant::mJSVal");
 }
 
 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");
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -286,17 +286,17 @@ nsXPCWrappedJS::DeleteCycleCollectable(v
 {
     delete this;
 }
 
 void
 nsXPCWrappedJS::TraceJS(JSTracer* trc)
 {
     MOZ_ASSERT(mRefCnt >= 2 && IsValid(), "must be strongly referenced");
-    JS::TraceEdge(trc, &mJSObj, "nsXPCWrappedJS::mJSObj");
+    JS_CallObjectTracer(trc, &mJSObj, "nsXPCWrappedJS::mJSObj");
 }
 
 NS_IMETHODIMP
 nsXPCWrappedJS::GetWeakReference(nsIWeakReference** aInstancePtr)
 {
     if (!IsRootWrapper())
         return mRoot->GetWeakReference(aInstancePtr);
 
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -2355,10 +2355,10 @@ XPCJSObjectHolder::XPCJSObjectHolder(JSO
 XPCJSObjectHolder::~XPCJSObjectHolder()
 {
     RemoveFromRootSet();
 }
 
 void
 XPCJSObjectHolder::TraceJS(JSTracer* trc)
 {
-    JS::TraceEdge(trc, &mJSObj, "XPCJSObjectHolder::mJSObj");
+    JS_CallObjectTracer(trc, &mJSObj, "XPCJSObjectHolder::mJSObj");
 }
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -462,29 +462,29 @@ XPCWrappedNativeScope::~XPCWrappedNative
         mAddonScopes[i].finalize(rt);
     mGlobalJSObject.finalize(rt);
 }
 
 // static
 void
 XPCWrappedNativeScope::TraceWrappedNativesInAllScopes(JSTracer* trc, XPCJSRuntime* rt)
 {
-    // Do JS::TraceEdge for all wrapped natives with external references, as
+    // Do JS_CallTracer for all wrapped natives with external references, as
     // well as any DOM expando objects.
     for (XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) {
         for (auto i = cur->mWrappedNativeMap->Iter(); !i.Done(); i.Next()) {
             auto entry = static_cast<Native2WrappedNativeMap::Entry*>(i.Get());
             XPCWrappedNative* wrapper = entry->value;
             if (wrapper->HasExternalReference() && !wrapper->IsWrapperExpired())
                 wrapper->TraceSelf(trc);
         }
 
         if (cur->mDOMExpandoSet) {
             for (DOMExpandoSet::Enum e(*cur->mDOMExpandoSet); !e.empty(); e.popFront())
-                JS::TraceEdge(trc, &e.mutableFront(), "DOM expando object");
+                JS_CallObjectTracer(trc, &e.mutableFront(), "DOM expando object");
         }
     }
 }
 
 static void
 SuspectDOMExpandos(JSObject* obj, nsCycleCollectionNoteRootCallback& cb)
 {
     MOZ_ASSERT(dom::GetDOMClass(obj) && dom::GetDOMClass(obj)->mDOMObjectIsISupports);
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -776,52 +776,52 @@ CycleCollectedJSRuntime::ContextCallback
   return self->CustomContextCallback(aContext, aOperation);
 }
 
 struct JsGcTracer : public TraceCallbacks
 {
   virtual void Trace(JS::Heap<JS::Value>* aPtr, const char* aName,
                      void* aClosure) const override
   {
-    JS::TraceEdge(static_cast<JSTracer*>(aClosure), aPtr, aName);
+    JS_CallValueTracer(static_cast<JSTracer*>(aClosure), aPtr, aName);
   }
   virtual void Trace(JS::Heap<jsid>* aPtr, const char* aName,
                      void* aClosure) const override
   {
-    JS::TraceEdge(static_cast<JSTracer*>(aClosure), aPtr, aName);
+    JS_CallIdTracer(static_cast<JSTracer*>(aClosure), aPtr, aName);
   }
   virtual void Trace(JS::Heap<JSObject*>* aPtr, const char* aName,
                      void* aClosure) const override
   {
-    JS::TraceEdge(static_cast<JSTracer*>(aClosure), aPtr, aName);
+    JS_CallObjectTracer(static_cast<JSTracer*>(aClosure), aPtr, aName);
   }
   virtual void Trace(JSObject** aPtr, const char* aName,
                      void* aClosure) const override
   {
     JS_CallUnbarrieredObjectTracer(static_cast<JSTracer*>(aClosure), aPtr, aName);
   }
   virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName,
                      void* aClosure) const override
   {
     JS_CallTenuredObjectTracer(static_cast<JSTracer*>(aClosure), aPtr, aName);
   }
   virtual void Trace(JS::Heap<JSString*>* aPtr, const char* aName,
                      void* aClosure) const override
   {
-    JS::TraceEdge(static_cast<JSTracer*>(aClosure), aPtr, aName);
+    JS_CallStringTracer(static_cast<JSTracer*>(aClosure), aPtr, aName);
   }
   virtual void Trace(JS::Heap<JSScript*>* aPtr, const char* aName,
                      void* aClosure) const override
   {
-    JS::TraceEdge(static_cast<JSTracer*>(aClosure), aPtr, aName);
+    JS_CallScriptTracer(static_cast<JSTracer*>(aClosure), aPtr, aName);
   }
   virtual void Trace(JS::Heap<JSFunction*>* aPtr, const char* aName,
                      void* aClosure) const override
   {
-    JS::TraceEdge(static_cast<JSTracer*>(aClosure), aPtr, aName);
+    JS_CallFunctionTracer(static_cast<JSTracer*>(aClosure), aPtr, aName);
   }
 };
 
 void
 mozilla::TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer)
 {
   nsXPCOMCycleCollectionParticipant* participant = nullptr;
   CallQueryInterface(aHolder, &participant);
--- a/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp
+++ b/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp
@@ -23,17 +23,17 @@ using namespace JS;
 using namespace mozilla;
 
 template<class ArrayT>
 static void
 TraceArray(JSTracer* trc, void* data)
 {
   ArrayT* array = static_cast<ArrayT *>(data);
   for (unsigned i = 0; i < array->Length(); ++i)
-    JS::TraceEdge(trc, &array->ElementAt(i), "array-element");
+    JS_CallObjectTracer(trc, &array->ElementAt(i), "array-element");
 }
 
 /*
  * Use arrays with initial size much smaller than the final number of elements
  * to test that moving Heap<T> elements works correctly.
  */
 const size_t ElementCount = 100;
 const size_t InitialElements = ElementCount / 10;