Bug 1149352 - Part 8: Move Object marking to TraceEdge; r=jonco
authorTerrence Cole <terrence@mozilla.com>
Mon, 30 Mar 2015 16:08:06 -0700
changeset 237594 08f50bc6e3e88acc28083e215b979ee9edf5f29d
parent 237593 898ac9f9b37f6234512857b5f140d8ca3c397af4
child 237595 4b51391dc2a19a6d777965d2056a661f9bd929b4
push id28540
push userphilringnalda@gmail.com
push dateSat, 04 Apr 2015 17:42:19 +0000
treeherdermozilla-central@035959eef3f9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1149352
milestone40.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 1149352 - Part 8: Move Object marking to TraceEdge; r=jonco
js/src/asmjs/AsmJSModule.cpp
js/src/builtin/TypedObject.cpp
js/src/frontend/ParseNode.cpp
js/src/gc/Marking.cpp
js/src/gc/Marking.h
js/src/gc/RootMarking.cpp
js/src/gc/StoreBuffer.cpp
js/src/gc/Tracer.cpp
js/src/gc/Zone.cpp
js/src/jit/BaselineFrame.cpp
js/src/jit/BaselineIC.cpp
js/src/jit/BaselineJIT.cpp
js/src/jit/Ion.cpp
js/src/jit/JitFrames.cpp
js/src/jit/JitcodeMap.cpp
js/src/jit/RematerializedFrame.cpp
js/src/jit/VMFunctions.cpp
js/src/jsapi.cpp
js/src/jscntxt.cpp
js/src/jscompartment.cpp
js/src/jsfriendapi.cpp
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsiter.cpp
js/src/jsobj.cpp
js/src/jsscript.cpp
js/src/jswatchpoint.cpp
js/src/jsweakmap.cpp
js/src/jsweakmap.h
js/src/vm/ArrayBufferObject.cpp
js/src/vm/Debugger.cpp
js/src/vm/ObjectGroup.cpp
js/src/vm/PIC.cpp
js/src/vm/RegExpObject.cpp
js/src/vm/SavedStacks.cpp
js/src/vm/ScopeObject.cpp
js/src/vm/SelfHosting.cpp
js/src/vm/Shape.cpp
js/src/vm/Shape.h
js/src/vm/Stack.cpp
js/src/vm/TypeInference.cpp
js/src/vm/UnboxedObject.cpp
--- a/js/src/asmjs/AsmJSModule.cpp
+++ b/js/src/asmjs/AsmJSModule.cpp
@@ -129,17 +129,17 @@ AsmJSModule::~AsmJSModule()
 
 void
 AsmJSModule::trace(JSTracer* trc)
 {
     for (unsigned i = 0; i < globals_.length(); i++)
         globals_[i].trace(trc);
     for (unsigned i = 0; i < exits_.length(); i++) {
         if (exitIndexToGlobalDatum(i).fun)
-            MarkObject(trc, &exitIndexToGlobalDatum(i).fun, "asm.js imported function");
+            TraceEdge(trc, &exitIndexToGlobalDatum(i).fun, "asm.js imported function");
     }
     for (unsigned i = 0; i < exports_.length(); i++)
         exports_[i].trace(trc);
     for (unsigned i = 0; i < names_.length(); i++)
         TraceManuallyBarrieredEdge(trc, &names_[i].name(), "asm.js module function name");
 #if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
     for (unsigned i = 0; i < profiledFunctions_.length(); i++)
         profiledFunctions_[i].trace(trc);
@@ -150,17 +150,17 @@ AsmJSModule::trace(JSTracer* trc)
 #endif
     if (globalArgumentName_)
         TraceManuallyBarrieredEdge(trc, &globalArgumentName_, "asm.js global argument name");
     if (importArgumentName_)
         TraceManuallyBarrieredEdge(trc, &importArgumentName_, "asm.js import argument name");
     if (bufferArgumentName_)
         TraceManuallyBarrieredEdge(trc, &bufferArgumentName_, "asm.js buffer argument name");
     if (maybeHeap_)
-        gc::MarkObject(trc, &maybeHeap_, "asm.js heap");
+        TraceEdge(trc, &maybeHeap_, "asm.js heap");
 }
 
 void
 AsmJSModule::addSizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, size_t* asmJSModuleCode,
                            size_t* asmJSModuleData)
 {
     *asmJSModuleCode += pod.totalBytes_;
     *asmJSModuleData += mallocSizeOf(this) +
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -1636,17 +1636,17 @@ OutlineTypedObject::obj_trace(JSTracer* 
     // When this is called for compacting GC, the related objects we touch here
     // may not have had their slots updated yet. Note that this does not apply
     // to generational GC because these objects (type descriptors and
     // prototypes) are never allocated in the nursery.
     TypeDescr& descr = typedObj.maybeForwardedTypeDescr();
 
     // Mark the owner, watching in case it is moved by the tracer.
     JSObject* oldOwner = typedObj.owner_;
-    gc::MarkObjectUnbarriered(trc, &typedObj.owner_, "typed object owner");
+    TraceManuallyBarrieredEdge(trc, &typedObj.owner_, "typed object owner");
     JSObject* owner = typedObj.owner_;
 
     uint8_t* oldData = typedObj.outOfLineTypedMem();
     uint8_t* newData = oldData;
 
     // Update the data pointer if the owner moved and the owner's data is
     // inline with it. Note that an array buffer pointing to data in an inline
     // typed object will never be used as an owner for another outline typed
@@ -2941,17 +2941,17 @@ MemoryTracingVisitor::visitReference(Ref
         TraceEdge(trace_, heapValue, "reference-val");
         return;
       }
 
       case ReferenceTypeDescr::TYPE_OBJECT:
       {
         HeapPtrObject* objectPtr = reinterpret_cast<js::HeapPtrObject*>(mem);
         if (*objectPtr)
-            gc::MarkObject(trace_, objectPtr, "reference-obj");
+            TraceEdge(trace_, objectPtr, "reference-obj");
         return;
       }
 
       case ReferenceTypeDescr::TYPE_STRING:
       {
         HeapPtrString* stringPtr = reinterpret_cast<js::HeapPtrString*>(mem);
         if (*stringPtr)
             TraceEdge(trace_, stringPtr, "reference-str");
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -1123,14 +1123,14 @@ ObjectBox::asFunctionBox()
     return static_cast<FunctionBox*>(this);
 }
 
 void
 ObjectBox::trace(JSTracer* trc)
 {
     ObjectBox* box = this;
     while (box) {
-        MarkObjectRoot(trc, &box->object, "parser.object");
+        TraceRoot(trc, &box->object, "parser.object");
         if (box->isFunctionBox())
             box->asFunctionBox()->bindings.trace(trc);
         box = box->traceLink;
     }
 }
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -289,23 +289,16 @@ template<>
 void
 SetMaybeAliveFlag(JSObject* thing)
 {
     thing->compartment()->maybeAlive = true;
 }
 
 template<>
 void
-SetMaybeAliveFlag(NativeObject* thing)
-{
-    thing->compartment()->maybeAlive = true;
-}
-
-template<>
-void
 SetMaybeAliveFlag(JSScript* thing)
 {
     thing->compartment()->maybeAlive = true;
 }
 
 #define FOR_EACH_GC_LAYOUT(D) \
     D(Object, JSObject) \
     D(String, JSString) \
@@ -337,16 +330,17 @@ FOR_EACH_GC_LAYOUT(NAMES)
     D(DebugScopeObject*) \
     D(GlobalObject*) \
     D(JSObject*) \
     D(JSFunction*) \
     D(NestedScopeObject*) \
     D(PlainObject*) \
     D(SavedFrame*) \
     D(ScopeObject*) \
+    D(ScriptSourceObject*) \
     D(SharedArrayBufferObject*) \
     D(SharedTypedArrayObject*) \
     D(JSScript*) \
     D(LazyScript*) \
     D(Shape*) \
     D(JSAtom*) \
     D(JSString*) \
     D(JSFlatString*) \
@@ -1089,34 +1083,16 @@ Update##base##IfRelocated(JSRuntime* rt,
 }                                                                                                 \
                                                                                                   \
 type *                                                                                            \
 Update##base##IfRelocated(JSRuntime* rt, type** thingp)                                           \
 {                                                                                                 \
     return UpdateIfRelocated<type>(rt, thingp);                                                   \
 }
 
-
-DeclMarkerImpl(Object, NativeObject)
-DeclMarkerImpl(Object, ArrayObject)
-DeclMarkerImpl(Object, ArgumentsObject)
-DeclMarkerImpl(Object, ArrayBufferObject)
-DeclMarkerImpl(Object, ArrayBufferObjectMaybeShared)
-DeclMarkerImpl(Object, ArrayBufferViewObject)
-DeclMarkerImpl(Object, DebugScopeObject)
-DeclMarkerImpl(Object, GlobalObject)
-DeclMarkerImpl(Object, JSObject)
-DeclMarkerImpl(Object, JSFunction)
-DeclMarkerImpl(Object, NestedScopeObject)
-DeclMarkerImpl(Object, PlainObject)
-DeclMarkerImpl(Object, SavedFrame)
-DeclMarkerImpl(Object, ScopeObject)
-DeclMarkerImpl(Object, SharedArrayBufferObject)
-DeclMarkerImpl(Object, SharedTypedArrayObject)
-
 } /* namespace gc */
 } /* namespace js */
 
 /*** Externally Typed Marking ***/
 
 void
 gc::MarkKind(JSTracer* trc, void** thingp, JSGCTraceKind kind)
 {
@@ -1352,17 +1328,17 @@ ScanBaseShape(GCMarker* gcmarker, BaseSh
 void
 BaseShape::markChildren(JSTracer* trc)
 {
     if (isOwned())
         TraceEdge(trc, &unowned_, "base");
 
     JSObject* global = compartment()->unsafeUnbarrieredMaybeGlobal();
     if (global)
-        MarkObjectUnbarriered(trc, &global, "global");
+        TraceManuallyBarrieredEdge(trc, &global, "global");
 }
 
 static void
 PushMarkStack(GCMarker* gcmarker, BaseShape* thing)
 {
     JS_COMPARTMENT_ASSERT(gcmarker->runtime(), thing);
     MOZ_ASSERT(!IsInsideNursery(thing));
 
@@ -1553,35 +1529,35 @@ gc::MarkCycleCollectorChildren(JSTracer*
 {
     /*
      * We need to mark the global, but it's OK to only do this once instead of
      * doing it for every Shape in our lineage, since it's always the same
      * global.
      */
     JSObject* global = shape->compartment()->unsafeUnbarrieredMaybeGlobal();
     MOZ_ASSERT(global);
-    MarkObjectUnbarriered(trc, &global, "global");
+    TraceManuallyBarrieredEdge(trc, &global, "global");
 
     do {
         MOZ_ASSERT(global == shape->compartment()->unsafeUnbarrieredMaybeGlobal());
 
         MOZ_ASSERT(shape->base());
         shape->base()->assertConsistency();
 
         TraceEdge(trc, &shape->propidRef(), "propid");
 
         if (shape->hasGetterObject()) {
             JSObject* tmp = shape->getterObject();
-            MarkObjectUnbarriered(trc, &tmp, "getter");
+            TraceManuallyBarrieredEdge(trc, &tmp, "getter");
             MOZ_ASSERT(tmp == shape->getterObject());
         }
 
         if (shape->hasSetterObject()) {
             JSObject* tmp = shape->setterObject();
-            MarkObjectUnbarriered(trc, &tmp, "setter");
+            TraceManuallyBarrieredEdge(trc, &tmp, "setter");
             MOZ_ASSERT(tmp == shape->setterObject());
         }
 
         shape = shape->previous();
     } while (shape);
 }
 
 static void
@@ -1625,39 +1601,39 @@ gc::MarkChildren(JSTracer* trc, ObjectGr
 {
     unsigned count = group->getPropertyCount();
     for (unsigned i = 0; i < count; i++) {
         if (ObjectGroup::Property* prop = group->getProperty(i))
             TraceEdge(trc, &prop->id, "group_property");
     }
 
     if (group->proto().isObject())
-        MarkObject(trc, &group->protoRaw(), "group_proto");
+        TraceEdge(trc, &group->protoRaw(), "group_proto");
 
     if (group->newScript())
         group->newScript()->trace(trc);
 
     if (group->maybePreliminaryObjects())
         group->maybePreliminaryObjects()->trace(trc);
 
     if (group->maybeUnboxedLayout())
         group->unboxedLayout().trace(trc);
 
     if (ObjectGroup* unboxedGroup = group->maybeOriginalUnboxedGroup()) {
         TraceManuallyBarrieredEdge(trc, &unboxedGroup, "group_original_unboxed_group");
         group->setOriginalUnboxedGroup(unboxedGroup);
     }
 
     if (JSObject* descr = group->maybeTypeDescr()) {
-        MarkObjectUnbarriered(trc, &descr, "group_type_descr");
+        TraceManuallyBarrieredEdge(trc, &descr, "group_type_descr");
         group->setTypeDescr(&descr->as<TypeDescr>());
     }
 
     if (JSObject* fun = group->maybeInterpretedFunction()) {
-        MarkObjectUnbarriered(trc, &fun, "group_function");
+        TraceManuallyBarrieredEdge(trc, &fun, "group_function");
         group->setInterpretedFunction(&fun->as<JSFunction>());
     }
 }
 
 template<typename T>
 static void
 PushArenaTyped(GCMarker* gcmarker, ArenaHeader* aheader)
 {
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -137,34 +137,16 @@ void Mark##base##Unbarriered(JSTracer* t
 void Mark##base##Range(JSTracer* trc, size_t len, HeapPtr<type*>* thing, const char* name);       \
 void Mark##base##RootRange(JSTracer* trc, size_t len, type** thing, const char* name);            \
 bool Is##base##Marked(type** thingp);                                                             \
 bool Is##base##Marked(BarrieredBase<type*>* thingp);                                              \
 bool Is##base##AboutToBeFinalized(type** thingp);                                                 \
 bool Is##base##AboutToBeFinalized(BarrieredBase<type*>* thingp);                                  \
 type* Update##base##IfRelocated(JSRuntime* rt, BarrieredBase<type*>* thingp);                     \
 type* Update##base##IfRelocated(JSRuntime* rt, type** thingp);
-
-DeclMarker(Object, NativeObject)
-DeclMarker(Object, ArrayObject)
-DeclMarker(Object, ArgumentsObject)
-DeclMarker(Object, ArrayBufferObject)
-DeclMarker(Object, ArrayBufferObjectMaybeShared)
-DeclMarker(Object, ArrayBufferViewObject)
-DeclMarker(Object, DebugScopeObject)
-DeclMarker(Object, GlobalObject)
-DeclMarker(Object, JSObject)
-DeclMarker(Object, JSFunction)
-DeclMarker(Object, NestedScopeObject)
-DeclMarker(Object, PlainObject)
-DeclMarker(Object, SavedFrame)
-DeclMarker(Object, ScopeObject)
-DeclMarker(Object, SharedArrayBufferObject)
-DeclMarker(Object, SharedTypedArrayObject)
-
 #undef DeclMarker
 
 void
 MarkPermanentAtom(JSTracer* trc, JSAtom* atom, const char* name);
 
 void
 MarkWellKnownSymbol(JSTracer* trc, JS::Symbol* sym);
 
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -89,17 +89,17 @@ MarkExactStackRootList(JSTracer* trc, So
         rooter = rooter->previous();
     }
 }
 
 template<class T>
 static void
 MarkExactStackRootsAcrossTypes(T context, JSTracer* trc)
 {
-    MarkExactStackRootList<JSObject*, MarkObjectRoot>(trc, context, "exact-object");
+    MarkExactStackRootList<JSObject*, TraceRoot>(trc, context, "exact-object");
     MarkExactStackRootList<Shape*, TraceRoot>(trc, context, "exact-shape");
     MarkExactStackRootList<BaseShape*, TraceRoot>(trc, context, "exact-baseshape");
     MarkExactStackRootList<ObjectGroup*, TraceRoot>(
         trc, context, "exact-objectgroup");
     MarkExactStackRootList<JSString*, TraceRoot>(trc, context, "exact-string");
     MarkExactStackRootList<JS::Symbol*, TraceRoot>(trc, context, "exact-symbol");
     MarkExactStackRootList<jit::JitCode*, TraceRoot>(trc, context, "exact-jitcode");
     MarkExactStackRootList<JSScript*, TraceRoot>(trc, context, "exact-script");
@@ -174,23 +174,23 @@ AutoGCRooter::trace(JSTracer* trc)
         AutoShapeVector::VectorImpl& vector = static_cast<js::AutoShapeVector*>(this)->vector;
         TraceRootRange(trc, vector.length(), const_cast<Shape**>(vector.begin()),
                        "js::AutoShapeVector.vector");
         return;
       }
 
       case OBJVECTOR: {
         AutoObjectVector::VectorImpl& vector = static_cast<AutoObjectVector*>(this)->vector;
-        MarkObjectRootRange(trc, vector.length(), vector.begin(), "js::AutoObjectVector.vector");
+        TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoObjectVector.vector");
         return;
       }
 
       case FUNVECTOR: {
         AutoFunctionVector::VectorImpl& vector = static_cast<AutoFunctionVector*>(this)->vector;
-        MarkObjectRootRange(trc, vector.length(), vector.begin(), "js::AutoFunctionVector.vector");
+        TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoFunctionVector.vector");
         return;
       }
 
       case STRINGVECTOR: {
         AutoStringVector::VectorImpl& vector = static_cast<AutoStringVector*>(this)->vector;
         TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoStringVector.vector");
         return;
       }
@@ -215,44 +215,44 @@ AutoGCRooter::trace(JSTracer* trc)
         AutoScriptVector::VectorImpl& vector = static_cast<AutoScriptVector*>(this)->vector;
         TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoScriptVector.vector");
         return;
       }
 
       case OBJOBJHASHMAP: {
         AutoObjectObjectHashMap::HashMapImpl& map = static_cast<AutoObjectObjectHashMap*>(this)->map;
         for (AutoObjectObjectHashMap::Enum e(map); !e.empty(); e.popFront()) {
-            MarkObjectRoot(trc, &e.front().value(), "AutoObjectObjectHashMap value");
+            TraceRoot(trc, &e.front().value(), "AutoObjectObjectHashMap value");
             trc->setTracingLocation((void*)&e.front().key());
             JSObject* key = e.front().key();
-            MarkObjectRoot(trc, &key, "AutoObjectObjectHashMap key");
+            TraceRoot(trc, &key, "AutoObjectObjectHashMap key");
             if (key != e.front().key())
                 e.rekeyFront(key);
         }
         return;
       }
 
       case OBJU32HASHMAP: {
         AutoObjectUnsigned32HashMap* self = static_cast<AutoObjectUnsigned32HashMap*>(this);
         AutoObjectUnsigned32HashMap::HashMapImpl& map = self->map;
         for (AutoObjectUnsigned32HashMap::Enum e(map); !e.empty(); e.popFront()) {
             JSObject* key = e.front().key();
-            MarkObjectRoot(trc, &key, "AutoObjectUnsignedHashMap key");
+            TraceRoot(trc, &key, "AutoObjectUnsignedHashMap key");
             if (key != e.front().key())
                 e.rekeyFront(key);
         }
         return;
       }
 
       case OBJHASHSET: {
         AutoObjectHashSet* self = static_cast<AutoObjectHashSet*>(this);
         AutoObjectHashSet::HashSetImpl& set = self->set;
         for (AutoObjectHashSet::Enum e(set); !e.empty(); e.popFront()) {
             JSObject* obj = e.front();
-            MarkObjectRoot(trc, &obj, "AutoObjectHashSet value");
+            TraceRoot(trc, &obj, "AutoObjectHashSet value");
             if (obj != e.front())
                 e.rekeyFront(obj);
         }
         return;
       }
 
       case HASHABLEVALUE: {
         AutoHashableValueRooter* rooter = static_cast<AutoHashableValueRooter*>(this);
@@ -330,91 +330,89 @@ void
 StackShape::trace(JSTracer* trc)
 {
     if (base)
         TraceRoot(trc, &base, "StackShape base");
 
     TraceRoot(trc, (jsid*) &propid, "StackShape id");
 
     if ((attrs & JSPROP_GETTER) && rawGetter)
-        MarkObjectRoot(trc, (JSObject**)&rawGetter, "StackShape getter");
+        TraceRoot(trc, (JSObject**)&rawGetter, "StackShape getter");
 
     if ((attrs & JSPROP_SETTER) && rawSetter)
-        MarkObjectRoot(trc, (JSObject**)&rawSetter, "StackShape setter");
+        TraceRoot(trc, (JSObject**)&rawSetter, "StackShape setter");
 }
 
 void
 JSPropertyDescriptor::trace(JSTracer* trc)
 {
     if (obj)
-        MarkObjectRoot(trc, &obj, "Descriptor::obj");
+        TraceRoot(trc, &obj, "Descriptor::obj");
     TraceRoot(trc, &value, "Descriptor::value");
     if ((attrs & JSPROP_GETTER) && getter) {
         JSObject* tmp = JS_FUNC_TO_DATA_PTR(JSObject*, getter);
-        MarkObjectRoot(trc, &tmp, "Descriptor::get");
+        TraceRoot(trc, &tmp, "Descriptor::get");
         getter = JS_DATA_TO_FUNC_PTR(JSGetterOp, tmp);
     }
     if ((attrs & JSPROP_SETTER) && setter) {
         JSObject* tmp = JS_FUNC_TO_DATA_PTR(JSObject*, setter);
-        MarkObjectRoot(trc, &tmp, "Descriptor::set");
+        TraceRoot(trc, &tmp, "Descriptor::set");
         setter = JS_DATA_TO_FUNC_PTR(JSSetterOp, tmp);
     }
 }
 
 namespace js {
 namespace gc {
 
 template<typename T>
 struct PersistentRootedMarker
 {
     typedef PersistentRooted<T> Element;
     typedef mozilla::LinkedList<Element> List;
     typedef void (*MarkFunc)(JSTracer* trc, T* ref, const char* name);
 
-    template <MarkFunc Mark>
     static void
     markChainIfNotNull(JSTracer* trc, List& list, const char* name)
     {
         for (Element* r = list.getFirst(); r; r = r->getNext()) {
             if (r->get())
-                Mark(trc, r->address(), name);
+                TraceRoot(trc, r->address(), name);
         }
     }
 
-    template <MarkFunc Mark>
     static void
     markChain(JSTracer* trc, List& list, const char* name)
     {
         for (Element* r = list.getFirst(); r; r = r->getNext())
-            Mark(trc, r->address(), name);
+            TraceRoot(trc, r->address(), name);
     }
 };
 }
 }
 
 void
 js::gc::MarkPersistentRootedChains(JSTracer* trc)
 {
     JSRuntime* rt = trc->runtime();
 
     // Mark the PersistentRooted chains of types that may be null.
-    PersistentRootedMarker<JSFunction*>::markChainIfNotNull<MarkObjectRoot>(
-        trc, rt->functionPersistentRooteds, "PersistentRooted<JSFunction*>");
-    PersistentRootedMarker<JSObject*>::markChainIfNotNull<MarkObjectRoot>(
-        trc, rt->objectPersistentRooteds, "PersistentRooted<JSObject*>");
-    PersistentRootedMarker<JSScript*>::markChainIfNotNull<TraceRoot>(
-        trc, rt->scriptPersistentRooteds, "PersistentRooted<JSScript*>");
-    PersistentRootedMarker<JSString*>::markChainIfNotNull<TraceRoot>(
-        trc, rt->stringPersistentRooteds, "PersistentRooted<JSString*>");
+    PersistentRootedMarker<JSFunction*>::markChainIfNotNull(trc, rt->functionPersistentRooteds,
+                                                            "PersistentRooted<JSFunction*>");
+    PersistentRootedMarker<JSObject*>::markChainIfNotNull(trc, rt->objectPersistentRooteds,
+                                                          "PersistentRooted<JSObject*>");
+    PersistentRootedMarker<JSScript*>::markChainIfNotNull(trc, rt->scriptPersistentRooteds,
+                                                          "PersistentRooted<JSScript*>");
+    PersistentRootedMarker<JSString*>::markChainIfNotNull(trc, rt->stringPersistentRooteds,
+                                                          "PersistentRooted<JSString*>");
 
     // Mark the PersistentRooted chains of types that are never null.
-    PersistentRootedMarker<jsid>::markChain<TraceRoot>(trc, rt->idPersistentRooteds,
-                                                       "PersistentRooted<jsid>");
-    PersistentRootedMarker<Value>::markChain<TraceRoot>(trc, rt->valuePersistentRooteds,
-                                                        "PersistentRooted<Value>");
+    PersistentRootedMarker<jsid>::markChain(trc, rt->idPersistentRooteds,
+                                            "PersistentRooted<jsid>");
+    PersistentRootedMarker<Value>::markChain(trc, rt->valuePersistentRooteds,
+                                             "PersistentRooted<Value>");
 }
 
 void
 js::gc::GCRuntime::markRuntime(JSTracer* trc,
                                TraceOrMarkRuntime traceOrMark,
                                TraceRootsOrUsedSaved rootsSource)
 {
     gcstats::AutoPhase ap(stats, gcstats::PHASE_MARK_ROOTS);
@@ -448,18 +446,17 @@ js::gc::GCRuntime::markRuntime(JSTracer*
             const RootEntry& entry = r.front();
             TraceRoot(trc, entry.key(), entry.value());
         }
 
         MarkPersistentRootedChains(trc);
     }
 
     if (rt->asyncStackForNewActivations)
-        MarkObjectRoot(trc, &rt->asyncStackForNewActivations,
-                       "asyncStackForNewActivations");
+        TraceRoot(trc, &rt->asyncStackForNewActivations, "asyncStackForNewActivations");
 
     if (rt->asyncCauseForNewActivations)
         TraceRoot(trc, &rt->asyncCauseForNewActivations, "asyncCauseForNewActivations");
 
     if (rt->scriptAndCountsVector) {
         ScriptAndCountsVector& vec = *rt->scriptAndCountsVector;
         for (size_t i = 0; i < vec.length(); i++)
             TraceRoot(trc, &vec[i].script, "scriptAndCountsVector");
--- a/js/src/gc/StoreBuffer.cpp
+++ b/js/src/gc/StoreBuffer.cpp
@@ -64,17 +64,17 @@ StoreBuffer::WholeCellEdges::mark(JSTrac
 
 void
 StoreBuffer::CellPtrEdge::mark(JSTracer* trc) const
 {
     if (!*edge)
         return;
 
     MOZ_ASSERT(GetGCThingTraceKind(*edge) == JSTRACE_OBJECT);
-    MarkObjectRoot(trc, reinterpret_cast<JSObject**>(edge), "store buffer edge");
+    TraceRoot(trc, reinterpret_cast<JSObject**>(edge), "store buffer edge");
 }
 
 void
 StoreBuffer::ValueEdge::mark(JSTracer* trc) const
 {
     if (!deref())
         return;
 
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -39,17 +39,17 @@ JS_PUBLIC_API(void)
 JS_CallUnbarrieredIdTracer(JSTracer* trc, jsid* idp, const char* name)
 {
     TraceManuallyBarrieredEdge(trc, idp, name);
 }
 
 JS_PUBLIC_API(void)
 JS_CallUnbarrieredObjectTracer(JSTracer* trc, JSObject** objp, const char* name)
 {
-    MarkObjectUnbarriered(trc, objp, name);
+    TraceManuallyBarrieredEdge(trc, objp, name);
 }
 
 JS_PUBLIC_API(void)
 JS_CallUnbarrieredStringTracer(JSTracer* trc, JSString** strp, const char* name)
 {
     TraceManuallyBarrieredEdge(trc, strp, name);
 }
 
@@ -69,17 +69,17 @@ 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)
 {
-    MarkObjectUnbarriered(trc, objp->unsafeGet(), 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);
 }
 
@@ -87,28 +87,28 @@ 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)
 {
-    MarkObjectUnbarriered(trc, funp->unsafeGet(), 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;
 
     trc->setTracingLocation((void*)objp);
-    MarkObjectUnbarriered(trc, &obj, name);
+    TraceManuallyBarrieredEdge(trc, &obj, name);
 
     objp->setPtr(obj);
 }
 
 JS_PUBLIC_API(void)
 JS_TraceChildren(JSTracer* trc, void* thing, JSGCTraceKind kind)
 {
     js::TraceChildren(trc, thing, kind);
@@ -151,17 +151,17 @@ JS_TraceIncomingCCWs(JSTracer* trc, cons
                   case CrossCompartmentKey::DebuggerSource:
                   case CrossCompartmentKey::DebuggerEnvironment:
                     obj = static_cast<JSObject*>(key.wrapped);
                     // Ignore CCWs whose wrapped value doesn't live in our given
                     // set of zones.
                     if (!zones.has(obj->zone()))
                         continue;
 
-                    MarkObjectUnbarriered(trc, &obj, "cross-compartment wrapper");
+                    TraceManuallyBarrieredEdge(trc, &obj, "cross-compartment wrapper");
                     MOZ_ASSERT(obj == key.wrapped);
                     break;
 
                   case CrossCompartmentKey::DebuggerScript:
                     script = static_cast<JSScript*>(key.wrapped);
                     // Ignore CCWs whose wrapped value doesn't live in our given
                     // set of zones.
                     if (!zones.has(script->zone()))
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -145,17 +145,17 @@ Zone::sweepBreakpoints(FreeOp* fop)
                 continue;
 
             Breakpoint* nextbp;
             for (Breakpoint* bp = site->firstBreakpoint(); bp; bp = nextbp) {
                 nextbp = bp->nextInSite();
                 HeapPtrNativeObject& dbgobj = bp->debugger->toJSObjectRef();
                 MOZ_ASSERT_IF(isGCSweeping() && dbgobj->zone()->isCollecting(),
                               dbgobj->zone()->isGCSweeping());
-                bool dying = scriptGone || IsObjectAboutToBeFinalized(&dbgobj);
+                bool dying = scriptGone || IsAboutToBeFinalized(&dbgobj);
                 MOZ_ASSERT_IF(!dying, !IsAboutToBeFinalized(&bp->getHandlerRef()));
                 if (dying)
                     bp->destroy(fop);
             }
         }
     }
 }
 
--- a/js/src/jit/BaselineFrame.cpp
+++ b/js/src/jit/BaselineFrame.cpp
@@ -37,27 +37,27 @@ BaselineFrame::trace(JSTracer* trc, JitF
     // Mark actual and formal args.
     if (isNonEvalFunctionFrame()) {
         unsigned numArgs = js::Max(numActualArgs(), numFormalArgs());
         TraceRootRange(trc, numArgs, argv(), "baseline-args");
     }
 
     // Mark scope chain, if it exists.
     if (scopeChain_)
-        gc::MarkObjectRoot(trc, &scopeChain_, "baseline-scopechain");
+        TraceRoot(trc, &scopeChain_, "baseline-scopechain");
 
     // Mark return value.
     if (hasReturnValue())
         TraceRoot(trc, returnValue().address(), "baseline-rval");
 
     if (isEvalFrame())
         TraceRoot(trc, &evalScript_, "baseline-evalscript");
 
     if (hasArgsObj())
-        gc::MarkObjectRoot(trc, &argsObj_, "baseline-args-obj");
+        TraceRoot(trc, &argsObj_, "baseline-args-obj");
 
     // Mark locals and stack values.
     JSScript* script = this->script();
     size_t nfixed = script->nfixed();
     size_t nlivefixed = script->nbodyfixed();
 
     if (nfixed != nlivefixed) {
         jsbytecode* pc;
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -196,63 +196,63 @@ ICStub::trace(JSTracer* trc)
             MOZ_ASSERT_IF(iter->next() == nullptr, iter->isTypeUpdate_Fallback());
             iter->trace(trc);
         }
     }
 
     switch (kind()) {
       case ICStub::Call_Scripted: {
         ICCall_Scripted* callStub = toCall_Scripted();
-        MarkObject(trc, &callStub->callee(), "baseline-callscripted-callee");
+        TraceEdge(trc, &callStub->callee(), "baseline-callscripted-callee");
         if (callStub->templateObject())
-            MarkObject(trc, &callStub->templateObject(), "baseline-callscripted-template");
+            TraceEdge(trc, &callStub->templateObject(), "baseline-callscripted-template");
         break;
       }
       case ICStub::Call_Native: {
         ICCall_Native* callStub = toCall_Native();
-        MarkObject(trc, &callStub->callee(), "baseline-callnative-callee");
+        TraceEdge(trc, &callStub->callee(), "baseline-callnative-callee");
         if (callStub->templateObject())
-            MarkObject(trc, &callStub->templateObject(), "baseline-callnative-template");
+            TraceEdge(trc, &callStub->templateObject(), "baseline-callnative-template");
         break;
       }
       case ICStub::Call_ClassHook: {
         ICCall_ClassHook* callStub = toCall_ClassHook();
         if (callStub->templateObject())
-            MarkObject(trc, &callStub->templateObject(), "baseline-callclasshook-template");
+            TraceEdge(trc, &callStub->templateObject(), "baseline-callclasshook-template");
         break;
       }
       case ICStub::Call_StringSplit: {
         ICCall_StringSplit* callStub = toCall_StringSplit();
-        MarkObject(trc, &callStub->templateObject(), "baseline-callstringsplit-template");
+        TraceEdge(trc, &callStub->templateObject(), "baseline-callstringsplit-template");
         TraceEdge(trc, &callStub->expectedArg(), "baseline-callstringsplit-arg");
         TraceEdge(trc, &callStub->expectedThis(), "baseline-callstringsplit-this");
         break;
       }
       case ICStub::GetElem_NativeSlot: {
         ICGetElem_NativeSlot* getElemStub = toGetElem_NativeSlot();
         TraceEdge(trc, &getElemStub->shape(), "baseline-getelem-native-shape");
         TraceEdge(trc, &getElemStub->name(), "baseline-getelem-native-name");
         break;
       }
       case ICStub::GetElem_NativePrototypeSlot: {
         ICGetElem_NativePrototypeSlot* getElemStub = toGetElem_NativePrototypeSlot();
         TraceEdge(trc, &getElemStub->shape(), "baseline-getelem-nativeproto-shape");
         TraceEdge(trc, &getElemStub->name(), "baseline-getelem-nativeproto-name");
-        MarkObject(trc, &getElemStub->holder(), "baseline-getelem-nativeproto-holder");
+        TraceEdge(trc, &getElemStub->holder(), "baseline-getelem-nativeproto-holder");
         TraceEdge(trc, &getElemStub->holderShape(), "baseline-getelem-nativeproto-holdershape");
         break;
       }
       case ICStub::GetElem_NativePrototypeCallNative:
       case ICStub::GetElem_NativePrototypeCallScripted: {
         ICGetElemNativePrototypeCallStub* callStub =
             reinterpret_cast<ICGetElemNativePrototypeCallStub*>(this);
         TraceEdge(trc, &callStub->shape(), "baseline-getelem-nativeprotocall-shape");
         TraceEdge(trc, &callStub->name(), "baseline-getelem-nativeprotocall-name");
-        MarkObject(trc, &callStub->getter(), "baseline-getelem-nativeprotocall-getter");
-        MarkObject(trc, &callStub->holder(), "baseline-getelem-nativeprotocall-holder");
+        TraceEdge(trc, &callStub->getter(), "baseline-getelem-nativeprotocall-getter");
+        TraceEdge(trc, &callStub->holder(), "baseline-getelem-nativeprotocall-holder");
         TraceEdge(trc, &callStub->holderShape(), "baseline-getelem-nativeprotocall-holdershape");
         break;
       }
       case ICStub::GetElem_Dense: {
         ICGetElem_Dense* getElemStub = toGetElem_Dense();
         TraceEdge(trc, &getElemStub->shape(), "baseline-getelem-dense-shape");
         break;
       }
@@ -285,27 +285,27 @@ ICStub::trace(JSTracer* trc)
       }
       case ICStub::SetElem_TypedArray: {
         ICSetElem_TypedArray* setElemStub = toSetElem_TypedArray();
         TraceEdge(trc, &setElemStub->shape(), "baseline-setelem-typedarray-shape");
         break;
       }
       case ICStub::TypeMonitor_SingleObject: {
         ICTypeMonitor_SingleObject* monitorStub = toTypeMonitor_SingleObject();
-        MarkObject(trc, &monitorStub->object(), "baseline-monitor-singleton");
+        TraceEdge(trc, &monitorStub->object(), "baseline-monitor-singleton");
         break;
       }
       case ICStub::TypeMonitor_ObjectGroup: {
         ICTypeMonitor_ObjectGroup* monitorStub = toTypeMonitor_ObjectGroup();
         TraceEdge(trc, &monitorStub->group(), "baseline-monitor-group");
         break;
       }
       case ICStub::TypeUpdate_SingleObject: {
         ICTypeUpdate_SingleObject* updateStub = toTypeUpdate_SingleObject();
-        MarkObject(trc, &updateStub->object(), "baseline-update-singleton");
+        TraceEdge(trc, &updateStub->object(), "baseline-update-singleton");
         break;
       }
       case ICStub::TypeUpdate_ObjectGroup: {
         ICTypeUpdate_ObjectGroup* updateStub = toTypeUpdate_ObjectGroup();
         TraceEdge(trc, &updateStub->group(), "baseline-update-group");
         break;
       }
       case ICStub::GetName_Global: {
@@ -347,17 +347,17 @@ ICStub::trace(JSTracer* trc)
       case ICStub::GetProp_Native: {
         ICGetProp_Native* propStub = toGetProp_Native();
         propStub->receiverGuard().trace(trc);
         break;
       }
       case ICStub::GetProp_NativePrototype: {
         ICGetProp_NativePrototype* propStub = toGetProp_NativePrototype();
         propStub->receiverGuard().trace(trc);
-        MarkObject(trc, &propStub->holder(), "baseline-getpropnativeproto-stub-holder");
+        TraceEdge(trc, &propStub->holder(), "baseline-getpropnativeproto-stub-holder");
         TraceEdge(trc, &propStub->holderShape(), "baseline-getpropnativeproto-stub-holdershape");
         break;
       }
       case ICStub::GetProp_NativeDoesNotExist: {
         ICGetProp_NativeDoesNotExist* propStub = toGetProp_NativeDoesNotExist();
         propStub->guard().trace(trc);
         JS_STATIC_ASSERT(ICGetProp_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH == 8);
         switch (propStub->protoChainDepth()) {
@@ -391,41 +391,41 @@ ICStub::trace(JSTracer* trc)
             propStub = toGetProp_CallDOMProxyNative();
         else
             propStub = toGetProp_CallDOMProxyWithGenerationNative();
         propStub->receiverGuard().trace(trc);
         if (propStub->expandoShape()) {
             TraceEdge(trc, &propStub->expandoShape(),
                       "baseline-getproplistbasenative-stub-expandoshape");
         }
-        MarkObject(trc, &propStub->holder(), "baseline-getproplistbasenative-stub-holder");
+        TraceEdge(trc, &propStub->holder(), "baseline-getproplistbasenative-stub-holder");
         TraceEdge(trc, &propStub->holderShape(), "baseline-getproplistbasenative-stub-holdershape");
-        MarkObject(trc, &propStub->getter(), "baseline-getproplistbasenative-stub-getter");
+        TraceEdge(trc, &propStub->getter(), "baseline-getproplistbasenative-stub-getter");
         break;
       }
       case ICStub::GetProp_DOMProxyShadowed: {
         ICGetProp_DOMProxyShadowed* propStub = toGetProp_DOMProxyShadowed();
         TraceEdge(trc, &propStub->shape(), "baseline-getproplistbaseshadowed-stub-shape");
         TraceEdge(trc, &propStub->name(), "baseline-getproplistbaseshadowed-stub-name");
         break;
       }
       case ICStub::GetProp_CallScripted: {
         ICGetProp_CallScripted* callStub = toGetProp_CallScripted();
         callStub->receiverGuard().trace(trc);
-        MarkObject(trc, &callStub->holder(), "baseline-getpropcallscripted-stub-holder");
+        TraceEdge(trc, &callStub->holder(), "baseline-getpropcallscripted-stub-holder");
         TraceEdge(trc, &callStub->holderShape(), "baseline-getpropcallscripted-stub-holdershape");
-        MarkObject(trc, &callStub->getter(), "baseline-getpropcallscripted-stub-getter");
+        TraceEdge(trc, &callStub->getter(), "baseline-getpropcallscripted-stub-getter");
         break;
       }
       case ICStub::GetProp_CallNative: {
         ICGetProp_CallNative* callStub = toGetProp_CallNative();
         callStub->receiverGuard().trace(trc);
-        MarkObject(trc, &callStub->holder(), "baseline-getpropcallnative-stub-holder");
+        TraceEdge(trc, &callStub->holder(), "baseline-getpropcallnative-stub-holder");
         TraceEdge(trc, &callStub->holderShape(), "baseline-getpropcallnative-stub-holdershape");
-        MarkObject(trc, &callStub->getter(), "baseline-getpropcallnative-stub-getter");
+        TraceEdge(trc, &callStub->getter(), "baseline-getpropcallnative-stub-getter");
         break;
       }
       case ICStub::SetProp_Native: {
         ICSetProp_Native* propStub = toSetProp_Native();
         TraceEdge(trc, &propStub->shape(), "baseline-setpropnative-stub-shape");
         TraceEdge(trc, &propStub->group(), "baseline-setpropnative-stub-group");
         break;
       }
@@ -455,49 +455,49 @@ ICStub::trace(JSTracer* trc)
         ICSetProp_TypedObject* propStub = toSetProp_TypedObject();
         TraceEdge(trc, &propStub->shape(), "baseline-setprop-typedobject-stub-shape");
         TraceEdge(trc, &propStub->group(), "baseline-setprop-typedobject-stub-group");
         break;
       }
       case ICStub::SetProp_CallScripted: {
         ICSetProp_CallScripted* callStub = toSetProp_CallScripted();
         callStub->guard().trace(trc);
-        MarkObject(trc, &callStub->holder(), "baseline-setpropcallscripted-stub-holder");
+        TraceEdge(trc, &callStub->holder(), "baseline-setpropcallscripted-stub-holder");
         TraceEdge(trc, &callStub->holderShape(), "baseline-setpropcallscripted-stub-holdershape");
-        MarkObject(trc, &callStub->setter(), "baseline-setpropcallscripted-stub-setter");
+        TraceEdge(trc, &callStub->setter(), "baseline-setpropcallscripted-stub-setter");
         break;
       }
       case ICStub::SetProp_CallNative: {
         ICSetProp_CallNative* callStub = toSetProp_CallNative();
         callStub->guard().trace(trc);
-        MarkObject(trc, &callStub->holder(), "baseline-setpropcallnative-stub-holder");
+        TraceEdge(trc, &callStub->holder(), "baseline-setpropcallnative-stub-holder");
         TraceEdge(trc, &callStub->holderShape(), "baseline-setpropcallnative-stub-holdershape");
-        MarkObject(trc, &callStub->setter(), "baseline-setpropcallnative-stub-setter");
+        TraceEdge(trc, &callStub->setter(), "baseline-setpropcallnative-stub-setter");
         break;
       }
       case ICStub::InstanceOf_Function: {
         ICInstanceOf_Function* instanceofStub = toInstanceOf_Function();
         TraceEdge(trc, &instanceofStub->shape(), "baseline-instanceof-fun-shape");
-        MarkObject(trc, &instanceofStub->prototypeObject(), "baseline-instanceof-fun-prototype");
+        TraceEdge(trc, &instanceofStub->prototypeObject(), "baseline-instanceof-fun-prototype");
         break;
       }
       case ICStub::NewArray_Fallback: {
         ICNewArray_Fallback* stub = toNewArray_Fallback();
-        MarkObject(trc, &stub->templateObject(), "baseline-newarray-template");
+        TraceEdge(trc, &stub->templateObject(), "baseline-newarray-template");
         break;
       }
       case ICStub::NewObject_Fallback: {
         ICNewObject_Fallback* stub = toNewObject_Fallback();
         if (stub->templateObject())
-            MarkObject(trc, &stub->templateObject(), "baseline-newobject-template");
+            TraceEdge(trc, &stub->templateObject(), "baseline-newobject-template");
         break;
       }
       case ICStub::Rest_Fallback: {
         ICRest_Fallback* stub = toRest_Fallback();
-        MarkObject(trc, &stub->templateObject(), "baseline-rest-template");
+        TraceEdge(trc, &stub->templateObject(), "baseline-rest-template");
         break;
       }
       default:
         break;
     }
 }
 
 void
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -409,17 +409,17 @@ BaselineScript::New(JSScript* jsscript, 
     return script;
 }
 
 void
 BaselineScript::trace(JSTracer* trc)
 {
     TraceEdge(trc, &method_, "baseline-method");
     if (templateScope_)
-        MarkObject(trc, &templateScope_, "baseline-template-scope");
+        TraceEdge(trc, &templateScope_, "baseline-template-scope");
 
     // Mark all IC stub codes hanging off the IC stub entries.
     for (size_t i = 0; i < numICEntries(); i++) {
         ICEntry& ent = icEntry(i);
         if (!ent.hasStub())
             continue;
         for (ICStub* stub = ent.firstStub(); stub; stub = stub->next())
             stub->trace(trc);
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -549,17 +549,17 @@ JitCompartment::sweep(FreeOp* fop, JSCom
     if (regExpExecStub_ && !IsMarkedUnbarriered(&regExpExecStub_))
         regExpExecStub_ = nullptr;
 
     if (regExpTestStub_ && !IsMarkedUnbarriered(&regExpTestStub_))
         regExpTestStub_ = nullptr;
 
     for (size_t i = 0; i <= SimdTypeDescr::LAST_TYPE; i++) {
         ReadBarrieredObject& obj = simdTemplateObjects_[i];
-        if (obj && IsObjectAboutToBeFinalized(obj.unsafeGet()))
+        if (obj && IsAboutToBeFinalized(&obj))
             obj.set(nullptr);
     }
 }
 
 void
 JitCompartment::toggleBarriers(bool enabled)
 {
     // Toggle barriers in compartment wide stubs that have patchable pre barriers.
@@ -1709,17 +1709,17 @@ AttachFinishedCompilations(JSContext* cx
 
         FinishOffThreadBuilder(cx, builder);
     }
 }
 
 void
 MIRGenerator::traceNurseryObjects(JSTracer* trc)
 {
-    MarkObjectRootRange(trc, nurseryObjects_.length(), nurseryObjects_.begin(), "ion-nursery-objects");
+    TraceRootRange(trc, nurseryObjects_.length(), nurseryObjects_.begin(), "ion-nursery-objects");
 }
 
 class MarkOffThreadNurseryObjects : public gc::BufferableRef
 {
   public:
     void mark(JSTracer* trc);
 };
 
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -967,17 +967,17 @@ EnsureExitFrame(CommonFrameLayout* frame
 CalleeToken
 MarkCalleeToken(JSTracer* trc, CalleeToken token)
 {
     switch (CalleeTokenTag tag = GetCalleeTokenTag(token)) {
       case CalleeToken_Function:
       case CalleeToken_FunctionConstructing:
       {
         JSFunction* fun = CalleeTokenToFunction(token);
-        MarkObjectRoot(trc, &fun, "jit-callee");
+        TraceRoot(trc, &fun, "jit-callee");
         return CalleeToToken(fun, tag == CalleeToken_FunctionConstructing);
       }
       case CalleeToken_Script:
       {
         JSScript* script = CalleeTokenToScript(token);
         TraceRoot(trc, &script, "jit-script");
         return CalleeToToken(script);
       }
@@ -1342,33 +1342,33 @@ MarkJitExitFrame(JSTracer* trc, const Ji
         // the common base class.
         IonOOLPropertyOpExitFrameLayout* oolgetter =
             frame.isExitFrameLayout<IonOOLPropertyOpExitFrameLayout>()
             ? frame.exitFrame()->as<IonOOLPropertyOpExitFrameLayout>()
             : frame.exitFrame()->as<IonOOLSetterOpExitFrameLayout>();
         TraceRoot(trc, oolgetter->stubCode(), "ion-ool-property-op-code");
         TraceRoot(trc, oolgetter->vp(), "ion-ool-property-op-vp");
         TraceRoot(trc, oolgetter->id(), "ion-ool-property-op-id");
-        gc::MarkObjectRoot(trc, oolgetter->obj(), "ion-ool-property-op-obj");
+        TraceRoot(trc, oolgetter->obj(), "ion-ool-property-op-obj");
         return;
     }
 
     if (frame.isExitFrameLayout<IonOOLProxyExitFrameLayout>()) {
         IonOOLProxyExitFrameLayout* oolproxy = frame.exitFrame()->as<IonOOLProxyExitFrameLayout>();
         TraceRoot(trc, oolproxy->stubCode(), "ion-ool-proxy-code");
         TraceRoot(trc, oolproxy->vp(), "ion-ool-proxy-vp");
         TraceRoot(trc, oolproxy->id(), "ion-ool-proxy-id");
-        gc::MarkObjectRoot(trc, oolproxy->proxy(), "ion-ool-proxy-proxy");
-        gc::MarkObjectRoot(trc, oolproxy->receiver(), "ion-ool-proxy-receiver");
+        TraceRoot(trc, oolproxy->proxy(), "ion-ool-proxy-proxy");
+        TraceRoot(trc, oolproxy->receiver(), "ion-ool-proxy-receiver");
         return;
     }
 
     if (frame.isExitFrameLayout<IonDOMExitFrameLayout>()) {
         IonDOMExitFrameLayout* dom = frame.exitFrame()->as<IonDOMExitFrameLayout>();
-        gc::MarkObjectRoot(trc, dom->thisObjAddress(), "ion-dom-args");
+        TraceRoot(trc, dom->thisObjAddress(), "ion-dom-args");
         if (dom->isMethodFrame()) {
             IonDOMMethodExitFrameLayout* method =
                 reinterpret_cast<IonDOMMethodExitFrameLayout*>(dom);
             size_t len = method->argc() + 2;
             Value* vp = method->vp();
             TraceRootRange(trc, len, vp, "ion-dom-args");
         } else {
             TraceRoot(trc, dom->vp(), "ion-dom-args");
@@ -1403,25 +1403,25 @@ MarkJitExitFrame(JSTracer* trc, const Ji
     for (uint32_t explicitArg = 0; explicitArg < f->explicitArgs; explicitArg++) {
         switch (f->argRootType(explicitArg)) {
           case VMFunction::RootNone:
             break;
           case VMFunction::RootObject: {
             // Sometimes we can bake in HandleObjects to nullptr.
             JSObject** pobj = reinterpret_cast<JSObject**>(argBase);
             if (*pobj)
-                gc::MarkObjectRoot(trc, pobj, "ion-vm-args");
+                TraceRoot(trc, pobj, "ion-vm-args");
             break;
           }
           case VMFunction::RootString:
           case VMFunction::RootPropertyName:
             TraceRoot(trc, reinterpret_cast<JSString**>(argBase), "ion-vm-args");
             break;
           case VMFunction::RootFunction:
-            gc::MarkObjectRoot(trc, reinterpret_cast<JSFunction**>(argBase), "ion-vm-args");
+            TraceRoot(trc, reinterpret_cast<JSFunction**>(argBase), "ion-vm-args");
             break;
           case VMFunction::RootValue:
             TraceRoot(trc, reinterpret_cast<Value*>(argBase), "ion-vm-args");
             break;
           case VMFunction::RootCell:
             gc::MarkGCThingRoot(trc, reinterpret_cast<void**>(argBase), "ion-vm-args");
             break;
         }
@@ -1438,24 +1438,24 @@ MarkJitExitFrame(JSTracer* trc, const Ji
         }
     }
 
     if (f->outParam == Type_Handle) {
         switch (f->outParamRootType) {
           case VMFunction::RootNone:
             MOZ_CRASH("Handle outparam must have root type");
           case VMFunction::RootObject:
-            gc::MarkObjectRoot(trc, footer->outParam<JSObject*>(), "ion-vm-out");
+            TraceRoot(trc, footer->outParam<JSObject*>(), "ion-vm-out");
             break;
           case VMFunction::RootString:
           case VMFunction::RootPropertyName:
             TraceRoot(trc, footer->outParam<JSString*>(), "ion-vm-out");
             break;
           case VMFunction::RootFunction:
-            gc::MarkObjectRoot(trc, footer->outParam<JSFunction*>(), "ion-vm-out");
+            TraceRoot(trc, footer->outParam<JSFunction*>(), "ion-vm-out");
             break;
           case VMFunction::RootValue:
             TraceRoot(trc, footer->outParam<Value>(), "ion-vm-outvp");
             break;
           case VMFunction::RootCell:
             gc::MarkGCThingRoot(trc, footer->outParam<void*>(), "ion-vm-out");
             break;
         }
--- a/js/src/jit/JitcodeMap.cpp
+++ b/js/src/jit/JitcodeMap.cpp
@@ -866,19 +866,19 @@ JitcodeGlobalEntry::IonEntry::markIfUnma
         if (!TypeSet::IsTypeMarked(&iter->type)) {
             TypeSet::MarkTypeUnbarriered(trc, &iter->type, "jitcodeglobaltable-ionentry-type");
             markedAny = true;
         }
         if (iter->hasAllocationSite() && !IsMarkedUnbarriered(&iter->script)) {
             TraceManuallyBarrieredEdge(trc, &iter->script,
                                        "jitcodeglobaltable-ionentry-type-addendum-script");
             markedAny = true;
-        } else if (iter->hasConstructor() && !IsObjectMarked(&iter->constructor)) {
-            MarkObjectUnbarriered(trc, &iter->constructor,
-                                  "jitcodeglobaltable-ionentry-type-addendum-constructor");
+        } else if (iter->hasConstructor() && !IsMarkedUnbarriered(&iter->constructor)) {
+            TraceManuallyBarrieredEdge(trc, &iter->constructor,
+                                       "jitcodeglobaltable-ionentry-type-addendum-constructor");
             markedAny = true;
         }
     }
 
     return markedAny;
 }
 
 void
@@ -894,17 +894,17 @@ JitcodeGlobalEntry::IonEntry::sweep()
          iter != optsAllTypes_->end(); iter++)
     {
         // Types may move under compacting GC. This method is only called on
         // entries that are sampled, and thus are not about to be finalized.
         MOZ_ALWAYS_FALSE(TypeSet::IsTypeAboutToBeFinalized(&iter->type));
         if (iter->hasAllocationSite())
             MOZ_ALWAYS_FALSE(IsAboutToBeFinalizedUnbarriered(&iter->script));
         else if (iter->hasConstructor())
-            MOZ_ALWAYS_FALSE(IsObjectAboutToBeFinalized(&iter->constructor));
+            MOZ_ALWAYS_FALSE(IsAboutToBeFinalizedUnbarriered(&iter->constructor));
     }
 }
 
 bool
 JitcodeGlobalEntry::IonEntry::isMarkedFromAnyThread()
 {
     for (unsigned i = 0; i < numScripts(); i++) {
         if (!IsMarkedUnbarriered(&sizedScriptList()->pairs[i].script) &&
--- a/js/src/jit/RematerializedFrame.cpp
+++ b/js/src/jit/RematerializedFrame.cpp
@@ -143,17 +143,17 @@ RematerializedFrame::initFunctionScopeOb
     hasCallObj_ = true;
     return true;
 }
 
 void
 RematerializedFrame::mark(JSTracer* trc)
 {
     TraceRoot(trc, &script_, "remat ion frame script");
-    gc::MarkObjectRoot(trc, &scopeChain_, "remat ion frame scope chain");
+    TraceRoot(trc, &scopeChain_, "remat ion frame scope chain");
     TraceRoot(trc, &returnValue_, "remat ion frame return value");
     TraceRoot(trc, &thisValue_, "remat ion frame this");
     TraceRootRange(trc, numActualArgs_ + script_->nfixed(), slots_, "remat ion frame stack");
 }
 
 void
 RematerializedFrame::dump()
 {
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -1254,17 +1254,17 @@ MarkStringFromIon(JSRuntime* rt, JSStrin
     if (*stringp)
         TraceManuallyBarrieredEdge(&rt->gc.marker, stringp, "write barrier");
 }
 
 void
 MarkObjectFromIon(JSRuntime* rt, JSObject** objp)
 {
     if (*objp)
-        gc::MarkObjectUnbarriered(&rt->gc.marker, objp, "write barrier");
+        TraceManuallyBarrieredEdge(&rt->gc.marker, objp, "write barrier");
 }
 
 void
 MarkShapeFromIon(JSRuntime* rt, Shape** shapep)
 {
     TraceManuallyBarrieredEdge(&rt->gc.marker, shapep, "write barrier");
 }
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1516,17 +1516,17 @@ JS_PUBLIC_API(void)
 JS_UpdateWeakPointerAfterGC(JS::Heap<JSObject*>* objp)
 {
     JS_UpdateWeakPointerAfterGCUnbarriered(objp->unsafeGet());
 }
 
 JS_PUBLIC_API(void)
 JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp)
 {
-    if (IsObjectAboutToBeFinalized(objp))
+    if (IsAboutToBeFinalizedUnbarriered(objp))
         *objp = nullptr;
 }
 
 JS_PUBLIC_API(void)
 JS_SetGCParameter(JSRuntime* rt, JSGCParamKey key, uint32_t value)
 {
     rt->gc.setParameter(key, value);
 }
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -82,17 +82,17 @@ js::AutoCycleDetector::~AutoCycleDetecto
 }
 
 void
 js::TraceCycleDetectionSet(JSTracer* trc, js::ObjectSet& set)
 {
     for (js::ObjectSet::Enum e(set); !e.empty(); e.popFront()) {
         JSObject* key = e.front();
         trc->setTracingLocation((void*)&e.front());
-        MarkObjectRoot(trc, &key, "cycle detector table entry");
+        TraceRoot(trc, &key, "cycle detector table entry");
         if (key != e.front())
             e.rekeyFront(key);
     }
 }
 
 JSContext*
 js::NewContext(JSRuntime* rt, size_t stackChunkSize)
 {
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -511,17 +511,17 @@ JSCompartment::markRoots(JSTracer* trc)
     if (jitCompartment_)
         jitCompartment_->mark(trc, this);
 
     /*
      * If a compartment is on-stack, we mark its global so that
      * JSContext::global() remains valid.
      */
     if (enterCompartmentDepth && global_.unbarrieredGet())
-        MarkObjectRoot(trc, global_.unsafeGet(), "on-stack compartment global");
+        TraceRoot(trc, global_.unsafeGet(), "on-stack compartment global");
 }
 
 void
 JSCompartment::sweepInnerViews()
 {
     innerViews.sweep(runtimeFromAnyThread());
 }
 
@@ -529,28 +529,28 @@ void
 JSCompartment::sweepSavedStacks()
 {
     savedStacks_.sweep(runtimeFromAnyThread());
 }
 
 void
 JSCompartment::sweepGlobalObject(FreeOp* fop)
 {
-    if (global_.unbarrieredGet() && IsObjectAboutToBeFinalized(global_.unsafeGet())) {
+    if (global_.unbarrieredGet() && IsAboutToBeFinalized(&global_)) {
         if (isDebuggee())
             Debugger::detachAllDebuggersFromGlobal(fop, global_);
         global_.set(nullptr);
     }
 }
 
 void
 JSCompartment::sweepSelfHostingScriptSource()
 {
     if (selfHostingScriptSource.unbarrieredGet() &&
-        IsObjectAboutToBeFinalized((JSObject**) selfHostingScriptSource.unsafeGet()))
+        IsAboutToBeFinalized(&selfHostingScriptSource))
     {
         selfHostingScriptSource.set(nullptr);
     }
 }
 
 void
 JSCompartment::sweepJitCompartment(FreeOp* fop)
 {
@@ -587,17 +587,17 @@ JSCompartment::sweepWeakMaps()
 void
 JSCompartment::sweepNativeIterators()
 {
     /* Sweep list of native iterators. */
     NativeIterator* ni = enumerators->next();
     while (ni != enumerators) {
         JSObject* iterObj = ni->iterObj();
         NativeIterator* next = ni->next();
-        if (gc::IsObjectAboutToBeFinalized(&iterObj))
+        if (gc::IsAboutToBeFinalizedUnbarriered(&iterObj))
             ni->unlink();
         ni = next;
     }
 }
 
 /*
  * Remove dead wrappers from the table. We must sweep all compartments, since
  * string entries in the crossCompartmentWrappers table are not marked during
@@ -612,34 +612,34 @@ JSCompartment::sweepCrossCompartmentWrap
         bool keyDying;
         switch (key.kind) {
           case CrossCompartmentKey::ObjectWrapper:
           case CrossCompartmentKey::DebuggerObject:
           case CrossCompartmentKey::DebuggerEnvironment:
           case CrossCompartmentKey::DebuggerSource:
               MOZ_ASSERT(IsInsideNursery(key.wrapped) ||
                          key.wrapped->asTenured().getTraceKind() == JSTRACE_OBJECT);
-              keyDying = IsObjectAboutToBeFinalized(
+              keyDying = IsAboutToBeFinalizedUnbarriered(
                   reinterpret_cast<JSObject**>(&key.wrapped));
               break;
           case CrossCompartmentKey::StringWrapper:
               MOZ_ASSERT(key.wrapped->asTenured().getTraceKind() == JSTRACE_STRING);
               keyDying = IsAboutToBeFinalizedUnbarriered(
                   reinterpret_cast<JSString**>(&key.wrapped));
               break;
           case CrossCompartmentKey::DebuggerScript:
               MOZ_ASSERT(key.wrapped->asTenured().getTraceKind() == JSTRACE_SCRIPT);
               keyDying = IsAboutToBeFinalizedUnbarriered(
                   reinterpret_cast<JSScript**>(&key.wrapped));
               break;
           default:
               MOZ_CRASH("Unknown key kind");
         }
         bool valDying = IsAboutToBeFinalized(&e.front().value());
-        bool dbgDying = key.debugger && IsObjectAboutToBeFinalized(&key.debugger);
+        bool dbgDying = key.debugger && IsAboutToBeFinalizedUnbarriered(&key.debugger);
         if (keyDying || valDying || dbgDying) {
             MOZ_ASSERT(key.kind != CrossCompartmentKey::StringWrapper);
             e.removeFront();
         } else if (key.wrapped != e.front().key().wrapped ||
                    key.debugger != e.front().key().debugger)
         {
             e.rekeyFront(key);
         }
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -1039,17 +1039,17 @@ js::GetAnyCompartmentInZone(JS::Zone* zo
     CompartmentsInZoneIter comp(zone);
     MOZ_ASSERT(!comp.done());
     return comp.get();
 }
 
 void
 JS::ObjectPtr::updateWeakPointerAfterGC()
 {
-    if (js::gc::IsObjectAboutToBeFinalized(value.unsafeGet()))
+    if (js::gc::IsAboutToBeFinalizedUnbarriered(value.unsafeGet()))
         value = nullptr;
 }
 
 void
 JS::ObjectPtr::trace(JSTracer* trc, const char* name)
 {
     JS_CallObjectTracer(trc, &value, name);
 }
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -753,17 +753,17 @@ JSFunction::trace(JSTracer* trc)
                 relazify(trc);
             } else {
                 TraceManuallyBarrieredEdge(trc, &u.i.s.script_, "script");
             }
         } else if (isInterpretedLazy() && u.i.s.lazy_) {
             TraceManuallyBarrieredEdge(trc, &u.i.s.lazy_, "lazyScript");
         }
         if (u.i.env_)
-            MarkObjectUnbarriered(trc, &u.i.env_, "fun_environment");
+            TraceManuallyBarrieredEdge(trc, &u.i.env_, "fun_environment");
     }
 }
 
 static void
 fun_trace(JSTracer* trc, JSObject* obj)
 {
     obj->as<JSFunction>().trace(trc);
 }
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -4549,21 +4549,21 @@ MarkIncomingCrossCompartmentPointers(JSR
         for (JSObject* src = c->gcIncomingGrayPointers;
              src;
              src = NextIncomingCrossCompartmentPointer(src, unlinkList))
         {
             JSObject* dst = CrossCompartmentPointerReferent(src);
             MOZ_ASSERT(dst->compartment() == c);
 
             if (color == GRAY) {
-                if (IsObjectMarked(&src) && src->asTenured().isMarked(GRAY))
+                if (IsMarkedUnbarriered(&src) && src->asTenured().isMarked(GRAY))
                     MarkGCThingUnbarriered(&rt->gc.marker, (void**)&dst,
                                            "cross-compartment gray pointer");
             } else {
-                if (IsObjectMarked(&src) && !src->asTenured().isMarked(GRAY))
+                if (IsMarkedUnbarriered(&src) && !src->asTenured().isMarked(GRAY))
                     MarkGCThingUnbarriered(&rt->gc.marker, (void**)&dst,
                                            "cross-compartment black pointer");
             }
         }
 
         if (unlinkList)
             c->gcIncomingGrayPointers = nullptr;
     }
@@ -5664,17 +5664,17 @@ AutoGCSlice::~AutoGCSlice()
 }
 
 void
 GCRuntime::pushZealSelectedObjects()
 {
 #ifdef JS_GC_ZEAL
     /* Push selected objects onto the mark stack and clear the list. */
     for (JSObject** obj = selectedForMarking.begin(); obj != selectedForMarking.end(); obj++)
-        MarkObjectUnbarriered(&marker, obj, "selected obj");
+        TraceManuallyBarrieredEdge(&marker, obj, "selected obj");
 #endif
 }
 
 static bool
 ShouldCleanUpEverything(JS::gcreason::Reason reason, JSGCInvocationKind gckind)
 {
     // During shutdown, we must clean everything up, for the sake of leak
     // detection. When a runtime has no contexts, or we're doing a GC before a
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -55,22 +55,22 @@ typedef Rooted<PropertyIteratorObject*> 
 static const gc::AllocKind ITERATOR_FINALIZE_KIND = gc::AllocKind::OBJECT2_BACKGROUND;
 
 void
 NativeIterator::mark(JSTracer* trc)
 {
     for (HeapPtrFlatString* str = begin(); str < end(); str++)
         TraceEdge(trc, str, "prop");
     if (obj)
-        MarkObject(trc, &obj, "obj");
+        TraceEdge(trc, &obj, "obj");
 
     // The SuppressDeletedPropertyHelper loop can GC, so make sure that if the
     // GC removes any elements from the list, it won't remove this one.
     if (iterObj_)
-        MarkObjectUnbarriered(trc, &iterObj_, "iterObj");
+        TraceManuallyBarrieredEdge(trc, &iterObj_, "iterObj");
 }
 
 struct IdHashPolicy {
     typedef jsid Lookup;
     static HashNumber hash(jsid id) {
         return JSID_BITS(id);
     }
     static bool match(jsid id1, jsid id2) {
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3972,17 +3972,17 @@ JSObject::markChildren(JSTracer* trc)
         TraceEdge(trc, &nobj->shape_, "shape");
 
         MarkObjectSlots(trc, nobj, 0, nobj->slotSpan());
 
         do {
             if (nobj->denseElementsAreCopyOnWrite()) {
                 HeapPtrNativeObject& owner = nobj->getElementsHeader()->ownerObject();
                 if (owner != nobj) {
-                    MarkObject(trc, &owner, "objectElementsOwner");
+                    TraceEdge(trc, &owner, "objectElementsOwner");
                     break;
                 }
             }
 
             TraceRange(trc,
                        nobj->getDenseInitializedLength(),
                        static_cast<HeapSlot*>(nobj->getDenseElementsAllowCopyOnWrite()),
                        "objectElements");
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -3434,39 +3434,39 @@ JSScript::markChildren(JSTracer* trc)
 
     for (uint32_t i = 0; i < natoms(); ++i) {
         if (atoms[i])
             TraceEdge(trc, &atoms[i], "atom");
     }
 
     if (hasObjects()) {
         ObjectArray* objarray = objects();
-        MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
+        TraceRange(trc, objarray->length, objarray->vector, "objects");
     }
 
     if (hasRegexps()) {
         ObjectArray* objarray = regexps();
-        MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
+        TraceRange(trc, objarray->length, objarray->vector, "objects");
     }
 
     if (hasConsts()) {
         ConstArray* constarray = consts();
         TraceRange(trc, constarray->length, constarray->vector, "consts");
     }
 
     if (sourceObject()) {
         MOZ_ASSERT(MaybeForwarded(sourceObject())->compartment() == compartment());
-        MarkObject(trc, &sourceObject_, "sourceObject");
+        TraceEdge(trc, &sourceObject_, "sourceObject");
     }
 
     if (functionNonDelazifying())
-        MarkObject(trc, &function_, "function");
+        TraceEdge(trc, &function_, "function");
 
     if (enclosingStaticScope_)
-        MarkObject(trc, &enclosingStaticScope_, "enclosingStaticScope");
+        TraceEdge(trc, &enclosingStaticScope_, "enclosingStaticScope");
 
     if (maybeLazyScript())
         TraceManuallyBarrieredEdge(trc, &lazyScript, "lazyScript");
 
     if (trc->isMarkingTracer()) {
         compartment()->mark();
 
         if (code())
@@ -3477,37 +3477,37 @@ JSScript::markChildren(JSTracer* trc)
 
     jit::TraceJitScripts(trc, this);
 }
 
 void
 LazyScript::markChildren(JSTracer* trc)
 {
     if (function_)
-        MarkObject(trc, &function_, "function");
+        TraceEdge(trc, &function_, "function");
 
     if (sourceObject_)
-        MarkObject(trc, &sourceObject_, "sourceObject");
+        TraceEdge(trc, &sourceObject_, "sourceObject");
 
     if (enclosingScope_)
-        MarkObject(trc, &enclosingScope_, "enclosingScope");
+        TraceEdge(trc, &enclosingScope_, "enclosingScope");
 
     if (script_)
         TraceEdge(trc, &script_, "realScript");
 
     // We rely on the fact that atoms are always tenured.
     FreeVariable* freeVariables = this->freeVariables();
     for (size_t i = 0; i < numFreeVariables(); i++) {
         JSAtom* atom = freeVariables[i].atom();
         TraceManuallyBarrieredEdge(trc, &atom, "lazyScriptFreeVariable");
     }
 
     HeapPtrFunction* innerFunctions = this->innerFunctions();
     for (size_t i = 0; i < numInnerFunctions(); i++)
-        MarkObject(trc, &innerFunctions[i], "lazyScriptInnerFunction");
+        TraceEdge(trc, &innerFunctions[i], "lazyScriptInnerFunction");
 }
 
 void
 LazyScript::finalize(FreeOp* fop)
 {
     if (table_)
         fop->free_(table_);
 }
--- a/js/src/jswatchpoint.cpp
+++ b/js/src/jswatchpoint.cpp
@@ -156,31 +156,31 @@ bool
 WatchpointMap::markIteratively(JSTracer* trc)
 {
     bool marked = false;
     for (Map::Enum e(map); !e.empty(); e.popFront()) {
         Map::Entry& entry = e.front();
         JSObject* priorKeyObj = entry.key().object;
         jsid priorKeyId(entry.key().id.get());
         bool objectIsLive =
-            IsObjectMarked(const_cast<PreBarrieredObject*>(&entry.key().object));
+            IsMarked(const_cast<PreBarrieredObject*>(&entry.key().object));
         if (objectIsLive || entry.value().held) {
             if (!objectIsLive) {
-                MarkObject(trc, const_cast<PreBarrieredObject*>(&entry.key().object),
+                TraceEdge(trc, const_cast<PreBarrieredObject*>(&entry.key().object),
                            "held Watchpoint object");
                 marked = true;
             }
 
             MOZ_ASSERT(JSID_IS_STRING(priorKeyId) ||
                        JSID_IS_INT(priorKeyId) ||
                        JSID_IS_SYMBOL(priorKeyId));
             TraceEdge(trc, const_cast<PreBarrieredId*>(&entry.key().id), "WatchKey::id");
 
-            if (entry.value().closure && !IsObjectMarked(&entry.value().closure)) {
-                MarkObject(trc, &entry.value().closure, "Watchpoint::closure");
+            if (entry.value().closure && !IsMarked(&entry.value().closure)) {
+                TraceEdge(trc, &entry.value().closure, "Watchpoint::closure");
                 marked = true;
             }
 
             /* We will sweep this entry in sweepAll if !objectIsLive. */
             if (priorKeyObj != entry.key().object || priorKeyId != entry.key().id)
                 e.rekeyFront(WatchKey(entry.key().object, entry.key().id));
         }
     }
@@ -191,20 +191,20 @@ void
 WatchpointMap::markAll(JSTracer* trc)
 {
     for (Map::Enum e(map); !e.empty(); e.popFront()) {
         Map::Entry& entry = e.front();
         WatchKey key = entry.key();
         WatchKey prior = key;
         MOZ_ASSERT(JSID_IS_STRING(prior.id) || JSID_IS_INT(prior.id) || JSID_IS_SYMBOL(prior.id));
 
-        MarkObject(trc, const_cast<PreBarrieredObject*>(&key.object),
+        TraceEdge(trc, const_cast<PreBarrieredObject*>(&key.object),
                    "held Watchpoint object");
         TraceEdge(trc, const_cast<PreBarrieredId*>(&key.id), "WatchKey::id");
-        MarkObject(trc, &entry.value().closure, "Watchpoint::closure");
+        TraceEdge(trc, &entry.value().closure, "Watchpoint::closure");
 
         if (prior.object != key.object || prior.id != key.id)
             e.rekeyFront(key);
     }
 }
 
 void
 WatchpointMap::sweepAll(JSRuntime* rt)
@@ -216,17 +216,17 @@ WatchpointMap::sweepAll(JSRuntime* rt)
 }
 
 void
 WatchpointMap::sweep()
 {
     for (Map::Enum e(map); !e.empty(); e.popFront()) {
         Map::Entry& entry = e.front();
         JSObject* obj(entry.key().object);
-        if (IsObjectAboutToBeFinalized(&obj)) {
+        if (IsAboutToBeFinalizedUnbarriered(&obj)) {
             MOZ_ASSERT(!entry.value().held);
             e.removeFront();
         } else if (obj != entry.key().object) {
             e.rekeyFront(WatchKey(obj, entry.key().id));
         }
     }
 }
 
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -76,17 +76,17 @@ WeakMapBase::unmarkCompartment(JSCompart
 
 void
 WeakMapBase::markAll(JSCompartment* c, JSTracer* tracer)
 {
     MOZ_ASSERT(tracer->eagerlyTraceWeakMaps() != DoNotTraceWeakMaps);
     for (WeakMapBase* m = c->gcWeakMapList; m; m = m->next) {
         m->trace(tracer);
         if (m->memberOf)
-            gc::MarkObject(tracer, &m->memberOf, "memberOf");
+            TraceEdge(tracer, &m->memberOf, "memberOf");
     }
 }
 
 bool
 WeakMapBase::markCompartmentIteratively(JSCompartment* c, JSTracer* tracer)
 {
     bool markedAny = false;
     for (WeakMapBase* m = c->gcWeakMapList; m; m = m->next) {
--- a/js/src/jsweakmap.h
+++ b/js/src/jsweakmap.h
@@ -183,17 +183,17 @@ class WeakMap : public HashMap<Key, Valu
     bool keyNeedsMark(JSObject* key) {
         if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp) {
             JSObject* delegate = op(key);
             /*
              * Check if the delegate is marked with any color to properly handle
              * gray marking when the key's delegate is black and the map is
              * gray.
              */
-            return delegate && gc::IsObjectMarked(&delegate);
+            return delegate && gc::IsMarkedUnbarriered(&delegate);
         }
         return false;
     }
 
     bool keyNeedsMark(gc::Cell* cell) {
         return false;
     }
 
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -964,17 +964,17 @@ ArrayBufferObject::trace(JSTracer* trc, 
     ArrayBufferObject& buf = obj->as<ArrayBufferObject>();
 
     if (!buf.forInlineTypedObject())
         return;
 
     JSObject* view = MaybeForwarded(buf.firstView());
     MOZ_ASSERT(view && view->is<InlineTransparentTypedObject>());
 
-    gc::MarkObjectUnbarriered(trc, &view, "array buffer inline typed object owner");
+    TraceManuallyBarrieredEdge(trc, &view, "array buffer inline typed object owner");
     buf.setSlot(DATA_SLOT, PrivateValue(view->as<InlineTransparentTypedObject>().inlineTypedMem()));
 }
 
 /* static */ void
 ArrayBufferObject::objectMoved(JSObject* obj, const JSObject* old)
 {
     ArrayBufferObject& dst = obj->as<ArrayBufferObject>();
     const ArrayBufferObject& src = old->as<ArrayBufferObject>();
@@ -1085,22 +1085,22 @@ InnerViewTable::removeViews(ArrayBufferO
     MOZ_ASSERT(p);
 
     map.remove(p);
 }
 
 bool
 InnerViewTable::sweepEntry(JSObject** pkey, ViewVector& views)
 {
-    if (IsObjectAboutToBeFinalized(pkey))
+    if (IsAboutToBeFinalizedUnbarriered(pkey))
         return true;
 
     MOZ_ASSERT(!views.empty());
     for (size_t i = 0; i < views.length(); i++) {
-        if (IsObjectAboutToBeFinalized(&views[i])) {
+        if (IsAboutToBeFinalizedUnbarriered(&views[i])) {
             views[i--] = views.back();
             views.popBack();
         }
     }
 
     return views.empty();
 }
 
@@ -1186,17 +1186,17 @@ ArrayBufferViewObject::trace(JSTracer* t
         MOZ_ASSERT(buf.dataPointer() != nullptr);
 
         if (buf.forInlineTypedObject()) {
             // The data is inline with an InlineTypedObject associated with the
             // buffer. Get a new address for the typed object if it moved.
             JSObject* view = buf.firstView();
 
             // Mark the object to move it into the tenured space.
-            MarkObjectUnbarriered(trc, &view, "typed array nursery owner");
+            TraceManuallyBarrieredEdge(trc, &view, "typed array nursery owner");
             MOZ_ASSERT(view->is<InlineTypedObject>() && view != obj);
 
             void* srcData = obj->getPrivate();
             void* dstData = view->as<InlineTypedObject>().inlineTypedMem() + offset;
             obj->setPrivateUnbarriered(dstData);
 
             // We can't use a direct forwarding pointer here, as there might
             // not be enough bytes available, and other views might have data
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2267,17 +2267,17 @@ Debugger::markAllIteratively(GCMarker* t
     /*
      * Find all Debugger objects in danger of GC. This code is a little
      * convoluted since the easiest way to find them is via their debuggees.
      */
     JSRuntime* rt = trc->runtime();
     for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
         if (c->isDebuggee()) {
             GlobalObject* global = c->maybeGlobal();
-            if (!IsObjectMarked(&global))
+            if (!IsMarkedUnbarriered(&global))
                 continue;
 
             /*
              * Every debuggee has at least one debugger, so in this case
              * getDebuggers can't return nullptr.
              */
             const GlobalObject::DebuggerVector* debuggers = global->getDebuggers();
             MOZ_ASSERT(debuggers);
@@ -2289,37 +2289,37 @@ Debugger::markAllIteratively(GCMarker* t
                  *   - dbg is actually in a compartment that is being marked
                  *   - it isn't already marked
                  *   - it actually has hooks that might be called
                  */
                 HeapPtrNativeObject& dbgobj = dbg->toJSObjectRef();
                 if (!dbgobj->zone()->isGCMarking())
                     continue;
 
-                bool dbgMarked = IsObjectMarked(&dbgobj);
+                bool dbgMarked = IsMarked(&dbgobj);
                 if (!dbgMarked && dbg->hasAnyLiveHooks()) {
                     /*
                      * obj could be reachable only via its live, enabled
                      * debugger hooks, which may yet be called.
                      */
-                    MarkObject(trc, &dbgobj, "enabled Debugger");
+                    TraceEdge(trc, &dbgobj, "enabled Debugger");
                     markedAny = true;
                     dbgMarked = true;
                 }
 
                 if (dbgMarked) {
                     /* Search for breakpoints to mark. */
                     for (Breakpoint* bp = dbg->firstBreakpoint(); bp; bp = bp->nextInDebugger()) {
                         if (IsMarkedUnbarriered(&bp->site->script)) {
                             /*
                              * The debugger and the script are both live.
                              * Therefore the breakpoint handler is live.
                              */
-                            if (!IsObjectMarked(&bp->getHandlerRef())) {
-                                MarkObject(trc, &bp->getHandlerRef(), "breakpoint handler");
+                            if (!IsMarked(&bp->getHandlerRef())) {
+                                TraceEdge(trc, &bp->getHandlerRef(), "breakpoint handler");
                                 markedAny = true;
                             }
                         }
                     }
                 }
             }
         }
     }
@@ -2334,69 +2334,69 @@ Debugger::markAllIteratively(GCMarker* t
 /* static */ void
 Debugger::markAll(JSTracer* trc)
 {
     JSRuntime* rt = trc->runtime();
     for (Debugger* dbg = rt->debuggerList.getFirst(); dbg; dbg = dbg->getNext()) {
         WeakGlobalObjectSet& debuggees = dbg->debuggees;
         for (WeakGlobalObjectSet::Enum e(debuggees); !e.empty(); e.popFront()) {
             GlobalObject* global = e.front();
-            MarkObjectUnbarriered(trc, &global, "Global Object");
+            TraceManuallyBarrieredEdge(trc, &global, "Global Object");
             if (global != e.front())
                 e.rekeyFront(ReadBarrieredGlobalObject(global));
         }
 
         HeapPtrNativeObject& dbgobj = dbg->toJSObjectRef();
-        MarkObject(trc, &dbgobj, "Debugger Object");
+        TraceEdge(trc, &dbgobj, "Debugger Object");
 
         dbg->scripts.trace(trc);
         dbg->sources.trace(trc);
         dbg->objects.trace(trc);
         dbg->environments.trace(trc);
 
         for (Breakpoint* bp = dbg->firstBreakpoint(); bp; bp = bp->nextInDebugger()) {
             TraceManuallyBarrieredEdge(trc, &bp->site->script, "breakpoint script");
-            MarkObject(trc, &bp->getHandlerRef(), "breakpoint handler");
+            TraceEdge(trc, &bp->getHandlerRef(), "breakpoint handler");
         }
     }
 }
 
 /* static */ void
 Debugger::traceObject(JSTracer* trc, JSObject* obj)
 {
     if (Debugger* dbg = Debugger::fromJSObject(obj))
         dbg->trace(trc);
 }
 
 void
 Debugger::trace(JSTracer* trc)
 {
     if (uncaughtExceptionHook)
-        MarkObject(trc, &uncaughtExceptionHook, "hooks");
+        TraceEdge(trc, &uncaughtExceptionHook, "hooks");
 
     /*
      * Mark Debugger.Frame objects. These are all reachable from JS, because the
      * corresponding JS frames are still on the stack.
      *
      * (Once we support generator frames properly, we will need
      * weakly-referenced Debugger.Frame objects as well, for suspended generator
      * frames.)
      */
     for (FrameMap::Range r = frames.all(); !r.empty(); r.popFront()) {
         RelocatablePtrNativeObject& frameobj = r.front().value();
         MOZ_ASSERT(MaybeForwarded(frameobj.get())->getPrivate());
-        MarkObject(trc, &frameobj, "live Debugger.Frame");
+        TraceEdge(trc, &frameobj, "live Debugger.Frame");
     }
 
     /*
      * Mark every allocation site in our allocation log.
      */
     for (AllocationSite* s = allocationsLog.getFirst(); s; s = s->getNext()) {
         if (s->frame)
-            MarkObject(trc, &s->frame, "allocation log SavedFrame");
+            TraceEdge(trc, &s->frame, "allocation log SavedFrame");
     }
 
     /* Trace the weak map from JSScript instances to Debugger.Script objects. */
     scripts.trace(trc);
 
     /* Trace the referent ->Debugger.Source weak map */
     sources.trace(trc);
 
@@ -2408,17 +2408,17 @@ Debugger::trace(JSTracer* trc)
 }
 
 /* static */ void
 Debugger::sweepAll(FreeOp* fop)
 {
     JSRuntime* rt = fop->runtime();
 
     for (Debugger* dbg = rt->debuggerList.getFirst(); dbg; dbg = dbg->getNext()) {
-        if (IsObjectAboutToBeFinalized(&dbg->object)) {
+        if (IsAboutToBeFinalized(&dbg->object)) {
             /*
              * dbg is being GC'd. Detach it from its debuggees. The debuggee
              * might be GC'd too. Since detaching requires access to both
              * objects, this must be done before finalize time.
              */
             for (WeakGlobalObjectSet::Enum e(dbg->debuggees); !e.empty(); e.popFront())
                 dbg->removeDebuggeeGlobal(fop, e.front(), &e);
         }
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -1406,17 +1406,17 @@ ObjectGroupCompartment::sweep(FreeOp* fo
             if (!key.type.isUnknown() && key.type.isGroup()) {
                 ObjectGroup* group = key.type.groupNoBarrier();
                 if (IsAboutToBeFinalizedUnbarriered(&group))
                     remove = true;
                 else
                     key.type = TypeSet::ObjectType(group);
             }
             if (key.proto && key.proto != TaggedProto::LazyProto &&
-                IsObjectAboutToBeFinalized(&key.proto))
+                IsAboutToBeFinalizedUnbarriered(&key.proto))
             {
                 remove = true;
             }
             if (IsAboutToBeFinalized(&e.front().value()))
                 remove = true;
 
             if (remove)
                 e.removeFront();
@@ -1475,17 +1475,17 @@ ObjectGroupCompartment::sweep(FreeOp* fo
 
 void
 ObjectGroupCompartment::sweepNewTable(NewTable* table)
 {
     if (table && table->initialized()) {
         for (NewTable::Enum e(*table); !e.empty(); e.popFront()) {
             NewEntry entry = e.front();
             if (IsAboutToBeFinalized(&entry.group) ||
-                (entry.associated && IsObjectAboutToBeFinalized(&entry.associated)))
+                (entry.associated && IsAboutToBeFinalizedUnbarriered(&entry.associated)))
             {
                 e.removeFront();
             } else {
                 /* Any rekeying necessary is handled by fixupNewObjectGroupTable() below. */
                 MOZ_ASSERT(entry.group.unbarrieredGet() == e.front().group.unbarrieredGet());
                 MOZ_ASSERT(entry.associated == e.front().associated);
             }
         }
--- a/js/src/vm/PIC.cpp
+++ b/js/src/vm/PIC.cpp
@@ -249,18 +249,18 @@ js::ForOfPIC::Chain::eraseChain()
 
 // Trace the pointers stored directly on the stub.
 void
 js::ForOfPIC::Chain::mark(JSTracer* trc)
 {
     if (!initialized_ || disabled_)
         return;
 
-    gc::MarkObject(trc, &arrayProto_, "ForOfPIC Array.prototype.");
-    gc::MarkObject(trc, &arrayIteratorProto_, "ForOfPIC ArrayIterator.prototype.");
+    TraceEdge(trc, &arrayProto_, "ForOfPIC Array.prototype.");
+    TraceEdge(trc, &arrayIteratorProto_, "ForOfPIC ArrayIterator.prototype.");
 
     TraceEdge(trc, &arrayProtoShape_, "ForOfPIC Array.prototype shape.");
     TraceEdge(trc, &arrayIteratorProtoShape_, "ForOfPIC ArrayIterator.prototype shape.");
 
     TraceEdge(trc, &canonicalIteratorFunc_, "ForOfPIC ArrayValues builtin.");
     TraceEdge(trc, &canonicalNextFunc_, "ForOfPIC ArrayIterator.prototype.next builtin.");
 
     // Free all the stubs in the chain.
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -925,17 +925,17 @@ RegExpCompartment::sweep(JSRuntime* rt)
             shared->clearMarked();
         } else {
             js_delete(shared);
             e.removeFront();
         }
     }
 
     if (matchResultTemplateObject_ &&
-        IsObjectAboutToBeFinalized(matchResultTemplateObject_.unsafeGet()))
+        IsAboutToBeFinalized(&matchResultTemplateObject_))
     {
         matchResultTemplateObject_.set(nullptr);
     }
 }
 
 bool
 RegExpCompartment::get(JSContext* cx, JSAtom* source, RegExpFlag flags, RegExpGuard* g)
 {
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -79,24 +79,20 @@ struct SavedFrame::Lookup {
     JSPrincipals* principals;
 
     void trace(JSTracer* trc) {
         TraceManuallyBarrieredEdge(trc, &source, "SavedFrame::Lookup::source");
         if (functionDisplayName) {
             TraceManuallyBarrieredEdge(trc, &functionDisplayName,
                                        "SavedFrame::Lookup::functionDisplayName");
         }
-        if (asyncCause) {
-            TraceManuallyBarrieredEdge(trc, &asyncCause,
-                                       "SavedFrame::Lookup::asyncCause");
-        }
-        if (parent) {
-            gc::MarkObjectUnbarriered(trc, &parent,
-                                      "SavedFrame::Lookup::parent");
-        }
+        if (asyncCause)
+            TraceManuallyBarrieredEdge(trc, &asyncCause, "SavedFrame::Lookup::asyncCause");
+        if (parent)
+            TraceManuallyBarrieredEdge(trc, &parent, "SavedFrame::Lookup::parent");
     }
 };
 
 class MOZ_STACK_CLASS SavedFrame::AutoLookupVector : public JS::CustomAutoRooter {
   public:
     explicit AutoLookupVector(JSContext* cx)
       : JS::CustomAutoRooter(cx),
         lookups(cx)
@@ -812,17 +808,17 @@ SavedStacks::saveCurrentStack(JSContext*
 void
 SavedStacks::sweep(JSRuntime* rt)
 {
     if (frames.initialized()) {
         for (SavedFrame::Set::Enum e(frames); !e.empty(); e.popFront()) {
             JSObject* obj = e.front().unbarrieredGet();
             JSObject* temp = obj;
 
-            if (IsObjectAboutToBeFinalized(&obj)) {
+            if (IsAboutToBeFinalizedUnbarriered(&obj)) {
                 e.removeFront();
             } else {
                 SavedFrame* frame = &obj->as<SavedFrame>();
                 bool parentMoved = frame->parentMoved();
 
                 if (parentMoved) {
                     frame->updatePrivateParent();
                 }
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -1167,17 +1167,17 @@ MissingScopeKey::match(MissingScopeKey s
 {
     return sk1.frame_ == sk2.frame_ && sk1.staticScope_ == sk2.staticScope_;
 }
 
 void
 LiveScopeVal::sweep()
 {
     if (staticScope_)
-        MOZ_ALWAYS_FALSE(IsObjectAboutToBeFinalized(staticScope_.unsafeGet()));
+        MOZ_ALWAYS_FALSE(IsAboutToBeFinalized(&staticScope_));
 }
 
 // Live ScopeIter values may be added to DebugScopes::liveScopes, as
 // LiveScopeVal instances.  They need to have write barriers when they are added
 // to the hash table, but no barriers when rehashing inside GC.  It's a nasty
 // hack, but the important thing is that LiveScopeVal and MissingScopeKey need to
 // alias each other.
 void
@@ -1866,17 +1866,17 @@ void
 DebugScopes::sweep(JSRuntime* rt)
 {
     /*
      * missingScopes points to debug scopes weakly so that debug scopes can be
      * released more eagerly.
      */
     for (MissingScopeMap::Enum e(missingScopes); !e.empty(); e.popFront()) {
         DebugScopeObject** debugScope = e.front().value().unsafeGet();
-        if (IsObjectAboutToBeFinalized(debugScope)) {
+        if (IsAboutToBeFinalizedUnbarriered(debugScope)) {
             /*
              * Note that onPopCall and onPopBlock rely on missingScopes to find
              * scope objects that we synthesized for the debugger's sake, and
              * clean up the synthetic scope objects' entries in liveScopes. So
              * if we remove an entry frcom missingScopes here, we must also
              * remove the corresponding liveScopes entry.
              *
              * Since the DebugScopeObject is the only thing using its scope
@@ -1904,17 +1904,17 @@ DebugScopes::sweep(JSRuntime* rt)
         ScopeObject* scope = e.front().key();
 
         e.front().value().sweep();
 
         /*
          * Scopes can be finalized when a debugger-synthesized ScopeObject is
          * no longer reachable via its DebugScopeObject.
          */
-        if (IsObjectAboutToBeFinalized(&scope))
+        if (IsAboutToBeFinalizedUnbarriered(&scope))
             e.removeFront();
         else if (scope != e.front().key())
             e.rekeyFront(scope);
     }
 }
 
 #ifdef JSGC_HASH_TABLE_CHECKS
 void
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1205,17 +1205,17 @@ JSRuntime::finishSelfHosting()
 {
     selfHostingGlobal_ = nullptr;
 }
 
 void
 JSRuntime::markSelfHostingGlobal(JSTracer* trc)
 {
     if (selfHostingGlobal_ && !parentRuntime)
-        MarkObjectRoot(trc, &selfHostingGlobal_, "self-hosting global");
+        TraceRoot(trc, &selfHostingGlobal_, "self-hosting global");
 }
 
 bool
 JSRuntime::isSelfHostingCompartment(JSCompartment* comp)
 {
     return selfHostingGlobal_->compartment() == comp;
 }
 
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -1533,17 +1533,17 @@ void
 JSCompartment::sweepInitialShapeTable()
 {
     if (initialShapes.initialized()) {
         for (InitialShapeSet::Enum e(initialShapes); !e.empty(); e.popFront()) {
             const InitialShapeEntry& entry = e.front();
             Shape* shape = entry.shape.unbarrieredGet();
             JSObject* proto = entry.proto.raw();
             if (IsAboutToBeFinalizedUnbarriered(&shape) ||
-                (entry.proto.isObject() && IsObjectAboutToBeFinalized(&proto)))
+                (entry.proto.isObject() && IsAboutToBeFinalizedUnbarriered(&proto)))
             {
                 e.removeFront();
             } else {
                 if (shape != entry.shape.unbarrieredGet() || proto != entry.proto.raw()) {
                     ReadBarrieredShape readBarrieredShape(shape);
                     InitialShapeEntry newKey(readBarrieredShape, TaggedProto(proto));
                     e.rekeyFront(newKey.getLookup(), newKey);
                 }
@@ -1578,12 +1578,12 @@ JSCompartment::fixupInitialShapeTable()
         }
     }
 }
 
 void
 AutoRooterGetterSetter::Inner::trace(JSTracer* trc)
 {
     if ((attrs & JSPROP_GETTER) && *pgetter)
-        gc::MarkObjectRoot(trc, (JSObject**) pgetter, "AutoRooterGetterSetter getter");
+        TraceRoot(trc, (JSObject**) pgetter, "AutoRooterGetterSetter getter");
     if ((attrs & JSPROP_SETTER) && *psetter)
-        gc::MarkObjectRoot(trc, (JSObject**) psetter, "AutoRooterGetterSetter setter");
+        TraceRoot(trc, (JSObject**) psetter, "AutoRooterGetterSetter setter");
 }
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -1361,20 +1361,20 @@ inline void
 Shape::markChildren(JSTracer* trc)
 {
     TraceEdge(trc, &base_, "base");
     TraceEdge(trc, &propidRef(), "propid");
     if (parent)
         TraceEdge(trc, &parent, "parent");
 
     if (hasGetterObject())
-        gc::MarkObjectUnbarriered(trc, &asAccessorShape().getterObj, "getter");
+        TraceManuallyBarrieredEdge(trc, &asAccessorShape().getterObj, "getter");
 
     if (hasSetterObject())
-        gc::MarkObjectUnbarriered(trc, &asAccessorShape().setterObj, "setter");
+        TraceManuallyBarrieredEdge(trc, &asAccessorShape().setterObj, "setter");
 }
 
 /*
  * Keep this function in sync with search. It neither hashifies the start
  * shape nor increments linear search count.
  */
 inline Shape*
 Shape::searchNoHashify(Shape* start, jsid id)
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -328,21 +328,21 @@ void
 InterpreterFrame::mark(JSTracer* trc)
 {
     /*
      * Normally we would use MarkRoot here, except that generators also take
      * this path. However, generators use a special write barrier when the stack
      * frame is copied to the floating frame. Therefore, no barrier is needed.
      */
     if (flags_ & HAS_SCOPECHAIN)
-        gc::MarkObjectUnbarriered(trc, &scopeChain_, "scope chain");
+        TraceManuallyBarrieredEdge(trc, &scopeChain_, "scope chain");
     if (flags_ & HAS_ARGS_OBJ)
-        gc::MarkObjectUnbarriered(trc, &argsObj_, "arguments");
+        TraceManuallyBarrieredEdge(trc, &argsObj_, "arguments");
     if (isFunctionFrame()) {
-        gc::MarkObjectUnbarriered(trc, &exec.fun, "fun");
+        TraceManuallyBarrieredEdge(trc, &exec.fun, "fun");
         if (isEvalFrame())
             TraceManuallyBarrieredEdge(trc, &u.evalScript, "eval script");
     } else {
         TraceManuallyBarrieredEdge(trc, &exec.script, "script");
     }
     if (trc->isMarkingTracer())
         script()->compartment()->zone()->active = true;
     if (hasReturnValue())
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -709,17 +709,17 @@ TypeSet::readBarrier(const TypeSet* type
 }
 
 /* static */ bool
 TypeSet::IsTypeMarked(TypeSet::Type* v)
 {
     bool rv;
     if (v->isSingletonUnchecked()) {
         JSObject* obj = v->singletonNoBarrier();
-        rv = IsObjectMarked(&obj);
+        rv = IsMarkedUnbarriered(&obj);
         *v = TypeSet::ObjectType(obj);
     } else if (v->isGroupUnchecked()) {
         ObjectGroup* group = v->groupNoBarrier();
         rv = IsMarkedUnbarriered(&group);
         *v = TypeSet::ObjectType(group);
     } else {
         rv = true;
     }
@@ -750,17 +750,17 @@ IsObjectKeyAboutToBeFinalized(TypeSet::O
     if (key->isGroup()) {
         ObjectGroup* group = key->groupNoBarrier();
         isAboutToBeFinalized = IsAboutToBeFinalizedUnbarriered(&group);
         if (!isAboutToBeFinalized)
             *keyp = TypeSet::ObjectKey::get(group);
     } else {
         MOZ_ASSERT(key->isSingleton());
         JSObject* singleton = key->singletonNoBarrier();
-        isAboutToBeFinalized = IsObjectAboutToBeFinalized(&singleton);
+        isAboutToBeFinalized = IsAboutToBeFinalizedUnbarriered(&singleton);
         if (!isAboutToBeFinalized)
             *keyp = TypeSet::ObjectKey::get(singleton);
     }
     return isAboutToBeFinalized;
 }
 
 bool
 TypeSet::IsTypeAboutToBeFinalized(TypeSet::Type* v)
@@ -1810,17 +1810,17 @@ class ConstraintDataFreezeObjectForTyped
     bool constraintHolds(JSContext* cx,
                          const HeapTypeSetKey& property, TemporaryTypeSet* expected)
     {
         return !invalidateOnNewObjectState(property.object()->maybeGroup());
     }
 
     bool shouldSweep() {
         // Note: |viewData| is only used for equality testing.
-        return IsObjectAboutToBeFinalized(&obj);
+        return IsAboutToBeFinalizedUnbarriered(&obj);
     }
 };
 
 // Constraint which triggers recompilation if an unboxed object in some group
 // is converted to a native object.
 class ConstraintDataFreezeObjectForUnboxedConvertedToNative
 {
   public:
@@ -3324,17 +3324,17 @@ PreliminaryObjectArray::full() const
 
 void
 PreliminaryObjectArray::sweep()
 {
     // All objects in the array are weak, so clear any that are about to be
     // destroyed.
     for (size_t i = 0; i < COUNT; i++) {
         JSObject** ptr = &objects[i];
-        if (*ptr && IsObjectAboutToBeFinalized(ptr))
+        if (*ptr && IsAboutToBeFinalizedUnbarriered(ptr))
             *ptr = nullptr;
     }
 }
 
 void
 PreliminaryObjectArrayWithTemplate::trace(JSTracer* trc)
 {
     TraceEdge(trc, &shape_, "PreliminaryObjectArrayWithTemplate_shape");
@@ -3875,20 +3875,20 @@ TypeNewScript::rollbackPartiallyInitiali
     }
 
     return found;
 }
 
 void
 TypeNewScript::trace(JSTracer* trc)
 {
-    MarkObject(trc, &function_, "TypeNewScript_function");
+    TraceEdge(trc, &function_, "TypeNewScript_function");
 
     if (templateObject_)
-        MarkObject(trc, &templateObject_, "TypeNewScript_templateObject");
+        TraceEdge(trc, &templateObject_, "TypeNewScript_templateObject");
 
     if (initializedShape_)
         TraceEdge(trc, &initializedShape_, "TypeNewScript_initializedShape");
 
     if (initializedGroup_)
         TraceEdge(trc, &initializedGroup_, "TypeNewScript_initializedGroup");
 }
 
--- a/js/src/vm/UnboxedObject.cpp
+++ b/js/src/vm/UnboxedObject.cpp
@@ -347,18 +347,19 @@ UnboxedPlainObject::getValue(const Unbox
         MOZ_CRASH("Invalid type for unboxed value");
     }
 }
 
 void
 UnboxedPlainObject::trace(JSTracer* trc, JSObject* obj)
 {
     if (obj->as<UnboxedPlainObject>().expando_) {
-        MarkObjectUnbarriered(trc, reinterpret_cast<NativeObject**>(&obj->as<UnboxedPlainObject>().expando_),
-                              "unboxed_expando");
+        TraceManuallyBarrieredEdge(trc,
+            reinterpret_cast<NativeObject**>(&obj->as<UnboxedPlainObject>().expando_),
+            "unboxed_expando");
     }
 
     const UnboxedLayout& layout = obj->as<UnboxedPlainObject>().layoutDontCheckGeneration();
     const int32_t* list = layout.traceList();
     if (!list)
         return;
 
     uint8_t* data = obj->as<UnboxedPlainObject>().data();
@@ -366,17 +367,17 @@ UnboxedPlainObject::trace(JSTracer* trc,
         HeapPtrString* heap = reinterpret_cast<HeapPtrString*>(data + *list);
         TraceEdge(trc, heap, "unboxed_string");
         list++;
     }
     list++;
     while (*list != -1) {
         HeapPtrObject* heap = reinterpret_cast<HeapPtrObject*>(data + *list);
         if (*heap)
-            MarkObject(trc, heap, "unboxed_object");
+            TraceEdge(trc, heap, "unboxed_object");
         list++;
     }
 
     // Unboxed objects don't have Values to trace.
     MOZ_ASSERT(*(list + 1) == -1);
 }
 
 /* static */ UnboxedExpandoObject*