Bug 1290337 - Part 3: Replace Value parameter to const Value& in simple case. r=shu
authorTooru Fujisawa <arai_a@mac.com>
Sun, 11 Sep 2016 18:15:22 +0900
changeset 316048 9796ed81f17a936804ec792c843dadf2c00023df
parent 316047 a3a7f0fa1186ada56b6a66f1181069790c61a3bd
child 316049 f81c58393110bf0a3cf9f6c39262dca1af57cdd0
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)
reviewersshu
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 3: Replace Value parameter to const Value& in simple case. r=shu
js/public/CallArgs.h
js/public/Conversions.h
js/public/Proxy.h
js/public/Value.h
js/src/builtin/ModuleObject.cpp
js/src/builtin/ModuleObject.h
js/src/builtin/Object.cpp
js/src/builtin/Object.h
js/src/builtin/RegExp.cpp
js/src/ds/IdValuePair.h
js/src/frontend/BytecodeEmitter.h
js/src/jsapi-tests/tests.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jscompartment.h
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsnum.cpp
js/src/jsnum.h
js/src/jsobjinlines.h
js/src/json.cpp
js/src/json.h
js/src/jsopcode.cpp
js/src/jswatchpoint.h
js/src/perf/jsperf.cpp
js/src/perf/jsperf.h
js/src/proxy/Proxy.cpp
js/src/vm/Debugger.cpp
js/src/vm/Debugger.h
js/src/vm/EnvironmentObject.cpp
js/src/vm/GeneratorObject.h
js/src/vm/GlobalObject.cpp
js/src/vm/GlobalObject.h
js/src/vm/Interpreter.h
js/src/vm/NativeObject.h
js/src/vm/ProxyObject.h
js/src/vm/Stack.h
js/src/vm/StructuredClone.cpp
js/src/vm/Symbol.cpp
js/src/vm/Symbol.h
--- a/js/public/CallArgs.h
+++ b/js/public/CallArgs.h
@@ -87,17 +87,17 @@ namespace detail {
  * Compute |this| for the |vp| inside a JSNative, either boxing primitives or
  * replacing with the global object as necessary.
  */
 extern JS_PUBLIC_API(Value)
 ComputeThis(JSContext* cx, JS::Value* vp);
 
 #ifdef JS_DEBUG
 extern JS_PUBLIC_API(void)
-CheckIsValidConstructible(Value v);
+CheckIsValidConstructible(const Value& v);
 #endif
 
 class MOZ_STACK_CLASS IncludeUsedRval
 {
   protected:
 #ifdef JS_DEBUG
     mutable bool usedRval_;
     void setUsedRval() const { usedRval_ = true; }
@@ -236,22 +236,22 @@ class MOZ_STACK_CLASS CallArgsBase : pub
         return MutableHandleValue::fromMarkedLocation(&argv_[-2]);
     }
 
   public:
     // These methods are publicly exposed, but they are *not* to be used when
     // implementing a JSNative method and encapsulating access to |vp| within
     // it.  You probably don't want to use these!
 
-    void setCallee(Value aCalleev) const {
+    void setCallee(const Value& aCalleev) const {
         this->clearUsedRval();
         argv_[-2] = aCalleev;
     }
 
-    void setThis(Value aThisv) const {
+    void setThis(const Value& aThisv) const {
         argv_[-1] = aThisv;
     }
 
     MutableHandleValue mutableThisv() const {
         return MutableHandleValue::fromMarkedLocation(&argv_[-1]);
     }
 
   public:
--- a/js/public/Conversions.h
+++ b/js/public/Conversions.h
@@ -25,17 +25,17 @@ struct JSContext;
 namespace js {
 
 /* DO NOT CALL THIS. Use JS::ToBoolean. */
 extern JS_PUBLIC_API(bool)
 ToBooleanSlow(JS::HandleValue v);
 
 /* DO NOT CALL THIS.  Use JS::ToNumber. */
 extern JS_PUBLIC_API(bool)
-ToNumberSlow(JSContext* cx, JS::Value v, double* dp);
+ToNumberSlow(JSContext* cx, const JS::Value& v, double* dp);
 
 /* DO NOT CALL THIS. Use JS::ToInt8. */
 extern JS_PUBLIC_API(bool)
 ToInt8Slow(JSContext *cx, JS::HandleValue v, int8_t *out);
 
 /* DO NOT CALL THIS. Use JS::ToUint8. */
 extern JS_PUBLIC_API(bool)
 ToUint8Slow(JSContext *cx, JS::HandleValue v, uint8_t *out);
--- a/js/public/Proxy.h
+++ b/js/public/Proxy.h
@@ -529,17 +529,17 @@ class MOZ_STACK_CLASS ProxyOptions {
     const Class* clasp_;
 };
 
 JS_FRIEND_API(JSObject*)
 NewProxyObject(JSContext* cx, const BaseProxyHandler* handler, HandleValue priv,
                JSObject* proto, const ProxyOptions& options = ProxyOptions());
 
 JSObject*
-RenewProxyObject(JSContext* cx, JSObject* obj, BaseProxyHandler* handler, Value priv);
+RenewProxyObject(JSContext* cx, JSObject* obj, BaseProxyHandler* handler, const Value& priv);
 
 class JS_FRIEND_API(AutoEnterPolicy)
 {
   public:
     typedef BaseProxyHandler::Action Action;
     AutoEnterPolicy(JSContext* cx, const BaseProxyHandler* handler,
                     HandleObject wrapper, HandleId id, Action act, bool mayThrow)
 #ifdef JS_DEBUG
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -956,17 +956,17 @@ JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(const
 #endif  /* JS_PUNBOX64 */
 
 static inline bool
 JSVAL_IS_TRACEABLE_IMPL(const jsval_layout& l)
 {
     return JSVAL_IS_GCTHING_IMPL(l) && !JSVAL_IS_NULL_IMPL(l);
 }
 
-static inline jsval_layout JSVAL_TO_IMPL(JS::Value v);
+static inline jsval_layout JSVAL_TO_IMPL(const JS::Value& v);
 static inline JS_VALUE_CONSTEXPR JS::Value IMPL_TO_JSVAL(const jsval_layout& l);
 
 namespace JS {
 
 static inline JS_VALUE_CONSTEXPR JS::Value UndefinedValue();
 
 /**
  * Returns a generic quiet NaN value, with all payload bits set to zero.
@@ -1397,17 +1397,17 @@ class Value
 
     void staticAssertions() {
         JS_STATIC_ASSERT(sizeof(JSValueType) == 1);
         JS_STATIC_ASSERT(sizeof(JSValueTag) == 4);
         JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4);
         JS_STATIC_ASSERT(sizeof(Value) == 8);
     }
 
-    friend jsval_layout (::JSVAL_TO_IMPL)(Value);
+    friend jsval_layout (::JSVAL_TO_IMPL)(const Value&);
     friend Value JS_VALUE_CONSTEXPR (::IMPL_TO_JSVAL)(const jsval_layout& l);
     friend Value JS_VALUE_CONSTEXPR (JS::UndefinedValue)();
 } JS_HAZ_GC_POINTER;
 
 inline bool
 IsOptimizedPlaceholderMagicValue(const Value& v)
 {
     if (v.isMagic()) {
@@ -1924,17 +1924,17 @@ DispatchTyped(F f, const JS::Value& val,
 
 template <class S> struct VoidDefaultAdaptor { static void defaultValue(S) {} };
 template <class S> struct IdentityDefaultAdaptor { static S defaultValue(const S& v) {return v;} };
 template <class S, bool v> struct BoolDefaultAdaptor { static bool defaultValue(S) { return v; } };
 
 } // namespace js
 
 inline jsval_layout
-JSVAL_TO_IMPL(JS::Value v)
+JSVAL_TO_IMPL(const JS::Value& v)
 {
     return v.data;
 }
 
 inline JS_VALUE_CONSTEXPR JS::Value
 IMPL_TO_JSVAL(const jsval_layout& l)
 {
 #if defined(JS_VALUE_IS_CONSTEXPR)
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -825,17 +825,17 @@ ModuleObject::state() const
 
 Value
 ModuleObject::hostDefinedField() const
 {
     return getReservedSlot(HostDefinedSlot);
 }
 
 void
-ModuleObject::setHostDefinedField(JS::Value value)
+ModuleObject::setHostDefinedField(const JS::Value& value)
 {
     setReservedSlot(HostDefinedSlot, value);
 }
 
 ModuleEnvironmentObject&
 ModuleObject::initialEnvironment() const
 {
     return getReservedSlot(InitialEnvironmentSlot).toObject().as<ModuleEnvironmentObject>();
--- a/js/src/builtin/ModuleObject.h
+++ b/js/src/builtin/ModuleObject.h
@@ -260,17 +260,17 @@ class ModuleObject : public NativeObject
     ArrayObject& starExportEntries() const;
     IndirectBindingMap& importBindings();
     JSObject* namespaceExports();
     IndirectBindingMap* namespaceBindings();
 
     static bool DeclarationInstantiation(JSContext* cx, HandleModuleObject self);
     static bool Evaluation(JSContext* cx, HandleModuleObject self);
 
-    void setHostDefinedField(JS::Value value);
+    void setHostDefinedField(const JS::Value& value);
 
     // For intrinsic_CreateModuleEnvironment.
     void createEnvironment();
 
     // For BytecodeEmitter.
     bool noteFunctionDeclaration(ExclusiveContext* cx, HandleAtom name, HandleFunction fun);
 
     // For intrinsic_InstantiateModuleFunctionDeclarations.
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -472,17 +472,17 @@ obj_setPrototypeOf(JSContext* cx, unsign
     /* Step 8. */
     args.rval().set(args[0]);
     return true;
 }
 
 #if JS_HAS_OBJ_WATCHPOINT
 
 bool
-js::WatchHandler(JSContext* cx, JSObject* obj_, jsid id_, JS::Value old,
+js::WatchHandler(JSContext* cx, JSObject* obj_, jsid id_, const JS::Value& old,
                  JS::Value* nvp, void* closure)
 {
     RootedObject obj(cx, obj_);
     RootedId id(cx, id_);
 
     /* Avoid recursion on (obj, id) already being watched on cx. */
     AutoResolving resolving(cx, obj, id, AutoResolving::WATCH);
     if (resolving.alreadyStarted())
--- a/js/src/builtin/Object.h
+++ b/js/src/builtin/Object.h
@@ -74,14 +74,14 @@ IdToStringOrSymbol(JSContext* cx, JS::Ha
 
 #if JS_HAS_TOSOURCE
 // Object.prototype.toSource. Function.prototype.toSource and uneval use this.
 JSString*
 ObjectToSource(JSContext* cx, JS::HandleObject obj);
 #endif // JS_HAS_TOSOURCE
 
 extern MOZ_MUST_USE bool
-WatchHandler(JSContext* cx, JSObject* obj, jsid id, JS::Value old,
+WatchHandler(JSContext* cx, JSObject* obj, jsid id, const JS::Value& old,
              JS::Value* nvp, void* closure);
 
 } /* namespace js */
 
 #endif /* builtin_Object_h */
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -1174,17 +1174,17 @@ js::regexp_test_no_statics(JSContext* cx
     size_t ignored = 0;
     RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, 0,
                                            nullptr, &ignored, DontUpdateRegExpStatics);
     args.rval().setBoolean(status == RegExpRunStatus_Success);
     return status != RegExpRunStatus_Error;
 }
 
 static void
-GetParen(JSLinearString* matched, JS::Value capture, JSSubString* out)
+GetParen(JSLinearString* matched, const JS::Value& capture, JSSubString* out)
 {
     if (capture.isUndefined()) {
         out->initEmpty(matched);
         return;
     }
     JSLinearString& captureLinear = capture.toString()->asLinear();
     out->init(&captureLinear, 0, captureLinear.length());
 }
--- a/js/src/ds/IdValuePair.h
+++ b/js/src/ds/IdValuePair.h
@@ -22,17 +22,17 @@ struct IdValuePair
     jsid id;
 
     IdValuePair()
       : value(UndefinedValue()), id(JSID_EMPTY)
     {}
     explicit IdValuePair(jsid idArg)
       : value(UndefinedValue()), id(idArg)
     {}
-    IdValuePair(jsid idArg, Value valueArg)
+    IdValuePair(jsid idArg, const Value& valueArg)
       : value(valueArg), id(idArg)
     {}
 
     void trace(JSTracer* trc) {
         TraceRoot(trc, &value, "IdValuePair::value");
         TraceRoot(trc, &id, "IdValuePair::id");
     }
 };
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -28,17 +28,17 @@ class ParseNode;
 template <typename ParseHandler> class Parser;
 class SharedContext;
 class TokenStream;
 
 class CGConstList {
     Vector<Value> list;
   public:
     explicit CGConstList(ExclusiveContext* cx) : list(cx) {}
-    MOZ_MUST_USE bool append(Value v) {
+    MOZ_MUST_USE bool append(const Value& v) {
         MOZ_ASSERT_IF(v.isString(), v.toString()->isAtom());
         return list.append(v);
     }
     size_t length() const { return list.length(); }
     void finish(ConstArray* array);
 };
 
 struct CGObjectList {
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -178,17 +178,17 @@ class JSAPITest
     }
 
 #define CHECK_NULL(actual) \
     do { \
         if (!checkNull(actual, #actual, __FILE__, __LINE__)) \
             return false; \
     } while (false)
 
-    bool checkSame(JS::Value actualArg, JS::Value expectedArg,
+    bool checkSame(const JS::Value& actualArg, const JS::Value& expectedArg,
                    const char* actualExpr, const char* expectedExpr,
                    const char* filename, int lineno) {
         bool same;
         JS::RootedValue actual(cx, actualArg), expected(cx, expectedArg);
         return (JS_SameValue(cx, actual, expected, &same) && same) ||
                fail(JSAPITestString("CHECK_SAME failed: expected JS_SameValue(cx, ") +
                     actualExpr + ", " + expectedExpr + "), got !JS_SameValue(cx, " +
                     jsvalToSource(actual) + ", " + jsvalToSource(expected) + ")", filename, lineno);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -3206,17 +3206,17 @@ JS_SetAllNonReservedSlotsToUndefined(JSC
 
 JS_PUBLIC_API(Value)
 JS_GetReservedSlot(JSObject* obj, uint32_t index)
 {
     return obj->as<NativeObject>().getReservedSlot(index);
 }
 
 JS_PUBLIC_API(void)
-JS_SetReservedSlot(JSObject* obj, uint32_t index, Value value)
+JS_SetReservedSlot(JSObject* obj, uint32_t index, const Value& value)
 {
     obj->as<NativeObject>().setReservedSlot(index, value);
 }
 
 JS_PUBLIC_API(JSObject*)
 JS_NewArrayObject(JSContext* cx, const JS::HandleValueArray& contents)
 {
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
@@ -4539,17 +4539,17 @@ JS::CompileModule(JSContext* cx, const R
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     module.set(frontend::CompileModule(cx, options, srcBuf));
     return !!module;
 }
 
 JS_PUBLIC_API(void)
-JS::SetModuleHostDefinedField(JSObject* module, JS::Value value)
+JS::SetModuleHostDefinedField(JSObject* module, const JS::Value& value)
 {
     module->as<ModuleObject>().setHostDefinedField(value);
 }
 
 JS_PUBLIC_API(JS::Value)
 JS::GetModuleHostDefinedField(JSObject* module)
 {
     return module->as<ModuleObject>().hostDefinedField();
@@ -6154,17 +6154,17 @@ JSErrorReport::initLinebuf(const char16_
 JS_PUBLIC_API(bool)
 JS_ThrowStopIteration(JSContext* cx)
 {
     AssertHeapIsIdle(cx);
     return ThrowStopIteration(cx);
 }
 
 JS_PUBLIC_API(bool)
-JS_IsStopIteration(Value v)
+JS_IsStopIteration(const Value& v)
 {
     return v.isObject() && v.toObject().is<StopIterationObject>();
 }
 
 extern MOZ_NEVER_INLINE JS_PUBLIC_API(void)
 JS_AbortIfWrongThread(JSContext* cx)
 {
     if (!CurrentThreadCanAccessRuntime(cx))
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3470,17 +3470,17 @@ JS_CreateMappedArrayBufferContents(int f
  */
 extern JS_PUBLIC_API(void)
 JS_ReleaseMappedArrayBufferContents(void* contents, size_t length);
 
 extern JS_PUBLIC_API(JS::Value)
 JS_GetReservedSlot(JSObject* obj, uint32_t index);
 
 extern JS_PUBLIC_API(void)
-JS_SetReservedSlot(JSObject* obj, uint32_t index, JS::Value v);
+JS_SetReservedSlot(JSObject* obj, uint32_t index, const JS::Value& v);
 
 
 /************************************************************************/
 
 /*
  * Functions and scripts.
  */
 extern JS_PUBLIC_API(JSFunction*)
@@ -4257,17 +4257,17 @@ extern JS_PUBLIC_API(bool)
 CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
               SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord);
 
 /**
  * Set the [[HostDefined]] field of a source text module record to the given
  * value.
  */
 extern JS_PUBLIC_API(void)
-SetModuleHostDefinedField(JSObject* module, JS::Value value);
+SetModuleHostDefinedField(JSObject* module, const JS::Value& value);
 
 /**
  * Get the [[HostDefined]] field of a source text module record.
  */
 extern JS_PUBLIC_API(JS::Value)
 GetModuleHostDefinedField(JSObject* module);
 
 /*
@@ -5621,17 +5621,17 @@ ExceptionStackOrNull(JS::HandleObject ob
 
 /*
  * Throws a StopIteration exception on cx.
  */
 extern JS_PUBLIC_API(bool)
 JS_ThrowStopIteration(JSContext* cx);
 
 extern JS_PUBLIC_API(bool)
-JS_IsStopIteration(JS::Value v);
+JS_IsStopIteration(const JS::Value& v);
 
 /**
  * A JS context always has an "owner thread". The owner thread is set when the
  * context is created (to the current thread) and practically all entry points
  * into the JS engine check that a context (or anything contained in the
  * context: runtime, compartment, object, etc) is only touched by its owner
  * thread. Embeddings may check this invariant outside the JS engine by calling
  * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -495,17 +495,17 @@ struct JSContext : public js::ExclusiveC
 
     MOZ_MUST_USE
     bool getPendingException(JS::MutableHandleValue rval);
 
     bool isThrowingOutOfMemory();
     bool isThrowingDebuggeeWouldRun();
     bool isClosingGenerator();
 
-    void setPendingException(js::Value v);
+    void setPendingException(const js::Value& v);
 
     void clearPendingException() {
         throwing = false;
         overRecursed_ = false;
         unwrappedException_.setUndefined();
     }
 
     bool isThrowingOverRecursed() const { return throwing && overRecursed_; }
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -364,17 +364,17 @@ inline LifoAlloc&
 ExclusiveContext::typeLifoAlloc()
 {
     return zone()->types.typeLifoAlloc;
 }
 
 }  /* namespace js */
 
 inline void
-JSContext::setPendingException(js::Value v)
+JSContext::setPendingException(const js::Value& v)
 {
     // overRecursed_ is set after the fact by ReportOverRecursed.
     this->overRecursed_ = false;
     this->throwing = true;
     this->unwrappedException_ = v;
     // We don't use assertSameCompartment here to allow
     // js::SetPendingExceptionCrossContext to work.
     MOZ_ASSERT_IF(v.isObject(), v.toObject().compartment() == compartment());
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -79,17 +79,17 @@ class CrossCompartmentKey
     using WrappedType = mozilla::Variant<
         JSObject*,
         JSString*,
         DebuggerAndScript,
         DebuggerAndObject>;
 
     explicit CrossCompartmentKey(JSObject* obj) : wrapped(obj) { MOZ_RELEASE_ASSERT(obj); }
     explicit CrossCompartmentKey(JSString* str) : wrapped(str) { MOZ_RELEASE_ASSERT(str); }
-    explicit CrossCompartmentKey(JS::Value v)
+    explicit CrossCompartmentKey(const JS::Value& v)
       : wrapped(v.isString() ? WrappedType(v.toString()) : WrappedType(&v.toObject()))
     {}
     explicit CrossCompartmentKey(NativeObject* debugger, JSObject* obj, DebuggerObjectKind kind)
       : wrapped(DebuggerAndObject(debugger, obj, kind))
     {
         MOZ_RELEASE_ASSERT(debugger);
         MOZ_RELEASE_ASSERT(obj);
     }
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -2298,17 +2298,17 @@ js::ReportIncompatible(JSContext* cx, co
         }
     }
 }
 
 namespace JS {
 namespace detail {
 
 JS_PUBLIC_API(void)
-CheckIsValidConstructible(Value calleev)
+CheckIsValidConstructible(const Value& calleev)
 {
     JSObject* callee = &calleev.toObject();
     if (callee->is<JSFunction>())
         MOZ_ASSERT(callee->as<JSFunction>().isConstructor());
     else
         MOZ_ASSERT(callee->constructHook() != nullptr);
 }
 
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -810,15 +810,15 @@ fun_call(JSContext* cx, unsigned argc, V
 
 } /* namespace js */
 
 #ifdef DEBUG
 namespace JS {
 namespace detail {
 
 JS_PUBLIC_API(void)
-CheckIsValidConstructible(Value calleev);
+CheckIsValidConstructible(const Value& calleev);
 
 } // namespace detail
 } // namespace JS
 #endif
 
 #endif /* jsfun_h */
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -1569,18 +1569,19 @@ js::StringToNumber(ExclusiveContext* cx,
         return false;
 
     return linearStr->hasLatin1Chars()
            ? CharsToNumber(cx, linearStr->latin1Chars(nogc), str->length(), result)
            : CharsToNumber(cx, linearStr->twoByteChars(nogc), str->length(), result);
 }
 
 bool
-js::ToNumberSlow(ExclusiveContext* cx, Value v, double* out)
+js::ToNumberSlow(ExclusiveContext* cx, const Value& v_, double* out)
 {
+    RootedValue v(cx, v_);
     MOZ_ASSERT(!v.isNumber());
     goto skip_int_double;
     for (;;) {
         if (v.isNumber()) {
             *out = v.toNumber();
             return true;
         }
 
@@ -1607,30 +1608,28 @@ js::ToNumberSlow(ExclusiveContext* cx, V
             MOZ_ASSERT(v.isUndefined());
             *out = GenericNaN();
             return true;
         }
 
         if (!cx->isJSContext())
             return false;
 
-        RootedValue v2(cx, v);
-        if (!ToPrimitive(cx->asJSContext(), JSTYPE_NUMBER, &v2))
+        if (!ToPrimitive(cx->asJSContext(), JSTYPE_NUMBER, &v))
             return false;
-        v = v2;
         if (v.isObject())
             break;
     }
 
     *out = GenericNaN();
     return true;
 }
 
 JS_PUBLIC_API(bool)
-js::ToNumberSlow(JSContext* cx, Value v, double* out)
+js::ToNumberSlow(JSContext* cx, const Value& v, double* out)
 {
     return ToNumberSlow(static_cast<ExclusiveContext*>(cx), v, out);
 }
 
 /*
  * Convert a value to an int8_t, according to the WebIDL rules for byte
  * conversion. Return converted value in *out on success, false on failure.
  */
--- a/js/src/jsnum.h
+++ b/js/src/jsnum.h
@@ -168,17 +168,17 @@ StringToNumber(ExclusiveContext* cx, JSS
 
 /* ES5 9.3 ToNumber, overwriting *vp with the appropriate number value. */
 MOZ_ALWAYS_INLINE MOZ_MUST_USE bool
 ToNumber(JSContext* cx, JS::MutableHandleValue vp)
 {
     if (vp.isNumber())
         return true;
     double d;
-    extern JS_PUBLIC_API(bool) ToNumberSlow(JSContext* cx, Value v, double* dp);
+    extern JS_PUBLIC_API(bool) ToNumberSlow(JSContext* cx, const Value& v, double* dp);
     if (!ToNumberSlow(cx, vp, &d))
         return false;
 
     vp.setNumber(d);
     return true;
 }
 
 MOZ_MUST_USE bool
@@ -253,17 +253,17 @@ ToInteger(JSContext* cx, HandleValue v, 
 {
     if (v.isInt32()) {
         *dp = v.toInt32();
         return true;
     }
     if (v.isDouble()) {
         *dp = v.toDouble();
     } else {
-        extern JS_PUBLIC_API(bool) ToNumberSlow(JSContext* cx, Value v, double* dp);
+        extern JS_PUBLIC_API(bool) ToNumberSlow(JSContext* cx, const Value& v, double* dp);
         if (!ToNumberSlow(cx, v, dp))
             return false;
     }
     *dp = JS::ToInteger(*dp);
     return true;
 }
 
 /* ES6 7.1.15 ToLength, but clamped to the [0,2^32-2] range.  If the
@@ -330,17 +330,17 @@ SafeMul(int32_t one, int32_t two, int32_
 #else
     *res = uint32_t(one) * uint32_t(two);
     int64_t ores = (int64_t)one * (int64_t)two;
     return ores == (int64_t)*res;
 #endif
 }
 
 extern MOZ_MUST_USE bool
-ToNumberSlow(ExclusiveContext* cx, Value v, double* dp);
+ToNumberSlow(ExclusiveContext* cx, const Value& v, double* dp);
 
 // Variant of ToNumber which takes an ExclusiveContext instead of a JSContext.
 // ToNumber is part of the API and can't use ExclusiveContext directly.
 MOZ_ALWAYS_INLINE MOZ_MUST_USE bool
 ToNumber(ExclusiveContext* cx, const Value& v, double* out)
 {
     if (v.isNumber()) {
         *out = v.toNumber();
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -615,17 +615,17 @@ HasObjectValueOf(JSObject* obj, JSContex
             return false;
     }
 
     return IsNativeFunction(v, obj_valueOf);
 }
 
 /* ES6 draft rev 28 (2014 Oct 14) 7.1.14 */
 inline bool
-ToPropertyKey(JSContext* cx, Value argument, MutableHandleId result)
+ToPropertyKey(JSContext* cx, const Value& argument, MutableHandleId result)
 {
     // Steps 1-2.
     RootedValue key(cx, argument);
     if (!ToPrimitive(cx, JSTYPE_STRING, &key))
         return false;
 
     // Steps 3-4.
     return ValueToId<CanGC>(cx, key, result);
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -588,17 +588,17 @@ Str(JSContext* cx, const Value& v, Strin
     if (!IsArray(cx, obj, &isArray))
         return false;
 
     return isArray ? JA(cx, obj, scx) : JO(cx, obj, scx);
 }
 
 /* ES6 24.3.2. */
 bool
-js::Stringify(JSContext* cx, MutableHandleValue vp, JSObject* replacer_, Value space_,
+js::Stringify(JSContext* cx, MutableHandleValue vp, JSObject* replacer_, const Value& space_,
               StringBuffer& sb, StringifyBehavior stringifyBehavior)
 {
     RootedObject replacer(cx, replacer_);
     RootedValue space(cx, space_);
 
     MOZ_ASSERT_IF(stringifyBehavior == StringifyBehavior::RestrictedSafe, space.isNull());
     MOZ_ASSERT_IF(stringifyBehavior == StringifyBehavior::RestrictedSafe, vp.isObject());
     /**
--- a/js/src/json.h
+++ b/js/src/json.h
@@ -26,17 +26,17 @@ enum class StringifyBehavior {
 
 /**
  * If maybeSafely is true, Stringify will attempt to assert the API requirements
  * of JS::ToJSONMaybeSafely as it traverses the graph, and will not try to
  * invoke .toJSON on things as it goes.
  */
 extern bool
 Stringify(JSContext* cx, js::MutableHandleValue vp, JSObject* replacer,
-          Value space, StringBuffer& sb, StringifyBehavior stringifyBehavior);
+          const Value& space, StringBuffer& sb, StringifyBehavior stringifyBehavior);
 
 template <typename CharT>
 extern bool
 ParseJSONWithReviver(JSContext* cx, const mozilla::Range<const CharT> chars,
                      HandleValue reviver, MutableHandleValue vp);
 
 } // namespace js
 
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -1405,17 +1405,17 @@ ExpressionDecompiler::getOutput(char** r
     js_memcpy(*res, sprinter.stringAt(0), len);
     (*res)[len] = 0;
     return true;
 }
 
 }  // anonymous namespace
 
 static bool
-FindStartPC(JSContext* cx, const FrameIter& iter, int spindex, int skipStackHits, Value v,
+FindStartPC(JSContext* cx, const FrameIter& iter, int spindex, int skipStackHits, const Value& v,
             jsbytecode** valuepc)
 {
     jsbytecode* current = *valuepc;
 
     if (spindex == JSDVG_IGNORE_STACK)
         return true;
 
     /*
--- a/js/src/jswatchpoint.h
+++ b/js/src/jswatchpoint.h
@@ -27,17 +27,17 @@ struct WatchKey {
     PreBarrieredId id;
 
     bool operator!=(const WatchKey& other) const {
         return object != other.object || id != other.id;
     }
 };
 
 typedef bool
-(* JSWatchPointHandler)(JSContext* cx, JSObject* obj, jsid id, JS::Value old,
+(* JSWatchPointHandler)(JSContext* cx, JSObject* obj, jsid id, const JS::Value& old,
                         JS::Value* newp, void* closure);
 
 struct Watchpoint {
     JSWatchPointHandler handler;
     PreBarrieredObject closure;  /* This is always marked in minor GCs and so doesn't require a postbarrier. */
     bool held;  /* true if currently running handler */
     Watchpoint(JSWatchPointHandler handler, JSObject* closure, bool held)
       : handler(handler), closure(closure), held(held) {}
--- a/js/src/perf/jsperf.cpp
+++ b/js/src/perf/jsperf.cpp
@@ -271,17 +271,17 @@ RegisterPerfMeasurement(JSContext* cx, H
         !JS_FreezeObject(cx, ctor)) {
         return 0;
     }
 
     return prototype;
 }
 
 PerfMeasurement*
-ExtractPerfMeasurement(Value wrapper)
+ExtractPerfMeasurement(const Value& wrapper)
 {
     if (wrapper.isPrimitive())
         return 0;
 
     // This is what JS_GetInstancePrivate does internally.  We can't
     // call JS_anything from here, because we don't have a JSContext.
     JSObject* obj = wrapper.toObjectOrNull();
     if (obj->getClass() != js::Valueify(&pm_class))
--- a/js/src/perf/jsperf.h
+++ b/js/src/perf/jsperf.h
@@ -121,13 +121,13 @@ extern JS_FRIEND_API(JSObject*)
     RegisterPerfMeasurement(JSContext* cx, JS::HandleObject global);
 
 /*
  * Given a Value which contains an instance of the aforementioned
  * wrapper class, extract the C++ object.  Returns nullptr if the
  * Value is not an instance of the wrapper.
  */
 extern JS_FRIEND_API(PerfMeasurement*)
-    ExtractPerfMeasurement(Value wrapper);
+    ExtractPerfMeasurement(const Value& wrapper);
 
 } // namespace JS
 
 #endif /* perf_jsperf_h */
--- a/js/src/proxy/Proxy.cpp
+++ b/js/src/proxy/Proxy.cpp
@@ -265,17 +265,17 @@ Proxy::hasOwn(JSContext* cx, HandleObjec
     *bp = false; // default result if we refuse to perform this action
     AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return handler->hasOwn(cx, proxy, id, bp);
 }
 
 static Value
-ValueToWindowProxyIfWindow(Value v)
+ValueToWindowProxyIfWindow(const Value& v)
 {
     if (v.isObject())
         return ObjectValue(*ToWindowProxyIfWindow(&v.toObject()));
     return v;
 }
 
 bool
 Proxy::get(JSContext* cx, HandleObject proxy, HandleValue receiver_, HandleId id,
@@ -769,17 +769,17 @@ js::NewProxyObject(JSContext* cx, const 
         MOZ_ASSERT(!proto_);
         proto_ = TaggedProto::LazyProto;
     }
 
     return ProxyObject::New(cx, handler, priv, TaggedProto(proto_), options);
 }
 
 void
-ProxyObject::renew(JSContext* cx, const BaseProxyHandler* handler, Value priv)
+ProxyObject::renew(JSContext* cx, const BaseProxyHandler* handler, const Value& priv)
 {
     MOZ_ASSERT(!IsInsideNursery(this));
     MOZ_ASSERT_IF(IsCrossCompartmentWrapper(this), IsDeadProxyObject(this));
     MOZ_ASSERT(getClass() == &ProxyObject::proxyClass);
     MOZ_ASSERT(!IsWindowProxy(this));
     MOZ_ASSERT(hasDynamicPrototype());
 
     setHandler(handler);
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1439,17 +1439,17 @@ Debugger::resultToCompletion(JSContext* 
         cx->clearPendingException();
     } else {
         *status = JSTRAP_ERROR;
         value.setUndefined();
     }
 }
 
 bool
-Debugger::newCompletionValue(JSContext* cx, JSTrapStatus status, Value value_,
+Debugger::newCompletionValue(JSContext* cx, JSTrapStatus status, const Value& value_,
                              MutableHandleValue result)
 {
     /*
      * We must be in the debugger's compartment, since that's where we want
      * to construct the completion value.
      */
     assertSameCompartment(cx, object.get());
     assertSameCompartment(cx, value_);
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -1014,17 +1014,17 @@ class Debugger : private mozilla::Linked
     static void resultToCompletion(JSContext* cx, bool ok, const Value& rv,
                                    JSTrapStatus* status, MutableHandleValue value);
 
     /*
      * Set |*result| to a JavaScript completion value corresponding to |status|
      * and |value|. |value| should be the return value or exception value, not
      * wrapped as a debuggee value. |cx| must be in the debugger compartment.
      */
-    MOZ_MUST_USE bool newCompletionValue(JSContext* cx, JSTrapStatus status, Value value,
+    MOZ_MUST_USE bool newCompletionValue(JSContext* cx, JSTrapStatus status, const Value& value,
                                          MutableHandleValue result);
 
     /*
      * Precondition: we are in the debuggee compartment (ac is entered) and ok
      * is true if the operation in the debuggee compartment succeeded, false on
      * error or exception.
      *
      * Postcondition: we are in the debugger compartment, having called
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -1711,17 +1711,17 @@ class DebugEnvironmentProxyHandler : pub
      * initialized by JSOP_FUNCTIONTHIS, the this-binding will be |undefined|.
      * In that case, we have to call createMissingThis to initialize the
      * this-binding.
      *
      * Note that an |undefined| this-binding is perfectly valid in strict-mode
      * code, but that's fine: createMissingThis will do the right thing in that
      * case.
      */
-    static bool isMaybeUninitializedThisValue(JSContext* cx, jsid id, Value v)
+    static bool isMaybeUninitializedThisValue(JSContext* cx, jsid id, const Value& v)
     {
         return isThis(cx, id) && v.isUndefined();
     }
 
     /*
      * Create a missing arguments object. If the function returns true but
      * argsObj is null, it means the env is dead.
      */
--- a/js/src/vm/GeneratorObject.h
+++ b/js/src/vm/GeneratorObject.h
@@ -111,17 +111,17 @@ class GeneratorObject : public NativeObj
     }
 
     bool isConstructing() const {
         return getFixedSlot(NEWTARGET_SLOT).isObject();
     }
     const Value& newTarget() const {
         return getFixedSlot(NEWTARGET_SLOT);
     }
-    void setNewTarget(Value newTarget) {
+    void setNewTarget(const Value& newTarget) {
         setFixedSlot(NEWTARGET_SLOT, newTarget);
     }
 
 
     // The yield index slot is abused for a few purposes.  It's undefined if
     // it hasn't been set yet (before the initial yield), and null if the
     // generator is closed. If the generator is running, the yield index is
     // YIELD_INDEX_RUNNING. If the generator is in that bizarre "closing"
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -404,17 +404,17 @@ GlobalObject::getOrCreateEval(JSContext*
 {
     if (!global->getOrCreateObjectPrototype(cx))
         return false;
     eval.set(&global->getSlot(EVAL).toObject());
     return true;
 }
 
 bool
-GlobalObject::valueIsEval(Value val)
+GlobalObject::valueIsEval(const Value& val)
 {
     Value eval = getSlot(EVAL);
     return eval.isObject() && eval == val;
 }
 
 /* static */ bool
 GlobalObject::initStandardClasses(JSContext* cx, Handle<GlobalObject*> global)
 {
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -700,17 +700,17 @@ class GlobalObject : public NativeObject
         //return warnOnceAbout(cx, obj, WARN_WATCH_DEPRECATED, JSMSG_OBJECT_WATCH_DEPRECATED);
         return true;
     }
 
     static bool getOrCreateEval(JSContext* cx, Handle<GlobalObject*> global,
                                 MutableHandleObject eval);
 
     // Infallibly test whether the given value is the eval function for this global.
-    bool valueIsEval(Value val);
+    bool valueIsEval(const Value& val);
 
     // Implemented in jsiter.cpp.
     static bool initIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
     static bool initArrayIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
     static bool initStringIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
 
     // Implemented in vm/GeneratorObject.cpp.
     static bool initLegacyGeneratorProto(JSContext* cx, Handle<GlobalObject*> global);
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -228,17 +228,17 @@ class RunState
     InvokeState* asInvoke() const {
         MOZ_ASSERT(isInvoke());
         return (InvokeState*)this;
     }
 
     JS::HandleScript script() const { return script_; }
 
     virtual InterpreterFrame* pushInterpreterFrame(JSContext* cx) = 0;
-    virtual void setReturnValue(Value v) = 0;
+    virtual void setReturnValue(const Value& v) = 0;
 
     bool maybeCreateThisForConstructor(JSContext* cx);
 
   private:
     RunState(const RunState& other) = delete;
     RunState(const ExecuteState& other) = delete;
     RunState(const InvokeState& other) = delete;
     void operator=(const RunState& other) = delete;
@@ -264,17 +264,17 @@ class ExecuteState : public RunState
     { }
 
     Value newTarget() { return newTargetValue_; }
     JSObject* environmentChain() const { return envChain_; }
     bool isDebuggerEval() const { return !!evalInFrame_; }
 
     virtual InterpreterFrame* pushInterpreterFrame(JSContext* cx);
 
-    virtual void setReturnValue(Value v) {
+    virtual void setReturnValue(const Value& v) {
         if (result_)
             *result_ = v;
     }
 };
 
 // Data to invoke a function.
 class InvokeState final : public RunState
 {
@@ -293,17 +293,17 @@ class InvokeState final : public RunStat
     bool createSingleton() const { return createSingleton_; }
     void setCreateSingleton() { createSingleton_ = true; }
 
     bool constructing() const { return construct_; }
     const CallArgs& args() const { return args_; }
 
     virtual InterpreterFrame* pushInterpreterFrame(JSContext* cx);
 
-    virtual void setReturnValue(Value v) {
+    virtual void setReturnValue(const Value& v) {
         args_.rval().set(v);
     }
 };
 
 extern bool
 RunScript(JSContext* cx, RunState& state);
 
 extern bool
--- a/js/src/vm/NativeObject.h
+++ b/js/src/vm/NativeObject.h
@@ -324,17 +324,17 @@ extern HeapSlot* const emptyObjectElemen
 struct Class;
 class GCMarker;
 class Shape;
 
 class NewObjectCache;
 
 #ifdef DEBUG
 static inline bool
-IsObjectValueInCompartment(Value v, JSCompartment* comp);
+IsObjectValueInCompartment(const Value& v, JSCompartment* comp);
 #endif
 
 // Operations which change an object's dense elements can either succeed, fail,
 // or be unable to complete. For native objects, the latter is used when the
 // object's elements must become sparse instead. The enum below is used for
 // such operations, and for similar operations on unboxed arrays and methods
 // that work on both kinds of objects.
 enum class DenseElementResult {
@@ -1303,17 +1303,17 @@ NativeObject::privateWriteBarrierPre(voi
 {
     JS::shadow::Zone* shadowZone = this->shadowZoneFromAnyThread();
     if (shadowZone->needsIncrementalBarrier() && *oldval && getClass()->hasTrace())
         getClass()->doTrace(shadowZone->barrierTracer(), this);
 }
 
 #ifdef DEBUG
 static inline bool
-IsObjectValueInCompartment(Value v, JSCompartment* comp)
+IsObjectValueInCompartment(const Value& v, JSCompartment* comp)
 {
     if (!v.isObject())
         return true;
     return v.toObject().compartment() == comp;
 }
 #endif
 
 
--- a/js/src/vm/ProxyObject.h
+++ b/js/src/vm/ProxyObject.h
@@ -99,17 +99,17 @@ class ProxyObject : public ShapedObject
         return clasp->isProxy() &&
                clasp->isTrace(proxy_Trace) &&
                !clasp->getCall() && !clasp->getConstruct();
     }
 
   public:
     static unsigned grayLinkExtraSlot(JSObject* obj);
 
-    void renew(JSContext* cx, const BaseProxyHandler* handler, Value priv);
+    void renew(JSContext* cx, const BaseProxyHandler* handler, const Value& priv);
 
     static void trace(JSTracer* trc, JSObject* obj);
 
     void nuke(const BaseProxyHandler* handler);
 
     // There is no class_ member to force specialization of JSObject::is<T>().
     // The implementation in JSObject is incorrect for proxies since it doesn't
     // take account of the handler type.
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -924,18 +924,18 @@ class AnyInvokeArgs : public JS::CallArg
 {
 };
 
 /** Base class for all function construction args. */
 class AnyConstructArgs : public JS::CallArgs
 {
     // Only js::Construct (or internal methods that call the qualified CallArgs
     // versions) should do these things!
-    void setCallee(Value v) = delete;
-    void setThis(Value v) = delete;
+    void setCallee(const Value& v) = delete;
+    void setThis(const Value& v) = delete;
     MutableHandleValue newTarget() const = delete;
     MutableHandleValue rval() const = delete;
 };
 
 namespace detail {
 
 /** Function call/construct args of statically-unknown count. */
 template <MaybeConstruct Construct>
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -332,17 +332,17 @@ struct JSStructuredCloneReader {
 };
 
 struct JSStructuredCloneWriter {
   public:
     explicit JSStructuredCloneWriter(JSContext* cx,
                                      JS::StructuredCloneScope scope,
                                      const JSStructuredCloneCallbacks* cb,
                                      void* cbClosure,
-                                     Value tVal)
+                                     const Value& tVal)
         : out(cx), scope(scope), objs(out.context()),
           counts(out.context()), entries(out.context()),
           memory(out.context()), callbacks(cb),
           closure(cbClosure), transferable(out.context(), tVal),
           transferableObjects(out.context(), GCHashSet<JSObject*>(cx))
     {}
 
     ~JSStructuredCloneWriter();
@@ -482,17 +482,17 @@ ReportDataCloneError(JSContext* cx,
         break;
     }
 }
 
 bool
 WriteStructuredClone(JSContext* cx, HandleValue v, JSStructuredCloneData* bufp,
                      JS::StructuredCloneScope scope,
                      const JSStructuredCloneCallbacks* cb, void* cbClosure,
-                     Value transferable)
+                     const Value& transferable)
 {
     JSStructuredCloneWriter w(cx, scope, cb, cbClosure, transferable);
     return w.init() && w.write(v) && w.extractBuffer(bufp);
 }
 
 bool
 ReadStructuredClone(JSContext* cx, JSStructuredCloneData& data,
                     JS::StructuredCloneScope scope, MutableHandleValue vp,
--- a/js/src/vm/Symbol.cpp
+++ b/js/src/vm/Symbol.cpp
@@ -124,23 +124,23 @@ js::SymbolDescriptiveString(JSContext* c
     str = sb.finishString();
     if (!str)
         return false;
     result.setString(str);
     return true;
 }
 
 bool
-js::IsSymbolOrSymbolWrapper(Value v)
+js::IsSymbolOrSymbolWrapper(const Value& v)
 {
     return v.isSymbol() || (v.isObject() && v.toObject().is<SymbolObject>());
 }
 
 JS::Symbol*
-js::ToSymbolPrimitive(Value v)
+js::ToSymbolPrimitive(const Value& v)
 {
     MOZ_ASSERT(IsSymbolOrSymbolWrapper(v));
     return v.isSymbol() ? v.toSymbol() : v.toObject().as<SymbolObject>().unbox();
 }
 
 
 JS::ubi::Node::Size
 JS::ubi::Concrete<JS::Symbol>::size(mozilla::MallocSizeOf mallocSizeOf) const
--- a/js/src/vm/Symbol.h
+++ b/js/src/vm/Symbol.h
@@ -127,16 +127,16 @@ class SymbolRegistry : public GCHashSet<
 
 namespace js {
 
 // ES6 rev 27 (2014 Aug 24) 19.4.3.3
 bool
 SymbolDescriptiveString(JSContext* cx, JS::Symbol* sym, JS::MutableHandleValue result);
 
 bool
-IsSymbolOrSymbolWrapper(JS::Value v);
+IsSymbolOrSymbolWrapper(const JS::Value& v);
 
 JS::Symbol*
-ToSymbolPrimitive(JS::Value v);
+ToSymbolPrimitive(const JS::Value& v);
 
 } /* namespace js */
 
 #endif /* vm_Symbol_h */