Bug 1198193 - Change all functions taking CallArgs to take const CallArgs& instead. r=Waldo
authorTill Schneidereit <till@tillschneidereit.net>
Thu, 27 Aug 2015 21:18:37 +0200
changeset 259795 c59612f82a95c89661dbbaf28e04854b7e1c7e19
parent 259781 e574e62e2e2d2fb9d80e96844a3bc10bb24c75d7
child 259796 34bbc3cb3e790ac777d1853a4f9bf16f4102640b
push id17213
push userryanvm@gmail.com
push dateFri, 28 Aug 2015 19:35:54 +0000
treeherderb2g-inbound@7db14bebae91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs1198193
milestone43.0a1
Bug 1198193 - Change all functions taking CallArgs to take const CallArgs& instead. r=Waldo
dom/xbl/nsXBLProtoImplField.cpp
js/public/CallArgs.h
js/public/CallNonGenericMethod.h
js/public/Proxy.h
js/src/asmjs/AsmJSLink.cpp
js/src/builtin/Intl.cpp
js/src/builtin/MapObject.cpp
js/src/builtin/MapObject.h
js/src/builtin/ModuleObject.cpp
js/src/builtin/RegExp.cpp
js/src/builtin/SymbolObject.cpp
js/src/builtin/SymbolObject.h
js/src/builtin/TestingFunctions.cpp
js/src/ctypes/CTypes.cpp
js/src/jit/Ion.cpp
js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
js/src/jsapi.cpp
js/src/jsbool.cpp
js/src/jsdate.cpp
js/src/jsfun.cpp
js/src/jsiter.cpp
js/src/jsnum.cpp
js/src/jsstr.cpp
js/src/jsweakmap.cpp
js/src/jswrapper.h
js/src/proxy/BaseProxyHandler.cpp
js/src/proxy/CrossCompartmentWrapper.cpp
js/src/proxy/DeadObjectProxy.cpp
js/src/proxy/DeadObjectProxy.h
js/src/proxy/DirectProxyHandler.cpp
js/src/proxy/Proxy.cpp
js/src/proxy/Proxy.h
js/src/proxy/ScriptedDirectProxyHandler.cpp
js/src/proxy/ScriptedDirectProxyHandler.h
js/src/proxy/ScriptedIndirectProxyHandler.cpp
js/src/proxy/ScriptedIndirectProxyHandler.h
js/src/proxy/SecurityWrapper.cpp
js/src/vm/ArrayBufferObject.cpp
js/src/vm/ArrayBufferObject.h
js/src/vm/CallNonGenericMethod.cpp
js/src/vm/DateObject.h
js/src/vm/ErrorObject.cpp
js/src/vm/ErrorObject.h
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
js/src/vm/SelfHosting.cpp
js/src/vm/SharedArrayObject.cpp
js/src/vm/SharedArrayObject.h
js/src/vm/SharedTypedArrayObject.cpp
js/src/vm/TypedArrayCommon.h
js/src/vm/TypedArrayObject.cpp
js/src/vm/TypedArrayObject.h
js/xpconnect/wrappers/FilteringWrapper.cpp
js/xpconnect/wrappers/FilteringWrapper.h
js/xpconnect/wrappers/WaiveXrayWrapper.cpp
js/xpconnect/wrappers/WaiveXrayWrapper.h
toolkit/components/finalizationwitness/FinalizationWitnessService.cpp
--- a/dom/xbl/nsXBLProtoImplField.cpp
+++ b/dom/xbl/nsXBLProtoImplField.cpp
@@ -216,17 +216,17 @@ InstallXBLField(JSContext* cx,
 
   if (!::JS_IsExceptionPending(cx)) {
     xpc::Throw(cx, rv);
   }
   return false;
 }
 
 bool
-FieldGetterImpl(JSContext *cx, JS::CallArgs args)
+FieldGetterImpl(JSContext *cx, const JS::CallArgs& args)
 {
   JS::Handle<JS::Value> thisv = args.thisv();
   MOZ_ASSERT(ValueHasISupportsPrivate(thisv));
 
   JS::Rooted<JSObject*> thisObj(cx, &thisv.toObject());
 
   // We should be in the compartment of |this|. If we got here via nativeCall,
   // |this| is not same-compartment with |callee|, and it's possible via
@@ -252,17 +252,17 @@ static bool
 FieldGetter(JSContext *cx, unsigned argc, JS::Value *vp)
 {
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   return JS::CallNonGenericMethod<ValueHasISupportsPrivate, FieldGetterImpl>
                                  (cx, args);
 }
 
 bool
-FieldSetterImpl(JSContext *cx, JS::CallArgs args)
+FieldSetterImpl(JSContext *cx, const JS::CallArgs& args)
 {
   JS::Handle<JS::Value> thisv = args.thisv();
   MOZ_ASSERT(ValueHasISupportsPrivate(thisv));
 
   JS::Rooted<JSObject*> thisObj(cx, &thisv.toObject());
 
   // We should be in the compartment of |this|. If we got here via nativeCall,
   // |this| is not same-compartment with |callee|, and it's possible via
--- a/js/public/CallArgs.h
+++ b/js/public/CallArgs.h
@@ -346,17 +346,17 @@ class MOZ_STACK_CLASS CallArgs : public 
         return args;
     }
 
   public:
     /*
      * Returns true if there are at least |required| arguments passed in. If
      * false, it reports an error message on the context.
      */
-    bool requireAtLeast(JSContext* cx, const char* fnname, unsigned required);
+    bool requireAtLeast(JSContext* cx, const char* fnname, unsigned required) const;
 
 };
 
 MOZ_ALWAYS_INLINE CallArgs
 CallArgsFromVp(unsigned argc, Value* vp)
 {
     return CallArgs::create(argc, vp + 2, vp[1].isMagic(JS_IS_CONSTRUCTING));
 }
--- a/js/public/CallNonGenericMethod.h
+++ b/js/public/CallNonGenericMethod.h
@@ -13,23 +13,23 @@
 
 namespace JS {
 
 // Returns true if |v| is considered an acceptable this-value.
 typedef bool (*IsAcceptableThis)(HandleValue v);
 
 // Implements the guts of a method; guaranteed to be provided an acceptable
 // this-value, as determined by a corresponding IsAcceptableThis method.
-typedef bool (*NativeImpl)(JSContext* cx, CallArgs args);
+typedef bool (*NativeImpl)(JSContext* cx, const CallArgs& args);
 
 namespace detail {
 
 // DON'T CALL THIS DIRECTLY.  It's for use only by CallNonGenericMethod!
 extern JS_PUBLIC_API(bool)
-CallMethodIfWrapped(JSContext* cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
+CallMethodIfWrapped(JSContext* cx, IsAcceptableThis test, NativeImpl impl, const CallArgs& args);
 
 } // namespace detail
 
 // Methods usually act upon |this| objects only from a single global object and
 // compartment.  Sometimes, however, a method must act upon |this| values from
 // multiple global objects or compartments.  In such cases the |this| value a
 // method might see will be wrapped, such that various access to the object --
 // to its class, its private data, its reserved slots, and so on -- will not
@@ -88,27 +88,27 @@ CallMethodIfWrapped(JSContext* cx, IsAcc
 // that succeeds, all well and good.  If it doesn't succeed, a TypeError will
 // be thrown.
 //
 // Note: JS::CallNonGenericMethod will only work correctly if it's called in
 //       tail position in a JSNative.  Do not call it from any other place.
 //
 template<IsAcceptableThis Test, NativeImpl Impl>
 MOZ_ALWAYS_INLINE bool
-CallNonGenericMethod(JSContext* cx, CallArgs args)
+CallNonGenericMethod(JSContext* cx, const CallArgs& args)
 {
     HandleValue thisv = args.thisv();
     if (Test(thisv))
         return Impl(cx, args);
 
     return detail::CallMethodIfWrapped(cx, Test, Impl, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-CallNonGenericMethod(JSContext* cx, IsAcceptableThis Test, NativeImpl Impl, CallArgs args)
+CallNonGenericMethod(JSContext* cx, IsAcceptableThis Test, NativeImpl Impl, const CallArgs& args)
 {
     HandleValue thisv = args.thisv();
     if (Test(thisv))
         return Impl(cx, args);
 
     return detail::CallMethodIfWrapped(cx, Test, Impl, args);
 }
 
--- a/js/public/Proxy.h
+++ b/js/public/Proxy.h
@@ -314,17 +314,18 @@ class JS_FRIEND_API(BaseProxyHandler)
     virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const;
 
     /* SpiderMonkey extensions. */
     virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
                                        MutableHandle<JSPropertyDescriptor> desc) const;
     virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const;
     virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy,
                                               AutoIdVector& props) const;
-    virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, CallArgs args) const;
+    virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
+                            const CallArgs& args) const;
     virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, bool* bp) const;
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext* cx) const;
     virtual const char* className(JSContext* cx, HandleObject proxy) const;
     virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const;
     virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const;
     virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const;
     virtual bool defaultValue(JSContext* cx, HandleObject obj, JSType hint, MutableHandleValue vp) const;
     virtual void trace(JSTracer* trc, JSObject* proxy) const;
@@ -403,17 +404,17 @@ class JS_FRIEND_API(DirectProxyHandler) 
     /* SpiderMonkey extensions. */
     virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
                                        MutableHandle<JSPropertyDescriptor> desc) const override;
     virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id,
                         bool* bp) const override;
     virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy,
                                               AutoIdVector& props) const override;
     virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                            CallArgs args) const override;
+                            const CallArgs& args) const override;
     virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
                              bool* bp) const override;
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
                                JSContext* cx) const override;
     virtual const char* className(JSContext* cx, HandleObject proxy) const override;
     virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
                                    unsigned indent) const override;
     virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
--- a/js/src/asmjs/AsmJSLink.cpp
+++ b/js/src/asmjs/AsmJSLink.cpp
@@ -523,17 +523,17 @@ LinkModuleToHeap(JSContext* cx, AsmJSMod
             return LinkFail(cx, "Unable to prepare ArrayBuffer for asm.js use");
     }
 
     module.initHeap(heap, cx);
     return true;
 }
 
 static bool
