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 200079 7165d1b0097ab84362be2a5cbf03173eee54f27f
parent 200078 3a821ea694d7631ad683057ed65198b32eaadc36
child 200080 57292971f11018f5f690abf59e82454e48c70082
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs989414
milestone32.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 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; }
 };