Bug 989414 - Convert ReadBarriered to take a T* as template parameter instead of T; r=jonco
authorTerrence Cole <terrence@mozilla.com>
Mon, 28 Apr 2014 11:25:16 -0700
changeset 181209 7165d1b0097ab84362be2a5cbf03173eee54f27f
parent 181208 3a821ea694d7631ad683057ed65198b32eaadc36
child 181210 57292971f11018f5f690abf59e82454e48c70082
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersjonco
bugs989414
milestone32.0a1
Bug 989414 - Convert ReadBarriered to take a T* as template parameter instead of T; r=jonco
js/src/gc/Barrier-inl.h
js/src/gc/Barrier.cpp
js/src/gc/Barrier.h
js/src/gc/Marking.h
js/src/jit/JitCompartment.h
js/src/jsapi.cpp
js/src/jscntxt.h
js/src/jscompartment.h
js/src/jscompartmentinlines.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/vm/RegExpObject.h
js/src/vm/ScopeObject.h
js/src/vm/Shape.cpp
js/src/vm/Shape.h
deleted file mode 100644
--- a/js/src/gc/Barrier-inl.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef gc_Barrier_inl_h
-#define gc_Barrier_inl_h
-
-#include "gc/Barrier.h"
-
-namespace js {
-
-inline const Value &
-ReadBarrieredValue::get() const
-{
-    if (value.isObject())
-        JSObject::readBarrier(&value.toObject());
-    else if (value.isString())
-        JSString::readBarrier(value.toString());
-    else
-        JS_ASSERT(!value.isMarkable());
-
-    return value;
-}
-
-inline
-ReadBarrieredValue::operator const Value &() const
-{
-    return get();
-}
-
-inline JSObject &
-ReadBarrieredValue::toObject() const
-{
-    return get().toObject();
-}
-
-} /* namespace js */
-
-#endif /* gc_Barrier_inl_h */
--- a/js/src/gc/Barrier.cpp
+++ b/js/src/gc/Barrier.cpp
@@ -8,16 +8,27 @@
 
 #include "jscompartment.h"
 #include "jsobj.h"
 
 #include "gc/Zone.h"
 
 namespace js {
 
+void
+ValueReadBarrier(const Value &value)
+{
+    if (value.isObject())
+        JSObject::readBarrier(&value.toObject());
+    else if (value.isString())
+        JSString::readBarrier(value.toString());
+    else
+        JS_ASSERT(!value.isMarkable());
+}
+
 #ifdef DEBUG
 bool
 HeapSlot::preconditionForSet(JSObject *owner, Kind kind, uint32_t slot)
 {
     return kind == Slot
          ? &owner->getSlotRef(slot) == this
          : &owner->getDenseElement(slot) == (const Value *)this;
 }
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -287,30 +287,35 @@ MOZ_ALWAYS_INLINE JS::Zone *
 ZoneOfValueFromAnyThread(const JS::Value &value)
 {
     JS_ASSERT(value.isMarkable());
     if (value.isObject())
         return ZoneOfObjectFromAnyThread(value.toObject());
     return static_cast<js::gc::Cell *>(value.toGCThing())->tenuredZoneFromAnyThread();
 }
 
+void
+ValueReadBarrier(const Value &value);
+
 template <typename T>
 struct InternalGCMethods {};
 
 template <typename T>
 struct InternalGCMethods<T *>
 {
     static bool isMarkable(T *v) { return v != nullptr; }
 
     static void preBarrier(T *v) { T::writeBarrierPre(v); }
     static void preBarrier(Zone *zone, T *v) { T::writeBarrierPre(zone, v); }
 
     static void postBarrier(T **vp) { T::writeBarrierPost(*vp, vp); }
     static void postBarrierRelocate(T **vp) { T::writeBarrierPostRelocate(*vp, vp); }
     static void postBarrierRemove(T **vp) { T::writeBarrierPostRemove(*vp, vp); }
+
+    static void readBarrier(T *v) { T::readBarrier(v); }
 };
 
 template <>
 struct InternalGCMethods<Value>
 {
     static JSRuntime *runtimeFromAnyThread(const Value &v) {
         JS_ASSERT(v.isMarkable());
         return static_cast<js::gc::Cell *>(v.toGCThing())->runtimeFromAnyThread();
@@ -362,16 +367,18 @@ struct InternalGCMethods<Value>
 
     static void postBarrierRemove(Value *vp) {
 #ifdef JSGC_GENERATIONAL
         JSRuntime *rt = static_cast<js::gc::Cell *>(vp->toGCThing())->runtimeFromAnyThread();
         JS::shadow::Runtime *shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt);
         shadowRuntime->gcStoreBufferPtr()->removeRelocatableValue(vp);
 #endif
     }
+
+    static void readBarrier(const Value &v) { ValueReadBarrier(v); }
 };
 
 template <>
 struct InternalGCMethods<jsid>
 {
     static bool isMarkable(jsid id) { return JSID_IS_OBJECT(id) || JSID_IS_STRING(id); }
 
     static void preBarrier(jsid id) {
@@ -674,68 +681,16 @@ BarrieredSetPair(Zone *zone,
         v2.pre();
     }
     v1.unsafeSet(val1);
     v2.unsafeSet(val2);
     v1.post();
     v2.post();
 }
 
-class ArrayBufferObject;
-class NestedScopeObject;
-class Shape;
-class BaseShape;
-class UnownedBaseShape;
-namespace jit {
-class JitCode;
-}
-namespace types {
-struct TypeObject;
-struct TypeObjectAddendum;
-}
-
-typedef BarrieredPtr<JSObject*> BarrieredPtrObject;
-typedef BarrieredPtr<JSScript*> BarrieredPtrScript;
-
-typedef PreBarriered<JSObject*> PreBarrieredObject;
-typedef PreBarriered<JSScript*> PreBarrieredScript;
-typedef PreBarriered<jit::JitCode*> PreBarrieredJitCode;
-
-typedef RelocatablePtr<JSObject*> RelocatablePtrObject;
-typedef RelocatablePtr<JSScript*> RelocatablePtrScript;
-typedef RelocatablePtr<NestedScopeObject*> RelocatablePtrNestedScopeObject;
-
-typedef HeapPtr<ArrayBufferObject*> HeapPtrArrayBufferObject;
-typedef HeapPtr<JSObject*> HeapPtrObject;
-typedef HeapPtr<JSFunction*> HeapPtrFunction;
-typedef HeapPtr<JSAtom*> HeapPtrAtom;
-typedef HeapPtr<JSString*> HeapPtrString;
-typedef HeapPtr<JSFlatString*> HeapPtrFlatString;
-typedef HeapPtr<JSLinearString*> HeapPtrLinearString;
-typedef HeapPtr<PropertyName*> HeapPtrPropertyName;
-typedef HeapPtr<JSScript*> HeapPtrScript;
-typedef HeapPtr<Shape*> HeapPtrShape;
-typedef HeapPtr<BaseShape*> HeapPtrBaseShape;
-typedef HeapPtr<UnownedBaseShape*> HeapPtrUnownedBaseShape;
-typedef HeapPtr<types::TypeObject*> HeapPtrTypeObject;
-typedef HeapPtr<types::TypeObjectAddendum*> HeapPtrTypeObjectAddendum;
-typedef HeapPtr<jit::JitCode*> HeapPtrJitCode;
-
-typedef BarrieredPtr<Value> BarrieredValue;
-typedef PreBarriered<Value> PreBarrieredValue;
-typedef RelocatablePtr<Value> RelocatableValue;
-typedef HeapPtr<Value> HeapValue;
-
-typedef BarrieredPtr<jsid> BarrieredId;
-typedef PreBarriered<jsid> PreBarrieredId;
-typedef RelocatablePtr<jsid> RelocatableId;
-typedef HeapPtr<jsid> HeapId;
-
-typedef ImmutableTenuredPtr<PropertyName*> ImmutablePropertyNamePtr;
-
 /* Useful for hashtables with a HeapPtr as key. */
 template <class T>
 struct HeapPtrHasher
 {
     typedef HeapPtr<T> Key;
     typedef T Lookup;
 
     static HashNumber hash(Lookup obj) { return DefaultHasher<T>::hash(obj); }
@@ -756,16 +711,120 @@ struct PreBarrieredHasher
     static HashNumber hash(Lookup obj) { return DefaultHasher<T>::hash(obj); }
     static bool match(const Key &k, Lookup l) { return k.get() == l; }
     static void rekey(Key &k, const Key& newKey) { k.unsafeSet(newKey); }
 };
 
 template <class T>
 struct DefaultHasher< PreBarriered<T> > : PreBarrieredHasher<T> { };
 
+/*
+ * Incremental GC requires that weak pointers have read barriers. This is mostly
+ * an issue for empty shapes stored in JSCompartment. The problem happens when,
+ * during an incremental GC, some JS code stores one of the compartment's empty
+ * shapes into an object already marked black. Normally, this would not be a
+ * problem, because the empty shape would have been part of the initial snapshot
+ * when the GC started. However, since this is a weak pointer, it isn't. So we
+ * may collect the empty shape even though a live object points to it. To fix
+ * this, we mark these empty shapes black whenever they get read out.
+ */
+template <class T>
+class ReadBarriered
+{
+    T value;
+
+  public:
+    ReadBarriered() : value(nullptr) {}
+    ReadBarriered(T value) : value(value) {}
+    ReadBarriered(const Rooted<T> &rooted) : value(rooted) {}
+
+    T get() const {
+        if (!InternalGCMethods<T>::isMarkable(value))
+            return GCMethods<T>::initial();
+        InternalGCMethods<T>::readBarrier(value);
+        return value;
+    }
+
+    operator T() const { return get(); }
+
+    T &operator*() const { return *get(); }
+    T operator->() const { return get(); }
+
+    T *unsafeGet() { return &value; }
+    T const * unsafeGet() const { return &value; }
+
+    void set(T v) { value = v; }
+};
+
+class ArrayBufferObject;
+class NestedScopeObject;
+class DebugScopeObject;
+class GlobalObject;
+class Shape;
+class BaseShape;
+class UnownedBaseShape;
+namespace jit {
+class JitCode;
+}
+namespace types {
+struct TypeObject;
+struct TypeObjectAddendum;
+}
+
+typedef BarrieredPtr<JSObject*> BarrieredPtrObject;
+typedef BarrieredPtr<JSScript*> BarrieredPtrScript;
+
+typedef PreBarriered<JSObject*> PreBarrieredObject;
+typedef PreBarriered<JSScript*> PreBarrieredScript;
+typedef PreBarriered<jit::JitCode*> PreBarrieredJitCode;
+
+typedef RelocatablePtr<JSObject*> RelocatablePtrObject;
+typedef RelocatablePtr<JSScript*> RelocatablePtrScript;
+typedef RelocatablePtr<NestedScopeObject*> RelocatablePtrNestedScopeObject;
+
+typedef HeapPtr<ArrayBufferObject*> HeapPtrArrayBufferObject;
+typedef HeapPtr<BaseShape*> HeapPtrBaseShape;
+typedef HeapPtr<JSAtom*> HeapPtrAtom;
+typedef HeapPtr<JSFlatString*> HeapPtrFlatString;
+typedef HeapPtr<JSFunction*> HeapPtrFunction;
+typedef HeapPtr<JSLinearString*> HeapPtrLinearString;
+typedef HeapPtr<JSObject*> HeapPtrObject;
+typedef HeapPtr<JSScript*> HeapPtrScript;
+typedef HeapPtr<JSString*> HeapPtrString;
+typedef HeapPtr<PropertyName*> HeapPtrPropertyName;
+typedef HeapPtr<Shape*> HeapPtrShape;
+typedef HeapPtr<UnownedBaseShape*> HeapPtrUnownedBaseShape;
+typedef HeapPtr<jit::JitCode*> HeapPtrJitCode;
+typedef HeapPtr<types::TypeObject*> HeapPtrTypeObject;
+typedef HeapPtr<types::TypeObjectAddendum*> HeapPtrTypeObjectAddendum;
+
+typedef BarrieredPtr<Value> BarrieredValue;
+typedef PreBarriered<Value> PreBarrieredValue;
+typedef RelocatablePtr<Value> RelocatableValue;
+typedef HeapPtr<Value> HeapValue;
+
+typedef BarrieredPtr<jsid> BarrieredId;
+typedef PreBarriered<jsid> PreBarrieredId;
+typedef RelocatablePtr<jsid> RelocatableId;
+typedef HeapPtr<jsid> HeapId;
+
+typedef ImmutableTenuredPtr<PropertyName*> ImmutablePropertyNamePtr;
+
+typedef ReadBarriered<DebugScopeObject*> ReadBarrieredDebugScopeObject;
+typedef ReadBarriered<GlobalObject*> ReadBarrieredGlobalObject;
+typedef ReadBarriered<JSFunction*> ReadBarrieredFunction;
+typedef ReadBarriered<JSObject*> ReadBarrieredObject;
+typedef ReadBarriered<ScriptSourceObject*> ReadBarrieredScriptSourceObject;
+typedef ReadBarriered<Shape*> ReadBarrieredShape;
+typedef ReadBarriered<UnownedBaseShape*> ReadBarrieredUnownedBaseShape;
+typedef ReadBarriered<jit::JitCode*> ReadBarrieredJitCode;
+typedef ReadBarriered<types::TypeObject*> ReadBarrieredTypeObject;
+
+typedef ReadBarriered<Value> ReadBarrieredValue;
+
 // A pre- and post-barriered Value that is specialized to be aware that it
 // resides in a slots or elements vector. This allows it to be relocated in
 // memory, but with substantially less overhead than a RelocatablePtr.
 class HeapSlot : public BarrieredValue
 {
   public:
     enum Kind {
         Slot = 0,
@@ -884,71 +943,16 @@ class HeapSlotArray
     operator const Value *() const { return Valueify(array); }
     operator HeapSlot *() const { return array; }
 
     HeapSlotArray operator +(int offset) const { return HeapSlotArray(array + offset); }
     HeapSlotArray operator +(uint32_t offset) const { return HeapSlotArray(array + offset); }
 };
 
 /*
- * Incremental GC requires that weak pointers have read barriers. This is mostly
- * an issue for empty shapes stored in JSCompartment. The problem happens when,
- * during an incremental GC, some JS code stores one of the compartment's empty
- * shapes into an object already marked black. Normally, this would not be a
- * problem, because the empty shape would have been part of the initial snapshot
- * when the GC started. However, since this is a weak pointer, it isn't. So we
- * may collect the empty shape even though a live object points to it. To fix
- * this, we mark these empty shapes black whenever they get read out.
- */
-template <class T>
-class ReadBarriered
-{
-    T *value;
-
-  public:
-    ReadBarriered() : value(nullptr) {}
-    ReadBarriered(T *value) : value(value) {}
-    ReadBarriered(const Rooted<T*> &rooted) : value(rooted) {}
-
-    T *get() const {
-        if (!value)
-            return nullptr;
-        T::readBarrier(value);
-        return value;
-    }
-
-    operator T*() const { return get(); }
-
-    T &operator*() const { return *get(); }
-    T *operator->() const { return get(); }
-
-    T **unsafeGet() { return &value; }
-    T * const * unsafeGet() const { return &value; }
-
-    void set(T *v) { value = v; }
-
-    operator bool() { return !!value; }
-};
-
-class ReadBarrieredValue
-{
-    Value value;
-
-  public:
-    ReadBarrieredValue() : value(UndefinedValue()) {}
-    ReadBarrieredValue(const Value &value) : value(value) {}
-
-    inline const Value &get() const;
-    Value *unsafeGet() { return &value; }
-    inline operator const Value &() const;
-
-    inline JSObject &toObject() const;
-};
-
-/*
  * Operations on a Heap thing inside the GC need to strip the barriers from
  * pointer operations. This template helps do that in contexts where the type
  * is templatized.
  */
 template <typename T> struct Unbarriered {};
 template <typename S> struct Unbarriered< PreBarriered<S> > { typedef S *type; };
 template <typename S> struct Unbarriered< RelocatablePtr<S> > { typedef S *type; };
 template <> struct Unbarriered<PreBarrieredValue> { typedef Value type; };
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -357,17 +357,17 @@ IsAboutToBeFinalized(const js::jit::VMFu
     /*
      * Preserves entries in the WeakCache<VMFunction, JitCode>
      * iff the JitCode has been marked.
      */
     return true;
 }
 
 inline bool
-IsAboutToBeFinalized(ReadBarriered<js::jit::JitCode> code)
+IsAboutToBeFinalized(ReadBarrieredJitCode code)
 {
     return IsJitCodeAboutToBeFinalized(code.unsafeGet());
 }
 #endif
 
 inline Cell *
 ToMarkable(const Value &v)
 {
--- a/js/src/jit/JitCompartment.h
+++ b/js/src/jit/JitCompartment.h
@@ -354,17 +354,17 @@ class JitZone
     }
 };
 
 class JitCompartment
 {
     friend class JitActivation;
 
     // Map ICStub keys to ICStub shared code objects.
-    typedef WeakValueCache<uint32_t, ReadBarriered<JitCode> > ICStubCodeMap;
+    typedef WeakValueCache<uint32_t, ReadBarrieredJitCode> ICStubCodeMap;
     ICStubCodeMap *stubCodes_;
 
     // Keep track of offset into various baseline stubs' code at return
     // point from called script.
     void *baselineCallReturnFromIonAddr_;
     void *baselineGetPropReturnFromIonAddr_;
     void *baselineSetPropReturnFromIonAddr_;
 
@@ -374,18 +374,18 @@ class JitCompartment
     void *baselineCallReturnFromStubAddr_;
     void *baselineGetPropReturnFromStubAddr_;
     void *baselineSetPropReturnFromStubAddr_;
 
     // Stub to concatenate two strings inline. Note that it can't be
     // stored in JitRuntime because masm.newGCString bakes in zone-specific
     // pointers. This has to be a weak pointer to avoid keeping the whole
     // compartment alive.
-    ReadBarriered<JitCode> stringConcatStub_;
-    ReadBarriered<JitCode> parallelStringConcatStub_;
+    ReadBarrieredJitCode stringConcatStub_;
+    ReadBarrieredJitCode parallelStringConcatStub_;
 
     // Set of JSScripts invoked by ForkJoin (i.e. the entry script). These
     // scripts are marked if their respective parallel IonScripts' age is less
     // than a certain amount. See IonScript::parallelAge_.
     typedef HashSet<PreBarrieredScript> ScriptSet;
     ScriptSet *activeParallelEntryScripts_;
 
     JitCode *generateStringConcatStub(JSContext *cx, ExecutionMode mode);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1106,17 +1106,17 @@ JS_TransplantObject(JSContext *cx, Handl
         // object will continue to work.
         if (!JSObject::swap(cx, origobj, target))
             MOZ_CRASH();
         newIdentity = origobj;
     } else if (WrapperMap::Ptr p = destination->lookupWrapper(origv)) {
         // There might already be a wrapper for the original object in
         // the new compartment. If there is, we use its identity and swap
         // in the contents of |target|.
-        newIdentity = &p->value().toObject();
+        newIdentity = &p->value().get().toObject();
 
         // When we remove origv from the wrapper map, its wrapper, newIdentity,
         // must immediately cease to be a cross-compartment wrapper. Neuter it.
         destination->removeWrapper(p);
         NukeCrossCompartmentWrapper(cx, newIdentity);
 
         if (!JSObject::swap(cx, newIdentity, target))
             MOZ_CRASH();
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -56,17 +56,17 @@ struct CallsiteCloneKey {
     }
 
     static inline bool match(const CallsiteCloneKey &a, const CallsiteCloneKey &b) {
         return a.script == b.script && a.offset == b.offset && a.original == b.original;
     }
 };
 
 typedef HashMap<CallsiteCloneKey,
-                ReadBarriered<JSFunction>,
+                ReadBarrieredFunction,
                 CallsiteCloneKey,
                 SystemAllocPolicy> CallsiteCloneTable;
 
 JSFunction *
 ExistingCloneFunctionAtCallsite(const CallsiteCloneTable &table, JSFunction *fun,
                                 JSScript *script, jsbytecode *pc);
 
 JSFunction *CloneFunctionAtCallsite(JSContext *cx, HandleFunction fun,
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -136,17 +136,17 @@ struct JSCompartment
 #endif
 
     void mark() { marked = true; }
 
   private:
     friend struct JSRuntime;
     friend struct JSContext;
     friend class js::ExclusiveContext;
-    js::ReadBarriered<js::GlobalObject> global_;
+    js::ReadBarrieredGlobalObject global_;
 
     unsigned                     enterCompartmentDepth;
 
   public:
     void enter() { enterCompartmentDepth++; }
     void leave() { enterCompartmentDepth--; }
     bool hasBeenEntered() { return !!enterCompartmentDepth; }
 
@@ -260,17 +260,17 @@ struct JSCompartment
      */
     js::CallsiteCloneTable callsiteClones;
     void sweepCallsiteClones();
 
     /*
      * Lazily initialized script source object to use for scripts cloned
      * from the self-hosting global.
      */
-    js::ReadBarriered<js::ScriptSourceObject> selfHostingScriptSource;
+    js::ReadBarrieredScriptSourceObject selfHostingScriptSource;
 
     /* During GC, stores the index of this compartment in rt->compartments. */
     unsigned                     gcIndex;
 
     /*
      * During GC, stores the head of a list of incoming pointers from gray cells.
      *
      * The objects in the list are either cross-compartment wrappers, or
--- a/js/src/jscompartmentinlines.h
+++ b/js/src/jscompartmentinlines.h
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jscompartmentinlines_h
 #define jscompartmentinlines_h
 
 #include "jscompartment.h"
 
-#include "gc/Barrier-inl.h"
+#include "gc/Barrier.h"
 
 inline void
 JSCompartment::initGlobal(js::GlobalObject &global)
 {
     JS_ASSERT(global.compartment() == this);
     JS_ASSERT(!global_);
     global_ = &global;
 }
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -2553,18 +2553,18 @@ struct types::ObjectTableKey
                 return false;
         }
         return true;
     }
 };
 
 struct types::ObjectTableEntry
 {
-    ReadBarriered<TypeObject> object;
-    ReadBarriered<Shape> shape;
+    ReadBarrieredTypeObject object;
+    ReadBarrieredShape shape;
     Type *types;
 };
 
 static inline void
 UpdateObjectTableEntryTypes(ExclusiveContext *cx, ObjectTableEntry &entry,
                             IdValuePair *properties, size_t nproperties)
 {
     if (entry.object->unknownProperties())
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -1183,17 +1183,17 @@ struct TypeObject : gc::BarrieredCell<Ty
 /*
  * Entries for the per-compartment set of type objects which are 'new' types to
  * use for some prototype and constructed with an optional script. This also
  * includes entries for the set of lazy type objects in the compartment, which
  * use a null script (though there are only a few of these per compartment).
  */
 struct TypeObjectWithNewScriptEntry
 {
-    ReadBarriered<TypeObject> object;
+    ReadBarrieredTypeObject object;
 
     // Note: This pointer is only used for equality and does not need a read barrier.
     JSFunction *newFunction;
 
     TypeObjectWithNewScriptEntry(TypeObject *object, JSFunction *newFunction)
       : object(object), newFunction(newFunction)
     {}
 
@@ -1328,24 +1328,30 @@ FinishCompilation(JSContext *cx, HandleS
                   CompilerConstraintList *constraints, RecompileInfo *precompileInfo);
 
 // Update the actual types in any scripts queried by constraints with any
 // speculative types added during the definite properties analysis.
 void
 FinishDefinitePropertiesAnalysis(JSContext *cx, CompilerConstraintList *constraints);
 
 struct ArrayTableKey;
-typedef HashMap<ArrayTableKey,ReadBarriered<TypeObject>,ArrayTableKey,SystemAllocPolicy> ArrayTypeTable;
+typedef HashMap<ArrayTableKey,
+                ReadBarrieredTypeObject,
+                ArrayTableKey,
+                SystemAllocPolicy> ArrayTypeTable;
 
 struct ObjectTableKey;
 struct ObjectTableEntry;
 typedef HashMap<ObjectTableKey,ObjectTableEntry,ObjectTableKey,SystemAllocPolicy> ObjectTypeTable;
 
 struct AllocationSiteKey;
-typedef HashMap<AllocationSiteKey,ReadBarriered<TypeObject>,AllocationSiteKey,SystemAllocPolicy> AllocationSiteTable;
+typedef HashMap<AllocationSiteKey,
+                ReadBarrieredTypeObject,
+                AllocationSiteKey,
+                SystemAllocPolicy> AllocationSiteTable;
 
 class HeapTypeSetKey;
 
 // Type set entry for either a JSObject with singleton type or a non-singleton TypeObject.
 struct TypeObjectKey
 {
     static intptr_t keyBits(TypeObjectKey *obj) { return (intptr_t) obj; }
     static TypeObjectKey *getKey(TypeObjectKey *obj) { return obj; }
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -318,17 +318,17 @@ class RegExpCompartment
     typedef HashSet<RegExpShared *, DefaultHasher<RegExpShared*>, RuntimeAllocPolicy> PendingSet;
     PendingSet inUse_;
 
     /*
      * This is the template object where the result of re.exec() is based on,
      * if there is a result. This is used in CreateRegExpMatchResult to set
      * the input/index properties faster.
      */
-    ReadBarriered<JSObject> matchResultTemplateObject_;
+    ReadBarrieredObject matchResultTemplateObject_;
 
     JSObject *createMatchResultTemplateObject(JSContext *cx);
 
   public:
     RegExpCompartment(JSRuntime *rt);
     ~RegExpCompartment();
 
     bool init(JSContext *cx);
--- a/js/src/vm/ScopeObject.h
+++ b/js/src/vm/ScopeObject.h
@@ -812,17 +812,17 @@ class DebugScopes
     static MOZ_ALWAYS_INLINE void proxiedScopesPostWriteBarrier(JSRuntime *rt, ObjectWeakMap *map,
                                                                const PreBarrieredObject &key);
 
     /*
      * The map from live frames which have optimized-away scopes to the
      * corresponding debug scopes.
      */
     typedef HashMap<ScopeIterKey,
-                    ReadBarriered<DebugScopeObject>,
+                    ReadBarrieredDebugScopeObject,
                     ScopeIterKey,
                     RuntimeAllocPolicy> MissingScopeMap;
     MissingScopeMap missingScopes;
     class MissingScopesRef;
     static MOZ_ALWAYS_INLINE void missingScopesPostWriteBarrier(JSRuntime *rt, MissingScopeMap *map,
                                                                const ScopeIterKey &key);
 
     /*
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -1548,17 +1548,17 @@ BaseShape::finalize(FreeOp *fop)
 }
 
 inline
 InitialShapeEntry::InitialShapeEntry() : shape(nullptr), proto(nullptr)
 {
 }
 
 inline
-InitialShapeEntry::InitialShapeEntry(const ReadBarriered<Shape> &shape, TaggedProto proto)
+InitialShapeEntry::InitialShapeEntry(const ReadBarrieredShape &shape, TaggedProto proto)
   : shape(shape), proto(proto)
 {
 }
 
 inline InitialShapeEntry::Lookup
 InitialShapeEntry::getLookup() const
 {
     return Lookup(shape->getObjectClass(), proto, shape->getObjectParent(), shape->getObjectMetadata(),
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -865,17 +865,17 @@ BaseShape::BaseShape(const StackBaseShap
     this->rawSetter = base.rawSetter;
     if ((base.flags & HAS_GETTER_OBJECT) && base.rawGetter)
         GetterSetterWriteBarrierPost(runtimeFromMainThread(), &this->getterObj);
     if ((base.flags & HAS_SETTER_OBJECT) && base.rawSetter)
         GetterSetterWriteBarrierPost(runtimeFromMainThread(), &this->setterObj);
     this->compartment_ = base.compartment;
 }
 
-typedef HashSet<ReadBarriered<UnownedBaseShape>,
+typedef HashSet<ReadBarrieredUnownedBaseShape,
                 StackBaseShape,
                 SystemAllocPolicy> BaseShapeSet;
 
 
 class Shape : public gc::BarrieredCell<Shape>
 {
     friend class ::JSObject;
     friend class ::JSFunction;
@@ -1380,17 +1380,17 @@ struct EmptyShape : public js::Shape
  */
 struct InitialShapeEntry
 {
     /*
      * Initial shape to give to the object. This is an empty shape, except for
      * certain classes (e.g. String, RegExp) which may add certain baked-in
      * properties.
      */
-    ReadBarriered<Shape> shape;
+    ReadBarrieredShape shape;
 
     /*
      * Matching prototype for the entry. The shape of an object determines its
      * prototype, but the prototype cannot be determined from the shape itself.
      */
     TaggedProto proto;
 
     /* State used to determine a match on an initial shape. */
@@ -1428,17 +1428,17 @@ struct InitialShapeEntry
             hashParent(hashParent), matchParent(matchParent),
             hashMetadata(hashMetadata), matchMetadata(matchMetadata),
             nfixed(nfixed), baseFlags(baseFlags)
         {}
 #endif
     };
 
     inline InitialShapeEntry();
-    inline InitialShapeEntry(const ReadBarriered<Shape> &shape, TaggedProto proto);
+    inline InitialShapeEntry(const ReadBarrieredShape &shape, TaggedProto proto);
 
     inline Lookup getLookup() const;
 
     static inline HashNumber hash(const Lookup &lookup);
     static inline bool match(const InitialShapeEntry &key, const Lookup &lookup);
     static void rekey(InitialShapeEntry &k, const InitialShapeEntry& newKey) { k = newKey; }
 };