-DynamicallyLinkModule(JSContext* cx, CallArgs args, AsmJSModule& module)
+DynamicallyLinkModule(JSContext* cx, const CallArgs& args, AsmJSModule& module)
 {
     module.setIsDynamicallyLinked(cx->runtime());
 
     HandleValue globalVal = args.get(0);
     HandleValue importVal = args.get(1);
     HandleValue bufferVal = args.get(2);
 
     Rooted<ArrayBufferObjectMaybeShared*> heap(cx);
@@ -602,17 +602,17 @@ DynamicallyLinkModule(JSContext* cx, Cal
 
     // See the comment in AllocateExecutableMemory.
     ExecutableAllocator::makeExecutable(module.codeBase(), module.codeBytes());
 
     return true;
 }
 
 static bool
-ChangeHeap(JSContext* cx, AsmJSModule& module, CallArgs args)
+ChangeHeap(JSContext* cx, AsmJSModule& module, const CallArgs& args)
 {
     HandleValue bufferArg = args.get(0);
     if (!IsArrayBuffer(bufferArg)) {
         ReportIncompatible(cx, args);
         return false;
     }
 
     Rooted<ArrayBufferObject*> newBuffer(cx, &bufferArg.toObject().as<ArrayBufferObject>());
@@ -814,17 +814,18 @@ NewExportedFunction(JSContext* cx, const
         return nullptr;
 
     fun->setExtendedSlot(ASM_MODULE_SLOT, ObjectValue(*moduleObj));
     fun->setExtendedSlot(ASM_EXPORT_INDEX_SLOT, Int32Value(exportIndex));
     return fun;
 }
 
 static bool
-HandleDynamicLinkFailure(JSContext* cx, CallArgs args, AsmJSModule& module, HandlePropertyName name)
+HandleDynamicLinkFailure(JSContext* cx, const CallArgs& args, AsmJSModule& module,
+                         HandlePropertyName name)
 {
     if (cx->isExceptionPending())
         return false;
 
     // Source discarding is allowed to affect JS semantics because it is never
     // enabled for normal JS content.
     bool haveSource = module.scriptSource()->hasSourceData();
     if (!haveSource && !JSScript::loadSource(cx, module.scriptSource(), &haveSource))
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -596,17 +596,17 @@ static const JSFunctionSpec collator_met
     JS_FS_END
 };
 
 /**
  * Collator constructor.
  * Spec: ECMAScript Internationalization API Specification, 10.1
  */
 static bool
-Collator(JSContext* cx, CallArgs args, bool construct)
+Collator(JSContext* cx, const CallArgs& args, bool construct)
 {
     RootedObject obj(cx);
 
     if (!construct) {
         // 10.1.2.1 step 3
         JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
         if (!intl)
             return false;
@@ -1091,17 +1091,17 @@ static const JSFunctionSpec numberFormat
     JS_FS_END
 };
 
 /**
  * NumberFormat constructor.
  * Spec: ECMAScript Internationalization API Specification, 11.1
  */
 static bool
-NumberFormat(JSContext* cx, CallArgs args, bool construct)
+NumberFormat(JSContext* cx, const CallArgs& args, bool construct)
 {
     RootedObject obj(cx);
 
     if (!construct) {
         // 11.1.2.1 step 3
         JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
         if (!intl)
             return false;
@@ -1561,17 +1561,17 @@ static const JSFunctionSpec dateTimeForm
     JS_FS_END
 };
 
 /**
  * DateTimeFormat constructor.
  * Spec: ECMAScript Internationalization API Specification, 12.1
  */
 static bool
-DateTimeFormat(JSContext* cx, CallArgs args, bool construct)
+DateTimeFormat(JSContext* cx, const CallArgs& args, bool construct)
 {
     RootedObject obj(cx);
 
     if (!construct) {
         // 12.1.2.1 step 3
         JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
         if (!intl)
             return false;
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -561,17 +561,17 @@ MapObject::size(JSContext* cx, HandleObj
 {
     ValueMap& map = extract(obj);
     static_assert(sizeof(map.count()) <= sizeof(uint32_t),
                   "map count must be precisely representable as a JS number");
     return map.count();
 }
 
 bool
-MapObject::size_impl(JSContext* cx, CallArgs args)
+MapObject::size_impl(JSContext* cx, const CallArgs& args)
 {
     RootedObject obj(cx, &args.thisv().toObject());
     args.rval().setNumber(size(cx, obj));
     return true;
 }
 
 bool
 MapObject::size(JSContext* cx, unsigned argc, Value* vp)
@@ -594,17 +594,17 @@ MapObject::get(JSContext* cx, HandleObje
         rval.set(p->value);
     else
         rval.setUndefined();
 
     return true;
 }
 
 bool
-MapObject::get_impl(JSContext* cx, CallArgs args)
+MapObject::get_impl(JSContext* cx, const CallArgs& args)
 {
     RootedObject obj(cx, &args.thisv().toObject());
     return get(cx, obj, args.get(0), args.rval());
 }
 
 bool
 MapObject::get(JSContext* cx, unsigned argc, Value* vp)
 {
@@ -621,17 +621,17 @@ MapObject::has(JSContext* cx, HandleObje
     if (!k.setValue(cx, key))
         return false;
 
     *rval = map.has(k);
     return true;
 }
 
 bool
-MapObject::has_impl(JSContext* cx, CallArgs args)
+MapObject::has_impl(JSContext* cx, const CallArgs& args)
 {
     bool found;
     RootedObject obj(cx, &args.thisv().toObject());
     if (has(cx, obj, args.get(0), &found)) {
         args.rval().setBoolean(found);
         return true;
     }
     return false;
@@ -640,17 +640,17 @@ MapObject::has_impl(JSContext* cx, CallA
 bool
 MapObject::has(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<MapObject::is, MapObject::has_impl>(cx, args);
 }
 
 bool
-MapObject::set_impl(JSContext* cx, CallArgs args)
+MapObject::set_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(MapObject::is(args.thisv()));
 
     ValueMap& map = extract(args);
     ARG0_KEY(cx, args, key);
     RelocatableValue rval(args.get(1));
     if (!map.put(key, rval)) {
         ReportOutOfMemory(cx);
@@ -680,17 +680,17 @@ MapObject::delete_(JSContext *cx, Handle
     if (!map.remove(k, rval)) {
         ReportOutOfMemory(cx);
         return false;
     }
     return true;
 }
 
 bool
-MapObject::delete_impl(JSContext *cx, CallArgs args)
+MapObject::delete_impl(JSContext *cx, const CallArgs& args)
 {
     // MapObject::mark does not mark deleted entries. Incremental GC therefore
     // requires that no RelocatableValue objects pointing to heap values be
     // left alive in the ValueMap.
     //
     // OrderedHashMap::remove() doesn't destroy the removed entry. It merely
     // calls OrderedHashMap::MapOps::makeEmpty. But that is sufficient, because
     // makeEmpty clears the value by doing e->value = Value(), and in the case
@@ -721,63 +721,63 @@ MapObject::iterator(JSContext* cx, Itera
                     HandleObject obj, MutableHandleValue iter)
 {
     ValueMap& map = extract(obj);
     Rooted<JSObject*> iterobj(cx, MapIteratorObject::create(cx, obj, &map, kind));
     return iterobj && (iter.setObject(*iterobj), true);
 }
 
 bool
-MapObject::iterator_impl(JSContext* cx, CallArgs args, IteratorKind kind)
+MapObject::iterator_impl(JSContext* cx, const CallArgs& args, IteratorKind kind)
 {
     RootedObject obj(cx, &args.thisv().toObject());
     return iterator(cx, kind, obj, args.rval());
 }
 
 bool
-MapObject::keys_impl(JSContext* cx, CallArgs args)
+MapObject::keys_impl(JSContext* cx, const CallArgs& args)
 {
     return iterator_impl(cx, args, Keys);
 }
 
 bool
 MapObject::keys(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod(cx, is, keys_impl, args);
 }
 
 bool
-MapObject::values_impl(JSContext* cx, CallArgs args)
+MapObject::values_impl(JSContext* cx, const CallArgs& args)
 {
     return iterator_impl(cx, args, Values);
 }
 
 bool
 MapObject::values(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod(cx, is, values_impl, args);
 }
 
 bool
-MapObject::entries_impl(JSContext* cx, CallArgs args)
+MapObject::entries_impl(JSContext* cx, const CallArgs& args)
 {
     return iterator_impl(cx, args, Entries);
 }
 
 bool
 MapObject::entries(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod(cx, is, entries_impl, args);
 }
 
 bool
-MapObject::clear_impl(JSContext* cx, CallArgs args)
+MapObject::clear_impl(JSContext* cx, const CallArgs& args)
 {
     RootedObject obj(cx, &args.thisv().toObject());
     args.rval().setUndefined();
     return clear(cx, obj);
 }
 
 bool
 MapObject::clear(JSContext* cx, unsigned argc, Value* vp)
@@ -819,17 +819,17 @@ class SetIteratorObject : public NativeO
                                      SetObject::IteratorKind kind);
     static bool next(JSContext* cx, unsigned argc, Value* vp);
     static void finalize(FreeOp* fop, JSObject* obj);
 
   private:
     static inline bool is(HandleValue v);
     inline ValueSet::Range* range();
     inline SetObject::IteratorKind kind() const;
-    static bool next_impl(JSContext* cx, CallArgs args);
+    static bool next_impl(JSContext* cx, const CallArgs& args);
 };
 
 } /* anonymous namespace */
 
 const Class SetIteratorObject::class_ = {
     "Set Iterator",
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(SetIteratorObject::SlotCount),
@@ -913,17 +913,17 @@ SetIteratorObject::finalize(FreeOp* fop,
 
 bool
 SetIteratorObject::is(HandleValue v)
 {
     return v.isObject() && v.toObject().is<SetIteratorObject>();
 }
 
 bool
-SetIteratorObject::next_impl(JSContext* cx, CallArgs args)
+SetIteratorObject::next_impl(JSContext* cx, const CallArgs& args)
 {
     SetIteratorObject& thisobj = args.thisv().toObject().as<SetIteratorObject>();
     ValueSet::Range* range = thisobj.range();
     RootedValue value(cx);
     bool done;
 
     if (!range || range->empty()) {
         js_delete(range);
@@ -1201,17 +1201,17 @@ SetObject::size(JSContext *cx, HandleObj
     MOZ_ASSERT(SetObject::is(obj));
     ValueSet &set = extract(obj);
     static_assert(sizeof(set.count()) <= sizeof(uint32_t),
                   "set count must be precisely representable as a JS number");
     return set.count();
 }
 
 bool
-SetObject::size_impl(JSContext* cx, CallArgs args)
+SetObject::size_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     ValueSet& set = extract(args);
     static_assert(sizeof(set.count()) <= sizeof(uint32_t),
                   "set count must be precisely representable as a JS number");
     args.rval().setNumber(set.count());
     return true;
@@ -1220,17 +1220,17 @@ SetObject::size_impl(JSContext* cx, Call
 bool
 SetObject::size(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<SetObject::is, SetObject::size_impl>(cx, args);
 }
 
 bool
-SetObject::has_impl(JSContext* cx, CallArgs args)
+SetObject::has_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     ValueSet& set = extract(args);
     ARG0_KEY(cx, args, key);
     args.rval().setBoolean(set.has(key));
     return true;
 }
@@ -1253,17 +1253,17 @@ SetObject::has(JSContext *cx, HandleObje
 bool
 SetObject::has(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<SetObject::is, SetObject::has_impl>(cx, args);
 }
 
 bool
-SetObject::add_impl(JSContext* cx, CallArgs args)
+SetObject::add_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     ValueSet& set = extract(args);
     ARG0_KEY(cx, args, key);
     if (!set.put(key)) {
         ReportOutOfMemory(cx);
         return false;
@@ -1294,17 +1294,17 @@ SetObject::delete_(JSContext *cx, Handle
     if (!set.remove(k, rval)) {
         ReportOutOfMemory(cx);
         return false;
     }
     return true;
 }
 
 bool
-SetObject::delete_impl(JSContext *cx, CallArgs args)
+SetObject::delete_impl(JSContext *cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     ValueSet& set = extract(args);
     ARG0_KEY(cx, args, key);
     bool found;
     if (!set.remove(key, &found)) {
         ReportOutOfMemory(cx);
@@ -1327,42 +1327,42 @@ SetObject::iterator(JSContext *cx, Itera
 {
     MOZ_ASSERT(SetObject::is(obj));
     ValueSet &set = extract(obj);
     Rooted<JSObject*> iterobj(cx, SetIteratorObject::create(cx, obj, &set, kind));
     return iterobj && (iter.setObject(*iterobj), true);
 }
 
 bool
-SetObject::iterator_impl(JSContext *cx, CallArgs args, IteratorKind kind)
+SetObject::iterator_impl(JSContext *cx, const CallArgs& args, IteratorKind kind)
 {
     Rooted<SetObject*> setobj(cx, &args.thisv().toObject().as<SetObject>());
     ValueSet& set = *setobj->getData();
     Rooted<JSObject*> iterobj(cx, SetIteratorObject::create(cx, setobj, &set, kind));
     if (!iterobj)
         return false;
     args.rval().setObject(*iterobj);
     return true;
 }
 
 bool
-SetObject::values_impl(JSContext* cx, CallArgs args)
+SetObject::values_impl(JSContext* cx, const CallArgs& args)
 {
     return iterator_impl(cx, args, Values);
 }
 
 bool
 SetObject::values(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod(cx, is, values_impl, args);
 }
 
 bool
-SetObject::entries_impl(JSContext* cx, CallArgs args)
+SetObject::entries_impl(JSContext* cx, const CallArgs& args)
 {
     return iterator_impl(cx, args, Entries);
 }
 
 bool
 SetObject::entries(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
@@ -1377,17 +1377,17 @@ SetObject::clear(JSContext *cx, HandleOb
     if (!set.clear()) {
         ReportOutOfMemory(cx);
         return false;
     }
     return true;
 }
 
 bool
-SetObject::clear_impl(JSContext *cx, CallArgs args)
+SetObject::clear_impl(JSContext *cx, const CallArgs& args)
 {
     Rooted<SetObject*> setobj(cx, &args.thisv().toObject().as<SetObject>());
     if (!setobj->getData()->clear()) {
         ReportOutOfMemory(cx);
         return false;
     }
     args.rval().setUndefined();
     return true;
--- a/js/src/builtin/MapObject.h
+++ b/js/src/builtin/MapObject.h
@@ -117,33 +117,33 @@ class MapObject : public NativeObject {
     static ValueMap & extract(CallReceiver call);
     static void mark(JSTracer* trc, JSObject* obj);
     static void finalize(FreeOp* fop, JSObject* obj);
     static bool construct(JSContext* cx, unsigned argc, Value* vp);
 
     static bool is(HandleValue v);
     static bool is(HandleObject o);
 
-    static bool iterator_impl(JSContext* cx, CallArgs args, IteratorKind kind);
+    static bool iterator_impl(JSContext* cx, const CallArgs& args, IteratorKind kind);
 
-    static bool size_impl(JSContext* cx, CallArgs args);
+    static bool size_impl(JSContext* cx, const CallArgs& args);
     static bool size(JSContext* cx, unsigned argc, Value* vp);
-    static bool get_impl(JSContext* cx, CallArgs args);
+    static bool get_impl(JSContext* cx, const CallArgs& args);
     static bool get(JSContext* cx, unsigned argc, Value* vp);
-    static bool has_impl(JSContext* cx, CallArgs args);
-    static bool set_impl(JSContext* cx, CallArgs args);
+    static bool has_impl(JSContext* cx, const CallArgs& args);
+    static bool set_impl(JSContext* cx, const CallArgs& args);
     static bool set(JSContext* cx, unsigned argc, Value* vp);
-    static bool delete_impl(JSContext* cx, CallArgs args);
+    static bool delete_impl(JSContext* cx, const CallArgs& args);
     static bool delete_(JSContext* cx, unsigned argc, Value* vp);
-    static bool keys_impl(JSContext* cx, CallArgs args);
+    static bool keys_impl(JSContext* cx, const CallArgs& args);
     static bool keys(JSContext* cx, unsigned argc, Value* vp);
-    static bool values_impl(JSContext* cx, CallArgs args);
+    static bool values_impl(JSContext* cx, const CallArgs& args);
     static bool values(JSContext* cx, unsigned argc, Value* vp);
-    static bool entries_impl(JSContext* cx, CallArgs args);
-    static bool clear_impl(JSContext* cx, CallArgs args);
+    static bool entries_impl(JSContext* cx, const CallArgs& args);
+    static bool clear_impl(JSContext* cx, const CallArgs& args);
     static bool clear(JSContext* cx, unsigned argc, Value* vp);
 };
 
 class MapIteratorObject : public NativeObject
 {
   public:
     static const Class class_;
 
@@ -197,29 +197,29 @@ class SetObject : public NativeObject {
     static ValueSet & extract(CallReceiver call);
     static void mark(JSTracer* trc, JSObject* obj);
     static void finalize(FreeOp* fop, JSObject* obj);
     static bool construct(JSContext* cx, unsigned argc, Value* vp);
 
     static bool is(HandleValue v);
     static bool is(HandleObject o);
 
-    static bool iterator_impl(JSContext* cx, CallArgs args, IteratorKind kind);
+    static bool iterator_impl(JSContext* cx, const CallArgs& args, IteratorKind kind);
 
-    static bool size_impl(JSContext* cx, CallArgs args);
+    static bool size_impl(JSContext* cx, const CallArgs& args);
     static bool size(JSContext* cx, unsigned argc, Value* vp);
-    static bool has_impl(JSContext* cx, CallArgs args);
-    static bool add_impl(JSContext* cx, CallArgs args);
+    static bool has_impl(JSContext* cx, const CallArgs& args);
+    static bool add_impl(JSContext* cx, const CallArgs& args);
     static bool add(JSContext* cx, unsigned argc, Value* vp);
-    static bool delete_impl(JSContext* cx, CallArgs args);
+    static bool delete_impl(JSContext* cx, const CallArgs& args);
     static bool delete_(JSContext* cx, unsigned argc, Value* vp);
-    static bool values_impl(JSContext* cx, CallArgs args);
-    static bool entries_impl(JSContext* cx, CallArgs args);
+    static bool values_impl(JSContext* cx, const CallArgs& args);
+    static bool entries_impl(JSContext* cx, const CallArgs& args);
     static bool entries(JSContext* cx, unsigned argc, Value* vp);
-    static bool clear_impl(JSContext* cx, CallArgs args);
+    static bool clear_impl(JSContext* cx, const CallArgs& args);
     static bool clear(JSContext* cx, unsigned argc, Value* vp);
 };
 
 extern bool
 InitSelfHostingCollectionIteratorFunctions(JSContext* cx, js::HandleObject obj);
 
 extern JSObject*
 InitMapClass(JSContext* cx, HandleObject obj);
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -12,17 +12,17 @@
 
 using namespace js;
 
 typedef JS::Rooted<ImportEntryObject*> RootedImportEntry;
 typedef JS::Rooted<ExportEntryObject*> RootedExportEntry;
 
 template<typename T, Value ValueGetter(T* obj)>
 static bool
-ModuleValueGetterImpl(JSContext* cx, CallArgs args)
+ModuleValueGetterImpl(JSContext* cx, const CallArgs& args)
 {
     args.rval().set(ValueGetter(&args.thisv().toObject().as<T>()));
     return true;
 }
 
 template<typename T, Value ValueGetter(T* obj)>
 static bool
 ModuleValueGetter(JSContext* cx, unsigned argc, Value* vp)
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -192,17 +192,17 @@ RegExpInitialize(JSContext* cx, RegExpOb
 }
 
 /*
  * ES6 draft rc4 21.2.3.1 steps 5-10.
  * ES6 draft rc4 B.2.5.1 steps 3-5.
  * Compile a new |RegExpShared| for the |RegExpObject|.
  */
 static bool
-CompileRegExpObject(JSContext* cx, RegExpObjectBuilder& builder, CallArgs args,
+CompileRegExpObject(JSContext* cx, RegExpObjectBuilder& builder, const CallArgs& args,
                     RegExpCreationMode creationMode, bool patternIsRegExp=false)
 {
     if (args.length() == 0) {
         /*
          * 21.2.3.1 step 10.
          * B.2.5.1 step 5.
          */
         RegExpStatics* res = cx->global()->getRegExpStatics(cx);
@@ -355,17 +355,17 @@ js::IsRegExp(JSContext* cx, HandleValue 
 
     /* Steps 5-6. */
     *result = IsObjectWithClass(value, ESClass_RegExp, cx);
     return true;
 }
 
 /* ES6 draft rc4 B.2.5.1. */
 MOZ_ALWAYS_INLINE bool
-regexp_compile_impl(JSContext* cx, CallArgs args)
+regexp_compile_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsRegExpObject(args.thisv()));
 
     /* Steps 3-5. */
     RegExpObjectBuilder builder(cx, &args.thisv().toObject().as<RegExpObject>());
     return CompileRegExpObject(cx, builder, args, CreateForCompile);
 }
 
@@ -432,17 +432,17 @@ js::regexp_construct_no_statics(JSContex
         return false;
 
     args.rval().setObject(*reobj);
     return true;
 }
 
 /* ES6 draft rev32 21.2.5.4. */
 MOZ_ALWAYS_INLINE bool
-regexp_global_impl(JSContext* cx, CallArgs args)
+regexp_global_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsRegExpObject(args.thisv()));
     Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
 
     /* Steps 4-6. */
     args.rval().setBoolean(reObj->global());
     return true;
 }
@@ -452,17 +452,17 @@ regexp_global(JSContext* cx, unsigned ar
 {
     /* Steps 1-3. */
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsRegExpObject, regexp_global_impl>(cx, args);
 }
 
 /* ES6 draft rev32 21.2.5.5. */
 MOZ_ALWAYS_INLINE bool
-regexp_ignoreCase_impl(JSContext* cx, CallArgs args)
+regexp_ignoreCase_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsRegExpObject(args.thisv()));
     Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
 
     /* Steps 4-6. */
     args.rval().setBoolean(reObj->ignoreCase());
     return true;
 }
@@ -472,17 +472,17 @@ regexp_ignoreCase(JSContext* cx, unsigne
 {
     /* Steps 1-3. */
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsRegExpObject, regexp_ignoreCase_impl>(cx, args);
 }
 
 /* ES6 draft rev32 21.2.5.7. */
 MOZ_ALWAYS_INLINE bool
-regexp_multiline_impl(JSContext* cx, CallArgs args)
+regexp_multiline_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsRegExpObject(args.thisv()));
     Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
 
     /* Steps 4-6. */
     args.rval().setBoolean(reObj->multiline());
     return true;
 }
@@ -492,17 +492,17 @@ regexp_multiline(JSContext* cx, unsigned
 {
     /* Steps 1-3. */
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsRegExpObject, regexp_multiline_impl>(cx, args);
 }
 
 /* ES6 draft rev32 21.2.5.10. */
 MOZ_ALWAYS_INLINE bool
-regexp_source_impl(JSContext* cx, CallArgs args)
+regexp_source_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsRegExpObject(args.thisv()));
     Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
 
     /* Step 5. */
     RootedAtom src(cx, reObj->getSource());
     if (!src)
         return false;
@@ -521,17 +521,17 @@ regexp_source(JSContext* cx, unsigned ar
 {
     /* Steps 1-4. */
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsRegExpObject, regexp_source_impl>(cx, args);
 }
 
 /* ES6 draft rev32 21.2.5.12. */
 MOZ_ALWAYS_INLINE bool
-regexp_sticky_impl(JSContext* cx, CallArgs args)
+regexp_sticky_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsRegExpObject(args.thisv()));
     Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
 
     /* Steps 4-6. */
     args.rval().setBoolean(reObj->sticky());
     return true;
 }
@@ -815,17 +815,17 @@ js::ExecuteRegExp(JSContext* cx, HandleO
             return RegExpRunStatus_Error;
     }
 
     return status;
 }
 
 /* ES5 15.10.6.2 (and 15.10.6.3, which calls 15.10.6.2). */
 static RegExpRunStatus
-ExecuteRegExp(JSContext* cx, CallArgs args, MatchPairs* matches)
+ExecuteRegExp(JSContext* cx, const CallArgs& args, MatchPairs* matches)
 {
     /* Step 1 (a) was performed by CallNonGenericMethod. */
     RootedObject regexp(cx, &args.thisv().toObject());
 
     /* Step 2. */
     RootedString string(cx, ToString<CanGC>(cx, args.get(0)));
     if (!string)
         return RegExpRunStatus_Error;
@@ -849,17 +849,17 @@ regexp_exec_impl(JSContext* cx, HandleOb
         rval.setNull();
         return true;
     }
 
     return CreateRegExpMatchResult(cx, string, matches, rval);
 }
 
 static bool
-regexp_exec_impl(JSContext* cx, CallArgs args)
+regexp_exec_impl(JSContext* cx, const CallArgs& args)
 {
     RootedObject regexp(cx, &args.thisv().toObject());
     RootedString string(cx, ToString<CanGC>(cx, args.get(0)));
     if (!string)
         return false;
 
     return regexp_exec_impl(cx, regexp, string, UpdateRegExpStatics, args.rval());
 }
@@ -894,17 +894,17 @@ js::regexp_exec_no_statics(JSContext* cx
     RootedObject regexp(cx, &args[0].toObject());
     RootedString string(cx, args[1].toString());
 
     return regexp_exec_impl(cx, regexp, string, DontUpdateRegExpStatics, args.rval());
 }
 
 /* ES5 15.10.6.3. */
 static bool
-regexp_test_impl(JSContext* cx, CallArgs args)
+regexp_test_impl(JSContext* cx, const CallArgs& args)
 {
     RegExpRunStatus status = ExecuteRegExp(cx, args, nullptr);
     args.rval().setBoolean(status == RegExpRunStatus_Success);
     return status != RegExpRunStatus_Error;
 }
 
 /* Separate interface for use by IonMonkey. */
 bool
--- a/js/src/builtin/SymbolObject.cpp
+++ b/js/src/builtin/SymbolObject.cpp
@@ -184,17 +184,17 @@ SymbolObject::keyFor(JSContext* cx, unsi
 MOZ_ALWAYS_INLINE bool
 IsSymbol(HandleValue v)
 {
     return v.isSymbol() || (v.isObject() && v.toObject().is<SymbolObject>());
 }
 
 // ES6 rev 27 (2014 Aug 24) 19.4.3.2
 bool
-SymbolObject::toString_impl(JSContext* cx, CallArgs args)
+SymbolObject::toString_impl(JSContext* cx, const CallArgs& args)
 {
     // steps 1-3
     HandleValue thisv = args.thisv();
     MOZ_ASSERT(IsSymbol(thisv));
     Rooted<Symbol*> sym(cx, thisv.isSymbol()
                             ? thisv.toSymbol()
                             : thisv.toObject().as<SymbolObject>().unbox());
 
@@ -206,17 +206,17 @@ bool
 SymbolObject::toString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsSymbol, toString_impl>(cx, args);
 }
 
 //ES6 rev 24 (2014 Apr 27) 19.4.3.3
 bool
-SymbolObject::valueOf_impl(JSContext* cx, CallArgs args)
+SymbolObject::valueOf_impl(JSContext* cx, const CallArgs& args)
 {
     // Step 3, the error case, is handled by CallNonGenericMethod.
     HandleValue thisv = args.thisv();
     MOZ_ASSERT(IsSymbol(thisv));
     if (thisv.isSymbol())
         args.rval().set(thisv);
     else
         args.rval().setSymbol(thisv.toObject().as<SymbolObject>().unbox());
--- a/js/src/builtin/SymbolObject.h
+++ b/js/src/builtin/SymbolObject.h
@@ -43,19 +43,19 @@ class SymbolObject : public NativeObject
 
     static bool convert(JSContext* cx, HandleObject obj, JSType type, MutableHandleValue vp);
 
     // Static methods.
     static bool for_(JSContext* cx, unsigned argc, Value* vp);
     static bool keyFor(JSContext* cx, unsigned argc, Value* vp);
 
     // Methods defined on Symbol.prototype.
-    static bool toString_impl(JSContext* cx, CallArgs args);
+    static bool toString_impl(JSContext* cx, const CallArgs& args);
     static bool toString(JSContext* cx, unsigned argc, Value* vp);
-    static bool valueOf_impl(JSContext* cx, CallArgs args);
+    static bool valueOf_impl(JSContext* cx, const CallArgs& args);
     static bool valueOf(JSContext* cx, unsigned argc, Value* vp);
 
     static const JSPropertySpec properties[];
     static const JSFunctionSpec methods[];
     static const JSFunctionSpec staticMethods[];
 };
 
 extern JSObject*
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -1680,17 +1680,17 @@ class CloneBufferObject : public NativeO
     // Discard an owned clone buffer.
     void discard() {
         if (data())
             JS_ClearStructuredClone(data(), nbytes(), nullptr, nullptr);
         setReservedSlot(DATA_SLOT, PrivateValue(nullptr));
     }
 
     static bool
-    setCloneBuffer_impl(JSContext* cx, CallArgs args) {
+    setCloneBuffer_impl(JSContext* cx, const CallArgs& args) {
         if (args.length() != 1 || !args[0].isString()) {
             JS_ReportError(cx,
                            "the first argument argument must be maxBytes, "
                            "maxMallocBytes, gcStackpoolLifespan, gcBytes or "
                            "gcNumber");
             JS_ReportError(cx, "clonebuffer setter requires a single string argument");
             return false;
         }
@@ -1721,17 +1721,17 @@ class CloneBufferObject : public NativeO
 
     static bool
     setCloneBuffer(JSContext* cx, unsigned int argc, JS::Value* vp) {
         CallArgs args = CallArgsFromVp(argc, vp);
         return CallNonGenericMethod<is, setCloneBuffer_impl>(cx, args);
     }
 
     static bool
-    getCloneBuffer_impl(JSContext* cx, CallArgs args) {
+    getCloneBuffer_impl(JSContext* cx, const CallArgs& args) {
         Rooted<CloneBufferObject*> obj(cx, &args.thisv().toObject().as<CloneBufferObject>());
         MOZ_ASSERT(args.length() == 0);
 
         if (!obj->data()) {
             args.rval().setUndefined();
             return true;
         }
 
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -228,20 +228,20 @@ namespace CType {
   static bool ConstructBasic(JSContext* cx, HandleObject obj, const CallArgs& args);
 
   static void Trace(JSTracer* trc, JSObject* obj);
   static void Finalize(JSFreeOp* fop, JSObject* obj);
 
   bool IsCType(HandleValue v);
   bool IsCTypeOrProto(HandleValue v);
 
-  bool PrototypeGetter(JSContext* cx, JS::CallArgs args);
-  bool NameGetter(JSContext* cx, JS::CallArgs args);
-  bool SizeGetter(JSContext* cx, JS::CallArgs args);
-  bool PtrGetter(JSContext* cx, JS::CallArgs args);
+  bool PrototypeGetter(JSContext* cx, const JS::CallArgs& args);
+  bool NameGetter(JSContext* cx, const JS::CallArgs& args);
+  bool SizeGetter(JSContext* cx, const JS::CallArgs& args);
+  bool PtrGetter(JSContext* cx, const JS::CallArgs& args);
 
   static bool CreateArray(JSContext* cx, unsigned argc, Value* vp);
   static bool ToString(JSContext* cx, unsigned argc, Value* vp);
   static bool ToSource(JSContext* cx, unsigned argc, Value* vp);
   static bool HasInstance(JSContext* cx, HandleObject obj, MutableHandleValue v, bool* bp);
 
 
   /*
@@ -262,51 +262,51 @@ namespace ABI {
 
 namespace PointerType {
   static bool Create(JSContext* cx, unsigned argc, Value* vp);
   static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args);
 
   bool IsPointerType(HandleValue v);
   bool IsPointer(HandleValue v);
 
-  bool TargetTypeGetter(JSContext* cx, JS::CallArgs args);
-  bool ContentsGetter(JSContext* cx, JS::CallArgs args);
-  bool ContentsSetter(JSContext* cx, JS::CallArgs args);
+  bool TargetTypeGetter(JSContext* cx, const JS::CallArgs& args);
+  bool ContentsGetter(JSContext* cx, const JS::CallArgs& args);
+  bool ContentsSetter(JSContext* cx, const JS::CallArgs& args);
 
   static bool IsNull(JSContext* cx, unsigned argc, Value* vp);
   static bool Increment(JSContext* cx, unsigned argc, Value* vp);
   static bool Decrement(JSContext* cx, unsigned argc, Value* vp);
   // The following is not an instance function, since we don't want to expose arbitrary
   // pointer arithmetic at this moment.
   static bool OffsetBy(JSContext* cx, const CallArgs& args, int offset);
 } // namespace PointerType
 
 namespace ArrayType {
   bool IsArrayType(HandleValue v);
   bool IsArrayOrArrayType(HandleValue v);
 
   static bool Create(JSContext* cx, unsigned argc, Value* vp);
   static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args);
 
-  bool ElementTypeGetter(JSContext* cx, JS::CallArgs args);
-  bool LengthGetter(JSContext* cx, JS::CallArgs args);
+  bool ElementTypeGetter(JSContext* cx, const JS::CallArgs& args);
+  bool LengthGetter(JSContext* cx, const JS::CallArgs& args);
 
   static bool Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp);
   static bool Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp,
                      ObjectOpResult& result);
   static bool AddressOfElement(JSContext* cx, unsigned argc, Value* vp);
 } // namespace ArrayType
 
 namespace StructType {
   bool IsStruct(HandleValue v);
 
   static bool Create(JSContext* cx, unsigned argc, Value* vp);
   static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args);
 
-  bool FieldsArrayGetter(JSContext* cx, JS::CallArgs args);
+  bool FieldsArrayGetter(JSContext* cx, const JS::CallArgs& args);
 
   enum {
     SLOT_FIELDNAME
   };
 
   static bool FieldGetter(JSContext* cx, unsigned argc, Value* vp);
   static bool FieldSetter(JSContext* cx, unsigned argc, Value* vp);
   static bool AddressOfField(JSContext* cx, unsigned argc, Value* vp);
@@ -317,20 +317,20 @@ namespace FunctionType {
   static bool Create(JSContext* cx, unsigned argc, Value* vp);
   static bool ConstructData(JSContext* cx, HandleObject typeObj,
     HandleObject dataObj, HandleObject fnObj, HandleObject thisObj, Value errVal);
 
   static bool Call(JSContext* cx, unsigned argc, Value* vp);
 
   bool IsFunctionType(HandleValue v);
 
-  bool ArgTypesGetter(JSContext* cx, JS::CallArgs args);
-  bool ReturnTypeGetter(JSContext* cx, JS::CallArgs args);
-  bool ABIGetter(JSContext* cx, JS::CallArgs args);
-  bool IsVariadicGetter(JSContext* cx, JS::CallArgs args);
+  bool ArgTypesGetter(JSContext* cx, const JS::CallArgs& args);
+  bool ReturnTypeGetter(JSContext* cx, const JS::CallArgs& args);
+  bool ABIGetter(JSContext* cx, const JS::CallArgs& args);
+  bool IsVariadicGetter(JSContext* cx, const JS::CallArgs& args);
 } // namespace FunctionType
 
 namespace CClosure {
   static void Trace(JSTracer* trc, JSObject* obj);
   static void Finalize(JSFreeOp* fop, JSObject* obj);
 
   // libffi callback
   static void ClosureStub(ffi_cif* cif, void* result, void** args,
@@ -347,30 +347,30 @@ namespace CClosure {
       void** args;
       ClosureInfo* cinfo;
   };
 } // namespace CClosure
 
 namespace CData {
   static void Finalize(JSFreeOp* fop, JSObject* obj);
 
-  bool ValueGetter(JSContext* cx, JS::CallArgs args);
-  bool ValueSetter(JSContext* cx, JS::CallArgs args);
+  bool ValueGetter(JSContext* cx, const JS::CallArgs& args);
+  bool ValueSetter(JSContext* cx, const JS::CallArgs& args);
 
   static bool Address(JSContext* cx, unsigned argc, Value* vp);
   static bool ReadString(JSContext* cx, unsigned argc, Value* vp);
   static bool ReadStringReplaceMalformed(JSContext* cx, unsigned argc, Value* vp);
   static bool ToSource(JSContext* cx, unsigned argc, Value* vp);
   static JSString* GetSourceString(JSContext* cx, HandleObject typeObj,
                                    void* data);
 
-  bool ErrnoGetter(JSContext* cx, JS::CallArgs args);
+  bool ErrnoGetter(JSContext* cx, const JS::CallArgs& args);
 
 #if defined(XP_WIN)
-  bool LastErrorGetter(JSContext* cx, JS::CallArgs args);
+  bool LastErrorGetter(JSContext* cx, const JS::CallArgs& args);
 #endif // defined(XP_WIN)
 } // namespace CData
 
 namespace CDataFinalizer {
   /*
    * Attach a C function as a finalizer to a JS object.
    *
    * This function is available from JS as |ctypes.withFinalizer|.
@@ -4322,55 +4322,55 @@ CType::IsCTypeOrProto(HandleValue v)
 {
   if (!v.isObject())
     return false;
   JSObject* obj = &v.toObject();
   return CType::IsCType(obj) || CType::IsCTypeProto(obj);
 }
 
 bool
-CType::PrototypeGetter(JSContext* cx, JS::CallArgs args)
+CType::PrototypeGetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
   unsigned slot = CType::IsCTypeProto(obj) ? (unsigned) SLOT_OURDATAPROTO
                                            : (unsigned) SLOT_PROTO;
   args.rval().set(JS_GetReservedSlot(obj, slot));
   MOZ_ASSERT(args.rval().isObject() || args.rval().isUndefined());
   return true;
 }
 
 bool
 CType::IsCType(HandleValue v)
 {
   return v.isObject() && CType::IsCType(&v.toObject());
 }
 
 bool
-CType::NameGetter(JSContext* cx, JS::CallArgs args)
+CType::NameGetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
   JSString* name = CType::GetName(cx, obj);
   if (!name)
     return false;
 
   args.rval().setString(name);
   return true;
 }
 
 bool
-CType::SizeGetter(JSContext* cx, JS::CallArgs args)
+CType::SizeGetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
   args.rval().set(JS_GetReservedSlot(obj, SLOT_SIZE));
   MOZ_ASSERT(args.rval().isNumber() || args.rval().isUndefined());
   return true;
 }
 
 bool
-CType::PtrGetter(JSContext* cx, JS::CallArgs args)
+CType::PtrGetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
   JSObject* pointerType = PointerType::CreateInternal(cx, obj);
   if (!pointerType)
     return false;
 
   args.rval().setObject(*pointerType);
   return true;
@@ -4731,17 +4731,17 @@ PointerType::IsPointer(HandleValue v)
 {
   if (!v.isObject())
     return false;
   JSObject* obj = &v.toObject();
   return CData::IsCData(obj) && CType::GetTypeCode(CData::GetCType(obj)) == TYPE_pointer;
 }
 
 bool
-PointerType::TargetTypeGetter(JSContext* cx, JS::CallArgs args)
+PointerType::TargetTypeGetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
   args.rval().set(JS_GetReservedSlot(obj, SLOT_TARGET_T));
   MOZ_ASSERT(args.rval().isObject());
   return true;
 }
 
 bool
@@ -4814,17 +4814,17 @@ PointerType::Increment(JSContext* cx, un
 bool
 PointerType::Decrement(JSContext* cx, unsigned argc, Value* vp)
 {
   CallArgs args = CallArgsFromVp(argc, vp);
   return OffsetBy(cx, args, -1);
 }
 
 bool
-PointerType::ContentsGetter(JSContext* cx, JS::CallArgs args)
+PointerType::ContentsGetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
   RootedObject baseType(cx, GetBaseType(CData::GetCType(obj)));
   if (!CType::IsSizeDefined(baseType)) {
     JS_ReportError(cx, "cannot get contents of undefined size");
     return false;
   }
 
@@ -4838,17 +4838,17 @@ PointerType::ContentsGetter(JSContext* c
   if (!ConvertToJS(cx, baseType, nullptr, data, false, false, &result))
     return false;
 
   args.rval().set(result);
   return true;
 }
 
 bool
-PointerType::ContentsSetter(JSContext* cx, JS::CallArgs args)
+PointerType::ContentsSetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
   RootedObject baseType(cx, GetBaseType(CData::GetCType(obj)));
   if (!CType::IsSizeDefined(baseType)) {
     JS_ReportError(cx, "cannot set contents of undefined size");
     return false;
   }
 
@@ -5171,26 +5171,26 @@ ArrayType::IsArrayOrArrayType(HandleValu
    // CType if we're dealing with a CData.
   if (CData::IsCData(obj)) {
     obj = CData::GetCType(obj);
   }
   return CType::IsCType(obj) && CType::GetTypeCode(obj) == TYPE_array;
 }
 
 bool
-ArrayType::ElementTypeGetter(JSContext* cx, JS::CallArgs args)
+ArrayType::ElementTypeGetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
   args.rval().set(JS_GetReservedSlot(obj, SLOT_ELEMENT_T));
   MOZ_ASSERT(args.rval().isObject());
   return true;
 }
 
 bool
-ArrayType::LengthGetter(JSContext* cx, JS::CallArgs args)
+ArrayType::LengthGetter(JSContext* cx, const JS::CallArgs& args)
 {
   JSObject* obj = &args.thisv().toObject();
 
   // This getter exists for both CTypes and CDatas of the ArrayType persuasion.
   // If we're dealing with a CData, get the CType from it.
   if (CData::IsCData(obj))
     obj = CData::GetCType(obj);
 
@@ -5868,17 +5868,17 @@ StructType::IsStruct(HandleValue v)
 {
   if (!v.isObject())
     return false;
   JSObject* obj = &v.toObject();
   return CType::IsCType(obj) && CType::GetTypeCode(obj) == TYPE_struct;
 }
 
 bool
-StructType::FieldsArrayGetter(JSContext* cx, JS::CallArgs args)
+StructType::FieldsArrayGetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
 
   args.rval().set(JS_GetReservedSlot(obj, SLOT_FIELDS));
 
   if (!CType::IsSizeDefined(obj)) {
     MOZ_ASSERT(args.rval().isUndefined());
     return true;
@@ -6669,17 +6669,17 @@ FunctionType::IsFunctionType(HandleValue
 {
   if (!v.isObject())
     return false;
   JSObject* obj = &v.toObject();
   return CType::IsCType(obj) && CType::GetTypeCode(obj) == TYPE_function;
 }
 
 bool
-FunctionType::ArgTypesGetter(JSContext* cx, JS::CallArgs args)
+FunctionType::ArgTypesGetter(JSContext* cx, const JS::CallArgs& args)
 {
   JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
 
   args.rval().set(JS_GetReservedSlot(obj, SLOT_ARGS_T));
   if (!args.rval().isUndefined())
     return true;
 
   FunctionInfo* fninfo = GetFunctionInfo(obj);
@@ -6705,33 +6705,33 @@ FunctionType::ArgTypesGetter(JSContext* 
     return false;
   JS_SetReservedSlot(obj, SLOT_ARGS_T, JS::ObjectValue(*argTypes));
 
   args.rval().setObject(*argTypes);
   return true;
 }
 
 bool
-FunctionType::ReturnTypeGetter(JSContext* cx, JS::CallArgs args)
+FunctionType::ReturnTypeGetter(JSContext* cx, const JS::CallArgs& args)
 {
   // Get the returnType object from the FunctionInfo.
   args.rval().setObject(*GetFunctionInfo(&args.thisv().toObject())->mReturnType);
   return true;
 }
 
 bool
-FunctionType::ABIGetter(JSContext* cx, JS::CallArgs args)
+FunctionType::ABIGetter(JSContext* cx, const JS::CallArgs& args)
 {
   // Get the abi object from the FunctionInfo.
   args.rval().setObject(*GetFunctionInfo(&args.thisv().toObject())->mABI);
   return true;
 }
 
 bool
-FunctionType::IsVariadicGetter(JSContext* cx, JS::CallArgs args)
+FunctionType::IsVariadicGetter(JSContext* cx, const JS::CallArgs& args)
 {
   args.rval().setBoolean(GetFunctionInfo(&args.thisv().toObject())->mIsVariadic);
   return true;
 }
 
 /*******************************************************************************
 ** CClosure implementation
 *******************************************************************************/
@@ -7147,27 +7147,27 @@ CData::IsCData(HandleValue v)
 
 bool
 CData::IsCDataProto(JSObject* obj)
 {
   return JS_GetClass(obj) == &sCDataProtoClass;
 }
 
 bool
-CData::ValueGetter(JSContext* cx, JS::CallArgs args)
+CData::ValueGetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
 
   // Convert the value to a primitive; do not create a new CData object.
   RootedObject ctype(cx, GetCType(obj));
   return ConvertToJS(cx, ctype, nullptr, GetData(obj), true, false, args.rval());
 }
 
 bool
-CData::ValueSetter(JSContext* cx, JS::CallArgs args)
+CData::ValueSetter(JSContext* cx, const JS::CallArgs& args)
 {
   RootedObject obj(cx, &args.thisv().toObject());
   args.rval().setUndefined();
   return ImplicitConvert(cx, args.get(0), GetCType(obj), GetData(obj),
                          ConversionType::Setter, nullptr);
 }
 
 bool
@@ -7421,25 +7421,25 @@ CData::ToSource(JSContext* cx, unsigned 
   if (!result)
     return false;
 
   args.rval().setString(result);
   return true;
 }
 
 bool
-CData::ErrnoGetter(JSContext* cx, JS::CallArgs args)
+CData::ErrnoGetter(JSContext* cx, const JS::CallArgs& args)
 {
   args.rval().set(JS_GetReservedSlot(&args.thisv().toObject(), SLOT_ERRNO));
   return true;
 }
 
 #if defined(XP_WIN)
 bool
-CData::LastErrorGetter(JSContext* cx, JS::CallArgs args)
+CData::LastErrorGetter(JSContext* cx, const JS::CallArgs& args)
 {
   args.rval().set(JS_GetReservedSlot(&args.thisv().toObject(), SLOT_LASTERROR));
   return true;
 }
 #endif // defined(XP_WIN)
 
 bool
 CDataFinalizer::Methods::ToSource(JSContext* cx, unsigned argc, Value* vp)
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -2563,17 +2563,17 @@ EnterIon(JSContext* cx, EnterJitData& da
 }
 
 bool
 jit::SetEnterJitData(JSContext* cx, EnterJitData& data, RunState& state, AutoValueVector& vals)
 {
     data.osrFrame = nullptr;
 
     if (state.isInvoke()) {
-        CallArgs& args = state.asInvoke()->args();
+        const CallArgs& args = state.asInvoke()->args();
         unsigned numFormals = state.script()->functionNonDelazifying()->nargs();
         data.constructing = state.asInvoke()->constructing();
         data.numActualArgs = args.length();
         data.maxArgc = Max(args.length(), numFormals) + 1;
         data.scopeChain = nullptr;
         data.calleeToken = CalleeToToken(&args.callee().as<JSFunction>(), data.constructing);
 
         if (data.numActualArgs >= numFormals) {
--- a/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
+++ b/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
@@ -15,17 +15,17 @@ static const uint32_t CUSTOM_SLOT = 0;
 
 static bool
 IsCustomClass(JS::Handle<JS::Value> v)
 {
   return v.isObject() && JS_GetClass(&v.toObject()) == &CustomClass;
 }
 
 static bool
-CustomMethodImpl(JSContext* cx, CallArgs args)
+CustomMethodImpl(JSContext* cx, const CallArgs& args)
 {
   MOZ_RELEASE_ASSERT(IsCustomClass(args.thisv()));
   args.rval().set(JS_GetReservedSlot(&args.thisv().toObject(), CUSTOM_SLOT));
   return true;
 }
 
 static bool
 CustomMethod(JSContext* cx, unsigned argc, Value* vp)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -113,17 +113,18 @@ using js::frontend::Parser;
 
 #ifdef HAVE_VA_LIST_AS_ARRAY
 #define JS_ADDRESSOF_VA_LIST(ap) ((va_list*)(ap))
 #else
 #define JS_ADDRESSOF_VA_LIST(ap) (&(ap))
 #endif
 
 bool
-JS::CallArgs::requireAtLeast(JSContext* cx, const char* fnname, unsigned required) {
+JS::CallArgs::requireAtLeast(JSContext* cx, const char* fnname, unsigned required) const
+{
     if (length() < required) {
         char numArgsStr[40];
         JS_snprintf(numArgsStr, sizeof numArgsStr, "%u", required - 1);
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
                              fnname, numArgsStr, required == 2 ? "" : "s");
         return false;
     }
 
--- a/js/src/jsbool.cpp
+++ b/js/src/jsbool.cpp
@@ -32,17 +32,17 @@ const Class BooleanObject::class_ = {
 MOZ_ALWAYS_INLINE bool
 IsBoolean(HandleValue v)
 {
     return v.isBoolean() || (v.isObject() && v.toObject().is<BooleanObject>());
 }
 
 #if JS_HAS_TOSOURCE
 MOZ_ALWAYS_INLINE bool
-bool_toSource_impl(JSContext* cx, CallArgs args)
+bool_toSource_impl(JSContext* cx, const CallArgs& args)
 {
     HandleValue thisv = args.thisv();
     MOZ_ASSERT(IsBoolean(thisv));
 
     bool b = thisv.isBoolean() ? thisv.toBoolean() : thisv.toObject().as<BooleanObject>().unbox();
 
     StringBuffer sb(cx);
     if (!sb.append("(new Boolean(") || !BooleanToStringBuffer(b, sb) || !sb.append("))"))
@@ -59,17 +59,17 @@ static bool
 bool_toSource(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsBoolean, bool_toSource_impl>(cx, args);
 }
 #endif
 
 MOZ_ALWAYS_INLINE bool
-bool_toString_impl(JSContext* cx, CallArgs args)
+bool_toString_impl(JSContext* cx, const CallArgs& args)
 {
     HandleValue thisv = args.thisv();
     MOZ_ASSERT(IsBoolean(thisv));
 
     bool b = thisv.isBoolean() ? thisv.toBoolean() : thisv.toObject().as<BooleanObject>().unbox();
     args.rval().setString(BooleanToString(cx, b));
     return true;
 }
@@ -77,17 +77,17 @@ bool_toString_impl(JSContext* cx, CallAr
 static bool
 bool_toString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsBoolean, bool_toString_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-bool_valueOf_impl(JSContext* cx, CallArgs args)
+bool_valueOf_impl(JSContext* cx, const CallArgs& args)
 {
     HandleValue thisv = args.thisv();
     MOZ_ASSERT(IsBoolean(thisv));
 
     bool b = thisv.isBoolean() ? thisv.toBoolean() : thisv.toObject().as<BooleanObject>().unbox();
     args.rval().setBoolean(b);
     return true;
 }
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -1369,31 +1369,31 @@ IsDate(HandleValue v)
 {
     return v.isObject() && v.toObject().is<DateObject>();
 }
 
 /*
  * See ECMA 15.9.5.4 thru 15.9.5.23
  */
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getTime_impl(JSContext* cx, CallArgs args)
+DateObject::getTime_impl(JSContext* cx, const CallArgs& args)
 {
     args.rval().set(args.thisv().toObject().as<DateObject>().UTCTime());
     return true;
 }
 
 static bool
 date_getTime(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getTime_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getYear_impl(JSContext* cx, CallArgs args)
+DateObject::getYear_impl(JSContext* cx, const CallArgs& args)
 {
     DateObject* dateObj = &args.thisv().toObject().as<DateObject>();
     dateObj->fillLocalTimeSlots(&cx->runtime()->dateTimeInfo);
 
     Value yearVal = dateObj->getReservedSlot(LOCAL_YEAR_SLOT);
     if (yearVal.isInt32()) {
         /* Follow ECMA-262 to the letter, contrary to IE JScript. */
         int year = yearVal.toInt32() - 1900;
@@ -1408,34 +1408,34 @@ DateObject::getYear_impl(JSContext* cx, 
 static bool
 date_getYear(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getYear_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getFullYear_impl(JSContext* cx, CallArgs args)
+DateObject::getFullYear_impl(JSContext* cx, const CallArgs& args)
 {
     DateObject* dateObj = &args.thisv().toObject().as<DateObject>();
     dateObj->fillLocalTimeSlots(&cx->runtime()->dateTimeInfo);
 
     args.rval().set(dateObj->getReservedSlot(LOCAL_YEAR_SLOT));
     return true;
 }
 
 static bool
 date_getFullYear(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getFullYear_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getUTCFullYear_impl(JSContext* cx, CallArgs args)
+DateObject::getUTCFullYear_impl(JSContext* cx, const CallArgs& args)
 {
     double result = args.thisv().toObject().as<DateObject>().UTCTime().toNumber();
     if (IsFinite(result))
         result = YearFromTime(result);
 
     args.rval().setNumber(result);
     return true;
 }
@@ -1443,66 +1443,66 @@ DateObject::getUTCFullYear_impl(JSContex
 static bool
 date_getUTCFullYear(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getUTCFullYear_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getMonth_impl(JSContext* cx, CallArgs args)
+DateObject::getMonth_impl(JSContext* cx, const CallArgs& args)
 {
     DateObject* dateObj = &args.thisv().toObject().as<DateObject>();
     dateObj->fillLocalTimeSlots(&cx->runtime()->dateTimeInfo);
 
     args.rval().set(dateObj->getReservedSlot(LOCAL_MONTH_SLOT));
     return true;
 }
 
 static bool
 date_getMonth(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getMonth_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getUTCMonth_impl(JSContext* cx, CallArgs args)
+DateObject::getUTCMonth_impl(JSContext* cx, const CallArgs& args)
 {
     double d = args.thisv().toObject().as<DateObject>().UTCTime().toNumber();
     args.rval().setNumber(MonthFromTime(d));
     return true;
 }
 
 static bool
 date_getUTCMonth(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getUTCMonth_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getDate_impl(JSContext* cx, CallArgs args)
+DateObject::getDate_impl(JSContext* cx, const CallArgs& args)
 {
     DateObject* dateObj = &args.thisv().toObject().as<DateObject>();
     dateObj->fillLocalTimeSlots(&cx->runtime()->dateTimeInfo);
 
     args.rval().set(dateObj->getReservedSlot(LOCAL_DATE_SLOT));
     return true;
 }
 
 static bool
 date_getDate(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getDate_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getUTCDate_impl(JSContext* cx, CallArgs args)
+DateObject::getUTCDate_impl(JSContext* cx, const CallArgs& args)
 {
     double result = args.thisv().toObject().as<DateObject>().UTCTime().toNumber();
     if (IsFinite(result))
         result = DateFromTime(result);
 
     args.rval().setNumber(result);
     return true;
 }
@@ -1510,34 +1510,34 @@ DateObject::getUTCDate_impl(JSContext* c
 static bool
 date_getUTCDate(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getUTCDate_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getDay_impl(JSContext* cx, CallArgs args)
+DateObject::getDay_impl(JSContext* cx, const CallArgs& args)
 {
     DateObject* dateObj = &args.thisv().toObject().as<DateObject>();
     dateObj->fillLocalTimeSlots(&cx->runtime()->dateTimeInfo);
 
     args.rval().set(dateObj->getReservedSlot(LOCAL_DAY_SLOT));
     return true;
 }
 
 static bool
 date_getDay(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getDay_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getUTCDay_impl(JSContext* cx, CallArgs args)
+DateObject::getUTCDay_impl(JSContext* cx, const CallArgs& args)
 {
     double result = args.thisv().toObject().as<DateObject>().UTCTime().toNumber();
     if (IsFinite(result))
         result = WeekDay(result);
 
     args.rval().setNumber(result);
     return true;
 }
@@ -1545,34 +1545,34 @@ DateObject::getUTCDay_impl(JSContext* cx
 static bool
 date_getUTCDay(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getUTCDay_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getHours_impl(JSContext* cx, CallArgs args)
+DateObject::getHours_impl(JSContext* cx, const CallArgs& args)
 {
     DateObject* dateObj = &args.thisv().toObject().as<DateObject>();
     dateObj->fillLocalTimeSlots(&cx->runtime()->dateTimeInfo);
 
     args.rval().set(dateObj->getReservedSlot(LOCAL_HOURS_SLOT));
     return true;
 }
 
 static bool
 date_getHours(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getHours_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getUTCHours_impl(JSContext* cx, CallArgs args)
+DateObject::getUTCHours_impl(JSContext* cx, const CallArgs& args)
 {
     double result = args.thisv().toObject().as<DateObject>().UTCTime().toNumber();
     if (IsFinite(result))
         result = HourFromTime(result);
 
     args.rval().setNumber(result);
     return true;
 }
@@ -1580,34 +1580,34 @@ DateObject::getUTCHours_impl(JSContext* 
 static bool
 date_getUTCHours(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getUTCHours_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getMinutes_impl(JSContext* cx, CallArgs args)
+DateObject::getMinutes_impl(JSContext* cx, const CallArgs& args)
 {
     DateObject* dateObj = &args.thisv().toObject().as<DateObject>();
     dateObj->fillLocalTimeSlots(&cx->runtime()->dateTimeInfo);
 
     args.rval().set(dateObj->getReservedSlot(LOCAL_MINUTES_SLOT));
     return true;
 }
 
 static bool
 date_getMinutes(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getMinutes_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getUTCMinutes_impl(JSContext* cx, CallArgs args)
+DateObject::getUTCMinutes_impl(JSContext* cx, const CallArgs& args)
 {
     double result = args.thisv().toObject().as<DateObject>().UTCTime().toNumber();
     if (IsFinite(result))
         result = MinFromTime(result);
 
     args.rval().setNumber(result);
     return true;
 }
@@ -1617,17 +1617,17 @@ date_getUTCMinutes(JSContext* cx, unsign
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getUTCMinutes_impl>(cx, args);
 }
 
 /* Date.getSeconds is mapped to getUTCSeconds */
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getUTCSeconds_impl(JSContext* cx, CallArgs args)
+DateObject::getUTCSeconds_impl(JSContext* cx, const CallArgs& args)
 {
     DateObject* dateObj = &args.thisv().toObject().as<DateObject>();
     dateObj->fillLocalTimeSlots(&cx->runtime()->dateTimeInfo);
 
     args.rval().set(dateObj->getReservedSlot(LOCAL_SECONDS_SLOT));
     return true;
 }
 
@@ -1636,17 +1636,17 @@ date_getUTCSeconds(JSContext* cx, unsign
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getUTCSeconds_impl>(cx, args);
 }
 
 /* Date.getMilliseconds is mapped to getUTCMilliseconds */
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getUTCMilliseconds_impl(JSContext* cx, CallArgs args)
+DateObject::getUTCMilliseconds_impl(JSContext* cx, const CallArgs& args)
 {
     double result = args.thisv().toObject().as<DateObject>().UTCTime().toNumber();
     if (IsFinite(result))
         result = msFromTime(result);
 
     args.rval().setNumber(result);
     return true;
 }
@@ -1654,17 +1654,17 @@ DateObject::getUTCMilliseconds_impl(JSCo
 static bool
 date_getUTCMilliseconds(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getUTCMilliseconds_impl>(cx, args);
 }
 
 /* static */ MOZ_ALWAYS_INLINE bool
-DateObject::getTimezoneOffset_impl(JSContext* cx, CallArgs args)
+DateObject::getTimezoneOffset_impl(JSContext* cx, const CallArgs& args)
 {
     DateObject* dateObj = &args.thisv().toObject().as<DateObject>();
     double utctime = dateObj->UTCTime().toNumber();
     double localtime = dateObj->cachedLocalTime(&cx->runtime()->dateTimeInfo);
 
     /*
      * Return the time zone offset in minutes for the current locale that is
      * appropriate for this time. This value would be a constant except for
@@ -1678,17 +1678,17 @@ DateObject::getTimezoneOffset_impl(JSCon
 static bool
 date_getTimezoneOffset(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, DateObject::getTimezoneOffset_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-date_setTime_impl(JSContext* cx, CallArgs args)
+date_setTime_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
     if (args.length() == 0) {
         dateObj->setUTCTime(ClippedTime::invalid(), args.rval());
         return true;
     }
 
     double result;
@@ -1733,17 +1733,17 @@ GetMinsOrDefault(JSContext* cx, const Ca
         *mins = MinFromTime(t);
         return true;
     }
     return ToNumber(cx, args[i], mins);
 }
 
 /* ES5 15.9.5.28. */
 MOZ_ALWAYS_INLINE bool
-date_setMilliseconds_impl(JSContext* cx, CallArgs args)
+date_setMilliseconds_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = LocalTime(dateObj->UTCTime().toNumber(), &cx->runtime()->dateTimeInfo);
 
     /* Step 2. */
     double milli;
@@ -1763,17 +1763,17 @@ static bool
 date_setMilliseconds(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setMilliseconds_impl>(cx, args);
 }
 
 /* ES5 15.9.5.29. */
 MOZ_ALWAYS_INLINE bool
-date_setUTCMilliseconds_impl(JSContext* cx, CallArgs args)
+date_setUTCMilliseconds_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = dateObj->UTCTime().toNumber();
 
     /* Step 2. */
     double milli;
@@ -1793,17 +1793,17 @@ static bool
 date_setUTCMilliseconds(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setUTCMilliseconds_impl>(cx, args);
 }
 
 /* ES5 15.9.5.30. */
 MOZ_ALWAYS_INLINE bool
-date_setSeconds_impl(JSContext* cx, CallArgs args)
+date_setSeconds_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = LocalTime(dateObj->UTCTime().toNumber(), &cx->runtime()->dateTimeInfo);
 
     /* Step 2. */
     double s;
@@ -1830,17 +1830,17 @@ date_setSeconds_impl(JSContext* cx, Call
 static bool
 date_setSeconds(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setSeconds_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-date_setUTCSeconds_impl(JSContext* cx, CallArgs args)
+date_setUTCSeconds_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = dateObj->UTCTime().toNumber();
 
     /* Step 2. */
     double s;
@@ -1867,17 +1867,17 @@ date_setUTCSeconds_impl(JSContext* cx, C
 static bool
 date_setUTCSeconds(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setUTCSeconds_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-date_setMinutes_impl(JSContext* cx, CallArgs args)
+date_setMinutes_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = LocalTime(dateObj->UTCTime().toNumber(), &cx->runtime()->dateTimeInfo);
 
     /* Step 2. */
     double m;
@@ -1909,17 +1909,17 @@ date_setMinutes_impl(JSContext* cx, Call
 static bool
 date_setMinutes(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setMinutes_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-date_setUTCMinutes_impl(JSContext* cx, CallArgs args)
+date_setUTCMinutes_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = dateObj->UTCTime().toNumber();
 
     /* Step 2. */
     double m;
@@ -1951,17 +1951,17 @@ date_setUTCMinutes_impl(JSContext* cx, C
 static bool
 date_setUTCMinutes(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setUTCMinutes_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-date_setHours_impl(JSContext* cx, CallArgs args)
+date_setHours_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = LocalTime(dateObj->UTCTime().toNumber(), &cx->runtime()->dateTimeInfo);
 
     /* Step 2. */
     double h;
@@ -1998,17 +1998,17 @@ date_setHours_impl(JSContext* cx, CallAr
 static bool
 date_setHours(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setHours_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-date_setUTCHours_impl(JSContext* cx, CallArgs args)
+date_setUTCHours_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = dateObj->UTCTime().toNumber();
 
     /* Step 2. */
     double h;
@@ -2045,17 +2045,17 @@ date_setUTCHours_impl(JSContext* cx, Cal
 static bool
 date_setUTCHours(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setUTCHours_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-date_setDate_impl(JSContext* cx, CallArgs args)
+date_setDate_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = LocalTime(dateObj->UTCTime().toNumber(), &cx->runtime()->dateTimeInfo);
 
     /* Step 2. */
     double date;
@@ -2077,17 +2077,17 @@ date_setDate_impl(JSContext* cx, CallArg
 static bool
 date_setDate(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setDate_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-date_setUTCDate_impl(JSContext* cx, CallArgs args)
+date_setUTCDate_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = dateObj->UTCTime().toNumber();
 
     /* Step 2. */
     double date;
@@ -2129,17 +2129,17 @@ GetMonthOrDefault(JSContext* cx, const C
         *month = MonthFromTime(t);
         return true;
     }
     return ToNumber(cx, args[i], month);
 }
 
 /* ES5 15.9.5.38. */
 MOZ_ALWAYS_INLINE bool
-date_setMonth_impl(JSContext* cx, CallArgs args)
+date_setMonth_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = LocalTime(dateObj->UTCTime().toNumber(), &cx->runtime()->dateTimeInfo);
 
     /* Step 2. */
     double m;
@@ -2166,17 +2166,17 @@ static bool
 date_setMonth(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setMonth_impl>(cx, args);
 }
 
 /* ES5 15.9.5.39. */
 MOZ_ALWAYS_INLINE bool
-date_setUTCMonth_impl(JSContext* cx, CallArgs args)
+date_setUTCMonth_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = dateObj->UTCTime().toNumber();
 
     /* Step 2. */
     double m;
@@ -2219,17 +2219,17 @@ static double
 ThisUTCTimeOrZero(Handle<DateObject*> dateObj)
 {
     double t = dateObj->as<DateObject>().UTCTime().toNumber();
     return IsNaN(t) ? +0 : t;
 }
 
 /* ES5 15.9.5.40. */
 MOZ_ALWAYS_INLINE bool
-date_setFullYear_impl(JSContext* cx, CallArgs args)
+date_setFullYear_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = ThisLocalTimeOrZero(dateObj, &cx->runtime()->dateTimeInfo);
 
     /* Step 2. */
     double y;
@@ -2261,17 +2261,17 @@ static bool
 date_setFullYear(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setFullYear_impl>(cx, args);
 }
 
 /* ES5 15.9.5.41. */
 MOZ_ALWAYS_INLINE bool
-date_setUTCFullYear_impl(JSContext* cx, CallArgs args)
+date_setUTCFullYear_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = ThisUTCTimeOrZero(dateObj);
 
     /* Step 2. */
     double y;
@@ -2303,17 +2303,17 @@ static bool
 date_setUTCFullYear(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setUTCFullYear_impl>(cx, args);
 }
 
 /* ES5 Annex B.2.5. */
 MOZ_ALWAYS_INLINE bool
-date_setYear_impl(JSContext* cx, CallArgs args)
+date_setYear_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     /* Step 1. */
     double t = ThisLocalTimeOrZero(dateObj, &cx->runtime()->dateTimeInfo);
 
     /* Step 2. */
     double y;
@@ -2402,17 +2402,17 @@ print_iso_extended_string(char* buf, siz
                 int(HourFromTime(utctime)),
                 int(MinFromTime(utctime)),
                 int(SecFromTime(utctime)),
                 int(msFromTime(utctime)));
 }
 
 /* ES5 B.2.6. */
 MOZ_ALWAYS_INLINE bool
-date_toGMTString_impl(JSContext* cx, CallArgs args)
+date_toGMTString_impl(JSContext* cx, const CallArgs& args)
 {
     double utctime = args.thisv().toObject().as<DateObject>().UTCTime().toNumber();
 
     char buf[100];
     if (!IsFinite(utctime))
         JS_snprintf(buf, sizeof buf, js_NaN_date_str);
     else
         print_gmt_string(buf, sizeof buf, utctime);
@@ -2428,17 +2428,17 @@ static bool
 date_toGMTString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_toGMTString_impl>(cx, args);
 }
 
 /* ES6 draft 2015-01-15 20.3.4.36. */
 MOZ_ALWAYS_INLINE bool
-date_toISOString_impl(JSContext* cx, CallArgs args)
+date_toISOString_impl(JSContext* cx, const CallArgs& args)
 {
     double utctime = args.thisv().toObject().as<DateObject>().UTCTime().toNumber();
     if (!IsFinite(utctime)) {
         JS_ReportErrorNumber(cx, js::GetErrorMessage, nullptr, JSMSG_INVALID_DATE);
         return false;
     }
 
     char buf[100];
@@ -2714,32 +2714,32 @@ ToLocaleStringHelper(JSContext* cx, Hand
 #else
                           "%c"
 #endif
                          , rval);
 }
 
 /* ES5 15.9.5.5. */
 MOZ_ALWAYS_INLINE bool
-date_toLocaleString_impl(JSContext* cx, CallArgs args)
+date_toLocaleString_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
     return ToLocaleStringHelper(cx, dateObj, args.rval());
 }
 
 static bool
 date_toLocaleString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_toLocaleString_impl>(cx, args);
 }
 
 /* ES5 15.9.5.6. */
 MOZ_ALWAYS_INLINE bool
-date_toLocaleDateString_impl(JSContext* cx, CallArgs args)
+date_toLocaleDateString_impl(JSContext* cx, const CallArgs& args)
 {
     /*
      * Use '%#x' for windows, because '%x' is backward-compatible and non-y2k
      * with msvc; '%#x' requests that a full year be used in the result string.
      */
     static const char format[] =
 #if defined(_WIN32) && !defined(__MWERKS__)
                                    "%#x"
@@ -2756,32 +2756,32 @@ static bool
 date_toLocaleDateString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_toLocaleDateString_impl>(cx, args);
 }
 
 /* ES5 15.9.5.7. */
 MOZ_ALWAYS_INLINE bool
-date_toLocaleTimeString_impl(JSContext* cx, CallArgs args)
+date_toLocaleTimeString_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
     return ToLocaleFormatHelper(cx, dateObj, "%X", args.rval());
 }
 
 static bool
 date_toLocaleTimeString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_toLocaleTimeString_impl>(cx, args);
 }
 #endif /* !EXPOSE_INTL_API */
 
 MOZ_ALWAYS_INLINE bool
-date_toLocaleFormat_impl(JSContext* cx, CallArgs args)
+date_toLocaleFormat_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
 
     if (args.length() == 0) {
         /*
          * Use '%#c' for windows, because '%c' is backward-compatible and non-y2k
          * with msvc; '%#c' requests that a full year be used in the result string.
          */
@@ -2809,47 +2809,47 @@ static bool
 date_toLocaleFormat(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_toLocaleFormat_impl>(cx, args);
 }
 
 /* ES5 15.9.5.4. */
 MOZ_ALWAYS_INLINE bool
-date_toTimeString_impl(JSContext* cx, CallArgs args)
+date_toTimeString_impl(JSContext* cx, const CallArgs& args)
 {
     return date_format(cx, args.thisv().toObject().as<DateObject>().UTCTime().toNumber(),
                        FORMATSPEC_TIME, args.rval());
 }
 
 static bool
 date_toTimeString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_toTimeString_impl>(cx, args);
 }
 
 /* ES5 15.9.5.3. */
 MOZ_ALWAYS_INLINE bool
-date_toDateString_impl(JSContext* cx, CallArgs args)
+date_toDateString_impl(JSContext* cx, const CallArgs& args)
 {
     return date_format(cx, args.thisv().toObject().as<DateObject>().UTCTime().toNumber(),
                        FORMATSPEC_DATE, args.rval());
 }
 
 static bool
 date_toDateString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_toDateString_impl>(cx, args);
 }
 
 #if JS_HAS_TOSOURCE
 MOZ_ALWAYS_INLINE bool
-date_toSource_impl(JSContext* cx, CallArgs args)
+date_toSource_impl(JSContext* cx, const CallArgs& args)
 {
     StringBuffer sb(cx);
     if (!sb.append("(new Date(") ||
         !NumberValueToStringBuffer(cx, args.thisv().toObject().as<DateObject>().UTCTime(), sb) ||
         !sb.append("))"))
     {
         return false;
     }
@@ -2891,17 +2891,17 @@ date_toString(JSContext* cx, unsigned ar
         if (cx->isExceptionPending())
             return false;
     }
     // Step 4.
     return date_format(cx, tv, FORMATSPEC_FULL, args.rval());
 }
 
 MOZ_ALWAYS_INLINE bool
-date_valueOf_impl(JSContext* cx, CallArgs args)
+date_valueOf_impl(JSContext* cx, const CallArgs& args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
     args.rval().set(dateObj->UTCTime());
     return true;
 }
 
 bool
 js::date_valueOf(JSContext* cx, unsigned argc, Value* vp)
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -136,17 +136,17 @@ ArgumentsRestrictions(JSContext* cx, Han
     {
         return false;
     }
 
     return true;
 }
 
 bool
-ArgumentsGetterImpl(JSContext* cx, CallArgs args)
+ArgumentsGetterImpl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsFunction(args.thisv()));
 
     RootedFunction fun(cx, &args.thisv().toObject().as<JSFunction>());
     if (!ArgumentsRestrictions(cx, fun))
         return false;
 
     // Return null if this function wasn't found on the stack.
@@ -173,17 +173,17 @@ ArgumentsGetterImpl(JSContext* cx, CallA
 static bool
 ArgumentsGetter(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsFunction, ArgumentsGetterImpl>(cx, args);
 }
 
 bool
-ArgumentsSetterImpl(JSContext* cx, CallArgs args)
+ArgumentsSetterImpl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsFunction(args.thisv()));
 
     RootedFunction fun(cx, &args.thisv().toObject().as<JSFunction>());
     if (!ArgumentsRestrictions(cx, fun))
         return false;
 
     // If the function passes the gauntlet, return |undefined|.
@@ -225,17 +225,17 @@ CallerRestrictions(JSContext* cx, Handle
     {
         return false;
     }
 
     return true;
 }
 
 bool
-CallerGetterImpl(JSContext* cx, CallArgs args)
+CallerGetterImpl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsFunction(args.thisv()));
 
     // Beware!  This function can be invoked on *any* function!  It can't
     // assume it'll never be invoked on natives, strict mode functions, bound
     // functions, or anything else that ordinarily has immutable .caller
     // defined with [[ThrowTypeError]].
     RootedFunction fun(cx, &args.thisv().toObject().as<JSFunction>());
@@ -286,17 +286,17 @@ CallerGetterImpl(JSContext* cx, CallArgs
 static bool
 CallerGetter(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsFunction, CallerGetterImpl>(cx, args);
 }
 
 bool
-CallerSetterImpl(JSContext* cx, CallArgs args)
+CallerSetterImpl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsFunction(args.thisv()));
 
     // Beware!  This function can be invoked on *any* function!  It can't
     // assume it'll never be invoked on natives, strict mode functions, bound
     // functions, or anything else that ordinarily has immutable .caller
     // defined with [[ThrowTypeError]].
     RootedFunction fun(cx, &args.thisv().toObject().as<JSFunction>());
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -930,17 +930,17 @@ NativeIteratorNext(JSContext* cx, Native
 
 MOZ_ALWAYS_INLINE bool
 IsIterator(HandleValue v)
 {
     return v.isObject() && v.toObject().hasClass(&PropertyIteratorObject::class_);
 }
 
 MOZ_ALWAYS_INLINE bool
-iterator_next_impl(JSContext* cx, CallArgs args)
+iterator_next_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsIterator(args.thisv()));
 
     RootedObject thisObj(cx, &args.thisv().toObject());
 
     NativeIterator* ni = thisObj.as<PropertyIteratorObject>()->getNativeIterator();
     RootedValue value(cx);
     bool done;
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -506,17 +506,17 @@ Extract(const Value& v)
 {
     if (v.isNumber())
         return v.toNumber();
     return v.toObject().as<NumberObject>().unbox();
 }
 
 #if JS_HAS_TOSOURCE
 MOZ_ALWAYS_INLINE bool
-num_toSource_impl(JSContext* cx, CallArgs args)
+num_toSource_impl(JSContext* cx, const CallArgs& args)
 {
     double d = Extract(args.thisv());
 
     StringBuffer sb(cx);
     if (!sb.append("(new Number(") ||
         !NumberValueToStringBuffer(cx, NumberValue(d), sb) ||
         !sb.append("))"))
     {
@@ -680,17 +680,17 @@ Int32ToCString(ToCStringBuf* cbuf, int32
     return cp.get();
 }
 
 template <AllowGC allowGC>
 static JSString*
 NumberToStringWithBase(ExclusiveContext* cx, double d, int base);
 
 MOZ_ALWAYS_INLINE bool
-num_toString_impl(JSContext* cx, CallArgs args)
+num_toString_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsNumber(args.thisv()));
 
     double d = Extract(args.thisv());
 
     int32_t base = 10;
     if (args.hasDefined(0)) {
         double d2;
@@ -717,17 +717,17 @@ bool
 js::num_toString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsNumber, num_toString_impl>(cx, args);
 }
 
 #if !EXPOSE_INTL_API
 MOZ_ALWAYS_INLINE bool
-num_toLocaleString_impl(JSContext* cx, CallArgs args)
+num_toLocaleString_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsNumber(args.thisv()));
 
     double d = Extract(args.thisv());
 
     RootedString str(cx, NumberToStringWithBase<CanGC>(cx, d, 10));
     if (!str) {
         JS_ReportOutOfMemory(cx);
@@ -851,17 +851,17 @@ static bool
 num_toLocaleString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsNumber, num_toLocaleString_impl>(cx, args);
 }
 #endif /* !EXPOSE_INTL_API */
 
 MOZ_ALWAYS_INLINE bool
-num_valueOf_impl(JSContext* cx, CallArgs args)
+num_valueOf_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsNumber(args.thisv()));
     args.rval().setNumber(Extract(args.thisv()));
     return true;
 }
 
 bool
 js::num_valueOf(JSContext* cx, unsigned argc, Value* vp)
@@ -886,17 +886,17 @@ ComputePrecisionInRange(JSContext* cx, i
 
     ToCStringBuf cbuf;
     if (char* numStr = NumberToCString(cx, &cbuf, prec, 10))
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PRECISION_RANGE, numStr);
     return false;
 }
 
 static bool
-DToStrResult(JSContext* cx, double d, JSDToStrMode mode, int precision, CallArgs args)
+DToStrResult(JSContext* cx, double d, JSDToStrMode mode, int precision, const CallArgs& args)
 {
     char buf[DTOSTR_VARIABLE_BUFFER_SIZE(MAX_PRECISION + 1)];
     char* numStr = js_dtostr(cx->mainThread().dtoaState, buf, sizeof buf, mode, precision, d);
     if (!numStr) {
         JS_ReportOutOfMemory(cx);
         return false;
     }
     JSString* str = NewStringCopyZ<CanGC>(cx, numStr);
@@ -906,17 +906,17 @@ DToStrResult(JSContext* cx, double d, JS
     return true;
 }
 
 /*
  * In the following three implementations, we allow a larger range of precision
  * than ECMA requires; this is permitted by ECMA-262.
  */
 MOZ_ALWAYS_INLINE bool
-num_toFixed_impl(JSContext* cx, CallArgs args)
+num_toFixed_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsNumber(args.thisv()));
 
     int precision;
     if (args.length() == 0) {
         precision = 0;
     } else {
         if (!ComputePrecisionInRange(cx, -20, MAX_PRECISION, args[0], &precision))
@@ -929,17 +929,17 @@ num_toFixed_impl(JSContext* cx, CallArgs
 static bool
 num_toFixed(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsNumber, num_toFixed_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-num_toExponential_impl(JSContext* cx, CallArgs args)
+num_toExponential_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsNumber(args.thisv()));
 
     JSDToStrMode mode;
     int precision;
     if (!args.hasDefined(0)) {
         mode = DTOSTR_STANDARD_EXPONENTIAL;
         precision = 0;
@@ -955,17 +955,17 @@ num_toExponential_impl(JSContext* cx, Ca
 static bool
 num_toExponential(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsNumber, num_toExponential_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-num_toPrecision_impl(JSContext* cx, CallArgs args)
+num_toPrecision_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsNumber(args.thisv()));
 
     double d = Extract(args.thisv());
 
     if (!args.hasDefined(0)) {
         JSString* str = NumberToStringWithBase<CanGC>(cx, d, 10);
         if (!str) {
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -68,17 +68,17 @@ using mozilla::Move;
 using mozilla::PodCopy;
 using mozilla::PodEqual;
 using mozilla::RangedPtr;
 using mozilla::UniquePtr;
 
 using JS::AutoCheckCannotGC;
 
 static JSLinearString*
-ArgToRootedString(JSContext* cx, CallArgs& args, unsigned argno)
+ArgToRootedString(JSContext* cx, const CallArgs& args, unsigned argno)
 {
     if (argno >= args.length())
         return cx->names().undefined;
 
     JSString* str = ToString<CanGC>(cx, args[argno]);
     if (!str)
         return nullptr;
 
@@ -485,17 +485,17 @@ MOZ_ALWAYS_INLINE bool
 IsString(HandleValue v)
 {
     return v.isString() || (v.isObject() && v.toObject().is<StringObject>());
 }
 
 #if JS_HAS_TOSOURCE
 
 MOZ_ALWAYS_INLINE bool
-str_toSource_impl(JSContext* cx, CallArgs args)
+str_toSource_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsString(args.thisv()));
 
     Rooted<JSString*> str(cx, ToString<CanGC>(cx, args.thisv()));
     if (!str)
         return false;
 
     str = QuoteString(cx, str, '"');
@@ -518,17 +518,17 @@ str_toSource(JSContext* cx, unsigned arg
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsString, str_toSource_impl>(cx, args);
 }
 
 #endif /* JS_HAS_TOSOURCE */
 
 MOZ_ALWAYS_INLINE bool
-str_toString_impl(JSContext* cx, CallArgs args)
+str_toString_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsString(args.thisv()));
 
     args.rval().setString(args.thisv().isString()
                               ? args.thisv().toString()
                               : args.thisv().toObject().as<StringObject>().unbox());
     return true;
 }
@@ -2092,17 +2092,17 @@ class MOZ_STACK_CLASS StringRegExpGuard
     }
 
   public:
     explicit StringRegExpGuard(JSContext* cx)
       : re_(cx), fm(cx), obj_(cx)
     { }
 
     /* init must succeed in order to call tryFlatMatch or normalizeRegExp. */
-    bool init(JSContext* cx, CallArgs args, bool convertVoid = false)
+    bool init(JSContext* cx, const CallArgs& args, bool convertVoid = false)
     {
         if (args.length() != 0 && IsObjectWithClass(args[0], ESClass_RegExp, cx))
             return init(cx, &args[0].toObject());
 
         if (convertVoid && !args.hasDefined(0)) {
             fm.pat_ = cx->runtime()->emptyString;
             return true;
         }
@@ -2170,17 +2170,17 @@ class MOZ_STACK_CLASS StringRegExpGuard
         } else {
             fm.match_ = StringMatch(&text->asLinear(), fm.pat_, 0);
         }
 
         return &fm;
     }
 
     /* If the pattern is not already a regular expression, make it so. */
-    bool normalizeRegExp(JSContext* cx, bool flat, unsigned optarg, CallArgs args)
+    bool normalizeRegExp(JSContext* cx, bool flat, unsigned optarg, const CallArgs& args)
     {
         if (re_.initialized())
             return true;
 
         /* Build RegExp from pattern string. */
         RootedString opt(cx);
         if (optarg < args.length()) {
             if (JSScript* script = cx->currentScript()) {
@@ -2245,17 +2245,17 @@ class MOZ_STACK_CLASS StringRegExpGuard
   private:
     StringRegExpGuard(const StringRegExpGuard&) = delete;
     void operator=(const StringRegExpGuard&) = delete;
 };
 
 } /* anonymous namespace */
 
 static bool
-DoMatchLocal(JSContext* cx, CallArgs args, RegExpStatics* res, HandleLinearString input,
+DoMatchLocal(JSContext* cx, const CallArgs& args, RegExpStatics* res, HandleLinearString input,
              RegExpShared& re)
 {
     ScopedMatchPairs matches(&cx->tempLifoAlloc());
     RegExpRunStatus status = re.execute(cx, input, 0, &matches);
     if (status == RegExpRunStatus_Error)
         return false;
 
     if (status == RegExpRunStatus_Success_NotFound) {
@@ -2271,17 +2271,17 @@ DoMatchLocal(JSContext* cx, CallArgs arg
         return false;
 
     args.rval().set(rval);
     return true;
 }
 
 /* ES5 15.5.4.10 step 8. */
 static bool
-DoMatchGlobal(JSContext* cx, CallArgs args, RegExpStatics* res, HandleLinearString input,
+DoMatchGlobal(JSContext* cx, const CallArgs& args, RegExpStatics* res, HandleLinearString input,
               StringRegExpGuard& g)
 {
     // Step 8a.
     //
     // This single zeroing of "lastIndex" covers all "lastIndex" changes in the
     // rest of String.prototype.match, particularly in steps 8f(i) and
     // 8f(iii)(2)(a).  Here's why.
     //
@@ -3331,17 +3331,17 @@ StrReplaceRegExp(JSContext* cx, ReplaceD
     if (!retstr)
         return false;
 
     rval.setString(retstr);
     return true;
 }
 
 static inline bool
-str_replace_regexp(JSContext* cx, CallArgs args, ReplaceData& rdata)
+str_replace_regexp(JSContext* cx, const CallArgs& args, ReplaceData& rdata)
 {
     if (!rdata.g.normalizeRegExp(cx, true, 2, args))
         return false;
 
     return StrReplaceRegExp(cx, rdata, args.rval());
 }
 
 bool
@@ -3407,17 +3407,18 @@ js::str_replace_string_raw(JSContext* cx
         rval.setString(string);
         return true;
     }
 
     return StrReplaceString(cx, rdata, *fm, rval);
 }
 
 static inline bool
-str_replace_flat_lambda(JSContext* cx, CallArgs outerArgs, ReplaceData& rdata, const FlatMatch& fm)
+str_replace_flat_lambda(JSContext* cx, const CallArgs& outerArgs, ReplaceData& rdata,
+                        const FlatMatch& fm)
 {
     RootedString matchStr(cx, NewDependentString(cx, rdata.str, fm.match(), fm.patternLength()));
     if (!matchStr)
         return false;
 
     /* lambda(matchStr, matchStart, textstr) */
     static const uint32_t lambdaArgc = 3;
     if (!rdata.fig.args().init(lambdaArgc))
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -216,17 +216,17 @@ ObjectValueMap::findZoneEdges()
 
 MOZ_ALWAYS_INLINE bool
 IsWeakMap(HandleValue v)
 {
     return v.isObject() && v.toObject().is<WeakMapObject>();
 }
 
 MOZ_ALWAYS_INLINE bool
-WeakMap_has_impl(JSContext* cx, CallArgs args)
+WeakMap_has_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsWeakMap(args.thisv()));
 
     if (!args.get(0).isObject()) {
         args.rval().setBoolean(false);
         return true;
     }
 
@@ -245,17 +245,17 @@ WeakMap_has_impl(JSContext* cx, CallArgs
 bool
 js::WeakMap_has(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsWeakMap, WeakMap_has_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-WeakMap_clear_impl(JSContext* cx, CallArgs args)
+WeakMap_clear_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsWeakMap(args.thisv()));
 
     // We can't js_delete the weakmap because the data gathered during GC is
     // used by the Cycle Collector.
     if (ObjectValueMap* map = args.thisv().toObject().as<WeakMapObject>().getMap())
         map->clear();
 
@@ -266,17 +266,17 @@ WeakMap_clear_impl(JSContext* cx, CallAr
 bool
 js::WeakMap_clear(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsWeakMap, WeakMap_clear_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-WeakMap_get_impl(JSContext* cx, CallArgs args)
+WeakMap_get_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsWeakMap(args.thisv()));
 
     if (!args.get(0).isObject()) {
         args.rval().setUndefined();
         return true;
     }
 
@@ -295,17 +295,17 @@ WeakMap_get_impl(JSContext* cx, CallArgs
 bool
 js::WeakMap_get(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsWeakMap, WeakMap_get_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
-WeakMap_delete_impl(JSContext* cx, CallArgs args)
+WeakMap_delete_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsWeakMap(args.thisv()));
 
     if (!args.get(0).isObject()) {
         args.rval().setBoolean(false);
         return true;
     }
 
@@ -387,17 +387,17 @@ SetWeakMapEntryInternal(JSContext* cx, H
         JS_ReportOutOfMemory(cx);
         return false;
     }
     WeakMapPostWriteBarrier(cx->runtime(), map, key.get());
     return true;
 }
 
 MOZ_ALWAYS_INLINE bool
-WeakMap_set_impl(JSContext* cx, CallArgs args)
+WeakMap_set_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsWeakMap(args.thisv()));
 
     if (!args.get(0).isObject()) {
         UniquePtr<char[], JS::FreePolicy> bytes =
             DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, args.get(0), nullptr);
         if (!bytes)
             return false;
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -142,17 +142,17 @@ class JS_FRIEND_API(CrossCompartmentWrap
 
     /* SpiderMonkey extensions. */
     virtual bool getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
                                        MutableHandle<JSPropertyDescriptor> desc) const override;
     virtual bool hasOwn(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const override;
     virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject wrapper,
                                               AutoIdVector& props) const override;
     virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                            CallArgs args) const override;
+                            const CallArgs& args) const override;
     virtual bool hasInstance(JSContext* cx, HandleObject wrapper, MutableHandleValue v,
                              bool* bp) const override;
     virtual const char* className(JSContext* cx, HandleObject proxy) const override;
     virtual JSString* fun_toString(JSContext* cx, HandleObject wrapper,
                                    unsigned indent) const override;
     virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override;
     virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override;
     virtual bool defaultValue(JSContext* cx, HandleObject wrapper, JSType hint,
@@ -239,17 +239,17 @@ class JS_FRIEND_API(SecurityWrapper) : p
     virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override;
     virtual bool preventExtensions(JSContext* cx, HandleObject wrapper,
                                    ObjectOpResult& result) const override;
     virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto,
                               ObjectOpResult& result) const override;
     virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const override;
 
     virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                            CallArgs args) const override;
+                            const CallArgs& args) const override;
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
                                JSContext* cx) const override;
     virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override;
     virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override;
     virtual bool defaultValue(JSContext* cx, HandleObject wrapper, JSType hint,
                               MutableHandleValue vp) const override;
 
     // Allow isCallable and isConstructor. They used to be class-level, and so could not be guarded
--- a/js/src/proxy/BaseProxyHandler.cpp
+++ b/js/src/proxy/BaseProxyHandler.cpp
@@ -294,17 +294,17 @@ bool
 BaseProxyHandler::defaultValue(JSContext* cx, HandleObject proxy, JSType hint,
                                MutableHandleValue vp) const
 {
     return OrdinaryToPrimitive(cx, proxy, hint, vp);
 }
 
 bool
 BaseProxyHandler::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                             CallArgs args) const
+                             const CallArgs& args) const
 {
     ReportIncompatible(cx, args);
     return false;
 }
 
 bool
 BaseProxyHandler::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
                               bool* bp) const
--- a/js/src/proxy/CrossCompartmentWrapper.cpp
+++ b/js/src/proxy/CrossCompartmentWrapper.cpp
@@ -309,17 +309,17 @@ CrossCompartmentWrapper::construct(JSCon
         if (!Wrapper::construct(cx, wrapper, args))
             return false;
     }
     return cx->compartment()->wrap(cx, args.rval());
 }
 
 bool
 CrossCompartmentWrapper::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                                    CallArgs srcArgs) const
+                                    const CallArgs& srcArgs) const
 {
     RootedObject wrapper(cx, &srcArgs.thisv().toObject());
     MOZ_ASSERT(srcArgs.thisv().isMagic(JS_IS_CONSTRUCTING) ||
                !UncheckedUnwrap(wrapper)->is<CrossCompartmentWrapperObject>());
 
     RootedObject wrapped(cx, wrappedObject(wrapper));
     {
         AutoCompartment call(cx, wrapped);
--- a/js/src/proxy/DeadObjectProxy.cpp
+++ b/js/src/proxy/DeadObjectProxy.cpp
@@ -94,17 +94,17 @@ bool
 DeadObjectProxy::construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const
 {
     ReportDead(cx);
     return false;
 }
 
 bool
 DeadObjectProxy::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                            CallArgs args) const
+                            const CallArgs& args) const
 {
     ReportDead(cx);
     return false;
 }
 
 bool
 DeadObjectProxy::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
                              bool* bp) const
--- a/js/src/proxy/DeadObjectProxy.h
+++ b/js/src/proxy/DeadObjectProxy.h
@@ -35,17 +35,17 @@ class DeadObjectProxy : public BaseProxy
                                    ObjectOpResult& result) const override;
     virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const override;
     virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
     virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
 
     /* SpiderMonkey extensions. */
     // BaseProxyHandler::getPropertyDescriptor will throw by calling getOwnPropertyDescriptor.
     virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                            CallArgs args) const override;
+                            const CallArgs& args) const override;
     virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
                              bool* bp) const override;
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
                                JSContext* cx) const override;
     virtual const char* className(JSContext* cx, HandleObject proxy) const override;
     virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const override;
     virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override;
     virtual bool defaultValue(JSContext* cx, HandleObject obj, JSType hint,
--- a/js/src/proxy/DirectProxyHandler.cpp
+++ b/js/src/proxy/DirectProxyHandler.cpp
@@ -92,17 +92,17 @@ DirectProxyHandler::construct(JSContext*
     if (!FillArgumentsFromArraylike(cx, cargs, args))
         return false;
 
     return Construct(cx, target, cargs, args.newTarget(), args.rval());
 }
 
 bool
 DirectProxyHandler::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                               CallArgs args) const
+                               const CallArgs& args) const
 {
     args.setThis(ObjectValue(*args.thisv().toObject().as<ProxyObject>().target()));
     if (!test(args.thisv())) {
         ReportIncompatible(cx, args);
         return false;
     }
 
     return CallNativeImpl(cx, impl, args);
--- a/js/src/proxy/Proxy.cpp
+++ b/js/src/proxy/Proxy.cpp
@@ -427,17 +427,17 @@ Proxy::construct(JSContext* cx, HandleOb
         args.rval().setUndefined();
         return policy.returnValue();
     }
 
     return handler->construct(cx, proxy, args);
 }
 
 bool
-Proxy::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, CallArgs args)
+Proxy::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, const CallArgs& args)
 {
     JS_CHECK_RECURSION(cx, return false);
     RootedObject proxy(cx, &args.thisv().toObject());
     // Note - we don't enter a policy here because our security architecture
     // guards against nativeCall by overriding the trap itself in the right
     // circumstances.
     return proxy->as<ProxyObject>().handler()->nativeCall(cx, test, impl, args);
 }
--- a/js/src/proxy/Proxy.h
+++ b/js/src/proxy/Proxy.h
@@ -48,17 +48,18 @@ class Proxy
     static bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args);
 
     /* SpiderMonkey extensions. */
     static bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
                                       MutableHandle<JSPropertyDescriptor> desc);
     static bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp);
     static bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy,
                                              AutoIdVector& props);
-    static bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
+    static bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
+                           const CallArgs& args);
     static bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, bool* bp);
     static bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext* cx);
     static const char* className(JSContext* cx, HandleObject proxy);
     static JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent);
     static bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g);
     static bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp);
     static bool defaultValue(JSContext* cx, HandleObject obj, JSType hint, MutableHandleValue vp);
 
--- a/js/src/proxy/ScriptedDirectProxyHandler.cpp
+++ b/js/src/proxy/ScriptedDirectProxyHandler.cpp
@@ -1075,17 +1075,17 @@ ScriptedDirectProxyHandler::construct(JS
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_CONSTRUCT_OBJECT);
         return false;
     }
     return true;
 }
 
 bool
 ScriptedDirectProxyHandler::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                                       CallArgs args) const
+                                       const CallArgs& args) const
 {
     ReportIncompatible(cx, args);
     return false;
 }
 
 bool
 ScriptedDirectProxyHandler::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
                                         bool* bp) const
--- a/js/src/proxy/ScriptedDirectProxyHandler.h
+++ b/js/src/proxy/ScriptedDirectProxyHandler.h
@@ -62,17 +62,17 @@ class ScriptedDirectProxyHandler : publi
     // the target's properties.
     virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy,
                                               AutoIdVector& props) const override {
         return BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, proxy, props);
     }
 
     // A scripted proxy should not be treated as generic in most contexts.
     virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                            CallArgs args) const override;
+                            const CallArgs& args) const override;
     virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
                              bool* bp) const override;
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
                                JSContext* cx) const override;
     virtual const char* className(JSContext* cx, HandleObject proxy) const override;
     virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
                                    unsigned indent) const override;
     virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
--- a/js/src/proxy/ScriptedIndirectProxyHandler.cpp
+++ b/js/src/proxy/ScriptedIndirectProxyHandler.cpp
@@ -421,17 +421,17 @@ ScriptedIndirectProxyHandler::getOwnEnum
     if (!IsCallable(value))
         return BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, proxy, props);
     return Trap(cx, handler, value, 0, nullptr, &value) &&
            ArrayToIdVector(cx, value, props);
 }
 
 bool
 ScriptedIndirectProxyHandler::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                                         CallArgs args) const
+                                         const CallArgs& args) const
 {
     return BaseProxyHandler::nativeCall(cx, test, impl, args);
 }
 
 JSString*
 ScriptedIndirectProxyHandler::fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const
 {
     assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
--- a/js/src/proxy/ScriptedIndirectProxyHandler.h
+++ b/js/src/proxy/ScriptedIndirectProxyHandler.h
@@ -42,17 +42,17 @@ class ScriptedIndirectProxyHandler : pub
 
     /* SpiderMonkey extensions. */
     virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
                                        MutableHandle<JSPropertyDescriptor> desc) const override;
     virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const override;
     virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy,
                                               AutoIdVector& props) const override;
     virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                            CallArgs args) const override;
+                            const CallArgs& args) const override;
     virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const override;
     virtual bool isScripted() const override { return true; }
 
     static const char family;
     static const ScriptedIndirectProxyHandler singleton;
 
 private:
     bool derivedSet(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v,
--- a/js/src/proxy/SecurityWrapper.cpp
+++ b/js/src/proxy/SecurityWrapper.cpp
@@ -25,17 +25,17 @@ SecurityWrapper<Base>::enter(JSContext* 
     ReportUnwrapDenied(cx);
     *bp = false;
     return false;
 }
 
 template <class Base>
 bool
 SecurityWrapper<Base>::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                                  CallArgs args) const
+                                  const CallArgs& args) const
 {
     ReportUnwrapDenied(cx);
     return false;
 }
 
 template <class Base>
 bool
 SecurityWrapper<Base>::setPrototype(JSContext* cx, HandleObject wrapper, HandleObject proto,
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -168,32 +168,32 @@ js::AsArrayBuffer(HandleObject obj)
 ArrayBufferObject&
 js::AsArrayBuffer(JSObject* obj)
 {
     MOZ_ASSERT(IsArrayBuffer(obj));
     return obj->as<ArrayBufferObject>();
 }
 
 MOZ_ALWAYS_INLINE bool
-ArrayBufferObject::byteLengthGetterImpl(JSContext* cx, CallArgs args)
+ArrayBufferObject::byteLengthGetterImpl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsArrayBuffer(args.thisv()));
     args.rval().setInt32(args.thisv().toObject().as<ArrayBufferObject>().byteLength());
     return true;
 }
 
 bool
 ArrayBufferObject::byteLengthGetter(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsArrayBuffer, byteLengthGetterImpl>(cx, args);
 }
 
 bool
-ArrayBufferObject::fun_slice_impl(JSContext* cx, CallArgs args)
+ArrayBufferObject::fun_slice_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsArrayBuffer(args.thisv()));
 
     Rooted<ArrayBufferObject*> thisObj(cx, &args.thisv().toObject().as<ArrayBufferObject>());
 
     // these are the default values
     uint32_t length = thisObj->byteLength();
     uint32_t begin = 0, end = length;
@@ -261,18 +261,18 @@ ReleaseAsmJSMappedData(void* base)
 {
     MOZ_CRASH("asm.js only uses mapped buffers when using signal-handler OOB checking");
 }
 #endif
 
 #ifdef NIGHTLY_BUILD
 # if defined(ASMJS_MAY_USE_SIGNAL_HANDLERS_FOR_OOB)
 static bool
-TransferAsmJSMappedBuffer(JSContext* cx, CallArgs args, Handle<ArrayBufferObject*> oldBuffer,
-                          size_t newByteLength)
+TransferAsmJSMappedBuffer(JSContext* cx, const CallArgs& args,
+                          Handle<ArrayBufferObject*> oldBuffer, size_t newByteLength)
 {
     size_t oldByteLength = oldBuffer->byteLength();
     MOZ_ASSERT(oldByteLength % AsmJSPageSize == 0);
     MOZ_ASSERT(newByteLength % AsmJSPageSize == 0);
 
     ArrayBufferObject::BufferContents stolen =
         ArrayBufferObject::stealContents(cx, oldBuffer, /* hasStealableContents = */ true);
     if (!stolen)
@@ -858,17 +858,17 @@ ArrayBufferObject::createSlice(JSContext
     ArrayBufferObject* slice = create(cx, length);
     if (!slice)
         return nullptr;
     memcpy(slice->dataPointer(), arrayBuffer->dataPointer() + begin, length);
     return slice;
 }
 
 bool
-ArrayBufferObject::createDataViewForThisImpl(JSContext* cx, CallArgs args)
+ArrayBufferObject::createDataViewForThisImpl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsArrayBuffer(args.thisv()));
 
     /*
      * This method is only called for |DataView(alienBuf, ...)| which calls
      * this as |createDataViewForThis.call(alienBuf, ..., DataView.prototype)|,
      * ergo there must be at least two arguments.
      */
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -99,18 +99,18 @@ class ArrayBufferObjectMaybeShared : pub
  * lazily when it is first accessed for a TypedArrayObject or TypedObject that
  * doesn't have an explicit buffer.
  *
  * ArrayBufferObject (or really the underlying memory) /is not racy/: the
  * memory is private to a single worker.
  */
 class ArrayBufferObject : public ArrayBufferObjectMaybeShared
 {
-    static bool byteLengthGetterImpl(JSContext* cx, CallArgs args);
-    static bool fun_slice_impl(JSContext* cx, CallArgs args);
+    static bool byteLengthGetterImpl(JSContext* cx, const CallArgs& args);
+    static bool fun_slice_impl(JSContext* cx, const CallArgs& args);
 
   public:
     static const uint8_t DATA_SLOT = 0;
     static const uint8_t BYTE_LENGTH_SLOT = 1;
     static const uint8_t FIRST_VIEW_SLOT = 2;
     static const uint8_t FLAGS_SLOT = 3;
 
     static const uint8_t RESERVED_SLOTS = 4;
@@ -222,21 +222,21 @@ class ArrayBufferObject : public ArrayBu
                                      OwnsState ownsState = OwnsData,
                                      NewObjectKind newKind = GenericObject);
     static ArrayBufferObject* create(JSContext* cx, uint32_t nbytes,
                                      NewObjectKind newKind = GenericObject);
 
     static JSObject* createSlice(JSContext* cx, Handle<ArrayBufferObject*> arrayBuffer,
                                  uint32_t begin, uint32_t end);
 
-    static bool createDataViewForThisImpl(JSContext* cx, CallArgs args);
+    static bool createDataViewForThisImpl(JSContext* cx, const CallArgs& args);
     static bool createDataViewForThis(JSContext* cx, unsigned argc, Value* vp);
 
     template<typename T>
-    static bool createTypedArrayFromBufferImpl(JSContext* cx, CallArgs args);
+    static bool createTypedArrayFromBufferImpl(JSContext* cx, const CallArgs& args);
 
     template<typename T>
     static bool createTypedArrayFromBuffer(JSContext* cx, unsigned argc, Value* vp);
 
     static void trace(JSTracer* trc, JSObject* obj);
     static void objectMoved(JSObject* obj, const JSObject* old);
 
     static BufferContents stealContents(JSContext* cx,
--- a/js/src/vm/CallNonGenericMethod.cpp
+++ b/js/src/vm/CallNonGenericMethod.cpp
@@ -11,17 +11,17 @@
 
 #include "proxy/Proxy.h"
 #include "vm/ProxyObject.h"
 
 using namespace js;
 
 bool
 JS::detail::CallMethodIfWrapped(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
-                                CallArgs args)
+                                const CallArgs& args)
 {
     HandleValue thisv = args.thisv();
     MOZ_ASSERT(!test(thisv));
 
     if (thisv.isObject()) {
         JSObject& thisObj = args.thisv().toObject();
         if (thisObj.is<ProxyObject>())
             return Proxy::nativeCall(cx, test, impl, args);
--- a/js/src/vm/DateObject.h
+++ b/js/src/vm/DateObject.h
@@ -60,30 +60,30 @@ class DateObject : public NativeObject
 
     inline double cachedLocalTime(DateTimeInfo* dtInfo);
 
     // Cache the local time, year, month, and so forth of the object.
     // If UTC time is not finite (e.g., NaN), the local time
     // slots will be set to the UTC time without conversion.
     void fillLocalTimeSlots(DateTimeInfo* dtInfo);
 
-    static MOZ_ALWAYS_INLINE bool getTime_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getYear_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getFullYear_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getUTCFullYear_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getMonth_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getUTCMonth_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getDate_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getUTCDate_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getDay_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getUTCDay_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getHours_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getUTCHours_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getMinutes_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getUTCMinutes_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getUTCSeconds_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getUTCMilliseconds_impl(JSContext* cx, CallArgs args);
-    static MOZ_ALWAYS_INLINE bool getTimezoneOffset_impl(JSContext* cx, CallArgs args);
+    static MOZ_ALWAYS_INLINE bool getTime_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getYear_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getFullYear_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getUTCFullYear_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getMonth_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getUTCMonth_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getDate_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getUTCDate_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getDay_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getUTCDay_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getHours_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getUTCHours_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getMinutes_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getUTCMinutes_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getUTCSeconds_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getUTCMilliseconds_impl(JSContext* cx, const CallArgs& args);
+    static MOZ_ALWAYS_INLINE bool getTimezoneOffset_impl(JSContext* cx, const CallArgs& args);
 };
 
 } // namespace js
 
 #endif // vm_DateObject_h_
--- a/js/src/vm/ErrorObject.cpp
+++ b/js/src/vm/ErrorObject.cpp
@@ -226,17 +226,17 @@ IsObject(HandleValue v)
 js::ErrorObject::setStack(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     // We accept any object here, because of poor-man's subclassing of Error.
     return CallNonGenericMethod<IsObject, setStack_impl>(cx, args);
 }
 
 /* static */ bool
-js::ErrorObject::setStack_impl(JSContext* cx, CallArgs args)
+js::ErrorObject::setStack_impl(JSContext* cx, const CallArgs& args)
 {
     const Value& thisValue = args.thisv();
     MOZ_ASSERT(thisValue.isObject());
     RootedObject thisObj(cx, &thisValue.toObject());
 
     if (!args.requireAtLeast(cx, "(set stack)", 1))
         return false;
     RootedValue val(cx, args[0]);
--- a/js/src/vm/ErrorObject.h
+++ b/js/src/vm/ErrorObject.h
@@ -103,17 +103,17 @@ class ErrorObject : public NativeObject
     JSString * getMessage() const {
         const HeapSlot& slot = getReservedSlotRef(MESSAGE_SLOT);
         return slot.isString() ? slot.toString() : nullptr;
     }
 
     // Getter and setter for the Error.prototype.stack accessor.
     static bool getStack(JSContext* cx, unsigned argc, Value* vp);
     static bool setStack(JSContext* cx, unsigned argc, Value* vp);
-    static bool setStack_impl(JSContext* cx, CallArgs args);
+    static bool setStack_impl(JSContext* cx, const CallArgs& args);
 };
 
 } // namespace js
 
 template<>
 inline bool
 JSObject::is<js::ErrorObject>() const
 {
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -716,17 +716,17 @@ struct AutoGCIfRequested
 
 /*
  * Find a function reference and its 'this' value implicit first parameter
  * under argc arguments on cx's stack, and call the function.  Push missing
  * required arguments, allocate declared local variables, and pop everything
  * when done.  Then push the return value.
  */
 bool
-js::Invoke(JSContext* cx, CallArgs args, MaybeConstruct construct)
+js::Invoke(JSContext* cx, const CallArgs& args, MaybeConstruct construct)
 {
     MOZ_ASSERT(args.length() <= ARGS_LENGTH_MAX);
     MOZ_ASSERT(!cx->zone()->types.activeAnalysis);
 
     /* Perform GC if necessary on exit from the function. */
     AutoGCIfRequested gcIfRequested(cx->runtime());
 
     /* MaybeConstruct is a subset of InitialFrameFlags */
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -59,17 +59,17 @@ extern JSObject*
 ValueToCallable(JSContext* cx, HandleValue v, int numToSkip = -1,
                 MaybeConstruct construct = NO_CONSTRUCT);
 
 /*
  * Invoke assumes that the given args have been pushed on the top of the
  * VM stack.
  */
 extern bool
-Invoke(JSContext* cx, CallArgs args, MaybeConstruct construct = NO_CONSTRUCT);
+Invoke(JSContext* cx, const CallArgs& args, MaybeConstruct construct = NO_CONSTRUCT);
 
 /*
  * This Invoke overload places the least requirements on the caller: it may be
  * called at any time and it takes care of copying the given callee, this, and
  * arguments onto the stack.
  */
 extern bool
 Invoke(JSContext* cx, const Value& thisv, const Value& fval, unsigned argc, const Value* argv,
@@ -204,33 +204,33 @@ class ExecuteState : public RunState
         if (result_)
             *result_ = v;
     }
 };
 
 // Data to invoke a function.
 class InvokeState : public RunState
 {
-    CallArgs& args_;
+    const CallArgs& args_;
     InitialFrameFlags initial_;
     bool createSingleton_;
 
   public:
-    InvokeState(JSContext* cx, CallArgs& args, InitialFrameFlags initial)
+    InvokeState(JSContext* cx, const CallArgs& args, InitialFrameFlags initial)
       : RunState(cx, Invoke, args.callee().as<JSFunction>().nonLazyScript()),
         args_(args),
         initial_(initial),
         createSingleton_(false)
     { }
 
     bool createSingleton() const { return createSingleton_; }
     void setCreateSingleton() { createSingleton_ = true; }
 
     bool constructing() const { return InitialFrameFlagsAreConstructing(initial_); }
-    CallArgs& args() const { return args_; }
+    const CallArgs& args() const { return args_; }
 
     virtual InterpreterFrame* pushInterpreterFrame(JSContext* cx);
 
     virtual void setReturnValue(Value v) {
         args_.rval().set(v);
     }
 };
 
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1141,17 +1141,17 @@ js::intrinsic_SetOverlappingTypedElement
     CopyToDisjointArray(target, targetOffset, copyOfSrcData.get(),
                         unsafeSrcTypeCrossCompartment, count);
 
     args.rval().setUndefined();
     return true;
 }
 
 bool
-CallSelfHostedNonGenericMethod(JSContext* cx, CallArgs args)
+CallSelfHostedNonGenericMethod(JSContext* cx, const CallArgs& args)
 {
     // This function is called when a self-hosted method is invoked on a
     // wrapper object, like a CrossCompartmentWrapper. The last argument is
     // the name of the self-hosted function. The other arguments are the
     // arguments to pass to this function.
 
     MOZ_ASSERT(args.length() > 0);
     RootedPropertyName name(cx, args[args.length() - 1].toString()->asAtom().asPropertyName());
--- a/js/src/vm/SharedArrayObject.cpp
+++ b/js/src/vm/SharedArrayObject.cpp
@@ -174,17 +174,17 @@ const JSFunctionSpec SharedArrayBufferOb
 };
 
 const JSFunctionSpec SharedArrayBufferObject::jsstaticfuncs[] = {
     JS_FN("isView", SharedArrayBufferObject::fun_isView, 1, 0),
     JS_FS_END
 };
 
 MOZ_ALWAYS_INLINE bool
-SharedArrayBufferObject::byteLengthGetterImpl(JSContext* cx, CallArgs args)
+SharedArrayBufferObject::byteLengthGetterImpl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsSharedArrayBuffer(args.thisv()));
     args.rval().setInt32(args.thisv().toObject().as<SharedArrayBufferObject>().byteLength());
     return true;
 }
 
 bool
 SharedArrayBufferObject::byteLengthGetter(JSContext* cx, unsigned argc, Value* vp)
--- a/js/src/vm/SharedArrayObject.h
+++ b/js/src/vm/SharedArrayObject.h
@@ -103,17 +103,17 @@ class SharedArrayRawBuffer
  * racy/: more than one worker can access the memory at the same time.
  *
  * A SharedTypedArrayObject (a view) references a SharedArrayBuffer
  * and keeps it alive.  The SharedArrayBuffer does /not/ reference its
  * views, nor do the views reference each other in any way.
  */
 class SharedArrayBufferObject : public ArrayBufferObjectMaybeShared
 {
-    static bool byteLengthGetterImpl(JSContext* cx, CallArgs args);
+    static bool byteLengthGetterImpl(JSContext* cx, const CallArgs& args);
 
   public:
     // RAWBUF_SLOT holds a pointer (as "private" data) to the
     // SharedArrayRawBuffer object, which is manually managed storage.
     static const uint8_t RAWBUF_SLOT = 0;
 
     static const uint8_t RESERVED_SLOTS = 1;
 
--- a/js/src/vm/SharedTypedArrayObject.cpp
+++ b/js/src/vm/SharedTypedArrayObject.cpp
@@ -304,17 +304,17 @@ class SharedTypedArrayObjectTemplate : p
             }
         }
 
         return fromBuffer(cx, dataObj, byteOffset, length);
     }
 
     template<Value ValueGetter(SharedTypedArrayObject* tarr)>
     static bool
-    GetterImpl(JSContext* cx, CallArgs args)
+    GetterImpl(JSContext* cx, const CallArgs& args)
     {
         MOZ_ASSERT(is(args.thisv()));
         args.rval().set(ValueGetter(&args.thisv().toObject().as<SharedTypedArrayObject>()));
         return true;
     }
 
     // ValueGetter is a function that takes an unwrapped typed array object and
     // returns a Value. Given such a function, Getter<> is a native that
@@ -323,17 +323,17 @@ class SharedTypedArrayObjectTemplate : p
     static bool
     Getter(JSContext* cx, unsigned argc, Value* vp)
     {
         CallArgs args = CallArgsFromVp(argc, vp);
         return CallNonGenericMethod(cx, is, GetterImpl<ValueGetter>, args);
     }
 
     static bool
-    BufferGetterImpl(JSContext* cx, CallArgs args)
+    BufferGetterImpl(JSContext* cx, const CallArgs& args)
     {
         MOZ_ASSERT(is(args.thisv()));
         Rooted<SharedTypedArrayObject*> tarray(cx, &args.thisv().toObject().as<SharedTypedArrayObject>());
         args.rval().set(bufferValue(tarray));
         return true;
     }
 
     static bool
--- a/js/src/vm/TypedArrayCommon.h
+++ b/js/src/vm/TypedArrayCommon.h
@@ -483,17 +483,17 @@ class TypedArrayMethods
   public:
     // subarray(start[, end])
     // %TypedArray%.prototype.subarray is a self-hosted method, so this code is
     // only used for shared typed arrays.  We should self-host both methods
     // eventually (but note TypedArraySubarray will require changes to be used
     // with shared typed arrays), but we need to rejigger the shared typed
     // array prototype chain before we can do that.
     static bool
-    subarray(JSContext* cx, CallArgs args)
+    subarray(JSContext* cx, const CallArgs& args)
     {
         MOZ_ASSERT(SomeTypedArray::is(args.thisv()));
 
         Rooted<SomeTypedArray*> tarray(cx, &args.thisv().toObject().as<SomeTypedArray>());
 
         // These are the default values.
         uint32_t initialLength = tarray->length();
         uint32_t begin = 0, end = initialLength;
@@ -575,17 +575,17 @@ class TypedArrayMethods
     /* copyWithin(target, start[, end]) */
     // ES6 draft rev 26, 22.2.3.5
     // %TypedArray%.prototype.copyWithin is a self-hosted method, so this code
     // is only used for shared typed arrays.  We should self-host both methods
     // eventually (but note TypedArrayCopyWithin will require changes to be
     // usable for shared typed arrays), but we need to rejigger the shared
     // typed array prototype chain before we can do that.
     static bool
-    copyWithin(JSContext* cx, CallArgs args)
+    copyWithin(JSContext* cx, const CallArgs& args)
     {
         MOZ_ASSERT(SomeTypedArray::is(args.thisv()));
 
         // Steps 1-2.
         Rooted<SomeTypedArray*> obj(cx, &args.thisv().toObject().as<SomeTypedArray>());
 
         // Steps 3-4.
         uint32_t len = obj->length();
@@ -662,17 +662,17 @@ class TypedArrayMethods
 
         // Step 19.
         args.rval().set(args.thisv());
         return true;
     }
 
     /* set(array[, offset]) */
     static bool
-    set(JSContext* cx, CallArgs args)
+    set(JSContext* cx, const CallArgs& args)
     {
         MOZ_ASSERT(SomeTypedArray::is(args.thisv()));
 
         Rooted<SomeTypedArray*> target(cx, &args.thisv().toObject().as<SomeTypedArray>());
 
         // The first argument must be either a typed array or arraylike.
         if (args.length() == 0 || !args[0].isObject()) {
             JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -733,17 +733,17 @@ TypedArray_byteLengthGetter(JSContext* c
 
 static bool
 TypedArray_byteOffsetGetter(JSContext* cx, unsigned argc, Value* vp)
 {
     return TypedArrayObject::Getter<TypedArrayObject::byteOffsetValue>(cx, argc, vp);
 }
 
 bool
-BufferGetterImpl(JSContext* cx, CallArgs args)
+BufferGetterImpl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(TypedArrayObject::is(args.thisv()));
     Rooted<TypedArrayObject*> tarray(cx, &args.thisv().toObject().as<TypedArrayObject>());
     if (!TypedArrayObject::ensureHasBuffer(cx, tarray))
         return false;
     args.rval().set(TypedArrayObject::bufferValue(tarray));
     return true;
 }
@@ -844,17 +844,17 @@ TypedArrayObject::sharedTypedArrayProtot
         TypedArrayObject::protoAccessors,
         FinishTypedArrayInit,
         ClassSpec::DontDefineConstructor
     }
 };
 
 template<typename T>
 bool
-ArrayBufferObject::createTypedArrayFromBufferImpl(JSContext* cx, CallArgs args)
+ArrayBufferObject::createTypedArrayFromBufferImpl(JSContext* cx, const CallArgs& args)
 {
     typedef TypedArrayObjectTemplate<T> ArrayType;
     MOZ_ASSERT(IsArrayBuffer(args.thisv()));
     MOZ_ASSERT(args.length() == 3);
 
     Rooted<JSObject*> buffer(cx, &args.thisv().toObject());
     Rooted<JSObject*> proto(cx, &args[2].toObject());
 
@@ -1197,17 +1197,17 @@ struct DataViewIO
             temp = swapBytes(temp);
         memcpy(unalignedBuffer, (void*) &temp, sizeof(ReadWriteType));
     }
 };
 
 template<typename NativeType>
 /* static */ bool
 DataViewObject::read(JSContext* cx, Handle<DataViewObject*> obj,
-                     CallArgs& args, NativeType* val, const char* method)
+                     const CallArgs& args, NativeType* val, const char* method)
 {
     if (args.length() < 1) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                              JSMSG_MORE_ARGS_NEEDED, method, "0", "s");
         return false;
     }
 
     uint32_t offset;
@@ -1254,17 +1254,17 @@ inline bool
 WebIDLCast<double>(JSContext* cx, HandleValue value, double* out)
 {
     return ToNumber(cx, value, out);
 }
 
 template<typename NativeType>
 /* static */ bool
 DataViewObject::write(JSContext* cx, Handle<DataViewObject*> obj,
-                      CallArgs& args, const char* method)
+                      const CallArgs& args, const char* method)
 {
     if (args.length() < 2) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                              JSMSG_MORE_ARGS_NEEDED, method, "1", "");
         return false;
     }
 
     uint32_t offset;
