Bug 1290337 - Part 7: Replace Value parameter to const Value& in GC. r=terrence
authorTooru Fujisawa <arai_a@mac.com>
Sun, 11 Sep 2016 18:15:22 +0900
changeset 316052 76234719298ad869a44d6d2272db71b1fd8d7278
parent 316051 6dbf0a82ba22448445d4e6706513c537f1bd0c6c
child 316053 e5865e178cc442982a37088902945487488377ee
push id30759
push userphilringnalda@gmail.com
push dateSat, 01 Oct 2016 06:25:09 +0000
treeherdermozilla-central@fcc62bbf09ee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1290337
milestone52.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 1290337 - Part 7: Replace Value parameter to const Value& in GC. r=terrence
js/public/Id.h
js/src/gc/Barrier.h
js/src/gc/Marking.cpp
js/src/gc/Marking.h
js/src/vm/TaggedProto.h
--- a/js/public/Id.h
+++ b/js/public/Id.h
@@ -192,17 +192,17 @@ struct BarrierMethods<jsid>
 {
     static void postBarrier(jsid* idp, jsid prev, jsid next) {}
 };
 
 // If the jsid is a GC pointer type, convert to that type and call |f| with
 // the pointer. If the jsid is not a GC type, calls F::defaultValue.
 template <typename F, typename... Args>
 auto
