Bug 1521732 - Part 3: Use RootedValueVector instead. r=sfink,jonco
authorYoshi Cheng-Hao Huang <allstars.chh@gmail.com>
Tue, 26 Mar 2019 13:58:20 +0000
changeset 466288 66414629b2e353ef5740bd57da3a8ffdf39e5ce0
parent 466287 e705c899efe9b7e0e01af2b23b8a9943ec5af2cf
child 466289 b48232ea7b093d787a1479510a80da7545303f53
push id35764
push useraciure@mozilla.com
push dateWed, 27 Mar 2019 16:35:35 +0000
treeherdermozilla-central@16f19322ec76 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink, jonco
bugs1521732
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1521732 - Part 3: Use RootedValueVector instead. r=sfink,jonco s/AutoValueVector/RootedValueVector/g Depends on D23183 Differential Revision: https://phabricator.services.mozilla.com/D23184
devtools/shared/heapsnapshot/HeapSnapshot.cpp
dom/base/ChromeUtils.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/bindings/BindingUtils.cpp
dom/bindings/Codegen.py
dom/bindings/ToJSValue.h
dom/plugins/base/nsJSNPRuntime.cpp
js/ipc/WrapperAnswer.cpp
js/ipc/WrapperOwner.cpp
js/public/TypeDecls.h
js/public/Vector.h
js/src/builtin/Object.cpp
js/src/builtin/ReflectParse.cpp
js/src/builtin/String.cpp
js/src/builtin/TypedObject.cpp
js/src/builtin/TypedObject.h
js/src/ctypes/CTypes.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/jit/BaselineBailouts.cpp
js/src/jit/Recover.cpp
js/src/jit/VMFunctions.cpp
js/src/jsapi-tests/testFunctionBinding.cpp
js/src/jsapi-tests/testMappedArrayBuffer.cpp
js/src/jsapi-tests/testNewObject.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/src/vm/JSObject.cpp
js/src/vm/JSScript.cpp
js/src/vm/NativeObject.h
js/src/vm/ProxyObject.h
js/src/vm/Stack.h
js/src/vm/StructuredClone.cpp
js/src/vm/TypedArrayObject-inl.h
js/src/wasm/WasmJS.cpp
js/src/wasm/WasmModule.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
toolkit/components/telemetry/core/Telemetry.cpp
toolkit/components/telemetry/core/TelemetryEvent.cpp
toolkit/components/telemetry/core/TelemetryHistogram.cpp
widget/android/EventDispatcher.cpp
--- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp
+++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp
@@ -589,20 +589,20 @@ void HeapSnapshot::ComputeShortestPaths(
   RootedObject resultsMap(cx, JS::NewMapObject(cx));
   if (NS_WARN_IF(!resultsMap)) {
     rv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
   for (auto iter = shortestPaths.targetIter(); !iter.done(); iter.next()) {
     JS::RootedValue key(cx, JS::NumberValue(iter.get().identifier()));
-    JS::AutoValueVector paths(cx);
+    JS::RootedValueVector paths(cx);
 
     bool ok = shortestPaths.forEachPath(iter.get(), [&](JS::ubi::Path& path) {
-      JS::AutoValueVector pathValues(cx);
+      JS::RootedValueVector pathValues(cx);
 
       for (JS::ubi::BackEdge* edge : path) {
         JS::RootedObject pathPart(cx, JS_NewPlainObject(cx));
         if (!pathPart) {
           return false;
         }
 
         JS::RootedValue predecessor(
--- a/dom/base/ChromeUtils.cpp
+++ b/dom/base/ChromeUtils.cpp
@@ -221,17 +221,17 @@ void ChromeUtils::ShallowClone(GlobalObj
                                JS::HandleObject aTarget,
                                JS::MutableHandleObject aRetval,
                                ErrorResult& aRv) {
   JSContext* cx = aGlobal.Context();
 
   auto cleanup = MakeScopeExit([&]() { aRv.NoteJSContextException(cx); });
 
   JS::Rooted<JS::IdVector> ids(cx, JS::IdVector(cx));
-  JS::AutoValueVector values(cx);
+  JS::RootedVector<JS::Value> values(cx);
   JS::AutoIdVector valuesIds(cx);
 
   {
     // cx represents our current Realm, so it makes sense to use it for the
     // CheckedUnwrapDynamic call.  We do want CheckedUnwrapDynamic, in case
     // someone is shallow-cloning a Window.
     JS::RootedObject obj(cx, js::CheckedUnwrapDynamic(aObj, cx));
     if (!obj) {
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -646,20 +646,20 @@ nsresult nsJSContext::InitContext() {
 nsresult nsJSContext::SetProperty(JS::Handle<JSObject*> aTarget,
                                   const char* aPropName, nsISupports* aArgs) {
   AutoJSAPI jsapi;
   if (NS_WARN_IF(!jsapi.Init(GetGlobalObject()))) {
     return NS_ERROR_FAILURE;
   }
   JSContext* cx = jsapi.cx();
 
-  JS::AutoValueVector args(cx);
+  JS::RootedVector<JS::Value> args(cx);
 
   JS::Rooted<JSObject*> global(cx, GetWindowProxy());
-  nsresult rv = ConvertSupportsTojsvals(aArgs, global, args);
+  nsresult rv = ConvertSupportsTojsvals(aArgs, global, &args);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // got the arguments, now attach them.
 
   for (uint32_t i = 0; i < args.length(); ++i) {
     if (!JS_WrapValue(cx, args[i])) {
       return NS_ERROR_FAILURE;
     }
@@ -669,19 +669,19 @@ nsresult nsJSContext::SetProperty(JS::Ha
   if (!array) {
     return NS_ERROR_FAILURE;
   }
 
   return JS_DefineProperty(cx, aTarget, aPropName, array, 0) ? NS_OK
                                                              : NS_ERROR_FAILURE;
 }
 
-nsresult nsJSContext::ConvertSupportsTojsvals(nsISupports* aArgs,
-                                              JS::Handle<JSObject*> aScope,
-                                              JS::AutoValueVector& aArgsOut) {
+nsresult nsJSContext::ConvertSupportsTojsvals(
+    nsISupports* aArgs, JS::Handle<JSObject*> aScope,
+    JS::MutableHandleVector<JS::Value> aArgsOut) {
   nsresult rv = NS_OK;
 
   // If the array implements nsIJSArgArray, copy the contents and return.
   nsCOMPtr<nsIJSArgArray> fastArray = do_QueryInterface(aArgs);
   if (fastArray) {
     uint32_t argc;
     JS::Value* argv;
     rv = fastArray->GetArgs(&argc, reinterpret_cast<void**>(&argv));
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -131,17 +131,17 @@ class nsJSContext : public nsIScriptCont
   }
 
  protected:
   virtual ~nsJSContext();
 
   // Helper to convert xpcom datatypes to jsvals.
   nsresult ConvertSupportsTojsvals(nsISupports *aArgs,
                                    JS::Handle<JSObject *> aScope,
-                                   JS::AutoValueVector &aArgsOut);
+                                   JS::MutableHandleVector<JS::Value> aArgsOut);
 
   nsresult AddSupportsPrimitiveTojsvals(nsISupports *aArg, JS::Value *aArgv);
 
  private:
   void Destroy();
 
   JS::Heap<JSObject *> mWindowProxy;
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -3386,17 +3386,17 @@ bool ForEachHandler(JSContext* aCx, unsi
   // Unpack callback and object from slots
   JS::Rooted<JS::Value> callbackFn(
       aCx,
       js::GetFunctionNativeReserved(&args.callee(), FOREACH_CALLBACK_SLOT));
   JS::Rooted<JS::Value> maplikeOrSetlikeObj(
       aCx, js::GetFunctionNativeReserved(&args.callee(),
                                          FOREACH_MAPLIKEORSETLIKEOBJ_SLOT));
   MOZ_ASSERT(aArgc == 3);
-  JS::AutoValueVector newArgs(aCx);
+  JS::RootedVector<JS::Value> newArgs(aCx);
   // Arguments are passed in as value, key, object. Keep value and key, replace
   // object with the maplike/setlike object.
   if (!newArgs.append(args.get(0))) {
     return false;
   }
   if (!newArgs.append(args.get(1))) {
     return false;
   }
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1229,17 +1229,17 @@ class CGHeaders(CGWrapper):
 
             if "::" in func:
                 # Strip out the function name and convert "::" to "/"
                 bindingHeaders.add("/".join(func.split("::")[:-1]) + ".h")
 
         # Now for non-callback descriptors make sure we include any
         # headers needed by Func declarations and other things like that.
         for desc in descriptors:
-            # If this is an iterator interface generated for a seperate
+            # If this is an iterator interface generated for a separate
             # iterable interface, skip generating type includes, as we have
             # what we need in IterableIterator.h
             if desc.interface.isExternal() or desc.interface.isIteratorInterface():
                 continue
 
             for m in desc.interface.members:
                 addHeaderForFunc(PropertyDefiner.getStringAttr(m, "Func"), desc)
                 staticTypeOverride = PropertyDefiner.getStringAttr(m, "StaticClassOverride")
@@ -16457,17 +16457,17 @@ class CallbackMember(CGNativeMember):
         self.body = self.getImpl()
 
     def getImpl(self):
         setupCall = self.getCallSetup()
         declRval = self.getRvalDecl()
         if self.argCount > 0:
             argvDecl = fill(
                 """
-                JS::AutoValueVector argv(cx);
+                JS::RootedVector<JS::Value> argv(cx);
                 if (!argv.resize(${argCount})) {
                   aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
                   return${errorReturn};
                 }
                 """,
                 argCount=self.argCountStr,
                 errorReturn=self.getDefaultRetval())
         else:
@@ -17092,27 +17092,27 @@ class CGMaplikeOrSetlikeMethodGenerator(
             }
             """,
             name=name,
             errorReturn=self.returnStmt))
 
     def appendKeyArgConversion(self):
         """
         Generates the key argument for methods. Helper functions will use
-        an AutoValueVector, while interface methods have seperate JS::Values.
+        a RootedVector<JS::Value>, while interface methods have separate JS::Values.
         """
         if self.helperImpl:
             return ([], ["argv[0]"], [])
         return ([self.appendArgConversion("arg0")], ["arg0Val"], [])
 
     def appendKeyAndValueArgConversion(self):
         """
         Generates arguments for methods that require a key and value. Helper
-        functions will use an AutoValueVector, while interface methods have
-        seperate JS::Values.
+        functions will use a RootedVector<JS::Value>, while interface methods have
+        separate JS::Values.
         """
         r = self.appendKeyArgConversion()
         if self.helperImpl:
             return self.mergeTuples(r, ([], ["argv[1]"], []))
         return self.mergeTuples(r, ([self.appendArgConversion("arg1")],
                                     ["arg1Val"],
                                     []))
 
--- a/dom/bindings/ToJSValue.h
+++ b/dom/bindings/ToJSValue.h
@@ -348,17 +348,17 @@ MOZ_MUST_USE bool ToJSValue(JSContext* a
 
 // Accept arrays of other things we accept
 template <typename T>
 MOZ_MUST_USE bool ToJSValue(JSContext* aCx, T* aArguments, size_t aLength,
                             JS::MutableHandle<JS::Value> aValue) {
   // Make sure we're called in a compartment
   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
 
-  JS::AutoValueVector v(aCx);
+  JS::RootedVector<JS::Value> v(aCx);
   if (!v.resize(aLength)) {
     return false;
   }
   for (size_t i = 0; i < aLength; ++i) {
     if (!ToJSValue(aCx, aArguments[i], v[i])) {
       return false;
     }
   }
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -718,17 +718,17 @@ static bool doInvoke(NPObject *npobj, NP
         ::JS_TypeOfValue(cx, fv) != JSTYPE_FUNCTION) {
       return false;
     }
   } else {
     fv.setObject(*jsobj);
   }
 
   // Convert args
-  JS::AutoValueVector jsargs(cx);
+  JS::RootedVector<JS::Value> jsargs(cx);
   if (!jsargs.reserve(argCount)) {
     ::JS_ReportOutOfMemory(cx);
     return false;
   }
   for (uint32_t i = 0; i < argCount; ++i) {
     jsargs.infallibleAppend(NPVariantToJSVal(npp, cx, args + i));
   }
 
--- a/js/ipc/WrapperAnswer.cpp
+++ b/js/ipc/WrapperAnswer.cpp
@@ -455,18 +455,18 @@ bool WrapperAnswer::RecvCallOrConstruct(
 
   RootedValue objv(cx);
   if (!fromVariant(cx, argv[0], &objv)) {
     return fail(aes, rs);
   }
 
   *result = JSVariant(UndefinedVariant());
 
-  AutoValueVector vals(cx);
-  AutoValueVector outobjects(cx);
+  RootedValueVector vals(cx);
+  RootedValueVector outobjects(cx);
   for (size_t i = 0; i < argv.Length(); i++) {
     if (argv[i].type() == JSParam::Tvoid_t) {
       // This is an outparam.
       RootedObject obj(cx, xpc::NewOutObject(cx));
       if (!obj) {
         return fail(aes, rs);
       }
       if (!outobjects.append(ObjectValue(*obj))) {
--- a/js/ipc/WrapperOwner.cpp
+++ b/js/ipc/WrapperOwner.cpp
@@ -575,17 +575,17 @@ bool CPOWProxyHandler::construct(JSConte
   FORWARD(callOrConstruct, (cx, proxy, args, true), false);
 }
 
 bool WrapperOwner::callOrConstruct(JSContext* cx, HandleObject proxy,
                                    const CallArgs& args, bool construct) {
   ObjectId objId = idOf(proxy);
 
   InfallibleTArray<JSParam> vals;
-  AutoValueVector outobjects(cx);
+  RootedValueVector outobjects(cx);
 
   RootedValue v(cx);
   for (size_t i = 0; i < args.length() + 2; i++) {
     // The |this| value for constructors is a magic value that we won't be
     // able to convert, so skip it.
     if (i == 1 && construct) {
       v = UndefinedValue();
     } else {
--- a/js/public/TypeDecls.h
+++ b/js/public/TypeDecls.h
@@ -100,13 +100,17 @@ typedef PersistentRooted<JSFunction*> Pe
 typedef PersistentRooted<PropertyKey> PersistentRootedId;
 typedef PersistentRooted<JSObject*> PersistentRootedObject;
 typedef PersistentRooted<JSScript*> PersistentRootedScript;
 typedef PersistentRooted<JSString*> PersistentRootedString;
 typedef PersistentRooted<JS::Symbol*> PersistentRootedSymbol;
 typedef PersistentRooted<JS::BigInt*> PersistentRootedBigInt;
 typedef PersistentRooted<Value> PersistentRootedValue;
 
+template <typename T>
+using HandleVector = Handle<StackGCVector<T>>;
+template <typename T>
+using MutableHandleVector = MutableHandle<StackGCVector<T>>;
 }  // namespace JS
 
 using jsid = JS::PropertyKey;
 
 #endif /* js_TypeDecls_h */
--- a/js/public/Vector.h
+++ b/js/public/Vector.h
@@ -21,16 +21,16 @@ struct TypeIsGCThing : mozilla::FalseTyp
 
 template <>
 struct TypeIsGCThing<JS::Value> : mozilla::TrueType {};
 
 }  // namespace detail
 
 template <typename T, size_t MinInlineCapacity = 0,
           class AllocPolicy = TempAllocPolicy,
-          // Don't use this with JS::Value!  Use JS::AutoValueVector instead.
+          // Don't use this with JS::Value!  Use JS::RootedValueVector instead.
           typename = typename mozilla::EnableIf<
               !detail::TypeIsGCThing<T>::value>::Type>
 using Vector = mozilla::Vector<T, MinInlineCapacity, AllocPolicy>;
 
 }  // namespace js
 
 #endif /* js_Vector_h */
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -1256,17 +1256,17 @@ static bool TryEnumerableOwnPropertiesNa
     // Ensure no extra indexed properties were added through enumerate().
     if (nobj->isIndexed()) {
       return true;
     }
   }
 
   *optimized = true;
 
-  AutoValueVector properties(cx);
+  RootedValueVector properties(cx);
   RootedValue key(cx);
   RootedValue value(cx);
 
   // We have ensured |nobj| contains no extra indexed properties, so the
   // only indexed properties we need to handle here are dense and typed
   // array elements.
 
   for (uint32_t i = 0, len = nobj->getDenseInitializedLength(); i < len; i++) {
@@ -1509,17 +1509,17 @@ static bool EnumerableOwnProperties(JSCo
 
   // Step 2.
   AutoIdVector ids(cx);
   if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY | JSITER_HIDDEN, &ids)) {
     return false;
   }
 
   // Step 3.
-  AutoValueVector properties(cx);
+  RootedValueVector properties(cx);
   size_t len = ids.length();
   if (!properties.resize(len)) {
     return false;
   }
 
   RootedId id(cx);
   RootedValue key(cx);
   RootedValue value(cx);
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -198,17 +198,17 @@ static const char* const nodeTypeNames[]
 static const char* const callbackNames[] = {
 #define ASTDEF(ast, str, method) method,
 #include "jsast.tbl"
 #undef ASTDEF
     nullptr};
 
 enum YieldKind { Delegating, NotDelegating };
 
-typedef AutoValueVector NodeVector;
+typedef RootedValueVector NodeVector;
 
 /*
  * ParseNode is a somewhat intricate data structure, and its invariants have
  * evolved, making it more likely that there could be a disconnect between the
  * parser and the AST serializer. We use these macros to check invariants on a
  * parse node and raise a dynamic error on failure.
  */
 #define LOCAL_ASSERT(expr)                                    \
--- a/js/src/builtin/String.cpp
+++ b/js/src/builtin/String.cpp
@@ -3075,17 +3075,17 @@ static ArrayObject* SplitHelper(JSContex
       return NewFullyAllocatedArrayTryUseGroup(cx, group, 0);
     }
 
     // Steps 12.c-e.
     return SingleElementStringArray(cx, group, str);
   }
 
   // Step 3 (reordered).
-  AutoValueVector splits(cx);
+  RootedValueVector splits(cx);
 
   // Step 8 (reordered).
   size_t lastEndIndex = 0;
 
   // Step 13.
   size_t index = 0;
 
   // Step 14.
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -771,18 +771,18 @@ JSObject* StructMetaTypeDescr::create(JS
   AutoIdVector ids(cx);
   if (!GetPropertyKeys(cx, fields, JSITER_OWNONLY | JSITER_SYMBOLS, &ids)) {
     return nullptr;
   }
 
   // Iterate through each field. Collect values for the various
   // vectors below and also track total size and alignment. Be wary
   // of overflow!
-  AutoValueVector fieldTypeObjs(cx);  // Type descriptor of each field.
-  bool opaque = false;                // Opacity of struct.
+  RootedValueVector fieldTypeObjs(cx);  // Type descriptor of each field.
+  bool opaque = false;                  // Opacity of struct.
 
   Vector<StructFieldProps> fieldProps(cx);
 
   RootedValue fieldTypeVal(cx);
   RootedId id(cx);
   Rooted<TypeDescr*> fieldType(cx);
 
   for (unsigned int i = 0; i < ids.length(); i++) {
@@ -833,25 +833,25 @@ JSObject* StructMetaTypeDescr::create(JS
   return createFromArrays(cx, structTypePrototype, opaque,
                           /* allowConstruct= */ true, ids, fieldTypeObjs,
                           fieldProps);
 }
 
 /* static */
 StructTypeDescr* StructMetaTypeDescr::createFromArrays(
     JSContext* cx, HandleObject structTypePrototype, bool opaque,
-    bool allowConstruct, AutoIdVector& ids, AutoValueVector& fieldTypeObjs,
+    bool allowConstruct, AutoIdVector& ids, JS::HandleValueVector fieldTypeObjs,
     Vector<StructFieldProps>& fieldProps) {
-  StringBuffer stringBuffer(cx);      // Canonical string repr
-  AutoValueVector fieldNames(cx);     // Name of each field.
-  AutoValueVector fieldOffsets(cx);   // Offset of each field field.
-  AutoValueVector fieldMuts(cx);      // Mutability of each field.
-  RootedObject userFieldOffsets(cx);  // User-exposed {f:offset} object
-  RootedObject userFieldTypes(cx);    // User-exposed {f:descr} object.
-  Layout layout;                      // Field offsetter
+  StringBuffer stringBuffer(cx);       // Canonical string repr
+  RootedValueVector fieldNames(cx);    // Name of each field.
+  RootedValueVector fieldOffsets(cx);  // Offset of each field field.
+  RootedValueVector fieldMuts(cx);     // Mutability of each field.
+  RootedObject userFieldOffsets(cx);   // User-exposed {f:offset} object
+  RootedObject userFieldTypes(cx);     // User-exposed {f:descr} object.
+  Layout layout;                       // Field offsetter
 
   userFieldOffsets = NewBuiltinClassInstance<PlainObject>(cx, TenuredObject);
   if (!userFieldOffsets) {
     return nullptr;
   }
 
   userFieldTypes = NewBuiltinClassInstance<PlainObject>(cx, TenuredObject);
   if (!userFieldTypes) {
--- a/js/src/builtin/TypedObject.h
+++ b/js/src/builtin/TypedObject.h
@@ -424,17 +424,17 @@ class StructMetaTypeDescr : public Nativ
                           HandleObject fields);
 
  public:
   // The prototype cannot be null.
   // The names in `ids` must all be non-numeric.
   // The type objects in `fieldTypeObjs` must all be TypeDescr objects.
   static StructTypeDescr* createFromArrays(
       JSContext* cx, HandleObject structTypePrototype, bool opaque,
-      bool allowConstruct, AutoIdVector& ids, AutoValueVector& fieldTypeObjs,
+      bool allowConstruct, AutoIdVector& ids, HandleValueVector fieldTypeObjs,
       Vector<StructFieldProps>& fieldProps);
 
   // Properties and methods to be installed on StructType.prototype,
   // and hence inherited by all struct type objects:
   static const JSPropertySpec typeObjectProperties[];
   static const JSFunctionSpec typeObjectMethods[];
 
   // Properties and methods to be installed on StructType.prototype.prototype,
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -6191,17 +6191,17 @@ JSObject* StructType::BuildFieldsArray(J
   MOZ_ASSERT(CType::IsCType(obj));
   MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_struct);
   MOZ_ASSERT(CType::IsSizeDefined(obj));
 
   const FieldInfoHash* fields = GetFieldInfo(obj);
   size_t len = fields->count();
 
   // Prepare a new array for the 'fields' property of the StructType.
-  JS::AutoValueVector fieldsVec(cx);
+  JS::RootedValueVector fieldsVec(cx);
   if (!fieldsVec.resize(len)) {
     return nullptr;
   }
 
   for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) {
     const FieldInfoHash::Entry& entry = r.front();
     // Add the field descriptor to the array.
     if (!AddFieldToArray(cx, fieldsVec[entry.value().mIndex], entry.key(),
@@ -6710,17 +6710,17 @@ static bool CreateFunctionInfo(JSContext
 
 bool FunctionType::Create(JSContext* cx, unsigned argc, Value* vp) {
   // Construct and return a new FunctionType object.
   CallArgs args = CallArgsFromVp(argc, vp);
   if (args.length() < 2 || args.length() > 3) {
     return ArgumentLengthError(cx, "FunctionType", "two or three", "s");
   }
 
-  AutoValueVector argTypes(cx);
+  JS::RootedValueVector argTypes(cx);
   RootedObject arrayObj(cx, nullptr);
 
   if (args.length() == 3) {
     // Prepare an array of Values for the arguments.
     bool isArray;
     if (!args[2].isObject()) {
       isArray = false;
     } else {
@@ -7073,17 +7073,17 @@ bool FunctionType::ArgTypesGetter(JSCont
   }
 
   FunctionInfo* fninfo = GetFunctionInfo(obj);
   size_t len = fninfo->mArgTypes.length();
 
   // Prepare a new array.
   JS::Rooted<JSObject*> argTypes(cx);
   {
-    JS::AutoValueVector vec(cx);
+    JS::RootedValueVector vec(cx);
     if (!vec.resize(len)) {
       return false;
     }
 
     for (size_t i = 0; i < len; ++i) {
       vec[i].setObject(*fninfo->mArgTypes[i]);
     }
 
@@ -7299,17 +7299,17 @@ bool CClosure::ArgClosure::operator()(JS
       break;
       default:
         break;
     }
     memset(result, 0, rvSize);
   }
 
   // Set up an array for converted arguments.
-  JS::AutoValueVector argv(cx);
+  JS::RootedValueVector argv(cx);
   if (!argv.resize(cif->nargs)) {
     JS_ReportOutOfMemory(cx);
     return false;
   }
 
   for (uint32_t i = 0; i < cif->nargs; ++i) {
     // Convert each argument, and have any CData objects created depend on
     // the existing buffers.
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -4374,17 +4374,17 @@ bool ParseNode::getConstantValue(JSConte
         count = as<CallSiteNode>().count() - 1;
         pn = as<CallSiteNode>().head()->pn_next;
       } else {
         MOZ_ASSERT(!as<ListNode>().hasNonConstInitializer());
         count = as<ListNode>().count();
         pn = as<ListNode>().head();
       }
 
-      AutoValueVector values(cx);
+      RootedValueVector values(cx);
       if (!values.appendN(MagicValue(JS_ELEMENTS_HOLE), count)) {
         return false;
       }
       size_t idx;
       for (idx = 0; pn; idx++, pn = pn->pn_next) {
         if (!pn->getConstantValue(cx, allowObjects, values[idx], values.begin(),
                                   idx)) {
           return false;
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -898,17 +898,17 @@ static bool InitFromBailout(JSContext* c
 
   // Inlining of SPREADCALL-like frames not currently supported.
   MOZ_ASSERT_IF(IsSpreadCallPC(pc), !iter.moreFrames());
 
   // Fixup inlined JSOP_FUNCALL, JSOP_FUNAPPLY, and accessors on the caller
   // side. On the caller side this must represent like the function wasn't
   // inlined.
   uint32_t pushedSlots = 0;
-  AutoValueVector savedCallerArgs(cx);
+  RootedValueVector savedCallerArgs(cx);
   bool needToSaveArgs =
       op == JSOP_FUNAPPLY || IsIonInlinableGetterOrSetterPC(pc);
   if (iter.moreFrames() && (op == JSOP_FUNCALL || needToSaveArgs)) {
     uint32_t inlined_args = 0;
     if (op == JSOP_FUNCALL) {
       inlined_args = 2 + GET_ARGC(pc) - 1;
     } else if (op == JSOP_FUNAPPLY) {
       inlined_args = 2 + blFrame->numActualArgs();
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -820,17 +820,17 @@ bool MHypot::writeRecoverData(CompactBuf
   writer.writeUnsigned(uint32_t(numOperands()));
   return true;
 }
 
 RHypot::RHypot(CompactBufferReader& reader)
     : numOperands_(reader.readUnsigned()) {}
 
 bool RHypot::recover(JSContext* cx, SnapshotIterator& iter) const {
-  JS::AutoValueVector vec(cx);
+  JS::RootedValueVector vec(cx);
 
   if (!vec.reserve(numOperands_)) {
     return false;
   }
 
   for (uint32_t i = 0; i < numOperands_; ++i) {
     vec.infallibleAppend(iter.read());
   }
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -963,17 +963,17 @@ bool NormalSuspend(JSContext* cx, Handle
   uint32_t stackDepth = frame->numValueSlots() - frame->script()->nfixed();
 
   // Return value is still on the stack.
   MOZ_ASSERT(stackDepth >= 1);
 
   // The expression stack slots are stored on the stack in reverse order, so
   // we copy them to a Vector and pass a pointer to that instead. We use
   // stackDepth - 1 because we don't want to include the return value.
-  AutoValueVector exprStack(cx);
+  RootedValueVector exprStack(cx);
   if (!exprStack.reserve(stackDepth - 1)) {
     return false;
   }
 
   size_t firstSlot = frame->numValueSlots() - stackDepth;
   for (size_t i = 0; i < stackDepth - 1; i++) {
     exprStack.infallibleAppend(*frame->valueSlot(firstSlot + i));
   }
--- a/js/src/jsapi-tests/testFunctionBinding.cpp
+++ b/js/src/jsapi-tests/testFunctionBinding.cpp
@@ -22,17 +22,17 @@ BEGIN_TEST(test_functionBinding) {
 
   // Named function shouldn't have it's binding.
   const char s1chars[] = "return (typeof s1) == 'undefined';";
   JS::AutoObjectVector emptyScopeChain(cx);
   CHECK(JS::CompileFunctionUtf8(cx, emptyScopeChain, options, "s1", 0, nullptr,
                                 s1chars, strlen(s1chars), &fun));
   CHECK(fun);
 
-  JS::AutoValueVector args(cx);
+  JS::RootedValueVector args(cx);
   RootedValue rval(cx);
   CHECK(JS::Call(cx, UndefinedHandleValue, fun, args, &rval));
   CHECK(rval.isBoolean());
   CHECK(rval.toBoolean());
 
   // Named function shouldn't have `anonymous` binding.
   const char s2chars[] = "return (typeof anonymous) == 'undefined';";
   CHECK(JS::CompileFunctionUtf8(cx, emptyScopeChain, options, "s2", 0, nullptr,
--- a/js/src/jsapi-tests/testMappedArrayBuffer.cpp
+++ b/js/src/jsapi-tests/testMappedArrayBuffer.cpp
@@ -156,17 +156,17 @@ bool TestStealContents() {
 }
 
 bool TestTransferObject() {
   JS::RootedObject obj1(cx, CreateNewObject(8, 12));
   CHECK(obj1);
   JS::RootedValue v1(cx, JS::ObjectValue(*obj1));
 
   // Create an Array of transferable values.
-  JS::AutoValueVector argv(cx);
+  JS::RootedValueVector argv(cx);
   if (!argv.append(v1)) {
     return false;
   }
 
   JS::RootedObject obj(
       cx, JS_NewArrayObject(cx, JS::HandleValueArray::subarray(argv, 0, 1)));
   CHECK(obj);
   JS::RootedValue transferable(cx, JS::ObjectValue(*obj));
--- a/js/src/jsapi-tests/testNewObject.cpp
+++ b/js/src/jsapi-tests/testNewObject.cpp
@@ -48,17 +48,17 @@ static bool constructHook(JSContext* cx,
   args[1].setUndefined();
   args[2].setUndefined();
 
   return true;
 }
 
 BEGIN_TEST(testNewObject_1) {
   static const size_t N = 1000;
-  JS::AutoValueVector argv(cx);
+  JS::RootedValueVector argv(cx);
   CHECK(argv.resize(N));
 
   JS::RootedValue v(cx);
   EVAL("Array", &v);
   JS::RootedObject Array(cx, v.toObjectOrNull());
 
   bool isArray;
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -6521,17 +6521,17 @@ static bool DisableSingleStepProfiling(J
 #ifdef SINGLESTEP_PROFILING
   CallArgs args = CallArgsFromVp(argc, vp);
 
   jit::Simulator* sim = cx->simulator();
   sim->disable_single_stepping();
 
   ShellContext* sc = GetShellContext(cx);
 
-  AutoValueVector elems(cx);
+  RootedValueVector elems(cx);
   for (size_t i = 0; i < sc->stacks.length(); i++) {
     JSString* stack =
         JS_NewUCStringCopyN(cx, sc->stacks[i].begin(), sc->stacks[i].length());
     if (!stack) {
       return false;
     }
     if (!elems.append(StringValue(stack))) {
       return false;
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2082,17 +2082,17 @@ template <typename HookIsEnabledFun /* b
 ResumeMode Debugger::dispatchHook(JSContext* cx, HookIsEnabledFun hookIsEnabled,
                                   FireHookFun fireHook) {
   // Determine which debuggers will receive this event, and in what order.
   // Make a copy of the list, since the original is mutable and we will be
   // calling into arbitrary JS.
   //
   // Note: In the general case, 'triggered' contains references to objects in
   // different compartments--every compartment *except* this one.
-  AutoValueVector triggered(cx);
+  RootedValueVector triggered(cx);
   Handle<GlobalObject*> global = cx->global();
   if (GlobalObject::DebuggerVector* debuggers = global->getDebuggers()) {
     for (auto p = debuggers->begin(); p != debuggers->end(); p++) {
       Debugger* dbg = *p;
       if (dbg->enabled && hookIsEnabled(dbg)) {
         if (!triggered.append(ObjectValue(*dbg->toJSObject()))) {
           return ResumeMode::Terminate;
         }
@@ -4042,17 +4042,17 @@ bool Debugger::hasDebuggee(JSContext* cx
 
 /* static */
 bool Debugger::getDebuggees(JSContext* cx, unsigned argc, Value* vp) {
   THIS_DEBUGGER(cx, argc, vp, "getDebuggees", args, dbg);
 
   // Obtain the list of debuggees before wrapping each debuggee, as a GC could
   // update the debuggees set while we are iterating it.
   unsigned count = dbg->debuggees.count();
-  AutoValueVector debuggees(cx);
+  RootedValueVector debuggees(cx);
   if (!debuggees.resize(count)) {
     return false;
   }
   unsigned i = 0;
   {
     JS::AutoCheckCannotGC nogc;
     for (WeakGlobalObjectSet::Enum e(dbg->debuggees); !e.empty();
          e.popFront()) {
@@ -9290,17 +9290,17 @@ static bool DebuggerGenericEval(JSContex
                                 HandleObject envArg, FrameIter* iter) {
   // Either we're specifying the frame, or a global.
   MOZ_ASSERT_IF(iter, !envArg);
   MOZ_ASSERT_IF(!iter, envArg && IsGlobalLexicalEnvironment(envArg));
 
   // Gather keys and values of bindings, if any. This must be done in the
   // debugger compartment, since that is where any exceptions must be thrown.
   AutoIdVector keys(cx);
-  AutoValueVector values(cx);
+  RootedValueVector values(cx);
   if (bindings) {
     if (!GetPropertyKeys(cx, bindings, JSITER_OWNONLY, &keys) ||
         !values.growBy(keys.length())) {
       return false;
     }
     for (size_t i = 0; i < keys.length(); i++) {
       MutableHandleValue valp = values[i];
       if (!GetProperty(cx, bindings, bindings, keys[i], valp) ||
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -1693,17 +1693,17 @@ XDRResult js::XDRObjectLiteral(XDRState<
 template XDRResult js::XDRObjectLiteral(XDRState<XDR_ENCODE>* xdr,
                                         MutableHandleObject obj);
 
 template XDRResult js::XDRObjectLiteral(XDRState<XDR_DECODE>* xdr,
                                         MutableHandleObject obj);
 
 /* static */
 bool NativeObject::fillInAfterSwap(JSContext* cx, HandleNativeObject obj,
-                                   const AutoValueVector& values, void* priv) {
+                                   HandleValueVector values, void* priv) {
   // This object has just been swapped with some other object, and its shape
   // no longer reflects its allocated size. Correct this information and
   // fill the slots in with the specified values.
   MOZ_ASSERT(obj->slotSpan() == values.length());
 
   // Make sure the shape's numFixedSlots() is correct.
   size_t nfixed =
       gc::GetGCKindSlots(obj->asTenured().getAllocKind(), obj->getClass());
@@ -1741,19 +1741,18 @@ bool NativeObject::fillInAfterSwap(JSCon
 void JSObject::fixDictionaryShapeAfterSwap() {
   // Dictionary shapes can point back to their containing objects, so after
   // swapping the guts of those objects fix the pointers up.
   if (isNative() && as<NativeObject>().inDictionaryMode()) {
     as<NativeObject>().shape()->listp = as<NativeObject>().shapePtr();
   }
 }
 
-static MOZ_MUST_USE bool CopyProxyValuesBeforeSwap(JSContext* cx,
-                                                   ProxyObject* proxy,
-                                                   AutoValueVector& values) {
+static MOZ_MUST_USE bool CopyProxyValuesBeforeSwap(
+    JSContext* cx, ProxyObject* proxy, MutableHandleValueVector values) {
   MOZ_ASSERT(values.empty());
 
   // Remove the GCPtrValues we're about to swap from the store buffer, to
   // ensure we don't trace bogus values.
   gc::StoreBuffer& sb = cx->runtime()->gc.storeBuffer();
 
   // Reserve space for the private slot and the reserved slots.
   if (!values.reserve(1 + proxy->numReservedSlots())) {
@@ -1769,17 +1768,17 @@ static MOZ_MUST_USE bool CopyProxyValues
     sb.unputValue(&valArray->reservedSlots.slots[i]);
     values.infallibleAppend(valArray->reservedSlots.slots[i]);
   }
 
   return true;
 }
 
 bool ProxyObject::initExternalValueArrayAfterSwap(
-    JSContext* cx, const AutoValueVector& values) {
+    JSContext* cx, const HandleValueVector values) {
   MOZ_ASSERT(getClass()->isProxy());
 
   size_t nreserved = numReservedSlots();
 
   // |values| contains the private slot and the reserved slots.
   MOZ_ASSERT(values.length() == 1 + nreserved);
 
   size_t nbytes = js::detail::ProxyValueArray::sizeOf(nreserved);
@@ -1891,27 +1890,27 @@ void JSObject::swap(JSContext* cx, Handl
 
     // When the objects have different sizes, they will have different
     // numbers of fixed slots before and after the swap, so the slots for
     // native objects will need to be rearranged.
     NativeObject* na = a->isNative() ? &a->as<NativeObject>() : nullptr;
     NativeObject* nb = b->isNative() ? &b->as<NativeObject>() : nullptr;
 
     // Remember the original values from the objects.
-    AutoValueVector avals(cx);
+    RootedValueVector avals(cx);
     void* apriv = nullptr;
     if (na) {
       apriv = na->hasPrivate() ? na->getPrivate() : nullptr;
       for (size_t i = 0; i < na->slotSpan(); i++) {
         if (!avals.append(na->getSlot(i))) {
           oomUnsafe.crash("JSObject::swap");
         }
       }
     }
-    AutoValueVector bvals(cx);
+    RootedValueVector bvals(cx);
     void* bpriv = nullptr;
     if (nb) {
       bpriv = nb->hasPrivate() ? nb->getPrivate() : nullptr;
       for (size_t i = 0; i < nb->slotSpan(); i++) {
         if (!bvals.append(nb->getSlot(i))) {
           oomUnsafe.crash("JSObject::swap");
         }
       }
@@ -1919,22 +1918,22 @@ void JSObject::swap(JSContext* cx, Handl
 
     // Do the same for proxies storing ProxyValueArray inline.
     ProxyObject* proxyA =
         a->is<ProxyObject>() ? &a->as<ProxyObject>() : nullptr;
     ProxyObject* proxyB =
         b->is<ProxyObject>() ? &b->as<ProxyObject>() : nullptr;
 
     if (aIsProxyWithInlineValues) {
-      if (!CopyProxyValuesBeforeSwap(cx, proxyA, avals)) {
+      if (!CopyProxyValuesBeforeSwap(cx, proxyA, &avals)) {
         oomUnsafe.crash("CopyProxyValuesBeforeSwap");
       }
     }
     if (bIsProxyWithInlineValues) {
-      if (!CopyProxyValuesBeforeSwap(cx, proxyB, bvals)) {
+      if (!CopyProxyValuesBeforeSwap(cx, proxyB, &bvals)) {
         oomUnsafe.crash("CopyProxyValuesBeforeSwap");
       }
     }
 
     // Swap the main fields of the objects, whether they are native objects or
     // proxies.
     char tmp[sizeof(JSObject_Slots0)];
     js_memcpy(&tmp, a, sizeof tmp);
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -4065,17 +4065,17 @@ bool PrivateScriptData::Clone(JSContext*
       if (!clone || !scopes.append(clone)) {
         return false;
       }
     }
   }
 
   /* Constants */
 
-  AutoValueVector consts(cx);
+  RootedValueVector consts(cx);
   if (nconsts != 0) {
     RootedValue val(cx);
     RootedValue clone(cx);
     for (const GCPtrValue& elem : srcData->consts()) {
       val = elem.get();
       if (val.isDouble()) {
         clone = val;
       } else if (val.isBigInt()) {
--- a/js/src/vm/NativeObject.h
+++ b/js/src/vm/NativeObject.h
@@ -933,17 +933,17 @@ class NativeObject : public ShapedObject
 
   static Shape* addAccessorPropertyInternal(
       JSContext* cx, HandleNativeObject obj, HandleId id, JSGetterOp getter,
       JSSetterOp setter, unsigned attrs, ShapeTable* table,
       ShapeTable::Entry* entry, const AutoKeepShapeCaches& keep);
 
   static MOZ_MUST_USE bool fillInAfterSwap(JSContext* cx,
                                            HandleNativeObject obj,
-                                           const AutoValueVector& values,
+                                           HandleValueVector values,
                                            void* priv);
 
  public:
   // Return true if this object has been converted from shared-immutable
   // prototype-rooted shape storage to dictionary-shapes in a doubly-linked
   // list.
   bool inDictionaryMode() const { return lastProperty()->inDictionary(); }
 
--- a/js/src/vm/ProxyObject.h
+++ b/js/src/vm/ProxyObject.h
@@ -57,18 +57,18 @@ class ProxyObject : public ShapedObject 
   bool usingInlineValueArray() const {
     return data.values() == inlineDataStart();
   }
   void setInlineValueArray() {
     data.reservedSlots =
         &reinterpret_cast<detail::ProxyValueArray*>(inlineDataStart())
              ->reservedSlots;
   }
-  MOZ_MUST_USE bool initExternalValueArrayAfterSwap(
-      JSContext* cx, const AutoValueVector& values);
+  MOZ_MUST_USE bool initExternalValueArrayAfterSwap(JSContext* cx,
+                                                    HandleValueVector values);
 
   const Value& private_() const { return GetProxyPrivate(this); }
 
   void setCrossCompartmentPrivate(const Value& priv);
   void setSameCompartmentPrivate(const Value& priv);
 
   JSObject* target() const { return private_().toObjectOrNull(); }
 
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -913,17 +913,17 @@ class AnyConstructArgs : public JS::Call
 
 namespace detail {
 
 /** Function call/construct args of statically-unknown count. */
 template <MaybeConstruct Construct>
 class GenericArgsBase : public mozilla::Conditional<Construct, AnyConstructArgs,
                                                     AnyInvokeArgs>::Type {
  protected:
-  AutoValueVector v_;
+  RootedValueVector v_;
 
   explicit GenericArgsBase(JSContext* cx) : v_(cx) {}
 
  public:
   bool init(JSContext* cx, unsigned argc) {
     if (argc > ARGS_LENGTH_MAX) {
       JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                                 JSMSG_TOO_MANY_ARGUMENTS);
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -59,16 +59,17 @@
 
 #include "vm/InlineCharBuffer-inl.h"
 #include "vm/JSContext-inl.h"
 #include "vm/JSObject-inl.h"
 
 using namespace js;
 
 using JS::CanonicalizeNaN;
+using JS::RootedValueVector;
 using mozilla::BitwiseCast;
 using mozilla::NativeEndian;
 using mozilla::NumbersAreIdentical;
 using mozilla::RangedPtr;
 
 // When you make updates here, make sure you consider whether you need to bump
 // the value of JS_STRUCTURED_CLONE_VERSION in js/public/StructuredClone.h.  You
 // will likely need to increment the version if anything at all changes in the
@@ -421,30 +422,30 @@ struct JSStructuredCloneReader {
 
   // The widest scope that the caller will accept, where
   // SameProcessSameThread is the widest (it can store anything it wants) and
   // DifferentProcess is the narrowest (it cannot contain pointers and must
   // be valid cross-process.)
   JS::StructuredCloneScope allowedScope;
 
   // Stack of objects with properties remaining to be read.
-  AutoValueVector objs;
+  RootedValueVector objs;
 
   // Array of all objects read during this deserialization, for resolving
   // backreferences.
   //
   // For backreferences to work correctly, objects must be added to this
   // array in exactly the order expected by the version of the Writer that
   // created the serialized data, even across years and format versions. This
   // is usually no problem, since both algorithms do a single linear pass
   // over the serialized data. There is one hitch; see readTypedArray.
   //
   // The values in this vector are objects, except it can temporarily have
   // one `undefined` placeholder value (the readTypedArray hack).
-  AutoValueVector allObjs;
+  RootedValueVector allObjs;
 
   // The user defined callbacks that will be used for cloning.
   const JSStructuredCloneCallbacks* callbacks;
 
   // Any value passed to JS_ReadStructuredClone.
   void* closure;
 
   friend bool JS_ReadTypedArray(JSStructuredCloneReader* r,
@@ -515,29 +516,29 @@ struct JSStructuredCloneWriter {
   inline void checkStack();
 
   SCOutput out;
 
   // Vector of objects with properties remaining to be written.
   //
   // NB: These can span multiple compartments, so the compartment must be
   // entered before any manipulation is performed.
-  AutoValueVector objs;
+  RootedValueVector objs;
 
   // counts[i] is the number of entries of objs[i] remaining to be written.
   // counts.length() == objs.length() and sum(counts) == entries.length().
   Vector<size_t> counts;
 
   // For JSObject: Property IDs as value
   AutoIdVector objectEntries;
 
   // For Map: Key followed by value
   // For Set: Key
   // For SavedFrame: parent SavedFrame
-  AutoValueVector otherEntries;
+  RootedValueVector otherEntries;
 
   // The "memory" list described in the HTML5 internal structured cloning
   // algorithm.  memory is a superset of objs; items are never removed from
   // Memory until a serialization operation is finished
   using CloneMemory =
       GCHashMap<JSObject*, uint32_t, MovableCellHasher<JSObject*>,
                 SystemAllocPolicy>;
   Rooted<CloneMemory> memory;
--- a/js/src/vm/TypedArrayObject-inl.h
+++ b/js/src/vm/TypedArrayObject-inl.h
@@ -447,17 +447,17 @@ class ElementSpecific {
       Ops::store(dest + i, infallibleValueToNative(srcValues[i]));
     }
     if (i == len) {
       return true;
     }
 
     // Convert any remaining elements by first collecting them into a
     // temporary list, and then copying them into the typed array.
-    AutoValueVector values(cx);
+    RootedValueVector values(cx);
     if (!values.append(srcValues + i, len - i)) {
       return false;
     }
 
     RootedValue v(cx);
     for (uint32_t j = 0; j < values.length(); i++, j++) {
       v = values[j];
 
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -811,17 +811,17 @@ bool WasmModuleObject::imports(JSContext
     return false;
   }
 
   KindNames names(cx);
   if (!InitKindNames(cx, &names)) {
     return false;
   }
 
-  AutoValueVector elems(cx);
+  RootedValueVector elems(cx);
   if (!elems.reserve(module->imports().length())) {
     return false;
   }
 
   const FuncImportVector& funcImports =
       module->metadata(module->code().stableTier()).funcImports;
 
   size_t numFuncImport = 0;
@@ -891,17 +891,17 @@ bool WasmModuleObject::exports(JSContext
     return false;
   }
 
   KindNames names(cx);
   if (!InitKindNames(cx, &names)) {
     return false;
   }
 
-  AutoValueVector elems(cx);
+  RootedValueVector elems(cx);
   if (!elems.reserve(module->exports().length())) {
     return false;
   }
 
   const FuncExportVector& funcExports =
       module->metadata(module->code().stableTier()).funcExports;
 
   size_t numFuncExport = 0;
@@ -980,17 +980,17 @@ bool WasmModuleObject::customSections(JS
     if (!name.initLengthUninitialized(JS::GetDeflatedUTF8StringLength(flat))) {
       return false;
     }
 
     JS::DeflateStringToUTF8Buffer(flat,
                                   RangedPtr<char>(name.begin(), name.length()));
   }
 
-  AutoValueVector elems(cx);
+  RootedValueVector elems(cx);
   RootedArrayBufferObject buf(cx);
   for (const CustomSection& cs : module->customSections()) {
     if (name.length() != cs.name.length()) {
       continue;
     }
     if (memcmp(name.begin(), cs.name.begin(), name.length())) {
       continue;
     }
--- a/js/src/wasm/WasmModule.cpp
+++ b/js/src/wasm/WasmModule.cpp
@@ -1170,17 +1170,18 @@ static bool CreateExportObject(JSContext
 
   instanceObj->initExportsObj(*exportObj);
   return true;
 }
 
 #ifdef ENABLE_WASM_GC
 static bool MakeStructField(JSContext* cx, const ValType& v, bool isMutable,
                             const char* format, uint32_t fieldNo,
-                            AutoIdVector* ids, AutoValueVector* fieldTypeObjs,
+                            AutoIdVector* ids,
+                            MutableHandleValueVector fieldTypeObjs,
                             Vector<StructFieldProps>* fieldProps) {
   char buf[20];
   sprintf(buf, format, fieldNo);
 
   JSAtom* atom = Atomize(cx, buf, strlen(buf));
   if (!atom) {
     return false;
   }
@@ -1223,17 +1224,17 @@ static bool MakeStructField(JSContext* c
       MOZ_CRASH("Bad field type");
   }
   MOZ_ASSERT(t != nullptr);
 
   if (!ids->append(id)) {
     return false;
   }
 
-  if (!fieldTypeObjs->append(ObjectValue(*t))) {
+  if (!fieldTypeObjs.append(ObjectValue(*t))) {
     return false;
   }
 
   if (!fieldProps->append(props)) {
     return false;
   }
 
   return true;
@@ -1267,17 +1268,17 @@ bool Module::makeStructTypeDescrs(
   RootedNativeObject toModule(cx, &typedObjectModule->as<NativeObject>());
   RootedObject prototype(
       cx,
       &toModule->getReservedSlot(TypedObjectModuleObject::StructTypePrototype)
            .toObject());
 
   for (const StructType& structType : structTypes()) {
     AutoIdVector ids(cx);
-    AutoValueVector fieldTypeObjs(cx);
+    RootedValueVector fieldTypeObjs(cx);
     Vector<StructFieldProps> fieldProps(cx);
     bool allowConstruct = true;
 
     uint32_t k = 0;
     for (StructField sf : structType.fields_) {
       const ValType& v = sf.type;
       if (v.code() == ValType::I64) {
         // TypedObjects don't yet have a notion of int64 fields.  Thus
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -837,17 +837,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
     JS_ReportErrorASCII(cx, "%s", str);
     NS_WARNING(str);
     return CheckForException(ccx, aes, obj, name, GetInterfaceName());
   }
 
   RootedValue fval(cx);
   RootedObject thisObj(cx, obj);
 
-  AutoValueVector args(cx);
+  RootedValueVector args(cx);
   AutoScriptEvaluate scriptEval(cx);
 
   XPCJSContext* xpccx = ccx.GetContext();
   AutoSavePendingResult apr(xpccx);
 
   // XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
   uint8_t paramCount = info->GetParamCount();
   uint8_t argc = paramCount;
--- a/toolkit/components/telemetry/core/Telemetry.cpp
+++ b/toolkit/components/telemetry/core/Telemetry.cpp
@@ -1817,17 +1817,17 @@ TelemetryImpl::GetAllStores(JSContext* a
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = TelemetryScalar::GetAllStores(stores);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  JS::AutoValueVector allStores(aCx);
+  JS::RootedVector<JS::Value> allStores(aCx);
   if (!allStores.reserve(stores.Count())) {
     return NS_ERROR_FAILURE;
   }
 
   for (auto iter = stores.Iter(); !iter.Done(); iter.Next()) {
     auto& value = iter.Get()->GetKey();
     JS::RootedValue store(aCx);
 
--- a/toolkit/components/telemetry/core/TelemetryEvent.cpp
+++ b/toolkit/components/telemetry/core/TelemetryEvent.cpp
@@ -581,17 +581,17 @@ nsresult SerializeEventsArray(const Even
 
   for (uint32_t i = 0; i < events.Length(); ++i) {
     const EventRecord& record = events[i];
 
     // Each entry is an array of one of the forms:
     // [timestamp, category, method, object, value]
     // [timestamp, category, method, object, null, extra]
     // [timestamp, category, method, object, value, extra]
-    JS::AutoValueVector items(cx);
+    JS::RootedVector<JS::Value> items(cx);
 
     // Add timestamp.
     JS::Rooted<JS::Value> val(cx);
     if (!items.append(JS::NumberValue(floor(record.Timestamp())))) {
       return NS_ERROR_FAILURE;
     }
 
     // Add category, method, object.
--- a/toolkit/components/telemetry/core/TelemetryHistogram.cpp
+++ b/toolkit/components/telemetry/core/TelemetryHistogram.cpp
@@ -2255,17 +2255,17 @@ bool internal_JSKeyedHistogram_Keys(JSCo
 
     if (NS_FAILED(
             keyed->GetKeys(locker, NS_ConvertUTF16toUTF8(storeName), keys))) {
       return false;
     }
   }
 
   // Convert keys from nsTArray<nsCString> to JS array.
-  JS::AutoValueVector autoKeys(cx);
+  JS::RootedVector<JS::Value> autoKeys(cx);
   if (!autoKeys.reserve(keys.Length())) {
     return false;
   }
 
   for (const auto& key : keys) {
     JS::RootedValue jsKey(cx);
     jsKey.setString(ToJSString(cx, key));
     if (!autoKeys.append(jsKey)) {
--- a/widget/android/EventDispatcher.cpp
+++ b/widget/android/EventDispatcher.cpp
@@ -392,17 +392,17 @@ template <typename Type, typename JNITyp
           JNIType* (JNIEnv::*GetElements)(ArrayType, jboolean*),
           void (JNIEnv::*ReleaseElements)(ArrayType, JNIType*, jint),
           JS::Value (*ToValue)(Type)>
 nsresult UnboxArrayPrimitive(JSContext* aCx, const jni::Object::LocalRef& aData,
                              JS::MutableHandleValue aOut) {
   JNIEnv* const env = aData.Env();
   const ArrayType jarray = ArrayType(aData.Get());
   JNIType* const array = (env->*GetElements)(jarray, nullptr);
-  JS::AutoValueVector elements(aCx);
+  JS::RootedVector<JS::Value> elements(aCx);
 
   if (NS_WARN_IF(!array)) {
     env->ExceptionClear();
     return NS_ERROR_FAILURE;
   }
 
   auto releaseArray = MakeScopeExit([env, jarray, array] {
     (env->*ReleaseElements)(jarray, array, JNI_ABORT);