@@ -1281,17 +1281,17 @@ DataViewObject::write(JSContext* cx, Han
     if (!data)
         return false;
 
     DataViewIO<NativeType>::toBuffer(data, &value, needToSwapBytes(toLittleEndian));
     return true;
 }
 
 bool
-DataViewObject::getInt8Impl(JSContext* cx, CallArgs args)
+DataViewObject::getInt8Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     int8_t val;
     if (!read(cx, thisView, args, &val, "getInt8"))
         return false;
@@ -1302,17 +1302,17 @@ DataViewObject::getInt8Impl(JSContext* c
 bool
 DataViewObject::fun_getInt8(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, getInt8Impl>(cx, args);
 }
 
 bool
-DataViewObject::getUint8Impl(JSContext* cx, CallArgs args)
+DataViewObject::getUint8Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     uint8_t val;
     if (!read(cx, thisView, args, &val, "getUint8"))
         return false;
@@ -1323,17 +1323,17 @@ DataViewObject::getUint8Impl(JSContext* 
 bool
 DataViewObject::fun_getUint8(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, getUint8Impl>(cx, args);
 }
 
 bool
-DataViewObject::getInt16Impl(JSContext* cx, CallArgs args)
+DataViewObject::getInt16Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     int16_t val;
     if (!read(cx, thisView, args, &val, "getInt16"))
         return false;
@@ -1344,17 +1344,17 @@ DataViewObject::getInt16Impl(JSContext* 
 bool
 DataViewObject::fun_getInt16(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, getInt16Impl>(cx, args);
 }
 
 bool
-DataViewObject::getUint16Impl(JSContext* cx, CallArgs args)
+DataViewObject::getUint16Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     uint16_t val;
     if (!read(cx, thisView, args, &val, "getUint16"))
         return false;
@@ -1365,17 +1365,17 @@ DataViewObject::getUint16Impl(JSContext*
 bool
 DataViewObject::fun_getUint16(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, getUint16Impl>(cx, args);
 }
 
 bool
-DataViewObject::getInt32Impl(JSContext* cx, CallArgs args)
+DataViewObject::getInt32Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     int32_t val;
     if (!read(cx, thisView, args, &val, "getInt32"))
         return false;
@@ -1386,17 +1386,17 @@ DataViewObject::getInt32Impl(JSContext* 
 bool
 DataViewObject::fun_getInt32(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, getInt32Impl>(cx, args);
 }
 
 bool
-DataViewObject::getUint32Impl(JSContext* cx, CallArgs args)
+DataViewObject::getUint32Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     uint32_t val;
     if (!read(cx, thisView, args, &val, "getUint32"))
         return false;
@@ -1407,17 +1407,17 @@ DataViewObject::getUint32Impl(JSContext*
 bool
 DataViewObject::fun_getUint32(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, getUint32Impl>(cx, args);
 }
 
 bool
-DataViewObject::getFloat32Impl(JSContext* cx, CallArgs args)
+DataViewObject::getFloat32Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     float val;
     if (!read(cx, thisView, args, &val, "getFloat32"))
         return false;
@@ -1429,17 +1429,17 @@ DataViewObject::getFloat32Impl(JSContext
 bool
 DataViewObject::fun_getFloat32(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, getFloat32Impl>(cx, args);
 }
 
 bool
-DataViewObject::getFloat64Impl(JSContext* cx, CallArgs args)
+DataViewObject::getFloat64Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     double val;
     if (!read(cx, thisView, args, &val, "getFloat64"))
         return false;
@@ -1451,17 +1451,17 @@ DataViewObject::getFloat64Impl(JSContext
 bool
 DataViewObject::fun_getFloat64(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, getFloat64Impl>(cx, args);
 }
 
 bool
-DataViewObject::setInt8Impl(JSContext* cx, CallArgs args)
+DataViewObject::setInt8Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     if (!write<int8_t>(cx, thisView, args, "setInt8"))
         return false;
     args.rval().setUndefined();
@@ -1471,17 +1471,17 @@ DataViewObject::setInt8Impl(JSContext* c
 bool
 DataViewObject::fun_setInt8(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, setInt8Impl>(cx, args);
 }
 
 bool
-DataViewObject::setUint8Impl(JSContext* cx, CallArgs args)
+DataViewObject::setUint8Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     if (!write<uint8_t>(cx, thisView, args, "setUint8"))
         return false;
     args.rval().setUndefined();
@@ -1491,17 +1491,17 @@ DataViewObject::setUint8Impl(JSContext* 
 bool
 DataViewObject::fun_setUint8(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, setUint8Impl>(cx, args);
 }
 
 bool
-DataViewObject::setInt16Impl(JSContext* cx, CallArgs args)
+DataViewObject::setInt16Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     if (!write<int16_t>(cx, thisView, args, "setInt16"))
         return false;
     args.rval().setUndefined();
@@ -1511,17 +1511,17 @@ DataViewObject::setInt16Impl(JSContext* 
 bool
 DataViewObject::fun_setInt16(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, setInt16Impl>(cx, args);
 }
 
 bool
-DataViewObject::setUint16Impl(JSContext* cx, CallArgs args)
+DataViewObject::setUint16Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     if (!write<uint16_t>(cx, thisView, args, "setUint16"))
         return false;
     args.rval().setUndefined();
@@ -1531,17 +1531,17 @@ DataViewObject::setUint16Impl(JSContext*
 bool
 DataViewObject::fun_setUint16(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, setUint16Impl>(cx, args);
 }
 
 bool
-DataViewObject::setInt32Impl(JSContext* cx, CallArgs args)
+DataViewObject::setInt32Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     if (!write<int32_t>(cx, thisView, args, "setInt32"))
         return false;
     args.rval().setUndefined();
@@ -1551,17 +1551,17 @@ DataViewObject::setInt32Impl(JSContext* 
 bool
 DataViewObject::fun_setInt32(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, setInt32Impl>(cx, args);
 }
 
 bool
-DataViewObject::setUint32Impl(JSContext* cx, CallArgs args)
+DataViewObject::setUint32Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     if (!write<uint32_t>(cx, thisView, args, "setUint32"))
         return false;
     args.rval().setUndefined();
@@ -1571,17 +1571,17 @@ DataViewObject::setUint32Impl(JSContext*
 bool
 DataViewObject::fun_setUint32(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, setUint32Impl>(cx, args);
 }
 
 bool
-DataViewObject::setFloat32Impl(JSContext* cx, CallArgs args)
+DataViewObject::setFloat32Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     if (!write<float>(cx, thisView, args, "setFloat32"))
         return false;
     args.rval().setUndefined();
@@ -1591,17 +1591,17 @@ DataViewObject::setFloat32Impl(JSContext
 bool
 DataViewObject::fun_setFloat32(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<is, setFloat32Impl>(cx, args);
 }
 
 bool
-DataViewObject::setFloat64Impl(JSContext* cx, CallArgs args)
+DataViewObject::setFloat64Impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(is(args.thisv()));
 
     Rooted<DataViewObject*> thisView(cx, &args.thisv().toObject().as<DataViewObject>());
 
     if (!write<double>(cx, thisView, args, "setFloat64"))
         return false;
     args.rval().setUndefined();
@@ -1923,17 +1923,17 @@ const JSFunctionSpec DataViewObject::jsf
     JS_FN("setUint32",  DataViewObject::fun_setUint32,    3,0),
     JS_FN("setFloat32", DataViewObject::fun_setFloat32,   3,0),
     JS_FN("setFloat64", DataViewObject::fun_setFloat64,   3,0),
     JS_FS_END
 };
 
 template<Value ValueGetter(DataViewObject* view)>
 bool
-DataViewObject::getterImpl(JSContext* cx, CallArgs args)
+DataViewObject::getterImpl(JSContext* cx, const CallArgs& args)
 {
     args.rval().set(ValueGetter(&args.thisv().toObject().as<DataViewObject>()));
     return true;
 }
 
 template<Value ValueGetter(DataViewObject* view)>
 bool
 DataViewObject::getter(JSContext* cx, unsigned argc, Value* vp)
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -200,17 +200,17 @@ class TypedArrayObject : public NativeOb
     }
 
     static void trace(JSTracer* trc, JSObject* obj);
 
     /* Initialization bits */
 
     template<Value ValueGetter(TypedArrayObject* tarr)>
     static bool
-    GetterImpl(JSContext* cx, CallArgs args)
+    GetterImpl(JSContext* cx, const CallArgs& args)
     {
         MOZ_ASSERT(is(args.thisv()));
         args.rval().set(ValueGetter(&args.thisv().toObject().as<TypedArrayObject>()));
         return true;
     }
 
     // ValueGetter is a function that takes an unwrapped typed array object and
     // returns a Value. Given such a function, Getter<> is a native that
@@ -359,17 +359,17 @@ class DataViewObject : public NativeObje
     }
 
     template <typename NativeType>
     static uint8_t*
     getDataPointer(JSContext* cx, Handle<DataViewObject*> obj, uint32_t offset);
 
     template<Value ValueGetter(DataViewObject* view)>
     static bool
-    getterImpl(JSContext* cx, CallArgs args);
+    getterImpl(JSContext* cx, const CallArgs& args);
 
     template<Value ValueGetter(DataViewObject* view)>
     static bool
     getter(JSContext* cx, unsigned argc, Value* vp);
 
     template<Value ValueGetter(DataViewObject* view)>
     static bool
     defineGetter(JSContext* cx, PropertyName* name, HandleNativeObject proto);
@@ -413,72 +413,72 @@ class DataViewObject : public NativeObje
     static bool constructWithProto(JSContext* cx, unsigned argc, Value* vp);
     static bool construct(JSContext* cx, JSObject* bufobj, const CallArgs& args,
                           HandleObject proto);
 
     static inline DataViewObject*
     create(JSContext* cx, uint32_t byteOffset, uint32_t byteLength,
            Handle<ArrayBufferObject*> arrayBuffer, JSObject* proto);
 
-    static bool getInt8Impl(JSContext* cx, CallArgs args);
+    static bool getInt8Impl(JSContext* cx, const CallArgs& args);
     static bool fun_getInt8(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool getUint8Impl(JSContext* cx, CallArgs args);
+    static bool getUint8Impl(JSContext* cx, const CallArgs& args);
     static bool fun_getUint8(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool getInt16Impl(JSContext* cx, CallArgs args);
+    static bool getInt16Impl(JSContext* cx, const CallArgs& args);
     static bool fun_getInt16(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool getUint16Impl(JSContext* cx, CallArgs args);
+    static bool getUint16Impl(JSContext* cx, const CallArgs& args);
     static bool fun_getUint16(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool getInt32Impl(JSContext* cx, CallArgs args);
+    static bool getInt32Impl(JSContext* cx, const CallArgs& args);
     static bool fun_getInt32(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool getUint32Impl(JSContext* cx, CallArgs args);
+    static bool getUint32Impl(JSContext* cx, const CallArgs& args);
     static bool fun_getUint32(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool getFloat32Impl(JSContext* cx, CallArgs args);
+    static bool getFloat32Impl(JSContext* cx, const CallArgs& args);
     static bool fun_getFloat32(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool getFloat64Impl(JSContext* cx, CallArgs args);
+    static bool getFloat64Impl(JSContext* cx, const CallArgs& args);
     static bool fun_getFloat64(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool setInt8Impl(JSContext* cx, CallArgs args);
+    static bool setInt8Impl(JSContext* cx, const CallArgs& args);
     static bool fun_setInt8(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool setUint8Impl(JSContext* cx, CallArgs args);
+    static bool setUint8Impl(JSContext* cx, const CallArgs& args);
     static bool fun_setUint8(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool setInt16Impl(JSContext* cx, CallArgs args);
+    static bool setInt16Impl(JSContext* cx, const CallArgs& args);
     static bool fun_setInt16(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool setUint16Impl(JSContext* cx, CallArgs args);
+    static bool setUint16Impl(JSContext* cx, const CallArgs& args);
     static bool fun_setUint16(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool setInt32Impl(JSContext* cx, CallArgs args);
+    static bool setInt32Impl(JSContext* cx, const CallArgs& args);
     static bool fun_setInt32(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool setUint32Impl(JSContext* cx, CallArgs args);
+    static bool setUint32Impl(JSContext* cx, const CallArgs& args);
     static bool fun_setUint32(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool setFloat32Impl(JSContext* cx, CallArgs args);
+    static bool setFloat32Impl(JSContext* cx, const CallArgs& args);
     static bool fun_setFloat32(JSContext* cx, unsigned argc, Value* vp);
 
-    static bool setFloat64Impl(JSContext* cx, CallArgs args);
+    static bool setFloat64Impl(JSContext* cx, const CallArgs& args);
     static bool fun_setFloat64(JSContext* cx, unsigned argc, Value* vp);
 
     static bool initClass(JSContext* cx);
     static void neuter(JSObject* view);
     template<typename NativeType>
     static bool read(JSContext* cx, Handle<DataViewObject*> obj,
-                     CallArgs& args, NativeType* val, const char* method);
+                     const CallArgs& args, NativeType* val, const char* method);
     template<typename NativeType>
     static bool write(JSContext* cx, Handle<DataViewObject*> obj,
-                      CallArgs& args, const char* method);
+                      const CallArgs& args, const char* method);
 
     void neuter(void* newData);
 
   private:
     static const JSFunctionSpec jsfuncs[];
 };
 
 static inline int32_t
--- a/js/xpconnect/wrappers/FilteringWrapper.cpp
+++ b/js/xpconnect/wrappers/FilteringWrapper.cpp
@@ -142,17 +142,17 @@ FilteringWrapper<Base, Policy>::construc
     if (!Policy::checkCall(cx, wrapper, args))
         return false;
     return Base::construct(cx, wrapper, args);
 }
 
 template <typename Base, typename Policy>
 bool
 FilteringWrapper<Base, Policy>::nativeCall(JSContext* cx, JS::IsAcceptableThis test,
-                                           JS::NativeImpl impl, JS::CallArgs args) const
+                                           JS::NativeImpl impl, const JS::CallArgs& args) const
 {
     if (Policy::allowNativeCall(cx, test, impl))
         return Base::Permissive::nativeCall(cx, test, impl, args);
     return Base::Restrictive::nativeCall(cx, test, impl, args);
 }
 
 template <typename Base, typename Policy>
 bool
--- a/js/xpconnect/wrappers/FilteringWrapper.h
+++ b/js/xpconnect/wrappers/FilteringWrapper.h
@@ -45,17 +45,17 @@ class FilteringWrapper : public Base {
                            JS::MutableHandle<JSObject*> objp) const override;
 
     virtual bool call(JSContext* cx, JS::Handle<JSObject*> wrapper,
                       const JS::CallArgs& args) const override;
     virtual bool construct(JSContext* cx, JS::Handle<JSObject*> wrapper,
                            const JS::CallArgs& args) const override;
 
     virtual bool nativeCall(JSContext* cx, JS::IsAcceptableThis test, JS::NativeImpl impl,
-                            JS::CallArgs args) const override;
+                            const JS::CallArgs& args) const override;
 
     virtual bool defaultValue(JSContext* cx, JS::Handle<JSObject*> obj, JSType hint,
                               JS::MutableHandleValue vp) const override;
 
     virtual bool getPrototype(JSContext* cx, JS::HandleObject wrapper,
                               JS::MutableHandleObject protop) const override;
 
     static const FilteringWrapper singleton;
--- a/js/xpconnect/wrappers/WaiveXrayWrapper.cpp
+++ b/js/xpconnect/wrappers/WaiveXrayWrapper.cpp
@@ -79,17 +79,17 @@ WaiveXrayWrapper::construct(JSContext* c
     return CrossCompartmentWrapper::construct(cx, wrapper, args) &&
            WrapperFactory::WaiveXrayAndWrap(cx, args.rval());
 }
 
 // NB: This is important as the other side of a handshake with FieldGetter. See
 // nsXBLProtoImplField.cpp.
 bool
 WaiveXrayWrapper::nativeCall(JSContext* cx, JS::IsAcceptableThis test,
-                             JS::NativeImpl impl, JS::CallArgs args) const
+                             JS::NativeImpl impl, const JS::CallArgs& args) const
 {
     return CrossCompartmentWrapper::nativeCall(cx, test, impl, args) &&
            WrapperFactory::WaiveXrayAndWrap(cx, args.rval());
 }
 
 bool
 WaiveXrayWrapper::getPrototype(JSContext* cx, HandleObject wrapper, MutableHandleObject protop) const
 {
--- a/js/xpconnect/wrappers/WaiveXrayWrapper.h
+++ b/js/xpconnect/wrappers/WaiveXrayWrapper.h
@@ -27,17 +27,17 @@ class WaiveXrayWrapper : public js::Cros
     virtual bool call(JSContext* cx, JS::Handle<JSObject*> wrapper,
                       const JS::CallArgs& args) const override;
     virtual bool construct(JSContext* cx, JS::Handle<JSObject*> wrapper,
                            const JS::CallArgs& args) const override;
 
     virtual bool enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
                            JS::MutableHandle<JSObject*> objp) const override;
     virtual bool nativeCall(JSContext* cx, JS::IsAcceptableThis test,
-                            JS::NativeImpl impl, JS::CallArgs args) const override;
+                            JS::NativeImpl impl, const JS::CallArgs& args) const override;
     virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper,
                                        JS::Handle<jsid> id,
                                        JS::MutableHandle<JSPropertyDescriptor> desc) const override;
 
     static const WaiveXrayWrapper singleton;
 };
 
 } // namespace xpc
--- a/toolkit/components/finalizationwitness/FinalizationWitnessService.cpp
+++ b/toolkit/components/finalizationwitness/FinalizationWitnessService.cpp
@@ -139,17 +139,17 @@ bool IsWitness(JS::Handle<JS::Value> v)
 /**
  * JS method |forget()|
  *
  * === JS documentation
  *
  *  Neutralize the witness. Once this method is called, the witness will
  *  never report any error.
  */
-bool ForgetImpl(JSContext* cx, JS::CallArgs args)
+bool ForgetImpl(JSContext* cx, const JS::CallArgs& args)
 {
   if (args.length() != 0) {
     JS_ReportError(cx, "forget() takes no arguments");
     return false;
   }
   JS::Rooted<JS::Value> valSelf(cx, args.thisv());
   JS::Rooted<JSObject*> objSelf(cx, &valSelf.toObject());