-DispatchTyped(F f, jsid& id, Args&&... args)
+DispatchTyped(F f, const jsid& id, Args&&... args)
   -> decltype(f(static_cast<JSString*>(nullptr), mozilla::Forward<Args>(args)...))
 {
     if (JSID_IS_STRING(id))
         return f(JSID_TO_STRING(id), mozilla::Forward<Args>(args)...);
     if (JSID_IS_SYMBOL(id))
         return f(JSID_TO_SYMBOL(id), mozilla::Forward<Args>(args)...);
     MOZ_ASSERT(!JSID_IS_GCTHING(id));
     return F::defaultValue(id);
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -274,20 +274,20 @@ template <typename S> struct PreBarrierF
 
 template <typename S> struct ReadBarrierFunctor : public VoidDefaultAdaptor<S> {
     template <typename T> void operator()(T* t);
 };
 
 template <>
 struct InternalBarrierMethods<Value>
 {
-    static bool isMarkable(Value v) { return v.isMarkable(); }
-    static bool isMarkableTaggedPointer(Value v) { return isMarkable(v); }
+    static bool isMarkable(const Value& v) { return v.isMarkable(); }
+    static bool isMarkableTaggedPointer(const Value& v) { return isMarkable(v); }
 
-    static void preBarrier(Value v) {
+    static void preBarrier(const Value& v) {
         DispatchTyped(PreBarrierFunctor<Value>(), v);
     }
 
     static void postBarrier(Value* vp, const Value& prev, const Value& next) {
         MOZ_ASSERT(!CurrentThreadIsIonCompiling());
         MOZ_ASSERT(vp);
 
         // If the target needs an entry, add it.
@@ -329,17 +329,17 @@ template <typename T>
 class BarrieredBaseMixins {};
 
 // Base class of all barrier types.
 template <typename T>
 class BarrieredBase : public BarrieredBaseMixins<T>
 {
   protected:
     // BarrieredBase is not directly instantiable.
-    explicit BarrieredBase(T v) : value(v) {}
+    explicit BarrieredBase(const T& v) : value(v) {}
 
     // Storage for all barrier classes. |value| must be a GC thing reference
     // type: either a direct pointer to a GC thing or a supported tagged
     // pointer that can reference GC things, such as JS::Value or jsid. Nested
     // barrier types are NOT supported. See assertTypeConstraints.
     T value;
 
   public:
@@ -350,35 +350,37 @@ class BarrieredBase : public BarrieredBa
 };
 
 // Base class for barriered pointer types that intercept only writes.
 template <class T>
 class WriteBarrieredBase : public BarrieredBase<T>
 {
   protected:
     // WriteBarrieredBase is not directly instantiable.
-    explicit WriteBarrieredBase(T v) : BarrieredBase<T>(v) {}
+    explicit WriteBarrieredBase(const T& v) : BarrieredBase<T>(v) {}
 
   public:
     DECLARE_POINTER_COMPARISON_OPS(T);
     DECLARE_POINTER_CONSTREF_OPS(T);
 
     // Use this if the automatic coercion to T isn't working.
     const T& get() const { return this->value; }
 
     // Use this if you want to change the value without invoking barriers.
     // Obviously this is dangerous unless you know the barrier is not needed.
-    void unsafeSet(T v) { this->value = v; }
+    void unsafeSet(const T& v) { this->value = v; }
 
     // For users who need to manually barrier the raw types.
     static void writeBarrierPre(const T& v) { InternalBarrierMethods<T>::preBarrier(v); }
 
   protected:
     void pre() { InternalBarrierMethods<T>::preBarrier(this->value); }
-    void post(T prev, T next) { InternalBarrierMethods<T>::postBarrier(&this->value, prev, next); }
+    void post(const T& prev, const T& next) {
+        InternalBarrierMethods<T>::postBarrier(&this->value, prev, next);
+    }
 };
 
 /*
  * PreBarriered only automatically handles pre-barriers. Post-barriers must be
  * manually implemented when using this class. GCPtr and HeapPtr should be used
  * in all cases that do not require explicit low-level control of moving
  * behavior, e.g. for HashMap keys.
  */
@@ -386,21 +388,21 @@ template <class T>
 class PreBarriered : public WriteBarrieredBase<T>
 {
   public:
     PreBarriered() : WriteBarrieredBase<T>(JS::GCPolicy<T>::initial()) {}
     /*
      * Allow implicit construction for use in generic contexts, such as
      * DebuggerWeakMap::markKeys.
      */
-    MOZ_IMPLICIT PreBarriered(T v) : WriteBarrieredBase<T>(v) {}
+    MOZ_IMPLICIT PreBarriered(const T& v) : WriteBarrieredBase<T>(v) {}
     explicit PreBarriered(const PreBarriered<T>& v) : WriteBarrieredBase<T>(v.value) {}
     ~PreBarriered() { this->pre(); }
 
-    void init(T v) {
+    void init(const T& v) {
         this->value = v;
     }
 
     /* Use to set the pointer to nullptr. */
     void clear() {
         this->pre();
         this->value = nullptr;
     }
@@ -425,33 +427,33 @@ class PreBarriered : public WriteBarrier
  * implemented by js::HeapPtr<T> or JS::Heap<T> at the cost of not
  * automatically handling deletion or movement.
  */
 template <class T>
 class GCPtr : public WriteBarrieredBase<T>
 {
   public:
     GCPtr() : WriteBarrieredBase<T>(JS::GCPolicy<T>::initial()) {}
-    explicit GCPtr(T v) : WriteBarrieredBase<T>(v) {
+    explicit GCPtr(const T& v) : WriteBarrieredBase<T>(v) {
         this->post(JS::GCPolicy<T>::initial(), v);
     }
     explicit GCPtr(const GCPtr<T>& v) : WriteBarrieredBase<T>(v) {
         this->post(JS::GCPolicy<T>::initial(), v);
     }
 #ifdef DEBUG
     ~GCPtr() {
         // No prebarrier necessary as this only happens when we are sweeping or
         // after we have just collected the nursery.  Note that the wrapped
         // pointer may already have been freed by this point.
         MOZ_ASSERT(CurrentThreadIsGCSweeping());
         Poison(this, JS_FREED_HEAP_PTR_PATTERN, sizeof(*this));
     }
 #endif
 
-    void init(T v) {
+    void init(const T& v) {
         this->value = v;
         this->post(JS::GCPolicy<T>::initial(), v);
     }
 
     DECLARE_POINTER_ASSIGN_OPS(GCPtr, T);
 
     T unbarrieredGet() const {
         return this->value;
@@ -518,17 +520,17 @@ class HeapPtr : public WriteBarrieredBas
         this->post(JS::GCPolicy<T>::initial(), this->value);
     }
 
     ~HeapPtr() {
         this->pre();
         this->post(this->value, JS::GCPolicy<T>::initial());
     }
 
-    void init(T v) {
+    void init(const T& v) {
         this->value = v;
         this->post(JS::GCPolicy<T>::initial(), this->value);
     }
 
     DECLARE_POINTER_ASSIGN_OPS(HeapPtr, T);
 
     /* Make this friend so it can access pre() and post(). */
     template <class T1, class T2>
@@ -551,21 +553,23 @@ class HeapPtr : public WriteBarrieredBas
 };
 
 // Base class for barriered pointer types that intercept reads and writes.
 template <typename T>
 class ReadBarrieredBase : public BarrieredBase<T>
 {
   protected:
     // ReadBarrieredBase is not directly instantiable.
-    explicit ReadBarrieredBase(T v) : BarrieredBase<T>(v) {}
+    explicit ReadBarrieredBase(const T& v) : BarrieredBase<T>(v) {}
 
   protected:
     void read() const { InternalBarrierMethods<T>::readBarrier(this->value); }
-    void post(T prev, T next) { InternalBarrierMethods<T>::postBarrier(&this->value, prev, next); }
+    void post(const T& prev, const T& next) {
+        InternalBarrierMethods<T>::postBarrier(&this->value, prev, next);
+    }
 };
 
 // Incremental GC requires that weak pointers have read barriers. See the block
 // comment at the top of Barrier.h for a complete discussion of why.
 //
 // Note that this class also has post-barriers, so is safe to use with nursery
 // pointers. However, when used as a hashtable key, care must still be taken to
 // insert manual post-barriers on the table for rekeying if the key is based in
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -310,17 +310,17 @@ ShouldMarkCrossCompartment(JSTracer* trc
                 DelayCrossCompartmentGrayMarking(src);
             return false;
         }
         return zone->isGCMarkingGray();
     }
 }
 
 static bool
-ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, Value val)
+ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, const Value& val)
 {
     return val.isMarkable() && ShouldMarkCrossCompartment(trc, src, (Cell*)val.toGCThing());
 }
 
 static void
 AssertZoneIsMarking(Cell* thing)
 {
     MOZ_ASSERT(TenuredCell::fromPointer(thing)->zone()->isGCMarking());
@@ -395,17 +395,17 @@ typename PtrBaseGCType<T>::type*
 ConvertToBase(T* thingp)
 {
     return reinterpret_cast<typename PtrBaseGCType<T>::type*>(thingp);
 }
 
 template <typename T> void DispatchToTracer(JSTracer* trc, T* thingp, const char* name);
 template <typename T> T DoCallback(JS::CallbackTracer* trc, T* thingp, const char* name);
 template <typename T> void DoMarking(GCMarker* gcmarker, T* thing);
-template <typename T> void DoMarking(GCMarker* gcmarker, T thing);
+template <typename T> void DoMarking(GCMarker* gcmarker, const T& thing);
 template <typename T> void NoteWeakEdge(GCMarker* gcmarker, T** thingp);
 template <typename T> void NoteWeakEdge(GCMarker* gcmarker, T* thingp);
 
 template <typename T>
 void
 js::TraceEdge(JSTracer* trc, WriteBarrieredBase<T>* thingp, const char* name)
 {
     DispatchToTracer(trc, ConvertToBase(thingp->unsafeUnbarrieredForTracing()), name);
@@ -802,17 +802,17 @@ DoMarking(GCMarker* gcmarker, T* thing)
 
 template <typename S>
 struct DoMarkingFunctor : public VoidDefaultAdaptor<S> {
     template <typename T> void operator()(T* t, GCMarker* gcmarker) { DoMarking(gcmarker, t); }
 };
 
 template <typename T>
 void
-DoMarking(GCMarker* gcmarker, T thing)
+DoMarking(GCMarker* gcmarker, const T& thing)
 {
     DispatchTyped(DoMarkingFunctor<T>(), thing, gcmarker);
 }
 
 template <typename T>
 void
 NoteWeakEdge(GCMarker* gcmarker, T** thingp)
 {
@@ -951,17 +951,17 @@ js::GCMarker::traverseEdge(S source, T* 
 template <typename V, typename S> struct TraverseEdgeFunctor : public VoidDefaultAdaptor<V> {
     template <typename T> void operator()(T t, GCMarker* gcmarker, S s) {
         return gcmarker->traverseEdge(s, t);
     }
 };
 
 template <typename S, typename T>
 void
-js::GCMarker::traverseEdge(S source, T thing)
+js::GCMarker::traverseEdge(S source, const T& thing)
 {
     DispatchTyped(TraverseEdgeFunctor<T, S>(), thing, this, source);
 }
 
 template <typename T>
 bool
 js::GCMarker::mark(T* thing)
 {
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -177,17 +177,17 @@ class GCMarker : public JSTracer
     void stop();
     void reset();
 
     // Mark the given GC thing and traverse its children at some point.
     template <typename T> void traverse(T thing);
 
     // Calls traverse on target after making additional assertions.
     template <typename S, typename T> void traverseEdge(S source, T* target);
-    template <typename S, typename T> void traverseEdge(S source, T target);
+    template <typename S, typename T> void traverseEdge(S source, const T& target);
 
     // Notes a weak graph edge for later sweeping.
     template <typename T> void noteWeakEdge(T* edge);
 
     /*
      * Care must be taken changing the mark color from gray to black. The cycle
      * collector depends on the invariant that there are no black to gray edges
      * in the GC heap. This invariant lets the CC not trace through black
--- a/js/src/vm/TaggedProto.h
+++ b/js/src/vm/TaggedProto.h
@@ -106,17 +106,17 @@ class RootedBase<TaggedProto> : public T
 template <>
 class BarrieredBaseMixins<TaggedProto> : public TaggedProtoOperations<GCPtr<TaggedProto>>
 {};
 
 // If the TaggedProto is a JSObject pointer, convert to that type and call |f|
 // with the pointer. If the TaggedProto is lazy, calls F::defaultValue.
 template <typename F, typename... Args>
 auto
-DispatchTyped(F f, TaggedProto& proto, Args&&... args)
+DispatchTyped(F f, const TaggedProto& proto, Args&&... args)
   -> decltype(f(static_cast<JSObject*>(nullptr), mozilla::Forward<Args>(args)...))
 {
     if (proto.isObject())
         return f(proto.toObject(), mozilla::Forward<Args>(args)...);
     return F::defaultValue(proto);
 }
 
 // Since JSObject pointers are either nullptr or a valid object and since the