Bug 939294 - Change xpidl jsval to handles. r=gabor,bz,khuey,bsmedberg,terrence
authorTom Schuster <evilpies@gmail.com>
Thu, 09 Jan 2014 18:39:36 +0100
changeset 179771 f017ae03bb6c453132c7023870557c4a5d469c97
parent 179770 913a1c5086c5e99da2e7bbc9a0957606214da983
child 179772 791cbd3d504764182ed616423fac99a6433a7e2e
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor, bz, khuey, bsmedberg, terrence
bugs939294
milestone29.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 939294 - Change xpidl jsval to handles. r=gabor,bz,khuey,bsmedberg,terrence
caps/src/nsScriptSecurityManager.cpp
content/base/public/nsDOMFile.h
content/base/src/FileIOObject.h
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMFile.cpp
content/base/src/nsDOMFileReader.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsFrameMessageManager.h
content/base/src/nsINode.cpp
content/base/src/nsInProcessTabChildGlobal.h
content/base/src/nsXMLHttpRequest.cpp
content/html/content/src/HTMLCanvasElement.cpp
content/html/content/src/HTMLMediaElement.cpp
content/media/WebVTTListener.cpp
content/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
content/media/webspeech/synth/ipc/SpeechSynthesisChild.h
content/media/webspeech/synth/nsSpeechTask.cpp
docshell/base/nsDocShell.cpp
dom/base/DOMRequest.cpp
dom/base/Navigator.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsHistory.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsScreen.cpp
dom/base/nsStructuredCloneContainer.cpp
dom/bindings/BindingUtils.cpp
dom/bluetooth/BluetoothPropertyContainer.cpp
dom/bluetooth/BluetoothService.cpp
dom/bluetooth/bluedroid/BluetoothHfpManager.cpp
dom/bluetooth/bluedroid/BluetoothUtils.cpp
dom/bluetooth/bluez/BluetoothHfpManager.cpp
dom/bluetooth/bluez/BluetoothUtils.cpp
dom/camera/DOMCameraCapabilities.cpp
dom/camera/DOMCameraCapabilities.h
dom/events/nsDOMEventTargetHelper.h
dom/events/nsDOMMessageEvent.cpp
dom/events/nsDOMNotifyAudioAvailableEvent.cpp
dom/events/nsDOMNotifyAudioAvailableEvent.h
dom/events/nsEventListenerService.cpp
dom/file/LockedFile.cpp
dom/file/MetadataHelper.h
dom/fmradio/FMRadioService.cpp
dom/icc/src/Icc.cpp
dom/icc/src/Icc.h
dom/icc/src/IccManager.cpp
dom/indexedDB/IndexedDatabaseManager.cpp
dom/ipc/Blob.cpp
dom/ipc/TabChild.h
dom/mobilemessage/src/MmsMessage.cpp
dom/mobilemessage/src/MobileMessageManager.cpp
dom/mobilemessage/src/MobileMessageService.cpp
dom/mobilemessage/src/MobileMessageThread.cpp
dom/mobilemessage/src/SmsFilter.cpp
dom/mobilemessage/src/ipc/SmsIPCService.cpp
dom/network/src/MobileConnection.cpp
dom/network/src/TCPSocketChild.cpp
dom/network/src/TCPSocketParent.cpp
dom/src/geolocation/nsGeolocation.cpp
dom/src/json/nsJSON.cpp
dom/src/json/nsJSON.h
dom/src/jsurl/nsJSProtocolHandler.cpp
dom/system/gonk/AudioManager.cpp
dom/system/gonk/AutoMounterSetting.cpp
dom/system/gonk/GonkGPSGeolocationProvider.cpp
dom/system/gonk/SystemWorkerManager.cpp
dom/system/gonk/TimeZoneSettingObserver.cpp
dom/wifi/WifiProxyService.cpp
dom/workers/File.cpp
dom/workers/XMLHttpRequest.cpp
embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
gfx/src/nsScriptableRegion.cpp
js/ductwork/debugger/JSDebugger.cpp
js/jsd/jsd_xpc.cpp
js/xpconnect/idl/nsIXPConnect.idl
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/loader/mozJSSubScriptLoader.cpp
js/xpconnect/loader/mozJSSubScriptLoader.h
js/xpconnect/public/xpc_map_end.h
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCJSWeakReference.cpp
js/xpconnect/src/XPCShellImpl.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/qsgen.py
js/xpconnect/tests/components/native/xpctest_params.cpp
js/xpconnect/wrappers/WrapperFactory.cpp
layout/inspector/inDOMUtils.cpp
netwerk/base/src/ArrayBufferInputStream.cpp
netwerk/protocol/app/AppProtocolHandler.cpp
storage/src/Variant_inl.h
toolkit/components/finalizationwitness/FinalizationWitnessService.cpp
toolkit/components/places/History.cpp
toolkit/components/places/PlaceInfo.cpp
toolkit/components/startup/nsAppStartup.cpp
toolkit/components/telemetry/Telemetry.cpp
toolkit/devtools/server/nsJSInspector.cpp
tools/profiler/nsProfiler.cpp
uriloader/exthandler/nsExternalHelperAppService.cpp
widget/xpwidgets/GfxInfoBase.cpp
widget/xpwidgets/GfxInfoBase.h
xpcom/ds/nsVariant.cpp
xpcom/idl-parser/header.py
xpcom/idl-parser/xpidl.py
xpcom/io/nsBinaryStream.cpp
xpfe/appshell/src/nsChromeTreeOwner.cpp
xpfe/appshell/src/nsContentTreeOwner.cpp
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1484,17 +1484,17 @@ nsScriptSecurityManager::GetSubjectPrinc
     // or the one associated with its global.
     MOZ_ASSERT(!!compartment);
 
     JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
     return nsJSPrincipals::get(principals);
 }
 
 NS_IMETHODIMP
-nsScriptSecurityManager::GetObjectPrincipal(const JS::Value &aObjectVal,
+nsScriptSecurityManager::GetObjectPrincipal(JS::Handle<JS::Value> aObjectVal,
                                             JSContext *aCx,
                                             nsIPrincipal **result)
 {
     NS_ENSURE_TRUE(aObjectVal.isObject(), NS_ERROR_FAILURE);
     JS::RootedObject obj(aCx, &aObjectVal.toObject());
     nsCOMPtr<nsIPrincipal> principal = doGetObjectPrincipal(obj);
     principal.forget(result);
     return NS_OK;
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -291,17 +291,17 @@ public:
     // Lazily get the content type and size
     mContentType.SetIsVoid(true);
     mName.SetIsVoid(true);
   }
 
   // Overrides
   NS_IMETHOD GetSize(uint64_t* aSize) MOZ_OVERRIDE;
   NS_IMETHOD GetType(nsAString& aType) MOZ_OVERRIDE;
-  NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate) MOZ_OVERRIDE;
+  NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::MutableHandle<JS::Value> aLastModifiedDate) MOZ_OVERRIDE;
   NS_IMETHOD GetMozLastModifiedDate(uint64_t* aLastModifiedDate) MOZ_OVERRIDE;
   NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
   NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE;
 
   void SetPath(const nsAString& aFullPath);
 
 protected:
   // Create slice
--- a/content/base/src/FileIOObject.h
+++ b/content/base/src/FileIOObject.h
@@ -43,22 +43,22 @@ public:
   {
     return mReadyState;
   }
   DOMError* GetError() const
   {
     return mError;
   }
 
-  NS_METHOD GetOnabort(JSContext* aCx, JS::Value* aValue);
-  NS_METHOD SetOnabort(JSContext* aCx, const JS::Value& aValue);
-  NS_METHOD GetOnerror(JSContext* aCx, JS::Value* aValue);
-  NS_METHOD SetOnerror(JSContext* aCx, const JS::Value& aValue);
-  NS_METHOD GetOnprogress(JSContext* aCx, JS::Value* aValue);
-  NS_METHOD SetOnprogress(JSContext* aCx, const JS::Value& aValue);
+  NS_METHOD GetOnabort(JSContext* aCx, JS::MutableHandle<JS::Value> aValue);
+  NS_METHOD SetOnabort(JSContext* aCx, JS::Handle<JS::Value> aValue);
+  NS_METHOD GetOnerror(JSContext* aCx, JS::MutableHandle<JS::Value> aValue);
+  NS_METHOD SetOnerror(JSContext* aCx, JS::Handle<JS::Value> aValue);
+  NS_METHOD GetOnprogress(JSContext* aCx, JS::MutableHandle<JS::Value> aValue);
+  NS_METHOD SetOnprogress(JSContext* aCx, JS::Handle<JS::Value> aValue);
 
   IMPL_EVENT_HANDLER(abort)
   IMPL_EVENT_HANDLER(error)
   IMPL_EVENT_HANDLER(progress)
 
   NS_DECL_NSITIMERCALLBACK
 
   NS_DECL_NSISTREAMLISTENER
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5630,17 +5630,17 @@ nsContentUtils::WrapNative(JSContext *cx
 
   if (!NS_IsMainThread()) {
     MOZ_CRASH();
   }
 
   nsresult rv = NS_OK;
   AutoPushJSContext context(cx);
   rv = sXPConnect->WrapNativeToJSVal(context, scope, native, cache, aIID,
-                                     aAllowWrapping, vp.address());
+                                     aAllowWrapping, vp);
   return rv;
 }
 
 nsresult
 nsContentUtils::CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
                                   JSObject** aResult)
 {
   if (!aCx) {
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -131,20 +131,23 @@ NS_IMETHODIMP
 nsDOMFileBase::GetPath(nsAString &aPath)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
   aPath = mPath;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileBase::GetLastModifiedDate(JSContext* cx, JS::Value *aLastModifiedDate)
+nsDOMFileBase::GetLastModifiedDate(JSContext* cx, JS::MutableHandle<JS::Value> aLastModifiedDate)
 {
-  JSObject* date = JS_NewDateObjectMsec(cx, JS_Now() / PR_USEC_PER_MSEC);
-  aLastModifiedDate->setObject(*date);
+  JS::Rooted<JSObject*> date(cx, JS_NewDateObjectMsec(cx, JS_Now() / PR_USEC_PER_MSEC));
+  if (!date) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  aLastModifiedDate.setObject(*date);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileBase::GetMozFullPath(nsAString &aFileName)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
 
@@ -497,36 +500,36 @@ nsDOMFileFile::CreateSlice(uint64_t aSta
 NS_IMETHODIMP
 nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
   return mFile->GetPath(aFilename);
 }
 
 NS_IMETHODIMP
-nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
+nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::MutableHandle<JS::Value> aLastModifiedDate)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
 
   PRTime msecs;
   if (IsDateUnknown()) {
     nsresult rv = mFile->GetLastModifiedTime(&msecs);
     NS_ENSURE_SUCCESS(rv, rv);
     mLastModificationDate = msecs;
   } else {
     msecs = mLastModificationDate;
   }
 
   JSObject* date = JS_NewDateObjectMsec(cx, msecs);
   if (date) {
-    aLastModifiedDate->setObject(*date);
+    aLastModifiedDate.setObject(*date);
   }
   else {
     date = JS_NewDateObjectMsec(cx, JS_Now() / PR_USEC_PER_MSEC);
-    aLastModifiedDate->setObject(*date);
+    aLastModifiedDate.setObject(*date);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileFile::GetSize(uint64_t *aFileSize)
 {
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -179,42 +179,41 @@ nsDOMFileReader::GetReadyState(uint16_t 
   *aReadyState = ReadyState();
   return NS_OK;
 }
 
 JS::Value
 nsDOMFileReader::GetResult(JSContext* aCx, ErrorResult& aRv)
 {
   JS::Rooted<JS::Value> result(aCx);
-  aRv = GetResult(aCx, result.address());
+  aRv = GetResult(aCx, &result);
   return result;
 }
 
 NS_IMETHODIMP
-nsDOMFileReader::GetResult(JSContext* aCx, JS::Value* aResult)
+nsDOMFileReader::GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult)
 {
   JS::Rooted<JS::Value> result(aCx);
   if (mDataFormat == FILE_AS_ARRAYBUFFER) {
     if (mReadyState == nsIDOMFileReader::DONE && mResultArrayBuffer) {
       result.setObject(*mResultArrayBuffer);
     } else {
       result.setNull();
     }
     if (!JS_WrapValue(aCx, &result)) {
       return NS_ERROR_FAILURE;
     }
-    *aResult = result;
+    aResult.set(result);
     return NS_OK;
   }
 
   nsString tmpResult = mResult;
-  if (!xpc::StringToJsval(aCx, tmpResult, &result)) {
+  if (!xpc::StringToJsval(aCx, tmpResult, aResult)) {
     return NS_ERROR_FAILURE;
   }
-  *aResult = result;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileReader::GetError(nsISupports** aError)
 {
   NS_IF_ADDREF(*aError = GetError());
   return NS_OK;
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -442,17 +442,17 @@ nsFrameMessageManager::RemoveDelayedFram
       mPendingScriptsGlobalStates.RemoveElementAt(i);
       break;
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsFrameMessageManager::GetDelayedFrameScripts(JSContext* aCx, JS::Value* aList)
+nsFrameMessageManager::GetDelayedFrameScripts(JSContext* aCx, JS::MutableHandle<JS::Value> aList)
 {
   // Frame message managers may return an incomplete list because scripts
   // that were loaded after it was connected are not added to the list.
   if (!IsGlobal() && !IsWindowLevel()) {
     NS_WARNING("Cannot retrieve list of pending frame scripts for frame"
                "message managers as it may be incomplete");
     return NS_ERROR_NOT_IMPLEMENTED;
   }
@@ -473,18 +473,17 @@ nsFrameMessageManager::GetDelayedFrameSc
     pair = JS_NewArrayObject(aCx, 2, pairElts);
     NS_ENSURE_TRUE(pair, NS_ERROR_OUT_OF_MEMORY);
 
     pairVal = JS::ObjectValue(*pair);
     NS_ENSURE_TRUE(JS_SetElement(aCx, array, i, &pairVal),
                    NS_ERROR_OUT_OF_MEMORY);
   }
 
-  *aList = JS::ObjectValue(*array);
-
+  aList.setObject(*array);
   return NS_OK;
 }
 
 static bool
 JSONCreator(const jschar* aBuf, uint32_t aLen, void* aData)
 {
   nsAString* result = static_cast<nsAString*>(aData);
   result->Append(static_cast<const char16_t*>(aBuf),
@@ -522,55 +521,55 @@ GetParamsForMessage(JSContext* aCx,
 
 
 // nsISyncMessageSender
 
 static bool sSendingSyncMessage = false;
 
 NS_IMETHODIMP
 nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
-                                       const JS::Value& aJSON,
-                                       const JS::Value& aObjects,
+                                       JS::Handle<JS::Value> aJSON,
+                                       JS::Handle<JS::Value> aObjects,
                                        nsIPrincipal* aPrincipal,
                                        JSContext* aCx,
                                        uint8_t aArgc,
-                                       JS::Value* aRetval)
+                                       JS::MutableHandle<JS::Value> aRetval)
 {
   return SendMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx, aArgc,
                      aRetval, true);
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::SendRpcMessage(const nsAString& aMessageName,
-                                      const JS::Value& aJSON,
-                                      const JS::Value& aObjects,
+                                      JS::Handle<JS::Value> aJSON,
+                                      JS::Handle<JS::Value> aObjects,
                                       nsIPrincipal* aPrincipal,
                                       JSContext* aCx,
                                       uint8_t aArgc,
-                                      JS::Value* aRetval)
+                                      JS::MutableHandle<JS::Value> aRetval)
 {
   return SendMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx, aArgc,
                      aRetval, false);
 }
 
 nsresult
 nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
-                                   const JS::Value& aJSON,
-                                   const JS::Value& aObjects,
+                                   JS::Handle<JS::Value> aJSON,
+                                   JS::Handle<JS::Value> aObjects,
                                    nsIPrincipal* aPrincipal,
                                    JSContext* aCx,
                                    uint8_t aArgc,
-                                   JS::Value* aRetval,
+                                   JS::MutableHandle<JS::Value> aRetval,
                                    bool aIsSync)
 {
   NS_ASSERTION(!IsGlobal(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!IsWindowLevel(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!mParentManager, "Should not have parent manager in content!");
 
-  *aRetval = JSVAL_VOID;
+  aRetval.setUndefined();
   NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
 
   if (sSendingSyncMessage && aIsSync) {
     // No kind of blocking send should be issued on top of a sync message.
     return NS_ERROR_UNEXPECTED;
   }
 
   StructuredCloneData data;
@@ -613,17 +612,17 @@ nsFrameMessageManager::SendMessage(const
     if (!JS_ParseJSON(aCx, static_cast<const jschar*>(retval[i].get()),
                       retval[i].Length(), &ret)) {
       return NS_ERROR_UNEXPECTED;
     }
     NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, &ret),
                    NS_ERROR_OUT_OF_MEMORY);
   }
 
-  *aRetval = OBJECT_TO_JSVAL(dataArray);
+  aRetval.setObject(*dataArray);
   return NS_OK;
 }
 
 nsresult
 nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
                                                     const nsAString& aMessage,
                                                     const StructuredCloneData& aData,
                                                     JS::Handle<JSObject *> aCpows,
@@ -673,33 +672,33 @@ nsFrameMessageManager::DispatchAsyncMess
                                       aPrincipal);
 }
 
 
 // nsIMessageSender
 
 NS_IMETHODIMP
 nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
-                                        const JS::Value& aJSON,
-                                        const JS::Value& aObjects,
+                                        JS::Handle<JS::Value> aJSON,
+                                        JS::Handle<JS::Value> aObjects,
                                         nsIPrincipal* aPrincipal,
                                         JSContext* aCx,
                                         uint8_t aArgc)
 {
   return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx,
                               aArgc);
 }
 
 
 // nsIMessageBroadcaster
 
 NS_IMETHODIMP
 nsFrameMessageManager::BroadcastAsyncMessage(const nsAString& aMessageName,
-                                             const JS::Value& aJSON,
-                                             const JS::Value& aObjects,
+                                             JS::Handle<JS::Value> aJSON,
+                                             JS::Handle<JS::Value> aObjects,
                                              JSContext* aCx,
                                              uint8_t aArgc)
 {
   return DispatchAsyncMessage(aMessageName, aJSON, aObjects, nullptr, aCx,
                               aArgc);
 }
 
 NS_IMETHODIMP
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -266,22 +266,22 @@ public:
     return sParentProcessManager;
   }
   static nsFrameMessageManager* GetChildProcessManager()
   {
     return sChildProcessManager;
   }
 private:
   nsresult SendMessage(const nsAString& aMessageName,
-                       const JS::Value& aJSON,
-                       const JS::Value& aObjects,
+                       JS::Handle<JS::Value> aJSON,
+                       JS::Handle<JS::Value> aObjects,
                        nsIPrincipal* aPrincipal,
                        JSContext* aCx,
                        uint8_t aArgc,
-                       JS::Value* aRetval,
+                       JS::MutableHandle<JS::Value> aRetval,
                        bool aIsSync);
 protected:
   friend class MMListenerRemover;
   // We keep the message listeners as arrays in a hastable indexed by the
   // message name. That gives us fast lookups in ReceiveMessage().
   nsClassHashtable<nsStringHashKey,
                    nsAutoTObserverArray<nsMessageListenerInfo, 1>> mListeners;
   nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -699,18 +699,17 @@ nsINode::SetUserData(const nsAString &aK
 
 JS::Value
 nsINode::SetUserData(JSContext* aCx, const nsAString& aKey,
                      JS::Handle<JS::Value> aData,
                      nsIDOMUserDataHandler* aHandler, ErrorResult& aError)
 {
   nsCOMPtr<nsIVariant> data;
   JS::Rooted<JS::Value> dataVal(aCx, aData);
-  aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, dataVal.address(),
-                                                       getter_AddRefs(data));
+  aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, dataVal, getter_AddRefs(data));
   if (aError.Failed()) {
     return JS::UndefinedValue();
   }
 
   nsCOMPtr<nsIVariant> oldData;
   aError = SetUserData(aKey, data, aHandler, getter_AddRefs(oldData));
   if (aError.Failed()) {
     return JS::UndefinedValue();
@@ -718,17 +717,17 @@ nsINode::SetUserData(JSContext* aCx, con
 
   if (!oldData) {
     return JS::NullValue();
   }
 
   JS::Rooted<JS::Value> result(aCx);
   JSAutoCompartment ac(aCx, GetWrapper());
   aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), oldData,
-                                                    result.address());
+                                                    &result);
   return result;
 }
 
 nsIVariant*
 nsINode::GetUserData(const nsAString& aKey)
 {
   OwnerDoc()->WarnOnceAbout(nsIDocument::eGetSetUserData);
   nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
@@ -745,17 +744,17 @@ nsINode::GetUserData(JSContext* aCx, con
   nsIVariant* data = GetUserData(aKey);
   if (!data) {
     return JS::NullValue();
   }
 
   JS::Rooted<JS::Value> result(aCx);
   JSAutoCompartment ac(aCx, GetWrapper());
   aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), data,
-                                                    result.address());
+                                                    &result);
   return result;
 }
 
 uint16_t
 nsINode::CompareDocumentPosition(nsINode& aOtherNode) const
 {
   if (this == &aOtherNode) {
     return 0;
--- a/content/base/src/nsInProcessTabChildGlobal.h
+++ b/content/base/src/nsInProcessTabChildGlobal.h
@@ -36,35 +36,35 @@ public:
                             nsFrameMessageManager* aChrome);
   virtual ~nsInProcessTabChildGlobal();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsInProcessTabChildGlobal,
                                            nsDOMEventTargetHelper)
   NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
   NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
-                             const JS::Value& aObject,
-                             const JS::Value& aRemote,
+                             JS::Handle<JS::Value> aObject,
+                             JS::Handle<JS::Value> aRemote,
                              nsIPrincipal* aPrincipal,
                              JSContext* aCx,
                              uint8_t aArgc,
-                             JS::Value* aRetval)
+                             JS::MutableHandle<JS::Value> aRetval)
   {
     return mMessageManager
       ? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote,
                                          aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
-                            const JS::Value& aObject,
-                            const JS::Value& aRemote,
+                            JS::Handle<JS::Value> aObject,
+                            JS::Handle<JS::Value> aRemote,
                             nsIPrincipal* aPrincipal,
                             JSContext* aCx,
                             uint8_t aArgc,
-                            JS::Value* aRetval)
+                            JS::MutableHandle<JS::Value> aRetval)
   {
     return mMessageManager
       ? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote,
                                         aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
   NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) MOZ_OVERRIDE;
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -916,20 +916,20 @@ nsXMLHttpRequest::SetResponseType(nsXMLH
 
   // Set the responseType attribute's value to the given value.
   mResponseType = aResponseType;
 
 }
 
 /* readonly attribute jsval response; */
 NS_IMETHODIMP
-nsXMLHttpRequest::GetResponse(JSContext *aCx, JS::Value *aResult)
+nsXMLHttpRequest::GetResponse(JSContext *aCx, JS::MutableHandle<JS::Value> aResult)
 {
   ErrorResult rv;
-  *aResult = GetResponse(aCx, rv);
+  aResult.set(GetResponse(aCx, rv));
   return rv.ErrorCode();
 }
 
 JS::Value
 nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
 {
   switch (mResponseType) {
   case XML_HTTP_RESPONSE_TYPE_DEFAULT:
@@ -2402,17 +2402,17 @@ GetRequestBody(nsIVariant* aBody, nsIInp
     if (sendable) {
       return GetRequestBody(sendable, aResult, aContentLength, aContentType, aCharset);
     }
 
     // ArrayBuffer?
     AutoSafeJSContext cx;
     JS::Rooted<JS::Value> realVal(cx);
 
-    nsresult rv = aBody->GetAsJSVal(realVal.address());
+    nsresult rv = aBody->GetAsJSVal(&realVal);
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal)) {
       JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(realVal));
       if (JS_IsArrayBufferObject(obj)) {
           ArrayBuffer buf(obj);
           return GetRequestBody(buf.Data(), buf.Length(), aResult,
                                 aContentLength, aContentType, aCharset);
       }
     }
--- a/content/html/content/src/HTMLCanvasElement.cpp
+++ b/content/html/content/src/HTMLCanvasElement.cpp
@@ -322,17 +322,17 @@ HTMLCanvasElement::ParseAttribute(int32_
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
 
 // HTMLCanvasElement::toDataURL
 
 NS_IMETHODIMP
-HTMLCanvasElement::ToDataURL(const nsAString& aType, const JS::Value& aParams,
+HTMLCanvasElement::ToDataURL(const nsAString& aType, JS::Handle<JS::Value> aParams,
                              JSContext* aCx, nsAString& aDataURL)
 {
   // do a trust check if this is a write-only canvas
   if (mWriteOnly && !nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   return ToDataURLImpl(aCx, aType, aParams, aDataURL);
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -1637,24 +1637,24 @@ HTMLMediaElement::MozGetMetadata(JSConte
       return nullptr;
     }
   }
 
   return tags;
 }
 
 NS_IMETHODIMP
-HTMLMediaElement::MozGetMetadata(JSContext* cx, JS::Value* aValue)
+HTMLMediaElement::MozGetMetadata(JSContext* cx, JS::MutableHandle<JS::Value> aValue)
 {
   ErrorResult rv;
 
   JSObject* obj = MozGetMetadata(cx, rv);
   if (!rv.Failed()) {
     MOZ_ASSERT(obj);
-    *aValue = JS::ObjectValue(*obj);
+    aValue.setObject(*obj);
   }
 
   return rv.ErrorCode();
 }
 
 uint32_t
 HTMLMediaElement::GetMozFrameBufferLength(ErrorResult& aRv) const
 {
--- a/content/media/WebVTTListener.cpp
+++ b/content/media/WebVTTListener.cpp
@@ -150,17 +150,17 @@ WebVTTListener::OnDataAvailable(nsIReque
     }
     count -= read;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-WebVTTListener::OnCue(const JS::Value &aCue, JSContext* aCx)
+WebVTTListener::OnCue(JS::Handle<JS::Value> aCue, JSContext* aCx)
 {
   if (!aCue.isObject()) {
     return NS_ERROR_FAILURE;
   }
 
   TextTrackCue* cue;
   nsresult rv = UNWRAP_OBJECT(VTTCue, &aCue.toObject(), cue);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -168,17 +168,17 @@ WebVTTListener::OnCue(const JS::Value &a
   cue->SetTrackElement(mElement);
   mElement->mTrack->AddCue(*cue);
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
-WebVTTListener::OnRegion(const JS::Value &aRegion, JSContext* aCx)
+WebVTTListener::OnRegion(JS::Handle<JS::Value> aRegion, JSContext* aCx)
 {
   if (!aRegion.isObject()) {
     return NS_ERROR_FAILURE;
   }
 
   TextTrackRegion* region;
   nsresult rv = UNWRAP_OBJECT(VTTRegion, &aRegion.toObject(), region);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
+++ b/content/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
@@ -147,17 +147,17 @@ SpeechTaskChild::SpeechTaskChild(SpeechS
 NS_IMETHODIMP
 SpeechTaskChild::Setup(nsISpeechTaskCallback* aCallback,
                        uint32_t aChannels, uint32_t aRate, uint8_t argc)
 {
   MOZ_CRASH("Should never be called from child");
 }
 
 NS_IMETHODIMP
-SpeechTaskChild::SendAudio(const JS::Value& aData, const JS::Value& aLandmarks,
+SpeechTaskChild::SendAudio(JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aLandmarks,
                            JSContext* aCx)
 {
   MOZ_CRASH("Should never be called from child");
 }
 
 NS_IMETHODIMP
 SpeechTaskChild::SendAudioNative(int16_t* aData, uint32_t aDataLen)
 {
--- a/content/media/webspeech/synth/ipc/SpeechSynthesisChild.h
+++ b/content/media/webspeech/synth/ipc/SpeechSynthesisChild.h
@@ -74,17 +74,17 @@ class SpeechTaskChild : public nsSpeechT
   friend class SpeechSynthesisRequestChild;
 public:
 
   SpeechTaskChild(SpeechSynthesisUtterance* aUtterance);
 
   NS_IMETHOD Setup(nsISpeechTaskCallback* aCallback,
                    uint32_t aChannels, uint32_t aRate, uint8_t argc) MOZ_OVERRIDE;
 
-  NS_IMETHOD SendAudio(const JS::Value& aData, const JS::Value& aLandmarks,
+  NS_IMETHOD SendAudio(JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aLandmarks,
                        JSContext* aCx) MOZ_OVERRIDE;
 
   NS_IMETHOD SendAudioNative(int16_t* aData, uint32_t aDataLen) MOZ_OVERRIDE;
 
   virtual void Pause();
 
   virtual void Resume();
 
--- a/content/media/webspeech/synth/nsSpeechTask.cpp
+++ b/content/media/webspeech/synth/nsSpeechTask.cpp
@@ -151,17 +151,17 @@ nsSpeechTask::Setup(nsISpeechTaskCallbac
   mStream->AddTrack(1, aRate, 0, segment);
   mStream->AddAudioOutput(this);
   mStream->SetAudioOutputVolume(this, mVolume);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSpeechTask::SendAudio(const JS::Value& aData, const JS::Value& aLandmarks,
+nsSpeechTask::SendAudio(JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aLandmarks,
                         JSContext* aCx)
 {
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
 
   NS_ENSURE_TRUE(mStream, NS_ERROR_NOT_AVAILABLE);
   NS_ENSURE_FALSE(mStream->IsDestroyed(), NS_ERROR_NOT_AVAILABLE);
   NS_ENSURE_TRUE(mChannels, NS_ERROR_FAILURE);
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -10450,17 +10450,17 @@ nsDocShell::SetReferrerURI(nsIURI * aURI
     mReferrerURI = aURI;        // This assigment addrefs
 }
 
 //*****************************************************************************
 // nsDocShell: Session History
 //*****************************************************************************
 
 NS_IMETHODIMP
-nsDocShell::AddState(const JS::Value &aData, const nsAString& aTitle,
+nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
                      const nsAString& aURL, bool aReplace, JSContext* aCx)
 {
     // Implements History.pushState and History.replaceState
 
     // Here's what we do, roughly in the order specified by HTML5:
     // 1. Serialize aData using structured clone.
     // 2. If the third argument is present,
     //     a. Resolve the url, relative to the first script's base URL
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -75,19 +75,19 @@ DOMRequest::GetReadyState(nsAString& aRe
     default:
       MOZ_CRASH("Unrecognized readyState.");
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-DOMRequest::GetResult(JS::Value* aResult)
+DOMRequest::GetResult(JS::MutableHandle<JS::Value> aResult)
 {
-  *aResult = Result();
+  aResult.set(Result());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequest::GetError(nsISupports** aError)
 {
   NS_IF_ADDREF(*aError = GetError());
   return NS_OK;
@@ -197,21 +197,20 @@ DOMRequestService::CreateCursor(nsIDOMWi
   NS_ENSURE_STATE(win);
   NS_ADDREF(*aCursor = new DOMCursor(win, aCallback));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequestService::FireSuccess(nsIDOMDOMRequest* aRequest,
-                               const JS::Value& aResult)
+                               JS::Handle<JS::Value> aResult)
 {
   NS_ENSURE_STATE(aRequest);
-  static_cast<DOMRequest*>(aRequest)->
-    FireSuccess(JS::Handle<JS::Value>::fromMarkedLocation(&aResult));
+  static_cast<DOMRequest*>(aRequest)->FireSuccess(aResult);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequestService::FireError(nsIDOMDOMRequest* aRequest,
                              const nsAString& aError)
 {
@@ -311,17 +310,17 @@ public:
   }
 private:
   nsRefPtr<DOMRequest> mReq;
   nsString mError;
 };
 
 NS_IMETHODIMP
 DOMRequestService::FireSuccessAsync(nsIDOMDOMRequest* aRequest,
-                                    const JS::Value& aResult)
+                                    JS::Handle<JS::Value> aResult)
 {
   NS_ENSURE_STATE(aRequest);
   return FireSuccessAsyncTask::Dispatch(static_cast<DOMRequest*>(aRequest), aResult);
 }
 
 NS_IMETHODIMP
 DOMRequestService::FireErrorAsync(nsIDOMDOMRequest* aRequest,
                                   const nsAString& aError)
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1316,17 +1316,17 @@ Navigator::EnsureMessagesManager()
 
   nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi =
     do_QueryInterface(messageManager);
   NS_ENSURE_TRUE(gpi, NS_ERROR_FAILURE);
 
   // We don't do anything with the return value.
   AutoJSContext cx;
   JS::Rooted<JS::Value> prop_val(cx);
-  rv = gpi->Init(mWindow, prop_val.address());
+  rv = gpi->Init(mWindow, &prop_val);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mMessagesManager = messageManager.forget();
 
   return NS_OK;
 }
 
 bool
@@ -1573,17 +1573,17 @@ Navigator::DoNewResolve(JSContext* aCx, 
 
   nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi(do_QueryInterface(native));
 
   if (gpi) {
     if (!mWindow) {
       return Throw(aCx, NS_ERROR_UNEXPECTED);
     }
 
-    rv = gpi->Init(mWindow, prop_val.address());
+    rv = gpi->Init(mWindow, &prop_val);
     if (NS_FAILED(rv)) {
       return Throw(aCx, rv);
     }
   }
 
   if (JSVAL_IS_PRIMITIVE(prop_val) && !JSVAL_IS_NULL(prop_val)) {
     rv = nsContentUtils::WrapNative(aCx, aObject, native, &prop_val, true);
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -612,17 +612,17 @@ WrapNative(JSContext *cx, JSObject *scop
 
   JSObject *wrapper = xpc_FastGetCachedWrapper(cache, scope, vp);
   if (wrapper) {
     return NS_OK;
   }
 
   return nsDOMClassInfo::XPConnect()->WrapNativeToJSVal(cx, scope, native,
                                                         cache, aIID,
-                                                        aAllowWrapping, vp.address());
+                                                        aAllowWrapping, vp);
 }
 
 static inline nsresult
 WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
            const nsIID* aIID, bool aAllowWrapping, JS::MutableHandle<JS::Value> vp)
 {
   return WrapNative(cx, scope, native, nullptr, aIID, vp, aAllowWrapping);
 }
@@ -1657,17 +1657,17 @@ nsDOMClassInfo::Construct(nsIXPConnectWr
 {
   NS_WARNING("nsDOMClassInfo::Construct Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *obj, const jsval &val, bool *bp,
+                            JSObject *obj, JS::Handle<JS::Value> val, bool *bp,
                             bool *_retval)
 {
   NS_WARNING("nsDOMClassInfo::HasInstance Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
@@ -3129,17 +3129,17 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
 
     nsCOMPtr<nsISupports> native(do_CreateInstance(name_struct->mCID, &rv));
     NS_ENSURE_SUCCESS(rv, rv);
 
     JS::Rooted<JS::Value> prop_val(cx, JS::UndefinedValue()); // Property value.
 
     nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi(do_QueryInterface(native));
     if (gpi) {
-      rv = gpi->Init(aWin, prop_val.address());
+      rv = gpi->Init(aWin, &prop_val);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     if (JSVAL_IS_PRIMITIVE(prop_val) && !JSVAL_IS_NULL(prop_val)) {
       JSObject *scope;
 
       if (aWin->IsOuterWindow()) {
         nsGlobalWindow *inner = aWin->GetCurrentInnerWindowInternal();
@@ -4503,17 +4503,17 @@ nsDOMConstructorSH::Construct(nsIXPConne
   }
 #endif
 
   return wrapped->Construct(wrapper, cx, obj, args, _retval);
 }
 
 NS_IMETHODIMP
 nsDOMConstructorSH::HasInstance(nsIXPConnectWrappedNative *wrapper,
-                                JSContext *cx, JSObject *aObj, const jsval &val,
+                                JSContext *cx, JSObject *aObj, JS::Handle<JS::Value> val,
                                 bool *bp, bool *_retval)
 {
   JS::Rooted<JSObject*> obj(cx, aObj);
   nsDOMConstructor *wrapped =
     static_cast<nsDOMConstructor *>(wrapper->Native());
 
 #ifdef DEBUG
   {
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -569,17 +569,17 @@ public:
                         JSObject **objp, bool *_retval) MOZ_OVERRIDE;
   NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                   JSObject *obj, const JS::CallArgs &args, bool *_retval) MOZ_OVERRIDE;
 
   NS_IMETHOD Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                        JSObject *obj, const JS::CallArgs &args, bool *_retval) MOZ_OVERRIDE;
 
   NS_IMETHOD HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                         JSObject *obj, const JS::Value &val, bool *bp,
+                         JSObject *obj, JS::Handle<JS::Value> val, bool *bp,
                          bool *_retval);
 
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsDOMConstructorSH(aData);
   }
 };
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2130,17 +2130,18 @@ nsDOMWindowUtils::SendContentCommandEven
     event.mTransferable = aTransferable;
   }
 
   nsEventStatus status;
   return widget->DispatchEvent(&event, status);
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetClassName(const JS::Value& aObject, JSContext* aCx, char** aName)
+nsDOMWindowUtils::GetClassName(JS::Handle<JS::Value> aObject, JSContext* aCx,
+                               char** aName)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // Our argument must be a non-null object.
   if (JSVAL_IS_PRIMITIVE(aObject)) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
@@ -2215,39 +2216,39 @@ nsDOMWindowUtils::IsInModalState(bool *r
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   NS_ENSURE_STATE(window);
 
   *retval = static_cast<nsGlobalWindow*>(window.get())->IsInModalState();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetParent(const JS::Value& aObject,
+nsDOMWindowUtils::GetParent(JS::Handle<JS::Value> aObject,
                             JSContext* aCx,
-                            JS::Value* aParent)
+                            JS::MutableHandle<JS::Value> aParent)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // First argument must be an object.
-  if (JSVAL_IS_PRIMITIVE(aObject)) {
+  if (aObject.isPrimitive()) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
   }
 
-  JS::Rooted<JSObject*> parent(aCx, JS_GetParent(JSVAL_TO_OBJECT(aObject)));
-  *aParent = OBJECT_TO_JSVAL(parent);
+  JS::Rooted<JSObject*> parent(aCx, JS_GetParent(&aObject.toObject()));
 
   // Outerize if necessary.
   if (parent) {
     if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) {
-      *aParent = OBJECT_TO_JSVAL(outerize(aCx, parent));
+      parent = outerize(aCx, parent);
     }
   }
 
+  aParent.setObject(*parent);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
@@ -2862,18 +2863,18 @@ GetFileOrBlob(const nsAString& aName, co
   rv = domFile->InitBlob(aCx, aOptionalArgCount, args, GetXPConnectNative);
   NS_ENSURE_SUCCESS(rv, rv);
 
   file.forget(aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetFile(const nsAString& aName, const JS::Value& aBlobParts,
-                          const JS::Value& aParameters, JSContext* aCx,
+nsDOMWindowUtils::GetFile(const nsAString& aName, JS::Handle<JS::Value> aBlobParts,
+                          JS::Handle<JS::Value> aParameters, JSContext* aCx,
                           uint8_t aOptionalArgCount, nsIDOMFile** aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsISupports> file;
   nsresult rv = GetFileOrBlob(aName, aBlobParts, aParameters, aCx,
@@ -2882,18 +2883,18 @@ nsDOMWindowUtils::GetFile(const nsAStrin
 
   nsCOMPtr<nsIDOMFile> result = do_QueryInterface(file);
   result.forget(aResult);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetBlob(const JS::Value& aBlobParts,
-                          const JS::Value& aParameters, JSContext* aCx,
+nsDOMWindowUtils::GetBlob(JS::Handle<JS::Value> aBlobParts,
+                          JS::Handle<JS::Value> aParameters, JSContext* aCx,
                           uint8_t aOptionalArgCount, nsIDOMBlob** aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsISupports> blob;
   nsresult rv = GetFileOrBlob(NullString(), aBlobParts, aParameters, aCx,
@@ -2902,17 +2903,17 @@ nsDOMWindowUtils::GetBlob(const JS::Valu
 
   nsCOMPtr<nsIDOMBlob> result = do_QueryInterface(blob);
   result.forget(aResult);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetFileId(const JS::Value& aFile, JSContext* aCx,
+nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
                             int64_t* aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   if (!JSVAL_IS_PRIMITIVE(aFile)) {
     JSObject* obj = JSVAL_TO_OBJECT(aFile);
@@ -2934,17 +2935,17 @@ nsDOMWindowUtils::GetFileId(const JS::Va
   }
 
   *aResult = -1;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
-                                    const jsval& aOptions,
+                                    JS::Handle<JS::Value> aOptions,
                                     int32_t* aRefCnt, int32_t* aDBRefCnt,
                                     int32_t* aSliceRefCnt, JSContext* aCx,
                                     bool* aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
@@ -3092,17 +3093,17 @@ nsDOMWindowUtils::GetPaintingSuppressed(
   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
   *aPaintingSuppressed = presShell->IsPaintingSuppressed();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::Value* aPlugins)
+nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugins)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   NS_ENSURE_STATE(window);
 
@@ -3110,17 +3111,17 @@ nsDOMWindowUtils::GetPlugins(JSContext* 
 
   nsTArray<nsIObjectLoadingContent*> plugins;
   doc->GetPlugins(plugins);
 
   JS::Rooted<JSObject*> jsPlugins(cx);
   nsresult rv = nsTArrayToJSArray(cx, plugins, jsPlugins.address());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aPlugins = OBJECT_TO_JSVAL(jsPlugins);
+  aPlugins.setObject(*jsPlugins);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -3747,17 +3747,17 @@ nsGlobalWindow::GetContent(JSContext* aC
   // Something tries to get .content on a ChromeWindow, try to fetch the CPOW.
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner();
   if (!treeOwner) {
     aError.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   JS::Rooted<JS::Value> val(aCx, JS::NullValue());
-  aError = treeOwner->GetContentWindow(aCx, val.address());
+  aError = treeOwner->GetContentWindow(aCx, &val);
   if (aError.Failed()) {
     return nullptr;
   }
 
   return val.toObjectOrNull();
 }
 
 already_AddRefed<nsIDOMWindow>
@@ -3813,22 +3813,22 @@ nsGlobalWindow::GetContent(nsIDOMWindow*
 {
   ErrorResult rv;
   *aContent = GetContentInternal(rv).get();
 
   return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::Value* aVal)
+nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
 {
   ErrorResult rv;
   JS::Rooted<JSObject*> content(aCx, GetContent(aCx, rv));
   if (!rv.Failed()) {
-    *aVal = JS::ObjectOrNullValue(content);
+    aVal.setObjectOrNull(content);
   }
 
   return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetPrompter(nsIPrompt** aPrompt)
 {
@@ -4950,17 +4950,17 @@ nsGlobalWindow::RequestAnimationFrame(co
   }
 
   int32_t handle;
   aError = mDoc->ScheduleFrameRequestCallback(aCallback, &handle);
   return handle;
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::RequestAnimationFrame(const JS::Value& aCallback,
+nsGlobalWindow::RequestAnimationFrame(JS::Handle<JS::Value> aCallback,
                                       JSContext* cx,
                                       int32_t* aHandle)
 {
   if (!aCallback.isObject() || !JS_ObjectIsCallable(cx, &aCallback.toObject())) {
     return NS_ERROR_INVALID_ARG;
   }
 
   JS::Rooted<JSObject*> callbackObj(cx, &aCallback.toObject());
@@ -7945,25 +7945,23 @@ nsGlobalWindow::PostMessageMoz(JSContext
       return;
     }
   }
 
   PostMessageMoz(aCx, aMessage, aTargetOrigin, transferArray, aError);
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::PostMessageMoz(const JS::Value& aMessage,
+nsGlobalWindow::PostMessageMoz(JS::Handle<JS::Value> aMessage,
                                const nsAString& aOrigin,
-                               const JS::Value& aTransfer,
+                               JS::Handle<JS::Value> aTransfer,
                                JSContext* aCx)
 {
-  JS::Rooted<JS::Value> message(aCx, aMessage);
-  JS::Rooted<JS::Value> transfer(aCx, aTransfer);
-  ErrorResult rv;
-  PostMessageMoz(aCx, message, aOrigin, transfer, rv);
+  ErrorResult rv;
+  PostMessageMoz(aCx, aMessage, aOrigin, aTransfer, rv);
 
   return rv.ErrorCode();
 }
 
 class nsCloseEvent : public nsRunnable {
 
   nsRefPtr<nsGlobalWindow> mWindow;
   bool mIndirect;
@@ -8778,32 +8776,32 @@ JS::Value
 nsGlobalWindow::ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
                                 const Optional<JS::Handle<JS::Value> >& aArgument,
                                 const nsAString& aOptions,
                                 ErrorResult& aError)
 {
   nsCOMPtr<nsIVariant> args;
   if (aArgument.WasPassed()) {
     aError = nsContentUtils::XPConnect()->JSToVariant(aCx,
-                                                      aArgument.Value().get(),
+                                                      aArgument.Value(),
                                                       getter_AddRefs(args));
   } else {
     args = CreateVoidVariant();
   }
 
   nsCOMPtr<nsIVariant> retVal = ShowModalDialog(aUrl, args, aOptions, aError);
   if (aError.Failed()) {
     return JS::UndefinedValue();
   }
 
   JS::Rooted<JS::Value> result(aCx);
   if (retVal) {
     aError = nsContentUtils::XPConnect()->VariantToJS(aCx,
                                                       FastGetGlobalJSObject(),
-                                                      retVal, result.address());
+                                                      retVal, &result);
   } else {
     result = JS::NullValue();
   }
   return result;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs_,
@@ -13274,79 +13272,79 @@ nsGlobalWindow::DisableNetworkEvent(uint
       }
       break;
   }
 }
 #endif // MOZ_B2G
 
 #define EVENT(name_, id_, type_, struct_)                                    \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
-                                             JS::Value *vp) {                \
+                                             JS::MutableHandle<JS::Value> vp) { \
     EventHandlerNonNull* h = GetOn##name_();                                 \
-    vp->setObjectOrNull(h ? h->Callable().get() : nullptr);                  \
+    vp.setObjectOrNull(h ? h->Callable().get() : nullptr);                   \
     return NS_OK;                                                            \
   }                                                                          \
   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
-                                             const JS::Value &v) {           \
+                                             JS::Handle<JS::Value> v) {      \
     nsRefPtr<EventHandlerNonNull> handler;                                   \
     JS::Rooted<JSObject*> callable(cx);                                      \
     if (v.isObject() &&                                                      \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
       handler = new EventHandlerNonNull(callable, GetIncumbentGlobal());     \
     }                                                                        \
     SetOn##name_(handler);                                                   \
     return NS_OK;                                                            \
   }
 #define ERROR_EVENT(name_, id_, type_, struct_)                              \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
-                                             JS::Value *vp) {                \
+                                             JS::MutableHandle<JS::Value> vp) { \
     nsEventListenerManager *elm = GetExistingListenerManager();              \
     if (elm) {                                                               \
       OnErrorEventHandlerNonNull* h = elm->GetOnErrorEventHandler();         \
       if (h) {                                                               \
-        *vp = JS::ObjectValue(*h->Callable());                               \
+        vp.setObject(*h->Callable());                                        \
         return NS_OK;                                                        \
       }                                                                      \
     }                                                                        \
-    *vp = JSVAL_NULL;                                                        \
+    vp.setNull();                                                            \
     return NS_OK;                                                            \
   }                                                                          \
   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
-                                             const JS::Value &v) {           \
+                                             JS::Handle<JS::Value> v) {      \
     nsEventListenerManager *elm = GetOrCreateListenerManager();              \
     if (!elm) {                                                              \
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
     nsRefPtr<OnErrorEventHandlerNonNull> handler;                            \
     JS::Rooted<JSObject*> callable(cx);                                      \
     if (v.isObject() &&                                                      \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
       handler = new OnErrorEventHandlerNonNull(callable, GetIncumbentGlobal()); \
     }                                                                        \
     elm->SetEventHandler(handler);                                           \
     return NS_OK;                                                            \
   }
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                       \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
-                                             JS::Value *vp) {                \
+                                             JS::MutableHandle<JS::Value> vp) { \
     nsEventListenerManager *elm = GetExistingListenerManager();              \
     if (elm) {                                                               \
       OnBeforeUnloadEventHandlerNonNull* h =                                 \
         elm->GetOnBeforeUnloadEventHandler();                                \
       if (h) {                                                               \
-        *vp = JS::ObjectValue(*h->Callable());                               \
+        vp.setObject(*h->Callable());                                        \
         return NS_OK;                                                        \
       }                                                                      \
     }                                                                        \
-    *vp = JSVAL_NULL;                                                        \
+    vp.setNull();                                                            \
     return NS_OK;                                                            \
   }                                                                          \
   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
-                                             const JS::Value &v) {           \
+                                             JS::Handle<JS::Value> v) {      \
     nsEventListenerManager *elm = GetOrCreateListenerManager();              \
     if (!elm) {                                                              \
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
     nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handler;                     \
     JS::Rooted<JSObject*> callable(cx);                                      \
     if (v.isObject() &&                                                      \
--- a/dom/base/nsHistory.cpp
+++ b/dom/base/nsHistory.cpp
@@ -120,17 +120,17 @@ nsHistory::GetState(JSContext* aCx, Erro
     return JS::UndefinedValue();
   }
 
   nsCOMPtr<nsIVariant> variant;
   doc->GetStateObject(getter_AddRefs(variant));
 
   if (variant) {
     JS::Rooted<JS::Value> jsData(aCx);
-    aRv = variant->GetAsJSVal(jsData.address());
+    aRv = variant->GetAsJSVal(&jsData);
 
     if (aRv.Failed()) {
       return JS::UndefinedValue();
     }
 
     if (!JS_WrapValue(aCx, &jsData)) {
       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
       return JS::UndefinedValue();
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1251,17 +1251,19 @@ nsJSContext::ConvertSupportsTojsvals(nsI
       argsArray->QueryElementAt(argCtr, NS_GET_IID(nsISupports),
                                 getter_AddRefs(arg));
       if (!arg) {
         *thisval = JSVAL_NULL;
         continue;
       }
       nsCOMPtr<nsIVariant> variant(do_QueryInterface(arg));
       if (variant != nullptr) {
-        rv = xpc->VariantToJS(cx, aScope, variant, thisval);
+        JS::Rooted<JS::Value> temp(cx);
+        rv = xpc->VariantToJS(cx, aScope, variant, &temp);
+        *thisval = temp.get();
       } else {
         // And finally, support the nsISupportsPrimitives supplied
         // by the AppShell.  It generally will pass only strings, but
         // as we have code for handling all, we may as well use it.
         rv = AddSupportsPrimitiveTojsvals(arg, thisval);
         if (rv == NS_ERROR_NO_INTERFACE) {
           // something else - probably an event object or similar -
           // just wrap it.
@@ -1278,17 +1280,19 @@ nsJSContext::ConvertSupportsTojsvals(nsI
             *thisval = v;
           }
         }
       }
     }
   } else {
     nsCOMPtr<nsIVariant> variant = do_QueryInterface(aArgs);
     if (variant) {
-      rv = xpc->VariantToJS(cx, aScope, variant, argv);
+      JS::Rooted<JS::Value> temp(cx);
+      rv = xpc->VariantToJS(cx, aScope, variant, &temp);
+      *argv = temp.get();
     } else {
       NS_ERROR("Not an array, not an interface?");
       rv = NS_ERROR_UNEXPECTED;
     }
   }
   if (NS_FAILED(rv))
     return rv;
   *aArgv = argv;
--- a/dom/base/nsScreen.cpp
+++ b/dom/base/nsScreen.cpp
@@ -233,21 +233,19 @@ nsScreen::GetLockOrientationPermission()
     return LOCK_ALLOWED;
   }
 
   // Other content must be full-screen in order to lock orientation.
   return doc->MozFullScreen() ? FULLSCREEN_LOCK_ALLOWED : LOCK_DENIED;
 }
 
 NS_IMETHODIMP
-nsScreen::MozLockOrientation(const JS::Value& aOrientation_, JSContext* aCx,
+nsScreen::MozLockOrientation(JS::Handle<JS::Value> aOrientation, JSContext* aCx,
                              bool* aReturn)
 {
-  JS::Rooted<JS::Value> aOrientation(aCx, aOrientation_);
-
   if (aOrientation.isObject()) {
     JS::Rooted<JSObject*> seq(aCx, &aOrientation.toObject());
     if (IsArrayLike(aCx, seq)) {
       uint32_t length;
       // JS_GetArrayLength actually works on all objects
       if (!JS_GetArrayLength(aCx, seq, &length)) {
         return NS_ERROR_FAILURE;
       }
--- a/dom/base/nsStructuredCloneContainer.cpp
+++ b/dom/base/nsStructuredCloneContainer.cpp
@@ -34,17 +34,17 @@ nsStructuredCloneContainer::nsStructured
 }
 
 nsStructuredCloneContainer::~nsStructuredCloneContainer()
 {
   free(mData);
 }
 
 nsresult
-nsStructuredCloneContainer::InitFromJSVal(const JS::Value & aData,
+nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
                                           JSContext* aCx)
 {
   NS_ENSURE_STATE(!mData);
   NS_ENSURE_ARG_POINTER(aCx);
 
   // Make sure that we serialize in the right context.
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   JS::Rooted<JS::Value> jsData(aCx, aData);
@@ -119,18 +119,17 @@ nsStructuredCloneContainer::DeserializeT
   // We want to be sure that mData doesn't contain transferable objects
   MOZ_ASSERT(!hasTransferable);
   NS_ENSURE_STATE(success && !hasTransferable);
 
   // Now wrap the JS::Value as an nsIVariant.
   nsCOMPtr<nsIVariant> varStateObj;
   nsCOMPtr<nsIXPConnect> xpconnect = do_GetService(nsIXPConnect::GetCID());
   NS_ENSURE_STATE(xpconnect);
-  xpconnect->JSValToVariant(aCx, jsStateObj.address(),
-                            getter_AddRefs(varStateObj));
+  xpconnect->JSValToVariant(aCx, jsStateObj, getter_AddRefs(varStateObj));
   NS_ENSURE_STATE(varStateObj);
 
   NS_ADDREF(*aData = varStateObj);
   return NS_OK;
 }
 
 nsresult
 nsStructuredCloneContainer::GetDataAsBase64(nsAString &aOut)
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -2029,17 +2029,17 @@ ConstructJSImplementation(JSContext* aCx
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
     // Initialize the object, if it implements nsIDOMGlobalPropertyInitializer.
     nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi =
       do_QueryInterface(implISupports);
     if (gpi) {
       JS::Rooted<JS::Value> initReturn(aCx);
-      nsresult rv = gpi->Init(window, initReturn.address());
+      nsresult rv = gpi->Init(window, &initReturn);
       if (NS_FAILED(rv)) {
         aRv.Throw(rv);
         return nullptr;
       }
       // With JS-implemented WebIDL, the return value of init() is not used to determine
       // if init() failed, so init() should only return undefined. Any kind of permission
       // or pref checking must happen by adding an attribute to the WebIDL interface.
       if (!initReturn.isUndefined()) {
--- a/dom/bluetooth/BluetoothPropertyContainer.cpp
+++ b/dom/bluetooth/BluetoothPropertyContainer.cpp
@@ -7,31 +7,33 @@
 #include "base/basictypes.h"
 #include "BluetoothPropertyContainer.h"
 #include "BluetoothService.h"
 #include "DOMRequest.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "nsServiceManagerUtils.h"
 
+#include "js/Value.h"
+
 USING_BLUETOOTH_NAMESPACE
 
 already_AddRefed<mozilla::dom::DOMRequest>
 BluetoothPropertyContainer::FirePropertyAlreadySet(nsPIDOMWindow* aOwner,
                                                    ErrorResult& aRv)
 {
   nsCOMPtr<nsIDOMRequestService> rs =
     do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
   if (!rs) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<mozilla::dom::DOMRequest> request = new DOMRequest(aOwner);
-  rs->FireSuccess(request, JS::UndefinedValue());
+  rs->FireSuccess(request, JS::UndefinedHandleValue);
 
   return request.forget();
 }
 
 already_AddRefed<mozilla::dom::DOMRequest>
 BluetoothPropertyContainer::SetProperty(nsPIDOMWindow* aOwner,
                                         const BluetoothNamedValue& aProperty,
                                         ErrorResult& aRv)
--- a/dom/bluetooth/BluetoothService.cpp
+++ b/dom/bluetooth/BluetoothService.cpp
@@ -241,17 +241,17 @@ private:
   bool mIsStartup;
 };
 
 class BluetoothService::StartupTask : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
-  NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
+  NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     if (!aResult.isBoolean()) {
       BT_WARNING("Setting for '" BLUETOOTH_ENABLED_SETTING "' is not a boolean!");
       return NS_OK;
     }
 
@@ -852,12 +852,12 @@ BluetoothService::Notify(const Bluetooth
     BT_WARNING(warningMsg.get());
     return;
   }
 
   nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
     do_GetService("@mozilla.org/system-message-internal;1");
   NS_ENSURE_TRUE_VOID(systemMessenger);
 
-  systemMessenger->BroadcastMessage(type,
-                                    OBJECT_TO_JSVAL(obj),
-                                    JS::UndefinedValue());
+  JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*obj));
+  systemMessenger->BroadcastMessage(type, value,
+                                    JS::UndefinedHandleValue);
 }
--- a/dom/bluetooth/bluedroid/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothHfpManager.cpp
@@ -200,17 +200,17 @@ IsValidDtmf(const char aChar) {
 }
 
 class BluetoothHfpManager::GetVolumeTask : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD
-  Handle(const nsAString& aName, const JS::Value& aResult)
+  Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     JSContext *cx = nsContentUtils::GetCurrentJSContext();
     NS_ENSURE_TRUE(cx, NS_OK);
 
     if (!aResult.isNumber()) {
       BT_WARNING("'" AUDIO_VOLUME_BT_SCO_ID "' is not a number!");
@@ -847,17 +847,19 @@ BluetoothHfpManager::HandleVoiceConnecti
   mRoam = (roaming) ? 1 : 0;
 
   // Service
   nsString regState;
   voiceInfo->GetState(regState);
   mService = (regState.EqualsLiteral("registered")) ? 1 : 0;
 
   // Signal
-  JS::Value value;
+  JSContext* cx = nsContentUtils::GetSafeJSContext();
+  NS_ENSURE_TRUE_VOID(cx);
+  JS::Rooted<JS::Value> value(cx);
   voiceInfo->GetRelSignalStrength(&value);
   NS_ENSURE_TRUE_VOID(value.isNumber());
   mSignal = (int)ceil(value.toNumber() / 20.0);
 
   UpdateDeviceCIND();
 
   // Operator name
   nsCOMPtr<nsIDOMMozMobileNetworkInfo> network;
--- a/dom/bluetooth/bluedroid/BluetoothUtils.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothUtils.cpp
@@ -123,19 +123,19 @@ BroadcastSystemMessage(const nsAString& 
     BT_WARNING("Failed to set properties of system message!");
     return false;
   }
 
   nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
     do_GetService("@mozilla.org/system-message-internal;1");
   NS_ENSURE_TRUE(systemMessenger, false);
 
-  systemMessenger->BroadcastMessage(aType,
-                                    OBJECT_TO_JSVAL(obj),
-                                    JS::UndefinedValue());
+  JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*obj));
+  systemMessenger->BroadcastMessage(aType, value,
+                                    JS::UndefinedHandleValue);
 
   return true;
 }
 
 void
 DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
                        const BluetoothValue& aValue,
                        const nsAString& aErrorStr)
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -157,17 +157,17 @@ static CINDItem sCINDItems[] = {
 };
 
 class BluetoothHfpManager::GetVolumeTask : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD
-  Handle(const nsAString& aName, const JS::Value& aResult)
+  Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     JSContext *cx = nsContentUtils::GetCurrentJSContext();
     NS_ENSURE_TRUE(cx, NS_OK);
 
     if (!aResult.isNumber()) {
       BT_WARNING("'" AUDIO_VOLUME_BT_SCO_ID "' is not a number!");
@@ -615,17 +615,19 @@ BluetoothHfpManager::HandleVoiceConnecti
   voiceInfo->GetState(regState);
   bool service = regState.EqualsLiteral("registered");
   if (service != sCINDItems[CINDType::SERVICE].value) {
     // Notify BluetoothRilListener of service change
     mListener->ServiceChanged(aClientId, service);
   }
   UpdateCIND(CINDType::SERVICE, service);
 
-  JS::Value value;
+  JSContext* cx = nsContentUtils::GetSafeJSContext();
+  NS_ENSURE_TRUE_VOID(cx);
+  JS::Rooted<JS::Value> value(cx);
   voiceInfo->GetRelSignalStrength(&value);
   NS_ENSURE_TRUE_VOID(value.isNumber());
   uint8_t signal = ceil(value.toNumber() / 20.0);
   UpdateCIND(CINDType::SIGNAL, signal);
 
   /**
    * Possible return values for mode are:
    * - null (unknown): set mNetworkSelectionMode to 0 (auto)
--- a/dom/bluetooth/bluez/BluetoothUtils.cpp
+++ b/dom/bluetooth/bluez/BluetoothUtils.cpp
@@ -121,19 +121,19 @@ BroadcastSystemMessage(const nsAString& 
     BT_WARNING("Failed to set properties of system message!");
     return false;
   }
 
   nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
     do_GetService("@mozilla.org/system-message-internal;1");
   NS_ENSURE_TRUE(systemMessenger, false);
 
-  systemMessenger->BroadcastMessage(aType,
-                                    OBJECT_TO_JSVAL(obj),
-                                    JS::UndefinedValue());
+  JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*obj));
+  systemMessenger->BroadcastMessage(aType, value,
+                                    JS::UndefinedHandleValue);
 
   return true;
 }
 
 void
 DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
                        const BluetoothValue& aValue,
                        const nsAString& aErrorStr)
--- a/dom/camera/DOMCameraCapabilities.cpp
+++ b/dom/camera/DOMCameraCapabilities.cpp
@@ -156,99 +156,111 @@ DOMCameraCapabilities::ParameterListToNe
       ++p;
     }
   }
 
   return JS_FreezeObject(aCx, aArray) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
-DOMCameraCapabilities::StringListToNewObject(JSContext* aCx, JS::Value* aArray, uint32_t aKey)
+DOMCameraCapabilities::StringListToNewObject(JSContext* aCx,
+                                             JS::MutableHandle<JS::Value> aArray,
+                                             uint32_t aKey)
 {
   JS::Rooted<JSObject*> array(aCx);
 
   nsresult rv = ParameterListToNewArray(aCx, &array, aKey, ParseStringItemAndAdd);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aArray = OBJECT_TO_JSVAL(array);
+  aArray.setObject(*array);
   return NS_OK;
 }
 
 nsresult
-DOMCameraCapabilities::DimensionListToNewObject(JSContext* aCx, JS::Value* aArray, uint32_t aKey)
+DOMCameraCapabilities::DimensionListToNewObject(JSContext* aCx,
+                                                JS::MutableHandle<JS::Value> aArray,
+                                                uint32_t aKey)
 {
   JS::Rooted<JSObject*> array(aCx);
-  nsresult rv;
 
-  rv = ParameterListToNewArray(aCx, &array, aKey, ParseDimensionItemAndAdd);
+  nsresult rv = ParameterListToNewArray(aCx, &array, aKey, ParseDimensionItemAndAdd);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aArray = OBJECT_TO_JSVAL(array);
+  aArray.setObject(*array);
   return NS_OK;
 }
 
 /* readonly attribute jsval previewSizes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetPreviewSizes(JSContext* cx, JS::Value* aPreviewSizes)
+DOMCameraCapabilities::GetPreviewSizes(JSContext* cx,
+                                       JS::MutableHandle<JS::Value> aPreviewSizes)
 {
   return DimensionListToNewObject(cx, aPreviewSizes, CAMERA_PARAM_SUPPORTED_PREVIEWSIZES);
 }
 
 /* readonly attribute jsval pictureSizes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetPictureSizes(JSContext* cx, JS::Value* aPictureSizes)
+DOMCameraCapabilities::GetPictureSizes(JSContext* cx,
+                                       JS::MutableHandle<JS::Value> aPictureSizes)
 {
   return DimensionListToNewObject(cx, aPictureSizes, CAMERA_PARAM_SUPPORTED_PICTURESIZES);
 }
 
 /* readonly attribute jsval thumbnailSizes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetThumbnailSizes(JSContext* cx, JS::Value* aThumbnailSizes)
+DOMCameraCapabilities::GetThumbnailSizes(JSContext* cx,
+                                         JS::MutableHandle<JS::Value> aThumbnailSizes)
 {
   return DimensionListToNewObject(cx, aThumbnailSizes, CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES);
 }
 
 /* readonly attribute jsval fileFormats; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetFileFormats(JSContext* cx, JS::Value* aFileFormats)
+DOMCameraCapabilities::GetFileFormats(JSContext* cx,
+                                      JS::MutableHandle<JS::Value> aFileFormats)
 {
   return StringListToNewObject(cx, aFileFormats, CAMERA_PARAM_SUPPORTED_PICTUREFORMATS);
 }
 
 /* readonly attribute jsval whiteBalanceModes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetWhiteBalanceModes(JSContext* cx, JS::Value* aWhiteBalanceModes)
+DOMCameraCapabilities::GetWhiteBalanceModes(JSContext* cx,
+                                            JS::MutableHandle<JS::Value> aWhiteBalanceModes)
 {
   return StringListToNewObject(cx, aWhiteBalanceModes, CAMERA_PARAM_SUPPORTED_WHITEBALANCES);
 }
 
 /* readonly attribute jsval sceneModes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetSceneModes(JSContext* cx, JS::Value* aSceneModes)
+DOMCameraCapabilities::GetSceneModes(JSContext* cx,
+                                     JS::MutableHandle<JS::Value> aSceneModes)
 {
   return StringListToNewObject(cx, aSceneModes, CAMERA_PARAM_SUPPORTED_SCENEMODES);
 }
 
 /* readonly attribute jsval effects; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetEffects(JSContext* cx, JS::Value* aEffects)
+DOMCameraCapabilities::GetEffects(JSContext* cx,
+                                  JS::MutableHandle<JS::Value> aEffects)
 {
   return StringListToNewObject(cx, aEffects, CAMERA_PARAM_SUPPORTED_EFFECTS);
 }
 
 /* readonly attribute jsval flashModes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetFlashModes(JSContext* cx, JS::Value* aFlashModes)
+DOMCameraCapabilities::GetFlashModes(JSContext* cx,
+                                     JS::MutableHandle<JS::Value> aFlashModes)
 {
   return StringListToNewObject(cx, aFlashModes, CAMERA_PARAM_SUPPORTED_FLASHMODES);
 }
 
 /* readonly attribute jsval focusModes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetFocusModes(JSContext* cx, JS::Value* aFocusModes)
+DOMCameraCapabilities::GetFocusModes(JSContext* cx,
+                                     JS::MutableHandle<JS::Value> aFocusModes)
 {
   return StringListToNewObject(cx, aFocusModes, CAMERA_PARAM_SUPPORTED_FOCUSMODES);
 }
 
 /* readonly attribute long maxFocusAreas; */
 NS_IMETHODIMP
 DOMCameraCapabilities::GetMaxFocusAreas(JSContext* cx, int32_t* aMaxFocusAreas)
 {
@@ -330,48 +342,48 @@ DOMCameraCapabilities::GetMaxMeteringAre
   }
 
   *aMaxMeteringAreas = atoi(value);
   return NS_OK;
 }
 
 /* readonly attribute jsval zoomRatios; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetZoomRatios(JSContext* cx, JS::Value* aZoomRatios)
+DOMCameraCapabilities::GetZoomRatios(JSContext* cx, JS::MutableHandle<JS::Value> aZoomRatios)
 {
   NS_ENSURE_TRUE(mCamera, NS_ERROR_NOT_AVAILABLE);
 
   const char* value = mCamera->GetParameterConstChar(CAMERA_PARAM_SUPPORTED_ZOOM);
   if (!value || strcmp(value, "true") != 0) {
     // if zoom is not supported, return a null object
-    *aZoomRatios = JSVAL_NULL;
+    aZoomRatios.setNull();
     return NS_OK;
   }
 
   JS::Rooted<JSObject*> array(cx);
 
   nsresult rv = ParameterListToNewArray(cx, &array, CAMERA_PARAM_SUPPORTED_ZOOMRATIOS, ParseZoomRatioItemAndAdd);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aZoomRatios = OBJECT_TO_JSVAL(array);
+  aZoomRatios.setObject(*array);
   return NS_OK;
 }
 
 /* readonly attribute jsval videoSizes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetVideoSizes(JSContext* cx, JS::Value* aVideoSizes)
+DOMCameraCapabilities::GetVideoSizes(JSContext* cx, JS::MutableHandle<JS::Value> aVideoSizes)
 {
   NS_ENSURE_TRUE(mCamera, NS_ERROR_NOT_AVAILABLE);
 
   nsTArray<mozilla::idl::CameraSize> sizes;
   nsresult rv = mCamera->GetVideoSizes(sizes);
   NS_ENSURE_SUCCESS(rv, rv);
   if (sizes.Length() == 0) {
-    // video recording not supported, return a null object
-    *aVideoSizes = JSVAL_NULL;
+    // video recording not supported, return null
+    aVideoSizes.setNull();
     return NS_OK;
   }
 
   JS::Rooted<JSObject*> array(cx, JS_NewArrayObject(cx, 0, nullptr));
   if (!array) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
@@ -387,31 +399,31 @@ DOMCameraCapabilities::GetVideoSizes(JSC
     }
 
     v = OBJECT_TO_JSVAL(o);
     if (!JS_SetElement(cx, array, i, &v)) {
       return NS_ERROR_FAILURE;
     }
   }
 
-  *aVideoSizes = OBJECT_TO_JSVAL(array);
+  aVideoSizes.setObject(*array);
   return NS_OK;
 }
 
 /* readonly attribute jsval recorderProfiles; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetRecorderProfiles(JSContext* cx, JS::Value* aRecorderProfiles)
+DOMCameraCapabilities::GetRecorderProfiles(JSContext* cx, JS::MutableHandle<JS::Value> aRecorderProfiles)
 {
   NS_ENSURE_TRUE(mCamera, NS_ERROR_NOT_AVAILABLE);
 
   nsRefPtr<RecorderProfileManager> profileMgr = mCamera->GetRecorderProfileManager();
   if (!profileMgr) {
-    *aRecorderProfiles = JSVAL_NULL;
+    aRecorderProfiles.setNull();
     return NS_OK;
   }
 
   JS::Rooted<JSObject*> o(cx);
   nsresult rv = profileMgr->GetJsObject(cx, o.address());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aRecorderProfiles = OBJECT_TO_JSVAL(o);
+  aRecorderProfiles.setObject(*o);
   return NS_OK;
 }
--- a/dom/camera/DOMCameraCapabilities.h
+++ b/dom/camera/DOMCameraCapabilities.h
@@ -27,18 +27,22 @@ public:
   }
 
   nsresult ParameterListToNewArray(
     JSContext* cx,
     JS::MutableHandle<JSObject*> aArray,
     uint32_t aKey,
     ParseItemAndAddFunc aParseItemAndAdd
   );
-  nsresult StringListToNewObject(JSContext* aCx, JS::Value* aArray, uint32_t aKey);
-  nsresult DimensionListToNewObject(JSContext* aCx, JS::Value* aArray, uint32_t aKey);
+  nsresult StringListToNewObject(JSContext* aCx,
+                                 JS::MutableHandle<JS::Value> aArray,
+                                 uint32_t aKey);
+  nsresult DimensionListToNewObject(JSContext* aCx,
+                                    JS::MutableHandle<JS::Value> aArray,
+                                    uint32_t aKey);
 
 private:
   DOMCameraCapabilities(const DOMCameraCapabilities&) MOZ_DELETE;
   DOMCameraCapabilities& operator=(const DOMCameraCapabilities&) MOZ_DELETE;
 
 protected:
   /* additional members */
   ~DOMCameraCapabilities()
--- a/dom/events/nsDOMEventTargetHelper.h
+++ b/dom/events/nsDOMEventTargetHelper.h
@@ -167,34 +167,36 @@ private:
   bool                       mHasOrHasHadOwnerWindow;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsDOMEventTargetHelper,
                               NS_DOMEVENTTARGETHELPER_IID)
 
 // XPIDL event handlers
 #define NS_IMPL_EVENT_HANDLER(_class, _event)                                 \
-    NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx, JS::Value* aValue)    \
+    NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx,                       \
+                                        JS::MutableHandle<JS::Value> aValue)  \
     {                                                                         \
-      GetEventHandler(nsGkAtoms::on##_event, aCx, aValue);                    \
+      GetEventHandler(nsGkAtoms::on##_event, aCx, aValue.address());          \
       return NS_OK;                                                           \
     }                                                                         \
     NS_IMETHODIMP _class::SetOn##_event(JSContext* aCx,                       \
-                                        const JS::Value& aValue)              \
+                                        JS::Handle<JS::Value> aValue)         \
     {                                                                         \
       return SetEventHandler(nsGkAtoms::on##_event, aCx, aValue);             \
     }
 
 #define NS_IMPL_FORWARD_EVENT_HANDLER(_class, _event, _baseclass)             \
-    NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx, JS::Value* aValue)    \
+    NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx,                       \
+                                        JS::MutableHandle<JS::Value> aValue)  \
     {                                                                         \
       return _baseclass::GetOn##_event(aCx, aValue);                          \
     }                                                                         \
     NS_IMETHODIMP _class::SetOn##_event(JSContext* aCx,                       \
-                                        const JS::Value& aValue)              \
+                                        JS::Handle<JS::Value> aValue)         \
     {                                                                         \
       return _baseclass::SetOn##_event(aCx, aValue);                          \
     }
 
 // WebIDL event handlers
 #define IMPL_EVENT_HANDLER(_event)                                        \
   inline mozilla::dom::EventHandlerNonNull* GetOn##_event()               \
   {                                                                       \
--- a/dom/events/nsDOMMessageEvent.cpp
+++ b/dom/events/nsDOMMessageEvent.cpp
@@ -58,20 +58,20 @@ nsDOMMessageEvent::~nsDOMMessageEvent()
 
 JSObject*
 nsDOMMessageEvent::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
   return mozilla::dom::MessageEventBinding::Wrap(aCx, aScope, this);
 }
 
 NS_IMETHODIMP
-nsDOMMessageEvent::GetData(JSContext* aCx, JS::Value* aData)
+nsDOMMessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData)
 {
   ErrorResult rv;
-  *aData = GetData(aCx, rv);
+  aData.set(GetData(aCx, rv));
   return rv.ErrorCode();
 }
 
 JS::Value
 nsDOMMessageEvent::GetData(JSContext* aCx, ErrorResult& aRv)
 {
   JS::Rooted<JS::Value> data(aCx, mData);
   if (!JS_WrapValue(aCx, &data)) {
@@ -166,17 +166,17 @@ nsDOMMessageEvent::Constructor(const moz
 
   return event.forget();
 }
 
 NS_IMETHODIMP
 nsDOMMessageEvent::InitMessageEvent(const nsAString& aType,
                                     bool aCanBubble,
                                     bool aCancelable,
-                                    const JS::Value& aData,
+                                    JS::Handle<JS::Value> aData,
                                     const nsAString& aOrigin,
                                     const nsAString& aLastEventId,
                                     nsIDOMWindow* aSource)
 {
   nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mData = aData;
--- a/dom/events/nsDOMNotifyAudioAvailableEvent.cpp
+++ b/dom/events/nsDOMNotifyAudioAvailableEvent.cpp
@@ -61,39 +61,39 @@ nsDOMNotifyAudioAvailableEvent::~nsDOMNo
   MOZ_COUNT_DTOR(nsDOMNotifyAudioAvailableEvent);
   if (mCachedArray) {
     mCachedArray = nullptr;
     mozilla::DropJSObjects(this);
   }
 }
 
 NS_IMETHODIMP
-nsDOMNotifyAudioAvailableEvent::GetFrameBuffer(JSContext* aCx, JS::Value* aResult)
+nsDOMNotifyAudioAvailableEvent::GetFrameBuffer(JSContext* aCx, JS::MutableHandle<JS::Value> aResult)
 {
   if (!mAllowAudioData) {
     // Media is not same-origin, don't allow the data out.
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   if (mCachedArray) {
-    *aResult = OBJECT_TO_JSVAL(mCachedArray);
+    aResult.setObject(*mCachedArray);
     return NS_OK;
   }
 
   // Cache this array so we don't recreate on next call.
   mozilla::HoldJSObjects(this);
 
   mCachedArray = JS_NewFloat32Array(aCx, mFrameBufferLength);
   if (!mCachedArray) {
     mozilla::DropJSObjects(this);
     return NS_ERROR_FAILURE;
   }
   memcpy(JS_GetFloat32ArrayData(mCachedArray), mFrameBuffer.get(), mFrameBufferLength * sizeof(float));
 
-  *aResult = OBJECT_TO_JSVAL(mCachedArray);
+  aResult.setObject(*mCachedArray);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMNotifyAudioAvailableEvent::GetTime(float *aRetVal)
 {
   *aRetVal = Time();
   return NS_OK;
--- a/dom/events/nsDOMNotifyAudioAvailableEvent.h
+++ b/dom/events/nsDOMNotifyAudioAvailableEvent.h
@@ -46,17 +46,17 @@ public:
                                JS::Handle<JSObject*> aScope) MOZ_OVERRIDE
   {
     return mozilla::dom::NotifyAudioAvailableEventBinding::Wrap(aCx, aScope, this);
   }
 
   JSObject* GetFrameBuffer(JSContext* aCx, mozilla::ErrorResult& aRv)
   {
     JS::Rooted<JS::Value> dummy(aCx);
-    aRv = GetFrameBuffer(aCx, dummy.address());
+    aRv = GetFrameBuffer(aCx, &dummy);
     return mCachedArray;
   }
 
   float Time()
   {
     return mTime;
   }
 
--- a/dom/events/nsEventListenerService.cpp
+++ b/dom/events/nsEventListenerService.cpp
@@ -60,20 +60,21 @@ nsEventListenerInfo::GetAllowsUntrusted(
 NS_IMETHODIMP
 nsEventListenerInfo::GetInSystemEventGroup(bool* aInSystemEventGroup)
 {
   *aInSystemEventGroup = mInSystemEventGroup;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsEventListenerInfo::GetListenerObject(JSContext* aCx, JS::Value* aObject)
+nsEventListenerInfo::GetListenerObject(JSContext* aCx,
+                                       JS::MutableHandle<JS::Value> aObject)
 {
   mozilla::Maybe<JSAutoCompartment> ac;
-  GetJSVal(aCx, ac, aObject);
+  GetJSVal(aCx, ac, aObject.address());
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS1(nsEventListenerService, nsIEventListenerService)
 
 // Caller must root *aJSVal!
 bool
 nsEventListenerInfo::GetJSVal(JSContext* aCx,
--- a/dom/file/LockedFile.cpp
+++ b/dom/file/LockedFile.cpp
@@ -486,53 +486,52 @@ LockedFile::GetActive(bool* aActive)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   *aActive = IsOpen();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LockedFile::GetLocation(JSContext* aCx,
-                        JS::Value* aLocation)
+                        JS::MutableHandle<JS::Value> aLocation)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (mLocation == UINT64_MAX) {
-    *aLocation = JSVAL_NULL;
+    aLocation.setNull();
   }
   else {
-    *aLocation = JS_NumberValue(double(mLocation));
+    aLocation.setDouble(double(mLocation));
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LockedFile::SetLocation(JSContext* aCx,
-                        const JS::Value& aLocation)
+                        JS::Handle<JS::Value> aLocation)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   // Null means the end-of-file.
-  if (JSVAL_IS_NULL(aLocation)) {
+  if (aLocation.isNull()) {
     mLocation = UINT64_MAX;
     return NS_OK;
   }
 
   uint64_t location;
-  JS::Rooted<JS::Value> value(aCx, aLocation);
-  if (!JS::ToUint64(aCx, value, &location)) {
+  if (!JS::ToUint64(aCx, aLocation, &location)) {
     return NS_ERROR_TYPE_ERR;
   }
 
   mLocation = location;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-LockedFile::GetMetadata(const JS::Value& aParameters,
+LockedFile::GetMetadata(JS::Handle<JS::Value> aParameters,
                         JSContext* aCx,
                         nsISupports** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!IsOpen()) {
     return NS_ERROR_DOM_FILEHANDLE_LOCKEDFILE_INACTIVE_ERR;
   }
@@ -541,17 +540,17 @@ LockedFile::GetMetadata(const JS::Value&
   if (!GetOwner()) {
     return NS_OK;
   }
 
   nsRefPtr<MetadataParameters> params = new MetadataParameters();
 
   // Get optional arguments.
   if (!JSVAL_IS_VOID(aParameters) && !JSVAL_IS_NULL(aParameters)) {
-    nsresult rv = params->Init(aCx, &aParameters);
+    nsresult rv = params->Init(aCx, aParameters);
     NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
 
     if (!params->IsConfigured()) {
       return NS_ERROR_TYPE_ERR;
     }
   }
   else {
     params->Init(true, true);
@@ -653,27 +652,27 @@ LockedFile::ReadAsText(uint64_t aSize,
   mLocation += aSize;
 
   nsRefPtr<nsIDOMDOMRequest> request = fileRequest.forget();
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-LockedFile::Write(const JS::Value& aValue,
+LockedFile::Write(JS::Handle<JS::Value> aValue,
                   JSContext* aCx,
                   nsISupports** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   return WriteOrAppend(aValue, aCx, _retval, false);
 }
 
 NS_IMETHODIMP
-LockedFile::Append(const JS::Value& aValue,
+LockedFile::Append(JS::Handle<JS::Value> aValue,
                    JSContext* aCx,
                    nsISupports** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   return WriteOrAppend(aValue, aCx, _retval, true);
 }
 
--- a/dom/file/MetadataHelper.h
+++ b/dom/file/MetadataHelper.h
@@ -26,19 +26,19 @@ class MetadataHelper;
 class MetadataParameters
 {
   friend class MetadataHelper;
 
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MetadataParameters)
 
   nsresult
-  Init(JSContext* aCx, const JS::Value* aVal)
+  Init(JSContext* aCx, JS::Handle<JS::Value> aVal)
   {
-    return mConfig.Init(aCx, aVal);
+    return mConfig.Init(aCx, aVal.address());
   }
 
   void
   Init(bool aRequestSize, bool aRequestLastModified)
   {
     mConfig.size = aRequestSize;
     mConfig.lastModified = aRequestLastModified;
   }
--- a/dom/fmradio/FMRadioService.cpp
+++ b/dom/fmradio/FMRadioService.cpp
@@ -132,17 +132,17 @@ class ReadRilSettingTask MOZ_FINAL : pub
 {
 public:
   NS_DECL_ISUPPORTS
 
   ReadRilSettingTask(nsRefPtr<FMRadioReplyRunnable> aPendingRequest)
     : mPendingRequest(aPendingRequest) { }
 
   NS_IMETHOD
-  Handle(const nsAString& aName, const JS::Value& aResult)
+  Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     FMRadioService* fmRadioService = FMRadioService::Singleton();
     MOZ_ASSERT(mPendingRequest == fmRadioService->mPendingRequest);
 
     fmRadioService->mHasReadRilSetting = true;
 
     if (!aResult.isBoolean()) {
       // Failed to read the setting value, set the state back to Disabled.
--- a/dom/icc/src/Icc.cpp
+++ b/dom/icc/src/Icc.cpp
@@ -51,17 +51,17 @@ Icc::NotifyStkEvent(const nsAString& aNa
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   AutoPushJSContext cx(sc->GetNativeContext());
   JS::Rooted<JS::Value> value(cx);
 
   if (!aMessage.IsEmpty()) {
     nsCOMPtr<nsIJSON> json(new nsJSON());
-    nsresult rv = json->DecodeToJSVal(aMessage, cx, value.address());
+    nsresult rv = json->DecodeToJSVal(aMessage, cx, &value);
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     value = JS::NullValue();
   }
 
   MozStkCommandEventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
@@ -110,18 +110,18 @@ Icc::GetCardState(nsString& aCardState) 
 
   nsresult rv = mProvider->GetCardState(mClientId, aCardState);
   if (NS_FAILED(rv)) {
     aCardState.SetIsVoid(true);
   }
 }
 
 void
-Icc::SendStkResponse(const JSContext* aCx, const JS::Value& aCommand,
-                     const JS::Value& aResponse, ErrorResult& aRv)
+Icc::SendStkResponse(const JSContext* aCx, JS::Handle<JS::Value> aCommand,
+                     JS::Handle<JS::Value> aResponse, ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   nsresult rv = mProvider->SendStkResponse(mClientId, GetOwner(), aCommand,
                                            aResponse);
@@ -144,33 +144,33 @@ Icc::SendStkMenuSelection(uint16_t aItem
                                                 aItemIdentifier,
                                                 aHelpRequested);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
   }
 }
 
 void
-Icc::SendStkTimerExpiration(const JSContext* aCx, const JS::Value& aTimer,
+Icc::SendStkTimerExpiration(const JSContext* aCx, JS::Handle<JS::Value> aTimer,
                             ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   nsresult rv = mProvider->SendStkTimerExpiration(mClientId, GetOwner(),
                                                   aTimer);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
   }
 }
 
 void
-Icc::SendStkEventDownload(const JSContext* aCx, const JS::Value& aEvent,
+Icc::SendStkEventDownload(const JSContext* aCx, JS::Handle<JS::Value> aEvent,
                           ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   nsresult rv = mProvider->SendStkEventDownload(mClientId, GetOwner(), aEvent);
@@ -194,17 +194,17 @@ Icc::GetCardLock(const nsAString& aLockT
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget();
 }
 
 already_AddRefed<nsISupports>
-Icc::UnlockCardLock(const JSContext* aCx, const JS::Value& aInfo,
+Icc::UnlockCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
                     ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
@@ -214,17 +214,18 @@ Icc::UnlockCardLock(const JSContext* aCx
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget();
 }
 
 already_AddRefed<nsISupports>
-Icc::SetCardLock(const JSContext* aCx, const JS::Value& aInfo, ErrorResult& aRv)
+Icc::SetCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
+                 ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
   nsresult rv = mProvider->SetCardLock(mClientId, GetOwner(), aInfo,
@@ -274,17 +275,17 @@ Icc::ReadContacts(const nsAString& aCont
     return nullptr;
   }
 
   return request.forget();
 }
 
 already_AddRefed<nsISupports>
 Icc::UpdateContact(const JSContext* aCx, const nsAString& aContactType,
-                   const JS::Value& aContact, const nsAString& aPin2,
+                   JS::Handle<JS::Value> aContact, const nsAString& aPin2,
                    ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
@@ -314,18 +315,18 @@ Icc::IccOpenChannel(const nsAString& aAi
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget();
 }
 
 already_AddRefed<nsISupports>
-Icc::IccExchangeAPDU(const JSContext* aCx, int32_t aChannel, const jsval& aApdu,
-                     ErrorResult& aRv)
+Icc::IccExchangeAPDU(const JSContext* aCx, int32_t aChannel,
+                     JS::Handle<JS::Value> aApdu, ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
   nsresult rv = mProvider->IccExchangeAPDU(mClientId, GetOwner(), aChannel,
--- a/dom/icc/src/Icc.h
+++ b/dom/icc/src/Icc.h
@@ -46,58 +46,59 @@ public:
   // MozIcc WebIDL
   already_AddRefed<nsIDOMMozIccInfo>
   GetIccInfo() const;
 
   void
   GetCardState(nsString& aCardState) const;
 
   void
-  SendStkResponse(const JSContext* aCx, const JS::Value& aCommand,
-                  const JS::Value& aResponse, ErrorResult& aRv);
+  SendStkResponse(const JSContext* aCx, JS::Handle<JS::Value> aCommand,
+                  JS::Handle<JS::Value> aResponse, ErrorResult& aRv);
 
   void
   SendStkMenuSelection(uint16_t aItemIdentifier, bool aHelpRequested,
                        ErrorResult& aRv);
 
   void
-  SendStkTimerExpiration(const JSContext* aCx, const JS::Value& aTimer,
+  SendStkTimerExpiration(const JSContext* aCx, JS::Handle<JS::Value> aTimer,
                          ErrorResult& aRv);
 
   void
-  SendStkEventDownload(const JSContext* aCx, const JS::Value& aEvent,
+  SendStkEventDownload(const JSContext* aCx, JS::Handle<JS::Value> aEvent,
                        ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   GetCardLock(const nsAString& aLockType, ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
-  UnlockCardLock(const JSContext* aCx, const JS::Value& aInfo,
+  UnlockCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
                  ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
-  SetCardLock(const JSContext* aCx, const JS::Value& aInfo, ErrorResult& aRv);
+  SetCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
+              ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   GetCardLockRetryCount(const nsAString& aLockType, ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   ReadContacts(const nsAString& aContactType, ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   UpdateContact(const JSContext* aCx, const nsAString& aContactType,
-                const JS::Value& aContact, const nsAString& aPin2,
+                JS::Handle<JS::Value> aContact, const nsAString& aPin2,
                 ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   IccOpenChannel(const nsAString& aAid, ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
-  IccExchangeAPDU(const JSContext* aCx, int32_t aChannel, const jsval& aApdu,
-                  ErrorResult& aRv);
+  IccExchangeAPDU(const JSContext* aCx, int32_t aChannel,
+                  JS::Handle<JS::Value> aApdu, ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   IccCloseChannel(int32_t aChannel, ErrorResult& aRv);
 
   IMPL_EVENT_HANDLER(iccinfochange)
   IMPL_EVENT_HANDLER(cardstatechange)
   IMPL_EVENT_HANDLER(stkcommand)
   IMPL_EVENT_HANDLER(stksessionend)
--- a/dom/icc/src/IccManager.cpp
+++ b/dom/icc/src/IccManager.cpp
@@ -125,17 +125,17 @@ IccManager::Unroot()
     mozilla::DropJSObjects(this);
     mRooted = false;
   }
 }
 
 // nsIDOMMozIccManager
 
 NS_IMETHODIMP
-IccManager::GetIccIds(JS::Value* aIccIds)
+IccManager::GetIccIds(JS::MutableHandle<JS::Value> aIccIds)
 {
   if (!mJsIccIds) {
     nsTArray<nsString> iccIds;
     for (uint32_t i = 0; i < mIccListeners.Length(); i++) {
       nsRefPtr<Icc> icc = mIccListeners[i]->GetIcc();
       if (icc) {
         iccIds.AppendElement(icc->GetIccId());
       }
@@ -149,17 +149,17 @@ IccManager::GetIccIds(JS::Value* aIccIds
     JS::Rooted<JSObject*> jsIccIds(cx);
     rv = nsTArrayToJSArray(cx, iccIds, jsIccIds.address());
     NS_ENSURE_SUCCESS(rv, rv);
 
     mJsIccIds = jsIccIds;
     Root();
   }
 
-  aIccIds->setObject(*mJsIccIds);
+  aIccIds.setObject(*mJsIccIds);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IccManager::GetIccById(const nsAString& aIccId, nsISupports** aIcc)
 {
   *aIcc = nullptr;
 
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -641,17 +641,17 @@ IndexedDatabaseManager::BlockAndGetFileR
 }
 
 NS_IMPL_ADDREF(IndexedDatabaseManager)
 NS_IMPL_RELEASE_WITH_DESTROY(IndexedDatabaseManager, Destroy())
 NS_IMPL_QUERY_INTERFACE2(IndexedDatabaseManager, nsIIndexedDatabaseManager,
                                                  nsIObserver)
 
 NS_IMETHODIMP
-IndexedDatabaseManager::InitWindowless(const jsval& aGlobal, JSContext* aCx)
+IndexedDatabaseManager::InitWindowless(JS::Handle<JS::Value> aGlobal, JSContext* aCx)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   JS::Rooted<JSObject*> global(aCx, JSVAL_TO_OBJECT(aGlobal));
   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
     NS_WARNING("Passed object is not a global object!");
     return NS_ERROR_FAILURE;
   }
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -1048,26 +1048,27 @@ public:
 
   virtual void*
   GetPBlob() MOZ_OVERRIDE
   {
     return static_cast<typename ActorType::ProtocolType*>(mActor);
   }
 
   NS_IMETHOD
-  GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate) MOZ_OVERRIDE
+  GetLastModifiedDate(JSContext* cx,
+                      JS::MutableHandle<JS::Value> aLastModifiedDate) MOZ_OVERRIDE
   {
     if (IsDateUnknown()) {
-      aLastModifiedDate->setNull();
+      aLastModifiedDate.setNull();
     } else {
       JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
       if (!date) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
-      aLastModifiedDate->setObject(*date);
+      aLastModifiedDate.setObject(*date);
     }
     return NS_OK;
   }
 };
 
 template <>
 void
 RemoteBlob<Parent>::MaybeSetInputStream(const ConstructorParamsType& aParams)
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -57,35 +57,35 @@ class TabChildGlobal : public nsDOMEvent
 public:
   TabChildGlobal(TabChild* aTabChild);
   void Init();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
   NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
   NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
-                             const JS::Value& aObject,
-                             const JS::Value& aRemote,
+                             JS::Handle<JS::Value> aObject,
+                             JS::Handle<JS::Value> aRemote,
                              nsIPrincipal* aPrincipal,
                              JSContext* aCx,
                              uint8_t aArgc,
-                             JS::Value* aRetval)
+                             JS::MutableHandle<JS::Value> aRetval)
   {
     return mMessageManager
       ? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote,
                                          aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
-                            const JS::Value& aObject,
-                            const JS::Value& aRemote,
+                            JS::Handle<JS::Value> aObject,
+                            JS::Handle<JS::Value> aRemote,
                             nsIPrincipal* aPrincipal,
                             JSContext* aCx,
                             uint8_t aArgc,
-                            JS::Value* aRetval)
+                            JS::MutableHandle<JS::Value> aRetval)
   {
     return mMessageManager
       ? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote,
                                         aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
   NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) MOZ_OVERRIDE;
--- a/dom/mobilemessage/src/MmsMessage.cpp
+++ b/dom/mobilemessage/src/MmsMessage.cpp
@@ -466,24 +466,24 @@ MmsMessage::GetDelivery(nsAString& aDeli
     default:
       MOZ_CRASH("We shouldn't get any other delivery state!");
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MmsMessage::GetDeliveryInfo(JSContext* aCx, JS::Value* aDeliveryInfo)
+MmsMessage::GetDeliveryInfo(JSContext* aCx, JS::MutableHandle<JS::Value> aDeliveryInfo)
 {
   // TODO Bug 850525 It'd be better to depend on the delivery of MmsMessage
   // to return a more correct value. Ex, if .delivery = 'received', we should
   // also make .deliveryInfo = null, since the .deliveryInfo is useless.
   uint32_t length = mDeliveryInfo.Length();
   if (length == 0) {
-    *aDeliveryInfo = JSVAL_NULL;
+    aDeliveryInfo.setNull();
     return NS_OK;
   }
 
   JS::Rooted<JSObject*> deliveryInfo(
     aCx, JS_NewArrayObject(aCx, length, nullptr));
   NS_ENSURE_TRUE(deliveryInfo, NS_ERROR_OUT_OF_MEMORY);
 
   for (uint32_t i = 0; i < length; ++i) {
@@ -547,35 +547,35 @@ MmsMessage::GetDeliveryInfo(JSContext* a
     }
 
     tmpJsVal = OBJECT_TO_JSVAL(infoJsObj);
     if (!JS_SetElement(aCx, deliveryInfo, i, &tmpJsVal)) {
       return NS_ERROR_FAILURE;
     }
   }
 
-  aDeliveryInfo->setObject(*deliveryInfo);
+  aDeliveryInfo.setObject(*deliveryInfo);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MmsMessage::GetSender(nsAString& aSender)
 {
   aSender = mSender;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MmsMessage::GetReceivers(JSContext* aCx, JS::Value* aReceivers)
+MmsMessage::GetReceivers(JSContext* aCx, JS::MutableHandle<JS::Value> aReceivers)
 {
   JS::Rooted<JSObject*> reveiversObj(aCx);
   nsresult rv = nsTArrayToJSArray(aCx, mReceivers, reveiversObj.address());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  aReceivers->setObject(*reveiversObj);
+  aReceivers.setObject(*reveiversObj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MmsMessage::GetTimestamp(DOMTimeStamp* aTimestamp)
 {
   *aTimestamp = mTimestamp;
   return NS_OK;
@@ -605,17 +605,17 @@ MmsMessage::GetSubject(nsAString& aSubje
 NS_IMETHODIMP
 MmsMessage::GetSmil(nsAString& aSmil)
 {
   aSmil = mSmil;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MmsMessage::GetAttachments(JSContext* aCx, JS::Value* aAttachments)
+MmsMessage::GetAttachments(JSContext* aCx, JS::MutableHandle<JS::Value> aAttachments)
 {
   uint32_t length = mAttachments.Length();
 
   JS::Rooted<JSObject*> attachments(
     aCx, JS_NewArrayObject(aCx, length, nullptr));
   NS_ENSURE_TRUE(attachments, NS_ERROR_OUT_OF_MEMORY);
 
   for (uint32_t i = 0; i < length; ++i) {
@@ -667,17 +667,17 @@ MmsMessage::GetAttachments(JSContext* aC
     }
 
     tmpJsVal = OBJECT_TO_JSVAL(attachmentObj);
     if (!JS_SetElement(aCx, attachments, i, &tmpJsVal)) {
       return NS_ERROR_FAILURE;
     }
   }
 
-  aAttachments->setObject(*attachments);
+  aAttachments.setObject(*attachments);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MmsMessage::GetExpiryDate(DOMTimeStamp* aExpiryDate)
 {
   *aExpiryDate = mExpiryDate;
   return NS_OK;
--- a/dom/mobilemessage/src/MobileMessageManager.cpp
+++ b/dom/mobilemessage/src/MobileMessageManager.cpp
@@ -158,24 +158,23 @@ MobileMessageManager::Send(JSContext* aC
     return rv;
   }
 
   *aRequest = rval;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MobileMessageManager::Send(const JS::Value& aNumber_,
+MobileMessageManager::Send(JS::Handle<JS::Value> aNumber,
                            const nsAString& aMessage,
-                           const JS::Value& aSendParams,
+                           JS::Handle<JS::Value> aSendParams,
                            JSContext* aCx,
                            uint8_t aArgc,
-                           JS::Value* aReturn)
+                           JS::MutableHandle<JS::Value> aReturn)
 {
-  JS::Rooted<JS::Value> aNumber(aCx, aNumber_);
   if (!aNumber.isString() &&
       !(aNumber.isObject() && JS_IsArrayObject(aCx, &aNumber.toObject()))) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsresult rv;
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -205,17 +204,17 @@ MobileMessageManager::Send(const JS::Val
     }
     if (sendParams.mServiceId.WasPassed()) {
       serviceId = sendParams.mServiceId.Value();
     }
   }
 
   if (aNumber.isString()) {
     JS::Rooted<JSString*> str(aCx, aNumber.toString());
-    return Send(aCx, global, serviceId, str, aMessage, aReturn);
+    return Send(aCx, global, serviceId, str, aMessage, aReturn.address());
   }
 
   // Must be an array then.
   JS::Rooted<JSObject*> numbers(aCx, &aNumber.toObject());
 
   uint32_t size;
   if (!JS_GetArrayLength(aCx, numbers, &size)) {
     return NS_ERROR_FAILURE;
@@ -243,23 +242,23 @@ MobileMessageManager::Send(const JS::Val
   }
 
   JS::Rooted<JSObject*> obj(aCx);
   obj = JS_NewArrayObject(aCx, requests.length(), requests.begin());
   if (!obj) {
     return NS_ERROR_FAILURE;
   }
 
-  aReturn->setObject(*obj);
+  aReturn.setObject(*obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MobileMessageManager::SendMMS(const JS::Value& aParams,
-                              const JS::Value& aSendParams,
+MobileMessageManager::SendMMS(JS::Handle<JS::Value> aParams,
+                              JS::Handle<JS::Value> aSendParams,
                               JSContext* aCx,
                               uint8_t aArgc,
                               nsIDOMDOMRequest** aRequest)
 {
   nsCOMPtr<nsIMmsService> mmsService = do_GetService(MMS_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(mmsService, NS_ERROR_FAILURE);
 
   // Use the default one unless |aSendParams.serviceId| is available.
@@ -318,17 +317,17 @@ MobileMessageManager::GetMessageId(JSCon
   if (mmsMessage) {
     return mmsMessage->GetId(aId);
   }
 
   return NS_ERROR_INVALID_ARG;
 }
 
 NS_IMETHODIMP
-MobileMessageManager::Delete(const JS::Value& aParam, JSContext* aCx,
+MobileMessageManager::Delete(JS::Handle<JS::Value> aParam, JSContext* aCx,
                              nsIDOMDOMRequest** aRequest)
 {
   // We expect Int32, SmsMessage, MmsMessage, Int32[], SmsMessage[], MmsMessage[]
   if (!aParam.isObject() && !aParam.isInt32()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsresult rv = NS_OK;
--- a/dom/mobilemessage/src/MobileMessageService.cpp
+++ b/dom/mobilemessage/src/MobileMessageService.cpp
@@ -33,19 +33,19 @@ MobileMessageService::CreateSmsMessage(i
                                        uint64_t aThreadId,
                                        const nsAString& aIccId,
                                        const nsAString& aDelivery,
                                        const nsAString& aDeliveryStatus,
                                        const nsAString& aSender,
                                        const nsAString& aReceiver,
                                        const nsAString& aBody,
                                        const nsAString& aMessageClass,
-                                       const JS::Value& aTimestamp,
-                                       const JS::Value& aSentTimestamp,
-                                       const JS::Value& aDeliveryTimestamp,
+                                       JS::Handle<JS::Value> aTimestamp,
+                                       JS::Handle<JS::Value> aSentTimestamp,
+                                       JS::Handle<JS::Value> aDeliveryTimestamp,
                                        const bool aRead,
                                        JSContext* aCx,
                                        nsIDOMMozSmsMessage** aMessage)
 {
   return SmsMessage::Create(aId,
                             aThreadId,
                             aIccId,
                             aDelivery,
@@ -62,26 +62,26 @@ MobileMessageService::CreateSmsMessage(i
                             aMessage);
 }
 
 NS_IMETHODIMP
 MobileMessageService::CreateMmsMessage(int32_t               aId,
                                        uint64_t              aThreadId,
                                        const nsAString&      aIccId,
                                        const nsAString&      aDelivery,
-                                       const JS::Value&      aDeliveryInfo,
+                                       JS::Handle<JS::Value> aDeliveryInfo,
                                        const nsAString&      aSender,
-                                       const JS::Value&      aReceivers,
-                                       const JS::Value&      aTimestamp,
-                                       const JS::Value&      aSentTimestamp,
+                                       JS::Handle<JS::Value> aReceivers,
+                                       JS::Handle<JS::Value> aTimestamp,
+                                       JS::Handle<JS::Value> aSentTimestamp,
                                        bool                  aRead,
                                        const nsAString&      aSubject,
                                        const nsAString&      aSmil,
-                                       const JS::Value&      aAttachments,
-                                       const JS::Value&      aExpiryDate,
+                                       JS::Handle<JS::Value> aAttachments,
+                                       JS::Handle<JS::Value> aExpiryDate,
                                        bool                  aReadReportRequested,
                                        JSContext*            aCx,
                                        nsIDOMMozMmsMessage** aMessage)
 {
   return MmsMessage::Create(aId,
                             aThreadId,
                             aIccId,
                             aDelivery,
@@ -109,18 +109,18 @@ MobileMessageService::CreateSmsSegmentIn
   nsCOMPtr<nsIDOMMozSmsSegmentInfo> info =
       new SmsSegmentInfo(aSegments, aCharsPerSegment, aCharsAvailableInLastSegment);
   info.forget(aSegmentInfo);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageService::CreateThread(uint64_t aId,
-                                   const JS::Value& aParticipants,
-                                   const JS::Value& aTimestamp,
+                                   JS::Handle<JS::Value> aParticipants,
+                                   JS::Handle<JS::Value> aTimestamp,
                                    const nsAString& aLastMessageSubject,
                                    const nsAString& aBody,
                                    uint64_t aUnreadCount,
                                    const nsAString& aLastMessageType,
                                    JSContext* aCx,
                                    nsIDOMMozMobileMessageThread** aThread)
 {
   return MobileMessageThread::Create(aId,
--- a/dom/mobilemessage/src/MobileMessageThread.cpp
+++ b/dom/mobilemessage/src/MobileMessageThread.cpp
@@ -157,24 +157,24 @@ NS_IMETHODIMP
 MobileMessageThread::GetUnreadCount(uint64_t* aUnreadCount)
 {
   *aUnreadCount = mData.unreadCount();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageThread::GetParticipants(JSContext* aCx,
-                                     JS::Value* aParticipants)
+                                     JS::MutableHandle<JS::Value> aParticipants)
 {
   JS::Rooted<JSObject*> obj(aCx);
 
   nsresult rv = nsTArrayToJSArray(aCx, mData.participants(), obj.address());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  aParticipants->setObject(*obj);
+  aParticipants.setObject(*obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageThread::GetTimestamp(DOMTimeStamp* aDate)
 {
   *aDate = mData.timestamp();
   return NS_OK;
--- a/dom/mobilemessage/src/SmsFilter.cpp
+++ b/dom/mobilemessage/src/SmsFilter.cpp
@@ -46,33 +46,33 @@ SmsFilter::SmsFilter(const SmsFilterData
 /* static */ nsresult
 SmsFilter::NewSmsFilter(nsISupports** aSmsFilter)
 {
   NS_ADDREF(*aSmsFilter = new SmsFilter());
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::GetStartDate(JSContext* aCx, JS::Value* aStartDate)
+SmsFilter::GetStartDate(JSContext* aCx, JS::MutableHandle<JS::Value> aStartDate)
 {
   if (mData.startDate() == 0) {
-    *aStartDate = JSVAL_NULL;
+    aStartDate.setNull();
     return NS_OK;
   }
 
-  aStartDate->setObjectOrNull(JS_NewDateObjectMsec(aCx, mData.startDate()));
-  NS_ENSURE_TRUE(aStartDate->isObject(), NS_ERROR_FAILURE);
+  aStartDate.setObjectOrNull(JS_NewDateObjectMsec(aCx, mData.startDate()));
+  NS_ENSURE_TRUE(aStartDate.isObject(), NS_ERROR_FAILURE);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::SetStartDate(JSContext* aCx, const JS::Value& aStartDate)
+SmsFilter::SetStartDate(JSContext* aCx, JS::Handle<JS::Value> aStartDate)
 {
-  if (aStartDate == JSVAL_NULL) {
+  if (aStartDate.isNull()) {
     mData.startDate() = 0;
     return NS_OK;
   }
 
   if (!aStartDate.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
@@ -81,33 +81,33 @@ SmsFilter::SetStartDate(JSContext* aCx, 
     return NS_ERROR_INVALID_ARG;
   }
 
   mData.startDate() = js_DateGetMsecSinceEpoch(obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::GetEndDate(JSContext* aCx, JS::Value* aEndDate)
+SmsFilter::GetEndDate(JSContext* aCx, JS::MutableHandle<JS::Value> aEndDate)
 {
   if (mData.endDate() == 0) {
-    *aEndDate = JSVAL_NULL;
+    aEndDate.setNull();
     return NS_OK;
   }
 
-  aEndDate->setObjectOrNull(JS_NewDateObjectMsec(aCx, mData.endDate()));
-  NS_ENSURE_TRUE(aEndDate->isObject(), NS_ERROR_FAILURE);
+  aEndDate.setObjectOrNull(JS_NewDateObjectMsec(aCx, mData.endDate()));
+  NS_ENSURE_TRUE(aEndDate.isObject(), NS_ERROR_FAILURE);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::SetEndDate(JSContext* aCx, const JS::Value& aEndDate)
+SmsFilter::SetEndDate(JSContext* aCx, JS::Handle<JS::Value> aEndDate)
 {
-  if (aEndDate == JSVAL_NULL) {
+  if (aEndDate.isNull()) {
     mData.endDate() = 0;
     return NS_OK;
   }
 
   if (!aEndDate.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
@@ -116,22 +116,22 @@ SmsFilter::SetEndDate(JSContext* aCx, co
     return NS_ERROR_INVALID_ARG;
   }
 
   mData.endDate() = js_DateGetMsecSinceEpoch(obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::GetNumbers(JSContext* aCx, JS::Value* aNumbers)
+SmsFilter::GetNumbers(JSContext* aCx, JS::MutableHandle<JS::Value> aNumbers)
 {
   uint32_t length = mData.numbers().Length();
 
   if (length == 0) {
-    *aNumbers = JSVAL_NULL;
+    aNumbers.setNull();
     return NS_OK;
   }
 
   JS::AutoValueVector numbers(aCx);
   if (!numbers.resize(length)) {
     return NS_ERROR_FAILURE;
   }
 
@@ -145,24 +145,24 @@ SmsFilter::GetNumbers(JSContext* aCx, JS
     numbers[i].setString(str);
   }
 
   JSObject* obj = JS_NewArrayObject(aCx, numbers.length(), numbers.begin());
   if (!obj) {
     return NS_ERROR_FAILURE;
   }
 
-  aNumbers->setObject(*obj);
+  aNumbers.setObject(*obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::SetNumbers(JSContext* aCx, const JS::Value& aNumbers)
+SmsFilter::SetNumbers(JSContext* aCx, JS::Handle<JS::Value> aNumbers)
 {
-  if (aNumbers == JSVAL_NULL) {
+  if (aNumbers.isNull()) {
     mData.numbers().Clear();
     return NS_OK;
   }
 
   if (!aNumbers.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
@@ -236,61 +236,59 @@ SmsFilter::SetDelivery(const nsAString& 
     mData.delivery() = eDeliveryState_Sent;
     return NS_OK;
   }
 
   return NS_ERROR_INVALID_ARG;
 }
 
 NS_IMETHODIMP
-SmsFilter::GetRead(JSContext* aCx, JS::Value* aRead)
+SmsFilter::GetRead(JSContext* aCx, JS::MutableHandle<JS::Value> aRead)
 {
   if (mData.read() == eReadState_Unknown) {
-    *aRead = JSVAL_NULL;
+    aRead.setNull();
     return NS_OK;
   }
 
-  aRead->setBoolean(mData.read());
-
+  aRead.setBoolean(mData.read());
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::SetRead(JSContext* aCx, const JS::Value& aRead)
+SmsFilter::SetRead(JSContext* aCx, JS::Handle<JS::Value> aRead)
 {
-  if (aRead == JSVAL_NULL) {
+  if (aRead.isNull()) {
     mData.read() = eReadState_Unknown;
     return NS_OK;
   }
 
   if (!aRead.isBoolean()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   mData.read() = aRead.toBoolean() ? eReadState_Read : eReadState_Unread;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::GetThreadId(JSContext* aCx, JS::Value* aThreadId)
+SmsFilter::GetThreadId(JSContext* aCx, JS::MutableHandle<JS::Value> aThreadId)
 {
   if (!mData.threadId()) {
-    *aThreadId = JSVAL_NULL;
+    aThreadId.setNull();
     return NS_OK;
   }
 
-  aThreadId->setNumber(static_cast<double>(mData.threadId()));
-
+  aThreadId.setNumber(static_cast<double>(mData.threadId()));
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::SetThreadId(JSContext* aCx, const JS::Value& aThreadId)
+SmsFilter::SetThreadId(JSContext* aCx, JS::Handle<JS::Value> aThreadId)
 {
-  if (aThreadId == JSVAL_NULL) {
+  if (aThreadId.isNull()) {
     mData.threadId() = 0;
     return NS_OK;
   }
 
   if (!aThreadId.isNumber()) {
     return NS_ERROR_INVALID_ARG;
   }
 
--- a/dom/mobilemessage/src/ipc/SmsIPCService.cpp
+++ b/dom/mobilemessage/src/ipc/SmsIPCService.cpp
@@ -310,17 +310,17 @@ NS_IMETHODIMP
 SmsIPCService::GetMmsDefaultServiceId(uint32_t* aServiceId)
 {
   *aServiceId = mMmsDefaultServiceId;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 SmsIPCService::Send(uint32_t aServiceId,
-                    const JS::Value& aParameters,
+                    JS::Handle<JS::Value> aParameters,
                     nsIMobileMessageCallback *aRequest)
 {
   SendMmsMessageRequest req;
   if (!GetSendMmsMessageRequestFromParams(aServiceId, aParameters, req)) {
     return NS_ERROR_INVALID_ARG;
   }
   return SendRequest(SendMessageRequest(req), aRequest);
 }
--- a/dom/network/src/MobileConnection.cpp
+++ b/dom/network/src/MobileConnection.cpp
@@ -437,51 +437,51 @@ MobileConnection::SetCallForwardingOptio
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->SetCallForwardingOption(mClientId, GetOwner(), aCFInfo, aRequest);
 }
 
 NS_IMETHODIMP
-MobileConnection::GetCallBarringOption(const JS::Value& aOption,
+MobileConnection::GetCallBarringOption(JS::Handle<JS::Value> aOption,
                                        nsIDOMDOMRequest** aRequest)
 {
   *aRequest = nullptr;
 
   if (!CheckPermission("mobileconnection")) {
     return NS_OK;
   }
 
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->GetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
 }
 
 NS_IMETHODIMP
-MobileConnection::SetCallBarringOption(const JS::Value& aOption,
+MobileConnection::SetCallBarringOption(JS::Handle<JS::Value> aOption,
                                        nsIDOMDOMRequest** aRequest)
 {
   *aRequest = nullptr;
 
   if (!CheckPermission("mobileconnection")) {
     return NS_OK;
   }
 
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->SetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
 }
 
 NS_IMETHODIMP
-MobileConnection::ChangeCallBarringPassword(const JS::Value& aInfo,
+MobileConnection::ChangeCallBarringPassword(JS::Handle<JS::Value> aInfo,
                                             nsIDOMDOMRequest** aRequest)
 {
   *aRequest = nullptr;
 
   if (!CheckPermission("mobileconnection")) {
     return NS_OK;
   }
 
--- a/dom/network/src/TCPSocketChild.cpp
+++ b/dom/network/src/TCPSocketChild.cpp
@@ -75,17 +75,17 @@ TCPSocketChild::TCPSocketChild()
 : mWindowObj(nullptr)
 {
 }
 
 NS_IMETHODIMP
 TCPSocketChild::SendOpen(nsITCPSocketInternal* aSocket,
                          const nsAString& aHost, uint16_t aPort,
                          bool aUseSSL, const nsAString& aBinaryType,
-                         nsIDOMWindow* aWindow, const JS::Value& aWindowObj,
+                         nsIDOMWindow* aWindow, JS::Handle<JS::Value> aWindowObj,
                          JSContext* aCx)
 {
   mSocket = aSocket;
 
   MOZ_ASSERT(aWindowObj.isObject());
   mWindowObj = js::CheckedUnwrap(&aWindowObj.toObject());
   if (!mWindowObj) {
     return NS_ERROR_FAILURE;
@@ -193,17 +193,17 @@ TCPSocketChild::SendResume()
 NS_IMETHODIMP
 TCPSocketChild::SendClose()
 {
   PTCPSocketChild::SendClose();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TCPSocketChild::SendSend(const JS::Value& aData,
+TCPSocketChild::SendSend(JS::Handle<JS::Value> aData,
                          uint32_t aByteOffset,
                          uint32_t aByteLength,
                          uint32_t aTrackingNumber,
                          JSContext* aCx)
 {
   if (aData.isString()) {
     JSString* jsstr = aData.toString();
     nsDependentJSString str;
@@ -229,17 +229,17 @@ TCPSocketChild::SendSend(const JS::Value
     arr.SwapElements(fallibleArr);
     SendData(arr, aTrackingNumber);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TCPSocketChild::SetSocketAndWindow(nsITCPSocketInternal *aSocket,
-                                   const JS::Value& aWindowObj,
+                                   JS::Handle<JS::Value> aWindowObj,
                                    JSContext* aCx)
 {
   mSocket = aSocket;
   MOZ_ASSERT(aWindowObj.isObject());
   mWindowObj = js::CheckedUnwrap(&aWindowObj.toObject());
   if (!mWindowObj) {
     return NS_ERROR_FAILURE;
   }
--- a/dom/network/src/TCPSocketParent.cpp
+++ b/dom/network/src/TCPSocketParent.cpp
@@ -116,17 +116,17 @@ TCPSocketParent::RecvOpen(const nsString
     FireInteralError(this, __LINE__);
     return true;
   }
 
   return true;
 }
 
 NS_IMETHODIMP
-TCPSocketParent::InitJS(const JS::Value& aIntermediary, JSContext* aCx)
+TCPSocketParent::InitJS(JS::Handle<JS::Value> aIntermediary, JSContext* aCx)
 {
   MOZ_ASSERT(aIntermediary.isObject());
   mIntermediaryObj = &aIntermediary.toObject();
   return NS_OK;
 }
 
 bool
 TCPSocketParent::RecvStartTLS()
@@ -190,17 +190,17 @@ TCPSocketParent::RecvClose()
 {
   NS_ENSURE_TRUE(mSocket, true);
   nsresult rv = mSocket->Close();
   NS_ENSURE_SUCCESS(rv, true);
   return true;
 }
 
 NS_IMETHODIMP
-TCPSocketParent::SendEvent(const nsAString& aType, const JS::Value& aDataVal,
+TCPSocketParent::SendEvent(const nsAString& aType, JS::Handle<JS::Value> aDataVal,
                            const nsAString& aReadyState, JSContext* aCx)
 {
   if (!mIPCOpen) {
     NS_WARNING("Dropping callback due to no IPC connection");
     return NS_OK;
   }
 
   CallbackData data;
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -125,17 +125,17 @@ public:
   GeolocationSettingsCallback() {
     MOZ_COUNT_CTOR(GeolocationSettingsCallback);
   }
 
   virtual ~GeolocationSettingsCallback() {
     MOZ_COUNT_DTOR(GeolocationSettingsCallback);
   }
 
-  NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
+  NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     // The geolocation is enabled by default:
     bool value = true;
     if (aResult.isBoolean()) {
       value = aResult.toBoolean();
     }
--- a/dom/src/json/nsJSON.cpp
+++ b/dom/src/json/nsJSON.cpp
@@ -54,17 +54,17 @@ WarnDeprecatedMethod(DeprecationWarning 
                                          NS_LITERAL_CSTRING("DOM Core"), nullptr,
                                          nsContentUtils::eDOM_PROPERTIES,
                                          warning == EncodeWarning
                                          ? "nsIJSONEncodeDeprecatedWarning"
                                          : "nsIJSONDecodeDeprecatedWarning");
 }
 
 NS_IMETHODIMP
-nsJSON::Encode(const JS::Value& aValue, JSContext* cx, uint8_t aArgc,
+nsJSON::Encode(JS::Handle<JS::Value> aValue, JSContext* cx, uint8_t aArgc,
                nsAString &aJSON)
 {
   // This function should only be called from JS.
   nsresult rv = WarnDeprecatedMethod(EncodeWarning);
   if (NS_FAILED(rv))
     return rv;
 
   if (aArgc == 0) {
@@ -107,17 +107,17 @@ static nsresult CheckCharset(const char*
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJSON::EncodeToStream(nsIOutputStream *aStream,
                        const char* aCharset,
                        const bool aWriteBOM,
-                       const JS::Value& val,
+                       JS::Handle<JS::Value> val,
                        JSContext* cx,
                        uint8_t aArgc)
 {
   // This function should only be called from JS.
   NS_ENSURE_ARG(aStream);
   nsresult rv;
 
   rv = CheckCharset(aCharset);
@@ -354,17 +354,18 @@ nsJSONWriter::WriteToStream(nsIOutputStr
 
   NS_Free(destBuf);
   mDidWrite = true;
 
   return rv;
 }
 
 NS_IMETHODIMP
-nsJSON::Decode(const nsAString& json, JSContext* cx, JS::Value* aRetval)
+nsJSON::Decode(const nsAString& json, JSContext* cx,
+               JS::MutableHandle<JS::Value> aRetval)
 {
   nsresult rv = WarnDeprecatedMethod(DecodeWarning);
   if (NS_FAILED(rv))
     return rv;
 
   const char16_t *data;
   uint32_t len = NS_StringGetData(json, &data);
   nsCOMPtr<nsIInputStream> stream;
@@ -373,57 +374,55 @@ nsJSON::Decode(const nsAString& json, JS
                              len * sizeof(char16_t),
                              NS_ASSIGNMENT_DEPEND);
   NS_ENSURE_SUCCESS(rv, rv);
   return DecodeInternal(cx, stream, len, false, aRetval);
 }
 
 NS_IMETHODIMP
 nsJSON::DecodeFromStream(nsIInputStream *aStream, int32_t aContentLength,
-                         JSContext* cx, JS::Value* aRetval)
+                         JSContext* cx, JS::MutableHandle<JS::Value> aRetval)
 {
   return DecodeInternal(cx, aStream, aContentLength, true, aRetval);
 }
 
 NS_IMETHODIMP
-nsJSON::DecodeToJSVal(const nsAString &str, JSContext *cx, JS::Value *result)
+nsJSON::DecodeToJSVal(const nsAString &str, JSContext *cx,
+                      JS::MutableHandle<JS::Value> result)
 {
-  JS::Rooted<JS::Value> value(cx);
   if (!JS_ParseJSON(cx, static_cast<const jschar*>(PromiseFlatString(str).get()),
-                    str.Length(), &value)) {
+                    str.Length(), result)) {
     return NS_ERROR_UNEXPECTED;
   }
-
-  *result = value;
   return NS_OK;
 }
 
 nsresult
 nsJSON::DecodeInternal(JSContext* cx,
                        nsIInputStream *aStream,
                        int32_t aContentLength,
                        bool aNeedsConverter,
-                       JS::Value* aRetval)
+                       JS::MutableHandle<JS::Value> aRetval)
 {
   // Consume the stream
   nsCOMPtr<nsIChannel> jsonChannel;
   if (!mURI) {
     NS_NewURI(getter_AddRefs(mURI), NS_LITERAL_CSTRING("about:blank"), 0, 0 );
     if (!mURI)
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsresult rv =
     NS_NewInputStreamChannel(getter_AddRefs(jsonChannel), mURI, aStream,
                              NS_LITERAL_CSTRING("application/json"));
   if (!jsonChannel || NS_FAILED(rv))
     return NS_ERROR_FAILURE;
 
   nsRefPtr<nsJSONListener> jsonListener =
-    new nsJSONListener(cx, aRetval, aNeedsConverter);
+    new nsJSONListener(cx, aRetval.address(), aNeedsConverter);
 
   //XXX this stream pattern should be consolidated in netwerk
   rv = jsonListener->OnStartRequest(jsonChannel, nullptr);
   if (NS_FAILED(rv)) {
     jsonChannel->Cancel(rv);
     return rv;
   }
 
--- a/dom/src/json/nsJSON.h
+++ b/dom/src/json/nsJSON.h
@@ -54,17 +54,17 @@ protected:
   nsresult EncodeInternal(JSContext* cx,
                           const JS::Value& val,
                           nsJSONWriter* writer);
 
   nsresult DecodeInternal(JSContext* cx,
                           nsIInputStream* aStream,
                           int32_t aContentLength,
                           bool aNeedsConverter,
-                          JS::Value* aRetVal);
+                          JS::MutableHandle<JS::Value> aRetVal);
   nsCOMPtr<nsIURI> mURI;
 };
 
 nsresult
 NS_NewJSON(nsISupports* aOuter, REFNSIID aIID, void** aResult);
 
 class nsJSONListener : public nsIStreamListener
 {
--- a/dom/src/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/src/jsurl/nsJSProtocolHandler.cpp
@@ -288,17 +288,17 @@ nsresult nsJSThunk::EvaluateScript(nsICh
         JSAutoCompartment ac(cx, sandboxObj);
 
         // Push our JSContext on the context stack so the EvalInSandboxObject call (and
         // JS_ReportPendingException, if relevant) will use the principal of cx.
         nsCxPusher pusher;
         pusher.Push(cx);
         rv = xpc->EvalInSandboxObject(NS_ConvertUTF8toUTF16(script),
                                       /* filename = */ nullptr, cx,
-                                      sandboxObj, true, v.address());
+                                      sandboxObj, true, &v);
 
         // Propagate and report exceptions that happened in the
         // sandbox.
         if (JS_IsExceptionPending(cx)) {
             JS_ReportPendingException(cx);
         }
     } else {
         // No need to use the sandbox, evaluate the script directly in
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -116,17 +116,17 @@ public:
 
 class AudioChannelVolInitCallback MOZ_FINAL : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   AudioChannelVolInitCallback() {}
 
-  NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
+  NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     nsCOMPtr<nsIAudioManager> audioManager =
       do_GetService(NS_AUDIOMANAGER_CONTRACTID);
     NS_ENSURE_TRUE(JSVAL_IS_INT(aResult), NS_OK);
 
     int32_t volIndex = JSVAL_TO_INT(aResult);
     if (aName.EqualsLiteral("audio.volume.content")) {
       audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_CONTENT, volIndex);
--- a/dom/system/gonk/AutoMounterSetting.cpp
+++ b/dom/system/gonk/AutoMounterSetting.cpp
@@ -36,17 +36,17 @@ namespace system {
 
 class SettingsServiceCallback MOZ_FINAL : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   SettingsServiceCallback() {}
 
-  NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
+  NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     if (JSVAL_IS_INT(aResult)) {
       int32_t mode = JSVAL_TO_INT(aResult);
       SetAutoMounterMode(mode);
     }
     return NS_OK;
   }
 
@@ -62,17 +62,17 @@ NS_IMPL_ISUPPORTS1(SettingsServiceCallba
 class CheckVolumeSettingsCallback MOZ_FINAL : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   CheckVolumeSettingsCallback(const nsACString& aVolumeName)
   : mVolumeName(aVolumeName) {}
 
-  NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
+  NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     if (JSVAL_IS_BOOLEAN(aResult)) {
       bool isSharingEnabled = JSVAL_TO_BOOLEAN(aResult);
       SetAutoMounterSharingMode(mVolumeName, isSharingEnabled);
     }
     return NS_OK;
   }
 
@@ -114,18 +114,22 @@ AutoMounterSetting::AutoMounterSetting()
     do_GetService("@mozilla.org/settingsService;1");
   if (!settingsService) {
     ERR("Failed to get settingsLock service!");
     return;
   }
   nsCOMPtr<nsISettingsServiceLock> lock;
   settingsService->CreateLock(getter_AddRefs(lock));
   nsCOMPtr<nsISettingsServiceCallback> callback = new SettingsServiceCallback();
-  lock->Set(UMS_MODE, INT_TO_JSVAL(AUTOMOUNTER_DISABLE), callback, nullptr);
-  lock->Set(UMS_STATUS, INT_TO_JSVAL(mStatus), nullptr, nullptr);
+  mozilla::AutoSafeJSContext cx;
+  JS::Rooted<JS::Value> value(cx);
+  value.setInt32(AUTOMOUNTER_DISABLE);
+  lock->Set(UMS_MODE, value, callback, nullptr);
+  value.setInt32(mStatus);
+  lock->Set(UMS_STATUS, value, nullptr, nullptr);
 }
 
 AutoMounterSetting::~AutoMounterSetting()
 {
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
   if (observerService) {
     observerService->RemoveObserver(this, MOZSETTINGS_CHANGED);
@@ -188,17 +192,19 @@ public:
     MOZ_ASSERT(NS_IsMainThread());
     nsCOMPtr<nsISettingsService> settingsService =
       do_GetService("@mozilla.org/settingsService;1");
     NS_ENSURE_TRUE(settingsService, NS_ERROR_FAILURE);
     nsCOMPtr<nsISettingsServiceLock> lock;
     settingsService->CreateLock(getter_AddRefs(lock));
     // lock may be null if this gets called during shutdown.
     if (lock) {
-      lock->Set(UMS_STATUS, INT_TO_JSVAL(mStatus), nullptr, nullptr);
+      mozilla::AutoSafeJSContext cx;
+      JS::Rooted<JS::Value> value(cx, JS::Int32Value(mStatus));
+      lock->Set(UMS_STATUS, value, nullptr, nullptr);
     }
     return NS_OK;
   }
 
 private:
   int32_t mStatus;
 };
 
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -718,17 +718,17 @@ GonkGPSGeolocationProvider::ReceiveDataC
 {
   return NS_OK;
 }
 
 /** nsISettingsServiceCallback **/
 
 NS_IMETHODIMP
 GonkGPSGeolocationProvider::Handle(const nsAString& aName,
-                                   const JS::Value& aResult)
+                                   JS::Handle<JS::Value> aResult)
 {
   if (aName.EqualsLiteral("ril.supl.apn")) {
     JSContext *cx = nsContentUtils::GetCurrentJSContext();
     NS_ENSURE_TRUE(cx, NS_OK);
 
     // When we get the APN, we attempt to call data_call_open of AGPS.
     if (aResult.isString()) {
       // NB: No need to enter a compartment to read the contents of a string.
--- a/dom/system/gonk/SystemWorkerManager.cpp
+++ b/dom/system/gonk/SystemWorkerManager.cpp
@@ -338,47 +338,47 @@ SystemWorkerManager::GetInterface(const 
   }
 
   NS_WARNING("Got nothing for the requested IID!");
   return NS_ERROR_NO_INTERFACE;
 }
 
 nsresult
 SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
-                                       const JS::Value& aWorker,
+                                       JS::Handle<JS::Value> aWorker,
                                        JSContext *aCx)
 {
 #ifndef MOZ_B2G_RIL
   return NS_ERROR_NOT_IMPLEMENTED;
 #else
-  NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(aWorker), NS_ERROR_UNEXPECTED);
+  NS_ENSURE_TRUE(aWorker.isObject(), NS_ERROR_UNEXPECTED);
 
-  JSAutoCompartment ac(aCx, JSVAL_TO_OBJECT(aWorker));
+  JSAutoCompartment ac(aCx, &aWorker.toObject());
 
   WorkerCrossThreadDispatcher *wctd =
     GetWorkerCrossThreadDispatcher(aCx, aWorker);
   if (!wctd) {
     NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for ril");
     return NS_ERROR_FAILURE;
   }
 
   return RilConsumer::Register(aClientId, wctd);
 #endif // MOZ_B2G_RIL
 }
 
 nsresult
-SystemWorkerManager::RegisterNfcWorker(const JS::Value& aWorker,
+SystemWorkerManager::RegisterNfcWorker(JS::Handle<JS::Value> aWorker,
                                        JSContext* aCx)
 {
 #ifndef MOZ_NFC
   return NS_ERROR_NOT_IMPLEMENTED;
 #else
-  NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(aWorker), NS_ERROR_UNEXPECTED);
+  NS_ENSURE_TRUE(aWorker.isObject(), NS_ERROR_UNEXPECTED);
 
-  JSAutoCompartment ac(aCx, JSVAL_TO_OBJECT(aWorker));
+  JSAutoCompartment ac(aCx, &aWorker.toObject());
 
   WorkerCrossThreadDispatcher* wctd =
     GetWorkerCrossThreadDispatcher(aCx, aWorker);
   if (!wctd) {
     NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for nfc");
     return NS_ERROR_FAILURE;
   }
 
@@ -387,22 +387,22 @@ SystemWorkerManager::RegisterNfcWorker(c
 }
 
 nsresult
 SystemWorkerManager::InitNetd(JSContext *cx)
 {
   nsCOMPtr<nsIWorkerHolder> worker = do_GetService(kNetworkServiceCID);
   NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
 
-  JS::Value workerval;
+  JS::Rooted<JS::Value> workerval(cx);
   nsresult rv = worker->GetWorker(&workerval);
   NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(workerval), NS_ERROR_UNEXPECTED);
+  NS_ENSURE_TRUE(workerval.isObject(), NS_ERROR_UNEXPECTED);
 
-  JSAutoCompartment ac(cx, JSVAL_TO_OBJECT(workerval));
+  JSAutoCompartment ac(cx, &workerval.toObject());
 
   WorkerCrossThreadDispatcher *wctd =
     GetWorkerCrossThreadDispatcher(cx, workerval);
   if (!wctd) {
     NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for netd");
     return NS_ERROR_FAILURE;
   }
 
--- a/dom/system/gonk/TimeZoneSettingObserver.cpp
+++ b/dom/system/gonk/TimeZoneSettingObserver.cpp
@@ -47,17 +47,17 @@ public:
 
 class TimeZoneSettingCb MOZ_FINAL : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   TimeZoneSettingCb() {}
 
-  NS_IMETHOD Handle(const nsAString &aName, const JS::Value &aResult) {
+  NS_IMETHOD Handle(const nsAString &aName, JS::Handle<JS::Value> aResult) {
 
     JSContext *cx = nsContentUtils::GetCurrentJSContext();
     NS_ENSURE_TRUE(cx, NS_OK);
 
     // If we don't have time.timezone value in the settings, we need
     // to initialize the settings based on the current system timezone
     // to make settings consistent with system. This usually happens
     // at the very first boot. After that, settings must have a value.
@@ -69,28 +69,34 @@ public:
       int32_t timeZoneOffset = hal::GetTimezoneOffset();
       nsPrintfCString curTimeZone("UTC%+03d:%02d",
                                   -timeZoneOffset / 60,
                                   abs(timeZoneOffset) % 60);
 
       // Convert it to a JS string.
       NS_ConvertUTF8toUTF16 utf16Str(curTimeZone);
 
-      JSString *jsStr = JS_NewUCStringCopyN(cx, utf16Str.get(), utf16Str.Length());
+      JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx,
+                                                          utf16Str.get(),
+                                                          utf16Str.Length()));
+      if (!jsStr) {
+        return NS_ERROR_OUT_OF_MEMORY;
+      }
 
       // Set the settings based on the current system timezone.
       nsCOMPtr<nsISettingsServiceLock> lock;
       nsCOMPtr<nsISettingsService> settingsService =
         do_GetService("@mozilla.org/settingsService;1");
       if (!settingsService) {
         ERR("Failed to get settingsLock service!");
         return NS_OK;
       }
       settingsService->CreateLock(getter_AddRefs(lock));
-      lock->Set(TIME_TIMEZONE, STRING_TO_JSVAL(jsStr), nullptr, nullptr);
+      JS::Rooted<JS::Value> value(cx, JS::StringValue(jsStr));
+      lock->Set(TIME_TIMEZONE, value, nullptr, nullptr);
       return NS_OK;
     }
 
     // Set the system timezone based on the current settings.
     if (aResult.isString()) {
       return TimeZoneSettingObserver::SetTimeZone(aResult, cx);
     }
 
--- a/dom/wifi/WifiProxyService.cpp
+++ b/dom/wifi/WifiProxyService.cpp
@@ -232,24 +232,24 @@ WifiProxyService::Shutdown()
   if (mControlThread) {
     mControlThread->Shutdown();
     mControlThread = nullptr;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-WifiProxyService::SendCommand(const JS::Value& aOptions, const nsACString& aInterface,
+WifiProxyService::SendCommand(JS::Handle<JS::Value> aOptions,
+                              const nsACString& aInterface,
                               JSContext* aCx)
 {
   MOZ_ASSERT(NS_IsMainThread());
   WifiCommandOptions options;
 
-  if (!options.Init(aCx,
-                    JS::Handle<JS::Value>::fromMarkedLocation(&aOptions))) {
+  if (!options.Init(aCx, aOptions)) {
     NS_WARNING("Bad dictionary passed to WifiProxyService::SendCommand");
     return NS_ERROR_FAILURE;
   }
 
   // Dispatch the command to the control thread.
   CommandOptions commandOptions(options);
   nsCOMPtr<nsIRunnable> runnable = new ControlRunnable(commandOptions, aInterface);
   mControlThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -405,22 +405,19 @@ private:
 
   static bool
   GetLastModifiedDateImpl(JSContext* aCx, JS::CallArgs aArgs)
   {
     JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
     nsIDOMFile* file = GetInstancePrivate(aCx, obj, "lastModifiedDate");
     MOZ_ASSERT(file);
 
-    JS::Rooted<JS::Value> value(aCx);
-    if (NS_FAILED(file->GetLastModifiedDate(aCx, value.address()))) {
+    if (NS_FAILED(file->GetLastModifiedDate(aCx, aArgs.rval()))) {
       return false;
     }
-
-    aArgs.rval().set(value);
     return true;
   }
 
   static bool
   GetLastModifiedDate(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
     JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
     return JS::CallNonGenericMethod<IsFile, GetLastModifiedDateImpl>(aCx, args);
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1154,17 +1154,17 @@ EventRunnable::PreDispatch(JSContext* aC
   if (NS_SUCCEEDED(mResponseTextResult)) {
     mResponseResult = mResponseTextResult;
     if (mResponseText.IsVoid()) {
       mResponse = JSVAL_NULL;
     }
   }
   else {
     JS::Rooted<JS::Value> response(aCx);
-    mResponseResult = xhr->GetResponse(aCx, response.address());
+    mResponseResult = xhr->GetResponse(aCx, &response);
     if (NS_SUCCEEDED(mResponseResult)) {
       if (JSVAL_IS_UNIVERSAL(response)) {
         mResponse = response;
       }
       else {
         // Anything subject to GC must be cloned.
         JSStructuredCloneCallbacks* callbacks =
           aWorkerPrivate->IsChromeWorker() ?
@@ -1454,18 +1454,17 @@ SendRunnable::MainThreadRun()
 
     JSStructuredCloneCallbacks* callbacks =
       mWorkerPrivate->IsChromeWorker() ?
       ChromeWorkerStructuredCloneCallbacks(true) :
       WorkerStructuredCloneCallbacks(true);
 
     JS::Rooted<JS::Value> body(cx);
     if (mBody.read(cx, &body, callbacks, &mClonedObjects)) {
-      if (NS_FAILED(xpc->JSValToVariant(cx, body.address(),
-                                        getter_AddRefs(variant)))) {
+      if (NS_FAILED(xpc->JSValToVariant(cx, body, getter_AddRefs(variant)))) {
         rv = NS_ERROR_DOM_INVALID_STATE_ERR;
       }
     }
     else {
       rv = NS_ERROR_DOM_DATA_CLONE_ERR;
     }
 
     mBody.clear();
--- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
@@ -357,17 +357,18 @@ nsDocShellTreeOwner::GetPrimaryContentSh
 
    *aShell = (mPrimaryContentShell ? mPrimaryContentShell : mWebBrowser->mDocShell);
    NS_IF_ADDREF(*aShell);
 
    return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShellTreeOwner::GetContentWindow(JSContext* aCx, JS::Value* aVal)
+nsDocShellTreeOwner::GetContentWindow(JSContext* aCx,
+                                      JS::MutableHandle<JS::Value> aVal)
 {
   if (mTreeOwner)
     return mTreeOwner->GetContentWindow(aCx, aVal);
 
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -113,14 +113,14 @@ nsresult EvaluateAdminConfigScript(const
     }
 
     AutoSafeJSContext cx;
     JSAutoCompartment ac(cx, autoconfigSb);
 
     nsAutoCString script(js_buffer, length);
     JS::RootedValue v(cx);
     rv = xpc->EvalInSandboxObject(NS_ConvertASCIItoUTF16(script), filename, cx, autoconfigSb,
-                                  /* returnStringOnly = */ false, v.address());
+                                  /* returnStringOnly = */ false, &v);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
--- a/gfx/src/nsScriptableRegion.cpp
+++ b/gfx/src/nsScriptableRegion.cpp
@@ -122,31 +122,31 @@ NS_IMETHODIMP nsScriptableRegion::Contai
 
 
 NS_IMETHODIMP nsScriptableRegion::GetRegion(nsIntRegion* outRgn)
 {
   *outRgn = mRegion;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::Value* aRects)
+NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::MutableHandle<JS::Value> aRects)
 {
   uint32_t numRects = mRegion.GetNumRects();
 
   if (!numRects) {
-    *aRects = JSVAL_NULL;
+    aRects.setNull();
     return NS_OK;
   }
 
   JS::Rooted<JSObject*> destArray(aCx, JS_NewArrayObject(aCx, numRects * 4, nullptr));
   if (!destArray) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  *aRects = OBJECT_TO_JSVAL(destArray);
+  aRects.setObject(*destArray);
 
   uint32_t n = 0;
   nsIntRegionRectIterator iter(mRegion);
   const nsIntRect *rect;
 
   while ((rect = iter.Next())) {
     if (!JS_DefineElement(aCx, destArray, n, INT_TO_JSVAL(rect->x), nullptr, nullptr, JSPROP_ENUMERATE) ||
         !JS_DefineElement(aCx, destArray, n + 1, INT_TO_JSVAL(rect->y), nullptr, nullptr, JSPROP_ENUMERATE) ||
--- a/js/ductwork/debugger/JSDebugger.cpp
+++ b/js/ductwork/debugger/JSDebugger.cpp
@@ -31,17 +31,17 @@ JSDebugger::JSDebugger()
 {
 }
 
 JSDebugger::~JSDebugger()
 {
 }
 
 NS_IMETHODIMP
-JSDebugger::AddClass(const JS::Value &global, JSContext* cx)
+JSDebugger::AddClass(JS::Handle<JS::Value> global, JSContext* cx)
 {
   nsresult rv;
   nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
 
   if (!global.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -2359,26 +2359,24 @@ NS_IMETHODIMP
 jsdValue::Refresh()
 {
     ASSERT_VALID_EPHEMERAL;
     JSD_RefreshValue (mCx, mValue);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-jsdValue::GetWrappedValue(JSContext* aCx, JS::Value* aRetval)
+jsdValue::GetWrappedValue(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval)
 {
     ASSERT_VALID_EPHEMERAL;
 
-    JS::RootedValue value(aCx, JSD_GetValueWrappedJSVal(mCx, mValue));
-    if (!JS_WrapValue(aCx, &value)) {
+    aRetval.set(JSD_GetValueWrappedJSVal(mCx, mValue));
+    if (!JS_WrapValue(aCx, aRetval))
         return NS_ERROR_FAILURE;
-    }
-
-    *aRetval = value;
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 jsdValue::GetScript(jsdIScript **_rval)
 {
     ASSERT_VALID_EPHEMERAL;
     JSDScript *script = JSD_GetScriptForValue(mCx, mValue);
@@ -2982,17 +2980,17 @@ jsdService::ClearAllBreakpoints (void)
 
     JSD_LockScriptSubsystem(mCx);
     JSD_ClearAllExecutionHooks (mCx);
     JSD_UnlockScriptSubsystem(mCx);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-jsdService::WrapValue(const JS::Value &value, jsdIValue **_rval)
+jsdService::WrapValue(JS::Handle<JS::Value> value, jsdIValue **_rval)
 {
     ASSERT_VALID_CONTEXT;
     JSDValue *jsdv = JSD_NewValue(mCx, value);
     if (!jsdv)
         return NS_ERROR_FAILURE;
     
     *_rval = jsdValue::FromPtr (mCx, jsdv);
     return NS_OK;
--- a/js/xpconnect/idl/nsIXPConnect.idl
+++ b/js/xpconnect/idl/nsIXPConnect.idl
@@ -21,17 +21,16 @@ class nsAXPCNativeCallContext;
 /***************************************************************************/
 
 // NB: jsval and jsid are declared in nsrootidl.idl
 
 [ptr] native JSContextPtr(JSContext);
 [ptr] native JSClassPtr(JSClass);
 [ptr] native JSFreeOpPtr(JSFreeOp);
 [ptr] native JSObjectPtr(JSObject);
-[ptr] native JSValPtr(JS::Value);
 [ptr] native JSValConstPtr(const JS::Value);
       native JSPropertyOp(JSPropertyOp);
       native JSEqualityOp(JSEqualityOp);
 [ptr] native JSScriptPtr(JSScript);
 [ptr] native voidPtrPtr(void*);
 [ptr] native nsAXPCNativeCallContextPtr(nsAXPCNativeCallContext);
 [ptr] native nsWrapperCachePtr(nsWrapperCache);
 [ref] native JSCompartmentOptions(JS::CompartmentOptions);
@@ -404,17 +403,17 @@ interface nsIXPConnect : nsISupports
            in JSObjectPtr  aJSObj,
            in nsIIDRef     aIID,
            [iid_is(aIID),retval] out nsQIResult result);
 
     /**
      * Wraps the given jsval in a nsIVariant and returns the new variant.
      */
     nsIVariant
-    jSValToVariant(in JSContextPtr cx, in JSValPtr aJSVal);
+    jSValToVariant(in JSContextPtr cx, in jsval aJSVal);
 
     /**
     * This only succeeds if the JSObject is a nsIXPConnectWrappedNative.
     * A new wrapper is *never* constructed.
     */
     nsIXPConnectWrappedNative
     getWrappedNativeOfJSObject(in JSContextPtr aJSContext,
                                in JSObjectPtr  aJSObj);
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -172,17 +172,17 @@ File(JSContext *cx, unsigned argc, Value
     }
 
     nsXPConnect* xpc = nsXPConnect::XPConnect();
     JSObject* glob = CurrentGlobalOrNull(cx);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
                                 &NS_GET_IID(nsISupports),
-                                true, args.rval().address());
+                                true, args.rval());
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
         return false;
     }
     return true;
 }
 
 static bool
@@ -207,17 +207,17 @@ Blob(JSContext *cx, unsigned argc, Value
     }
 
     nsXPConnect* xpc = nsXPConnect::XPConnect();
     JSObject* glob = CurrentGlobalOrNull(cx);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
                                 &NS_GET_IID(nsISupports),
-                                true, args.rval().address());
+                                true, args.rval());
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
         return false;
     }
     return true;
 }
 
 static const JSFunctionSpec gGlobalFun[] = {
@@ -1079,20 +1079,20 @@ mozJSComponentLoader::UnloadModules()
     JS_DestroyContextNoGC(mContext);
     mContext = nullptr;
 
     mRuntimeService = nullptr;
 }
 
 NS_IMETHODIMP
 mozJSComponentLoader::Import(const nsACString& registryLocation,
-                             const Value& targetValArg,
-                             JSContext* cx,
+                             HandleValue targetValArg,
+                             JSContext *cx,
                              uint8_t optionalArgc,
-                             Value* retval)
+                             MutableHandleValue retval)
 {
     MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 
     RootedValue targetVal(cx, targetValArg);
     RootedObject targetObject(cx, nullptr);
     if (optionalArgc) {
         // The caller passed in the optional second argument. Get it.
         if (targetVal.isObject()) {
@@ -1128,17 +1128,17 @@ mozJSComponentLoader::Import(const nsACS
     nsresult rv = ImportInto(registryLocation, targetObject, cx, &global);
 
     if (global) {
         if (!JS_WrapObject(cx, &global)) {
             NS_ERROR("can't wrap return value");
             return NS_ERROR_FAILURE;
         }
 
-        *retval = ObjectValue(*global);
+        retval.setObject(*global);
     }
     return rv;
 }
 
 /* [noscript] JSObjectPtr importInto(in AUTF8String registryLocation,
                                      in JSObjectPtr targetObj); */
 NS_IMETHODIMP
 mozJSComponentLoader::ImportInto(const nsACString & aLocation,
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -179,55 +179,58 @@ mozJSSubScriptLoader::ReadScript(nsIURI 
     /* repent for our evil deeds */
     JS_SetErrorReporter(cx, er);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
-                                    const Value& targetArg,
+                                    HandleValue target,
                                     const nsAString& charset,
-                                    JSContext* cx,
-                                    Value* retval)
+                                    JSContext *cx,
+                                    MutableHandleValue retval)
 {
     /*
      * Loads a local url and evals it into the current cx
      * Synchronous (an async version would be cool too.)
      *   url: The url to load.  Must be local so that it can be loaded
      *        synchronously.
      *   target_obj: Optional object to eval the script onto (defaults to context
      *               global)
      *   charset: Optional character set to use for reading
      *   returns: Whatever jsval the script pointed to by the url returns.
      * Should ONLY (O N L Y !) be called from JavaScript code.
      */
     LoadSubScriptOptions options(cx);
     options.charset = charset;
-    options.target = targetArg.isObject() ? &targetArg.toObject() : nullptr;
+    options.target = target.isObject() ? &target.toObject() : nullptr;
     return DoLoadSubScriptWithOptions(url, options, cx, retval);
 }
 
 
 NS_IMETHODIMP
-mozJSSubScriptLoader::LoadSubScriptWithOptions(const nsAString& url, const Value& optionsVal,
-                                               JSContext* cx, Value* retval)
+mozJSSubScriptLoader::LoadSubScriptWithOptions(const nsAString& url,
+                                               HandleValue optionsVal,
+                                               JSContext *cx,
+                                               MutableHandleValue retval)
 {
     if (!optionsVal.isObject())
         return NS_ERROR_INVALID_ARG;
     LoadSubScriptOptions options(cx, &optionsVal.toObject());
     if (!options.Parse())
         return NS_ERROR_INVALID_ARG;
     return DoLoadSubScriptWithOptions(url, options, cx, retval);
 }
 
 nsresult
 mozJSSubScriptLoader::DoLoadSubScriptWithOptions(const nsAString& url,
                                                  LoadSubScriptOptions& options,
-                                                 JSContext* cx, Value* retval)
+                                                 JSContext *cx,
+                                                 MutableHandleValue retval)
 {
     nsresult rv = NS_OK;
 
     /* set the system principal if it's not here already */
     if (!mSystemPrincipal) {
         nsCOMPtr<nsIScriptSecurityManager> secman =
             do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
         if (!secman)
@@ -341,29 +344,28 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
         return rv;
 
     if (function) {
         script = JS_GetFunctionScript(cx, function);
     }
 
     loader->NoteSubScript(script, targetObj);
 
-    RootedValue rval(cx);
+
     bool ok = false;
     if (function) {
-        ok = JS_CallFunction(cx, targetObj, function, 0, nullptr, rval.address());
+        ok = JS_CallFunction(cx, targetObj, function, 0, nullptr, retval.address());
     } else {
-        ok = JS_ExecuteScriptVersion(cx, targetObj, script, rval.address(), version);
+        ok = JS_ExecuteScriptVersion(cx, targetObj, script, retval.address(), version);
     }
 
     if (ok) {
         JSAutoCompartment rac(cx, result_obj);
-        if (!JS_WrapValue(cx, &rval))
+        if (!JS_WrapValue(cx, retval))
             return NS_ERROR_UNEXPECTED;
-        *retval = rval;
     }
 
     if (cache && ok && writeScript) {
         WriteCachedScript(cache, cachePath, cx, mSystemPrincipal, script);
     }
 
     return NS_OK;
 }
--- a/js/xpconnect/loader/mozJSSubScriptLoader.h
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.h
@@ -35,12 +35,13 @@ private:
     nsresult ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj,
                         const nsAString& charset, const char *uriStr,
                         nsIIOService *serv, nsIPrincipal *principal,
                         bool reuseGlobal, JSScript **scriptp,
                         JSFunction **functionp);
 
     nsresult DoLoadSubScriptWithOptions(const nsAString& url,
                                         LoadSubScriptOptions& options,
-                                        JSContext* cx, JS::Value* retval);
+                                        JSContext* cx,
+                                        JS::MutableHandle<JS::Value> retval);
 
     nsCOMPtr<nsIPrincipal> mSystemPrincipal;
 };
--- a/js/xpconnect/public/xpc_map_end.h
+++ b/js/xpconnect/public/xpc_map_end.h
@@ -165,17 +165,17 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::Call(ns
 #endif
 
 #ifndef XPC_MAP_WANT_CONSTRUCT
 NS_IMETHODIMP XPC_MAP_CLASSNAME::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, const JS::CallArgs &args, bool *_retval)
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
 #ifndef XPC_MAP_WANT_HASINSTANCE
-NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, const JS::Value &val, bool *bp, bool *_retval)
+NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JS::HandleValue val, bool *bp, bool *_retval)
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
 #ifndef XPC_MAP_WANT_OUTER_OBJECT
 NS_IMETHODIMP XPC_MAP_CLASSNAME::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JSObject * *_retval)
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -1519,21 +1519,20 @@ nsXPCComponents_ID::CallOrConstruct(nsIX
     args.rval().setObject(*newobj);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsXPCComponents_ID::HasInstance(nsIXPConnectWrappedNative *wrapper,
                                 JSContext *cx, JSObject *obj,
-                                const jsval &val, bool *bp, bool *_retval)
+                                HandleValue val, bool *bp, bool *_retval)
 {
-    RootedValue v(cx, val);
     if (bp)
-        *bp = JSValIsInterfaceOfType(cx, v, NS_GET_IID(nsIJSID));
+        *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIJSID));
     return NS_OK;
 }
 
 /***************************************************************************/
 // JavaScript Constructor for nsIXPCException objects (Components.Exception)
 
 class nsXPCComponents_Exception :
   public nsIXPCComponents_Exception,
@@ -1885,17 +1884,17 @@ nsXPCComponents_Exception::CallOrConstru
     args.rval().setObject(*newObj);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsXPCComponents_Exception::HasInstance(nsIXPConnectWrappedNative *wrapper,
                                        JSContext * cx, JSObject * obj,
-                                       const jsval &val, bool *bp,
+                                       HandleValue val, bool *bp,
                                        bool *_retval)
 {
     using namespace mozilla::dom;
 
     RootedValue v(cx, val);
     if (bp) {
         Exception* e;
         *bp = NS_SUCCEEDED(UNWRAP_OBJECT(Exception, v.toObjectOrNull(), e)) ||
@@ -2489,22 +2488,21 @@ nsXPCComponents_Constructor::CallOrConst
     args.rval().setObject(*newObj);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsXPCComponents_Constructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
                                          JSContext * cx, JSObject * obj,
-                                         const jsval &val, bool *bp,
+                                         HandleValue val, bool *bp,
                                          bool *_retval)
 {
-    RootedValue v(cx, val);
     if (bp)
-        *bp = JSValIsInterfaceOfType(cx, v, NS_GET_IID(nsIXPCConstructor));
+        *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIXPCConstructor));
     return NS_OK;
 }
 
 class nsXPCComponents_Utils :
             public nsIXPCComponents_Utils,
             public nsIXPCScriptable
 {
 public:
@@ -2544,20 +2542,18 @@ nsXPCComponents_Utils::GetSandbox(nsIXPC
         mSandbox = NewSandboxConstructor();
 
     NS_ADDREF(*aSandbox = mSandbox);
     return NS_OK;
 }
 
 /* void reportError (); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::ReportError(const Value &errorArg, JSContext *cx)
+nsXPCComponents_Utils::ReportError(HandleValue error, JSContext *cx)
 {
-    RootedValue error(cx, errorArg);
-
     // This function shall never fail! Silently eat any failure conditions.
 
     nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
 
     nsCOMPtr<nsIScriptError> scripterr(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
 
     if (!scripterr || !console)
         return NS_OK;
@@ -2617,26 +2613,24 @@ nsXPCComponents_Utils::ReportError(const
 
     console->LogMessage(scripterr);
     return NS_OK;
 }
 
 /* void evalInSandbox(in AString source, in nativeobj sandbox); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
-                                     const Value& sandboxValArg,
-                                     const Value& versionArg,
-                                     const Value& filenameVal,
+                                     HandleValue sandboxVal,
+                                     HandleValue version,
+                                     HandleValue filenameVal,
                                      int32_t lineNumber,
                                      JSContext *cx,
                                      uint8_t optionalArgc,
-                                     Value *retval)
+                                     MutableHandleValue retval)
 {
-    RootedValue sandboxVal(cx, sandboxValArg);
-    RootedValue version(cx, versionArg);
     RootedObject sandbox(cx);
     if (!JS_ValueToObject(cx, sandboxVal, &sandbox) || !sandbox)
         return NS_ERROR_INVALID_ARG;
 
     // Optional third argument: JS version, as a string.
     JSVersion jsVersion = JSVERSION_DEFAULT;
     if (optionalArgc >= 1) {
         JSString *jsVersionStr = ToString(cx, version);
@@ -2658,18 +2652,17 @@ nsXPCComponents_Utils::EvalInSandbox(con
         if (jsVersion == JSVERSION_UNKNOWN)
             return NS_ERROR_INVALID_ARG;
     }
 
     // Optional fourth and fifth arguments: filename and line number.
     nsXPIDLCString filename;
     int32_t lineNo = (optionalArgc >= 3) ? lineNumber : 1;
     if (optionalArgc >= 2) {
-        RootedValue value(cx, filenameVal);
-        JSString *filenameStr = ToString(cx, value);
+        JSString *filenameStr = ToString(cx, filenameVal);
         if (!filenameStr)
             return NS_ERROR_INVALID_ARG;
 
         JSAutoByteString filenameBytes;
         if (!filenameBytes.encodeLatin1(cx, filenameStr))
             return NS_ERROR_INVALID_ARG;
         filename = filenameBytes.ptr();
     } else {
@@ -2681,73 +2674,63 @@ nsXPCComponents_Utils::EvalInSandbox(con
         nsCOMPtr<nsIStackFrame> frame;
         xpc->GetCurrentJSStack(getter_AddRefs(frame));
         if (frame) {
             frame->GetFilename(getter_Copies(filename));
             frame->GetLineNumber(&lineNo);
         }
     }
 
-    RootedValue rval(cx);
-    nsresult rv = xpc::EvalInSandbox(cx, sandbox, source, filename.get(), lineNo,
-                                     jsVersion, false, &rval);
-    NS_ENSURE_SUCCESS(rv, rv);
-    *retval = rval;
-    return NS_OK;
+    return xpc::EvalInSandbox(cx, sandbox, source, filename.get(), lineNo,
+                              jsVersion, false, retval);
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetSandboxMetadata(const Value &sandboxVal,
-                                          JSContext *cx, Value *rval)
+nsXPCComponents_Utils::GetSandboxMetadata(HandleValue sandboxVal,
+                                          JSContext *cx, MutableHandleValue rval)
 {
     if (!sandboxVal.isObject())
         return NS_ERROR_INVALID_ARG;
 
     RootedObject sandbox(cx, &sandboxVal.toObject());
     sandbox = js::CheckedUnwrap(sandbox);
     if (!sandbox || !xpc::IsSandbox(sandbox))
         return NS_ERROR_INVALID_ARG;
 
-    RootedValue metadata(cx);
-    nsresult rv = xpc::GetSandboxMetadata(cx, sandbox, &metadata);
-    NS_ENSURE_SUCCESS(rv, rv);
-    *rval = metadata;
-
-    return NS_OK;
+    return xpc::GetSandboxMetadata(cx, sandbox, rval);
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::SetSandboxMetadata(const Value &sandboxVal,
-                                          const Value &metadataVal,
+nsXPCComponents_Utils::SetSandboxMetadata(HandleValue sandboxVal,
+                                          HandleValue metadataVal,
                                           JSContext *cx)
 {
     if (!sandboxVal.isObject())
         return NS_ERROR_INVALID_ARG;
 
     RootedObject sandbox(cx, &sandboxVal.toObject());
     sandbox = js::CheckedUnwrap(sandbox);
     if (!sandbox || !xpc::IsSandbox(sandbox))
         return NS_ERROR_INVALID_ARG;
 
-    RootedValue metadata(cx, metadataVal);
-    nsresult rv = xpc::SetSandboxMetadata(cx, sandbox, metadata);
+    nsresult rv = xpc::SetSandboxMetadata(cx, sandbox, metadataVal);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
 /* JSObject import (in AUTF8String registryLocation,
  *                  [optional] in JSObject targetObj);
  */
 NS_IMETHODIMP
 nsXPCComponents_Utils::Import(const nsACString& registryLocation,
-                              const Value& targetObj,
+                              HandleValue targetObj,
                               JSContext* cx,
                               uint8_t optionalArgc,
-                              Value* retval)
+                              MutableHandleValue retval)
 {
     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
         do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
     if (!moduleloader)
         return NS_ERROR_FAILURE;
     return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
 }
 
@@ -2762,17 +2745,17 @@ nsXPCComponents_Utils::Unload(const nsAC
         return NS_ERROR_FAILURE;
     return moduleloader->Unload(registryLocation);
 }
 
 /*
  * JSObject importGlobalProperties (in jsval aPropertyList);
  */
 NS_IMETHODIMP
-nsXPCComponents_Utils::ImportGlobalProperties(const JS::Value& aPropertyList,
+nsXPCComponents_Utils::ImportGlobalProperties(HandleValue aPropertyList,
                                               JSContext* cx)
 {
     RootedObject global(cx, CurrentGlobalOrNull(cx));
     MOZ_ASSERT(global);
     GlobalProperties options;
     NS_ENSURE_TRUE(aPropertyList.isObject(), NS_ERROR_INVALID_ARG);
     RootedObject propertyList(cx, &aPropertyList.toObject());
     NS_ENSURE_TRUE(JS_IsArrayObject(cx, propertyList), NS_ERROR_INVALID_ARG);
@@ -2782,17 +2765,17 @@ nsXPCComponents_Utils::ImportGlobalPrope
         return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
 }
 
 /* xpcIJSWeakReference getWeakReference (); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetWeakReference(const Value &object, JSContext *cx,
+nsXPCComponents_Utils::GetWeakReference(HandleValue object, JSContext *cx,
                                         xpcIJSWeakReference **_retval)
 {
     nsRefPtr<xpcJSWeakReference> ref = new xpcJSWeakReference();
     nsresult rv = ref->Init(cx, object);
     NS_ENSURE_SUCCESS(rv, rv);
     ref.forget(_retval);
     return NS_OK;
 }
@@ -2871,74 +2854,73 @@ NS_IMETHODIMP
 nsXPCComponents_Utils::SchedulePreciseShrinkingGC(ScheduledGCCallback* aCallback)
 {
     nsRefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, true);
     return NS_DispatchToMainThread(event);
 }
 
 /* [implicit_jscontext] jsval nondeterministicGetWeakMapKeys(in jsval aMap); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(const Value &aMap,
+nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(HandleValue aMap,
                                                       JSContext *aCx,
-                                                      Value *aKeys)
+                                                      MutableHandleValue aKeys)
 {
     if (!aMap.isObject()) {
-        aKeys->setUndefined();
+        aKeys.setUndefined();
         return NS_OK;
     }
     RootedObject objRet(aCx);
     if (!JS_NondeterministicGetWeakMapKeys(aCx, &aMap.toObject(), objRet.address()))
         return NS_ERROR_OUT_OF_MEMORY;
-    *aKeys = objRet ? ObjectValue(*objRet) : UndefinedValue();
+     aKeys.set(objRet ? ObjectValue(*objRet) : UndefinedValue());
     return NS_OK;
 }
 
 /* void getDebugObject(); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::GetJSTestingFunctions(JSContext *cx,
-                                             Value *retval)
+                                             MutableHandleValue retval)
 {
     JSObject *obj = js::GetTestingFunctions(cx);
     if (!obj)
         return NS_ERROR_XPC_JAVASCRIPT_ERROR;
-    *retval = OBJECT_TO_JSVAL(obj);
+    retval.setObject(*obj);
     return NS_OK;
 }
 
 /* void getGlobalForObject(); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetGlobalForObject(const Value& object,
+nsXPCComponents_Utils::GetGlobalForObject(HandleValue object,
                                           JSContext *cx,
-                                          Value *retval)
+                                          MutableHandleValue retval)
 {
     // First argument must be an object.
-    if (JSVAL_IS_PRIMITIVE(object))
+    if (object.isPrimitive())
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
     // Wrappers are parented to their the global in their home compartment. But
     // when getting the global for a cross-compartment wrapper, we really want
     // a wrapper for the foreign global. So we need to unwrap before getting the
     // parent, enter the compartment for the duration of the call, and wrap the
     // result.
-    Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(object));
+    Rooted<JSObject*> obj(cx, &object.toObject());
     obj = js::UncheckedUnwrap(obj);
     {
         JSAutoCompartment ac(cx, obj);
         obj = JS_GetGlobalForObject(cx, obj);
     }
 
     if (!JS_WrapObject(cx, &obj))
         return NS_ERROR_FAILURE;
 
-    *retval = OBJECT_TO_JSVAL(obj);
-
     // Outerize if necessary.
     if (JSObjectOp outerize = js::GetObjectClass(obj)->ext.outerObject)
-      *retval = OBJECT_TO_JSVAL(outerize(cx, obj));
-
+      obj = outerize(cx, obj);
+
+    retval.setObject(*obj);
     return NS_OK;
 }
 
 /* jsval createObjectIn(in jsval vobj); */
 bool
 xpc::CreateObjectIn(JSContext *cx, HandleValue vobj, CreateObjectInOptions &options,
                     MutableHandleValue rval)
 {
@@ -2979,89 +2961,79 @@ xpc::CreateObjectIn(JSContext *cx, Handl
     if (!WrapperFactory::WaiveXrayAndWrap(cx, rval))
         return false;
 
     return true;
 }
 
 /* boolean isProxy(in value vobj); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::IsProxy(const Value &vobj, JSContext *cx, bool *rval)
+nsXPCComponents_Utils::IsProxy(HandleValue vobj, JSContext *cx, bool *rval)
 {
     if (!vobj.isObject()) {
         *rval = false;
         return NS_OK;
     }
 
     RootedObject obj(cx, &vobj.toObject());
     obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
     NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
 
     *rval = js::IsScriptedProxy(obj);
     return NS_OK;
 }
 
 /* jsval evalInWindow(in string source, in jsval window); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::EvalInWindow(const nsAString &source, const Value &window,
-                                    JSContext *cx, Value *rval)
+nsXPCComponents_Utils::EvalInWindow(const nsAString &source, HandleValue window,
+                                    JSContext *cx, MutableHandleValue rval)
 {
     if (!window.isObject())
         return NS_ERROR_INVALID_ARG;
 
     RootedObject rwindow(cx, &window.toObject());
-    RootedValue res(cx);
-    if (!xpc::EvalInWindow(cx, source, rwindow, &res))
+    if (!xpc::EvalInWindow(cx, source, rwindow, rval))
         return NS_ERROR_FAILURE;
-
-    *rval = res;
     return NS_OK;
 }
 
 /* jsval exportFunction(in jsval vfunction, in jsval vscope, in jsval vname); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::ExportFunction(const Value &vfunction, const Value &vscope,
-                                      const Value &voptions, JSContext *cx, Value *rval)
+nsXPCComponents_Utils::ExportFunction(HandleValue vfunction, HandleValue vscope,
+                                      HandleValue voptions, JSContext *cx,
+                                      MutableHandleValue rval)
 {
-    RootedValue rfunction(cx, vfunction);
-    RootedValue rscope(cx, vscope);
-    RootedValue roptions(cx, voptions);
-    RootedValue res(cx);
-    if (!xpc::ExportFunction(cx, rfunction, rscope, roptions, &res))
+    if (!xpc::ExportFunction(cx, vfunction, vscope, voptions, rval))
         return NS_ERROR_FAILURE;
-    *rval = res;
     return NS_OK;
 }
 
 /* jsval createObjectIn(in jsval vobj, [optional] in jsval voptions); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::CreateObjectIn(const Value &vobj, const Value &voptions,
-                                      JSContext *cx, Value *rval)
+nsXPCComponents_Utils::CreateObjectIn(HandleValue vobj, HandleValue voptions,
+                                      JSContext *cx, MutableHandleValue rval)
 {
     RootedObject optionsObject(cx, voptions.isObject() ? &voptions.toObject()
                                                        : nullptr);
     CreateObjectInOptions options(cx, optionsObject);
     if (voptions.isObject() &&
         !options.Parse())
     {
         return NS_ERROR_FAILURE;
     }
 
-    RootedValue rvobj(cx, vobj);
-    RootedValue res(cx);
-    if (!xpc::CreateObjectIn(cx, rvobj, options, &res))
+    if (!xpc::CreateObjectIn(cx, vobj, options, rval))
         return NS_ERROR_FAILURE;
-
-    *rval = res;
     return NS_OK;
 }
 
 /* jsval createObjectIn(in jsval vobj); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::CreateArrayIn(const Value &vobj, JSContext *cx, Value *rval)
+nsXPCComponents_Utils::CreateArrayIn(HandleValue vobj, JSContext *cx,
+                                     MutableHandleValue rval)
 {
     if (!cx)
         return NS_ERROR_FAILURE;
 
     // first argument must be an object
     if (vobj.isPrimitive())
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
@@ -3072,23 +3044,24 @@ nsXPCComponents_Utils::CreateArrayIn(con
         obj =  JS_NewArrayObject(cx, 0, nullptr);
         if (!obj)
             return NS_ERROR_FAILURE;
     }
 
     if (!JS_WrapObject(cx, &obj))
         return NS_ERROR_FAILURE;
 
-    *rval = ObjectValue(*obj);
+    rval.setObject(*obj);
     return NS_OK;
 }
 
 /* jsval createDateIn(in jsval vobj, in long long msec); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::CreateDateIn(const Value &vobj, int64_t msec, JSContext *cx, Value *rval)
+nsXPCComponents_Utils::CreateDateIn(HandleValue vobj, int64_t msec, JSContext *cx,
+                                    MutableHandleValue rval)
 {
     if (!cx)
         return NS_ERROR_FAILURE;
 
     // first argument must be an object
     if (!vobj.isObject())
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
@@ -3099,23 +3072,23 @@ nsXPCComponents_Utils::CreateDateIn(cons
         obj =  JS_NewDateObjectMsec(cx, msec);
         if (!obj)
             return NS_ERROR_FAILURE;
     }
 
     if (!JS_WrapObject(cx, &obj))
         return NS_ERROR_FAILURE;
 
-    *rval = ObjectValue(*obj);
+    rval.setObject(*obj);
     return NS_OK;
 }
 
 /* void makeObjectPropsNormal(jsval vobj); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::MakeObjectPropsNormal(const Value &vobj, JSContext *cx)
+nsXPCComponents_Utils::MakeObjectPropsNormal(HandleValue vobj, JSContext *cx)
 {
     if (!cx)
         return NS_ERROR_FAILURE;
 
     // first argument must be an object
     if (vobj.isPrimitive())
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
@@ -3145,32 +3118,32 @@ nsXPCComponents_Utils::MakeObjectPropsNo
             !JS_SetPropertyById(cx, obj, id, v))
             return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::IsDeadWrapper(const jsval &obj, bool *out)
+nsXPCComponents_Utils::IsDeadWrapper(HandleValue obj, bool *out)
 {
     *out = false;
-    if (JSVAL_IS_PRIMITIVE(obj))
+    if (obj.isPrimitive())
         return NS_ERROR_INVALID_ARG;
 
     // Make sure to unwrap first. Once a proxy is nuked, it ceases to be a
     // wrapper, meaning that, if passed to another compartment, we'll generate
     // a CCW for it. Make sure that IsDeadWrapper sees through the confusion.
-    *out = JS_IsDeadWrapper(js::CheckedUnwrap(JSVAL_TO_OBJECT(obj)));
+    *out = JS_IsDeadWrapper(js::CheckedUnwrap(&obj.toObject()));
     return NS_OK;
 }
 
 /* void recomputerWrappers(jsval vobj); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::RecomputeWrappers(const jsval &vobj, JSContext *cx)
+nsXPCComponents_Utils::RecomputeWrappers(HandleValue vobj, JSContext *cx)
 {
     // Determine the compartment of the given object, if any.
     JSCompartment *c = vobj.isObject()
                        ? js::GetObjectCompartment(js::UncheckedUnwrap(&vobj.toObject()))
                        : nullptr;
 
     // If no compartment was given, recompute all.
     if (!c)
@@ -3180,67 +3153,67 @@ nsXPCComponents_Utils::RecomputeWrappers
         js::RecomputeWrappers(cx, js::SingleCompartment(c), js::AllCompartments()) &&
         js::RecomputeWrappers(cx, js::AllCompartments(), js::SingleCompartment(c));
 
     return NS_OK;
 }
 
 /* jsval setWantXrays(jsval vscope); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::SetWantXrays(const jsval &vscope, JSContext *cx)
+nsXPCComponents_Utils::SetWantXrays(HandleValue vscope, JSContext *cx)
 {
     if (!vscope.isObject())
         return NS_ERROR_INVALID_ARG;
     JSObject *scopeObj = js::UncheckedUnwrap(&vscope.toObject());
     JSCompartment *compartment = js::GetObjectCompartment(scopeObj);
     EnsureCompartmentPrivate(scopeObj)->wantXrays = true;
     bool ok = js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
                                     js::AllCompartments());
     NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
     return NS_OK;
 }
 
 /* jsval forcePrivilegedComponentsForScope(jsval vscope); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::ForcePrivilegedComponentsForScope(const jsval &vscope,
+nsXPCComponents_Utils::ForcePrivilegedComponentsForScope(HandleValue vscope,
                                                          JSContext *cx)
 {
     if (!vscope.isObject())
         return NS_ERROR_INVALID_ARG;
     JSObject *scopeObj = js::UncheckedUnwrap(&vscope.toObject());
     XPCWrappedNativeScope *scope = GetObjectScope(scopeObj);
     scope->ForcePrivilegedComponents();
     return NS_OK;
 }
 
 /* jsval getComponentsForScope(jsval vscope); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetComponentsForScope(const jsval &vscope, JSContext *cx,
-                                             jsval *rval)
+nsXPCComponents_Utils::GetComponentsForScope(HandleValue vscope, JSContext *cx,
+                                             MutableHandleValue rval)
 {
     if (!vscope.isObject())
         return NS_ERROR_INVALID_ARG;
     JSObject *scopeObj = js::UncheckedUnwrap(&vscope.toObject());
     XPCWrappedNativeScope *scope = GetObjectScope(scopeObj);
     RootedObject components(cx, scope->GetComponentsJSObject());
     if (!components)
         return NS_ERROR_FAILURE;
     if (!JS_WrapObject(cx, &components))
         return NS_ERROR_FAILURE;
-    *rval = ObjectValue(*components);
+    rval.setObject(*components);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::Dispatch(const jsval &runnableArg, const jsval &scope,
+nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope,
                                 JSContext *cx)
 {
+    RootedValue runnable(cx, runnableArg);
     // Enter the given compartment, if any, and rewrap runnable.
     Maybe<JSAutoCompartment> ac;
-    RootedValue runnable(cx, runnableArg);
     if (scope.isObject()) {
         JSObject *scopeObj = js::UncheckedUnwrap(&scope.toObject());
         if (!scopeObj)
             return NS_ERROR_FAILURE;
         ac.construct(cx, scopeObj);
         if (!JS_WrapValue(cx, &runnable))
             return NS_ERROR_FAILURE;
     }
@@ -3286,96 +3259,96 @@ nsXPCComponents_Utils::SetGCZeal(int32_t
 {
 #ifdef JS_GC_ZEAL
     JS_SetGCZeal(cx, uint8_t(aValue), JS_DEFAULT_ZEAL_FREQ);
 #endif
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::NukeSandbox(const Value &obj, JSContext *cx)
+nsXPCComponents_Utils::NukeSandbox(HandleValue obj, JSContext *cx)
 {
     NS_ENSURE_TRUE(obj.isObject(), NS_ERROR_INVALID_ARG);
     JSObject *wrapper = &obj.toObject();
     NS_ENSURE_TRUE(IsWrapper(wrapper), NS_ERROR_INVALID_ARG);
     JSObject *sb = UncheckedUnwrap(wrapper);
     NS_ENSURE_TRUE(IsSandbox(sb), NS_ERROR_INVALID_ARG);
     NukeCrossCompartmentWrappers(cx, AllCompartments(),
                                  SingleCompartment(GetObjectCompartment(sb)),
                                  NukeWindowReferences);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::BlockScriptForGlobal(const JS::Value &globalArg,
+nsXPCComponents_Utils::BlockScriptForGlobal(HandleValue globalArg,
                                             JSContext *cx)
 {
     NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG);
     RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(),
                                             /* stopAtOuter = */ false));
     NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG);
     if (nsContentUtils::IsSystemPrincipal(GetObjectPrincipal(global))) {
         JS_ReportError(cx, "Script may not be disabled for system globals");
         return NS_ERROR_FAILURE;
     }
     Scriptability::Get(global).Block();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::UnblockScriptForGlobal(const JS::Value &globalArg,
+nsXPCComponents_Utils::UnblockScriptForGlobal(HandleValue globalArg,
                                               JSContext *cx)
 {
     NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG);
     RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(),
                                             /* stopAtOuter = */ false));
     NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG);
     if (nsContentUtils::IsSystemPrincipal(GetObjectPrincipal(global))) {
         JS_ReportError(cx, "Script may not be disabled for system globals");
         return NS_ERROR_FAILURE;
     }
     Scriptability::Get(global).Unblock();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::IsXrayWrapper(const Value &obj, bool* aRetval)
+nsXPCComponents_Utils::IsXrayWrapper(HandleValue obj, bool* aRetval)
 {
     *aRetval =
         obj.isObject() && xpc::WrapperFactory::IsXrayWrapper(&obj.toObject());
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::WaiveXrays(const Value &aVal, JSContext *aCx, jsval *aRetval)
+nsXPCComponents_Utils::WaiveXrays(HandleValue aVal, JSContext *aCx, MutableHandleValue aRetval)
 {
     RootedValue value(aCx, aVal);
     if (!xpc::WrapperFactory::WaiveXrayAndWrap(aCx, &value))
         return NS_ERROR_FAILURE;
-    *aRetval = value;
+    aRetval.set(value);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::UnwaiveXrays(const Value &aVal, JSContext *aCx, jsval *aRetval)
+nsXPCComponents_Utils::UnwaiveXrays(HandleValue aVal, JSContext *aCx, MutableHandleValue aRetval)
 {
     if (!aVal.isObject()) {
-        *aRetval = aVal;
+        aRetval.set(aVal);
         return NS_OK;
     }
 
     RootedObject obj(aCx, js::UncheckedUnwrap(&aVal.toObject()));
     if (!JS_WrapObject(aCx, &obj))
         return NS_ERROR_FAILURE;
-    *aRetval = ObjectValue(*obj);
+    aRetval.setObject(*obj);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetClassName(const Value &aObj, bool aUnwrap, JSContext *aCx, char **aRv)
+nsXPCComponents_Utils::GetClassName(HandleValue aObj, bool aUnwrap, JSContext *aCx, char **aRv)
 {
     if (!aObj.isObject())
         return NS_ERROR_INVALID_ARG;
     RootedObject obj(aCx, &aObj.toObject());
     if (aUnwrap)
         obj = js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);
     *aRv = NS_strdup(js::GetObjectClass(obj)->name);
     NS_ENSURE_TRUE(*aRv, NS_ERROR_OUT_OF_MEMORY);
@@ -3386,18 +3359,18 @@ NS_IMETHODIMP
 nsXPCComponents_Utils::GetDOMClassInfo(const nsAString& aClassName,
                                        nsIClassInfo** aClassInfo)
 {
     *aClassInfo = nullptr;
     return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetIncumbentGlobal(const Value &aCallback,
-                                          JSContext *aCx, Value *aOut)
+nsXPCComponents_Utils::GetIncumbentGlobal(HandleValue aCallback,
+                                          JSContext *aCx, MutableHandleValue aOut)
 {
     nsCOMPtr<nsIGlobalObject> global = mozilla::dom::GetIncumbentGlobal();
     RootedValue globalVal(aCx);
 
     if (!global) {
         globalVal = NullValue();
     } else {
         // Note: We rely on the wrap call for outerization.
@@ -3408,17 +3381,17 @@ nsXPCComponents_Utils::GetIncumbentGloba
 
     // Invoke the callback, if passed.
     if (aCallback.isObject()) {
         RootedValue ignored(aCx);
         if (!JS_CallFunctionValue(aCx, nullptr, aCallback, 1, globalVal.address(), ignored.address()))
             return NS_ERROR_FAILURE;
     }
 
-    *aOut = globalVal;
+    aOut.set(globalVal);
     return NS_OK;
 }
 
 /*
  * Below is a bunch of awkward junk to allow JS test code to trigger the
  * creation of an XPCWrappedJS, such that it ends up in the map. We need to
  * hand the caller some sort of reference to hold onto (to prevent the
  * refcount from dropping to zero as soon as the function returns), but trying
@@ -3433,17 +3406,17 @@ class WrappedJSHolder : public nsISuppor
     WrappedJSHolder() {}
     virtual ~WrappedJSHolder() {}
 
     nsRefPtr<nsXPCWrappedJS> mWrappedJS;
 };
 NS_IMPL_ISUPPORTS0(WrappedJSHolder);
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::GenerateXPCWrappedJS(const Value &aObj, const Value &aScope,
+nsXPCComponents_Utils::GenerateXPCWrappedJS(HandleValue aObj, HandleValue aScope,
                                             JSContext *aCx, nsISupports **aOut)
 {
     if (!aObj.isObject())
         return NS_ERROR_INVALID_ARG;
     RootedObject obj(aCx, &aObj.toObject());
     RootedObject scope(aCx, aScope.isObject() ? js::UncheckedUnwrap(&aScope.toObject())
                                               : CurrentGlobalOrNull(aCx));
     JSAutoCompartment ac(aCx, scope);
@@ -3569,55 +3542,54 @@ nsXPCComponents::GetStack(nsIStackFrame 
 NS_IMETHODIMP
 nsXPCComponents::GetManager(nsIComponentManager * *aManager)
 {
     MOZ_ASSERT(aManager, "bad param");
     return NS_GetComponentManager(aManager);
 }
 
 NS_IMETHODIMP
-nsXPCComponents::GetLastResult(JSContext *aCx, Value *aOut)
+nsXPCComponents::GetLastResult(JSContext *aCx, MutableHandleValue aOut)
 {
     XPCContext* xpcc = XPCContext::GetXPCContext(aCx);
     if (!xpcc)
         return NS_ERROR_FAILURE;
     nsresult res = xpcc->GetLastResult();
-    *aOut = JS_NumberValue(static_cast<double>(static_cast<uint32_t>(res)));
+    aOut.setNumber(static_cast<uint32_t>(res));
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents::GetReturnCode(JSContext *aCx, Value *aOut)
+nsXPCComponents::GetReturnCode(JSContext *aCx, MutableHandleValue aOut)
 {
     XPCContext* xpcc = XPCContext::GetXPCContext(aCx);
     if (!xpcc)
         return NS_ERROR_FAILURE;
     nsresult res = xpcc->GetPendingResult();
-    *aOut = JS_NumberValue(static_cast<double>(static_cast<uint32_t>(res)));
+    aOut.setNumber(static_cast<uint32_t>(res));
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents::SetReturnCode(JSContext *aCx, const Value &aCode)
+nsXPCComponents::SetReturnCode(JSContext *aCx, HandleValue aCode)
 {
     XPCContext* xpcc = XPCContext::GetXPCContext(aCx);
     if (!xpcc)
         return NS_ERROR_FAILURE;
-    RootedValue code(aCx, aCode);
     nsresult rv;
-    if (!ToUint32(aCx, code, (uint32_t*)&rv))
+    if (!ToUint32(aCx, aCode, (uint32_t*)&rv))
         return NS_ERROR_FAILURE;
     xpcc->SetPendingResult(rv);
     xpcc->SetLastResult(rv);
     return NS_OK;
 }
 
 // static
 /* void reportError (); */
-NS_IMETHODIMP nsXPCComponents::ReportError(const Value &error, JSContext *cx)
+NS_IMETHODIMP nsXPCComponents::ReportError(HandleValue error, JSContext *cx)
 {
     NS_WARNING("Components.reportError deprecated, use Components.utils.reportError");
 
     nsCOMPtr<nsIXPCComponents_Utils> utils;
     nsresult rv = GetUtils(getter_AddRefs(utils));
     if (NS_FAILED(rv))
         return rv;
 
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -542,25 +542,25 @@ xpc::HasInstance(JSContext *cx, HandleOb
 
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsJSIID::HasInstance(nsIXPConnectWrappedNative *wrapper,
                      JSContext * cx, JSObject * /* unused */,
-                     const jsval &val, bool *bp, bool *_retval)
+                     HandleValue val, bool *bp, bool *_retval)
 {
     *bp = false;
 
-    if (JSVAL_IS_PRIMITIVE(val))
+    if (val.isPrimitive())
         return NS_OK;
 
     // we have a JSObject
-    RootedObject obj(cx, JSVAL_TO_OBJECT(val));
+    RootedObject obj(cx, &val.toObject());
 
     const nsIID* iid;
     mInfo->GetIIDShared(&iid);
     return xpc::HasInstance(cx, obj, iid, bp);
 }
 
 /***************************************************************************/
 
@@ -680,18 +680,18 @@ GetWrapperObject(MutableHandleObject obj
 
     nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
     ccxp->GetCalleeWrapper(getter_AddRefs(wrapper));
     obj.set(wrapper->GetJSObject());
 }
 
 /* nsISupports createInstance (); */
 NS_IMETHODIMP
-nsJSCID::CreateInstance(const JS::Value& iidval, JSContext* cx,
-                        uint8_t optionalArgc, JS::Value* retval)
+nsJSCID::CreateInstance(HandleValue iidval, JSContext* cx,
+                        uint8_t optionalArgc, MutableHandleValue retval)
 {
     if (!mDetails.IsValid())
         return NS_ERROR_XPC_BAD_CID;
 
     RootedObject obj(cx);
     GetWrapperObject(&obj);
     if (!obj) {
         return NS_ERROR_UNEXPECTED;
@@ -716,25 +716,25 @@ nsJSCID::CreateInstance(const JS::Value&
     nsCOMPtr<nsISupports> inst;
     rv = compMgr->CreateInstance(mDetails.ID(), nullptr, *iid, getter_AddRefs(inst));
     MOZ_ASSERT(NS_FAILED(rv) || inst, "component manager returned success, but instance is null!");
 
     if (NS_FAILED(rv) || !inst)
         return NS_ERROR_XPC_CI_RETURNED_FAILURE;
 
     rv = nsXPConnect::XPConnect()->WrapNativeToJSVal(cx, obj, inst, nullptr, iid, true, retval);
-    if (NS_FAILED(rv) || JSVAL_IS_PRIMITIVE(*retval))
+    if (NS_FAILED(rv) || retval.isPrimitive())
         return NS_ERROR_XPC_CANT_CREATE_WN;
     return NS_OK;
 }
 
 /* nsISupports getService (); */
 NS_IMETHODIMP
-nsJSCID::GetService(const JS::Value& iidval, JSContext* cx,
-                    uint8_t optionalArgc, JS::Value* retval)
+nsJSCID::GetService(HandleValue iidval, JSContext* cx,
+                    uint8_t optionalArgc, MutableHandleValue retval)
 {
     if (!mDetails.IsValid())
         return NS_ERROR_XPC_BAD_CID;
 
     RootedObject obj(cx);
     GetWrapperObject(&obj);
     if (!obj) {
         return NS_ERROR_UNEXPECTED;
@@ -767,17 +767,17 @@ nsJSCID::GetService(const JS::Value& iid
     RootedObject instJSObj(cx);
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = nsXPConnect::XPConnect()->WrapNative(cx, obj, srvc, *iid, getter_AddRefs(holder));
     if (NS_FAILED(rv) || !holder ||
         // Assign, not compare
         !(instJSObj = holder->GetJSObject()))
         return NS_ERROR_XPC_CANT_CREATE_WN;
 
-    *retval = OBJECT_TO_JSVAL(instJSObj);
+    retval.setObject(*instJSObj);
     return NS_OK;
 }
 
 /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t argc, in JSValPtr argv, in JSValPtr vp); */
 NS_IMETHODIMP
 nsJSCID::Construct(nsIXPConnectWrappedNative *wrapper,
                    JSContext * cx, JSObject * objArg,
                    const CallArgs &args, bool *_retval)
@@ -795,17 +795,17 @@ nsJSCID::Construct(nsIXPConnectWrappedNa
     *_retval = XPCWrappedNative::CallMethod(ccx);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsJSCID::HasInstance(nsIXPConnectWrappedNative *wrapper,
                      JSContext * cx, JSObject * /* unused */,
-                     const jsval &val, bool *bp, bool *_retval)
+                     HandleValue val, bool *bp, bool *_retval)
 {
     *bp = false;
     nsresult rv = NS_OK;
 
     if (!JSVAL_IS_PRIMITIVE(val)) {
         // we have a JSObject
         RootedObject obj(cx, &val.toObject());
 
--- a/js/xpconnect/src/XPCJSWeakReference.cpp
+++ b/js/xpconnect/src/XPCJSWeakReference.cpp
@@ -48,51 +48,48 @@ nsresult xpcJSWeakReference::Init(JSCont
         NS_ERROR("can't get nsISupportsWeakReference wrapper for obj");
         return rv;
     }
 
     return wrapped->GetWeakReference(getter_AddRefs(mReferent));
 }
 
 NS_IMETHODIMP
-xpcJSWeakReference::Get(JSContext* aCx, JS::Value* aRetval)
+xpcJSWeakReference::Get(JSContext* aCx, MutableHandleValue aRetval)
 {
-    *aRetval = JSVAL_NULL;
+    aRetval.setNull();
 
     if (!mReferent) {
         return NS_OK;
     }
 
     nsCOMPtr<nsISupports> supports = do_QueryReferent(mReferent);
     if (!supports) {
         return NS_OK;
     }
 
     nsCOMPtr<nsIXPConnectWrappedJS> wrappedObj = do_QueryInterface(supports);
     if (!wrappedObj) {
         // We have a generic XPCOM object that supports weak references here.
         // Wrap it and pass it out.
         RootedObject global(aCx, CurrentGlobalOrNull(aCx));
-        RootedValue rval(aCx);
-        nsresult rv = nsContentUtils::WrapNative(aCx, global,
-                                                 supports, &NS_GET_IID(nsISupports),
-                                                 &rval);
-        *aRetval = rval;
-        return rv;
+        return nsContentUtils::WrapNative(aCx, global,
+                                          supports, &NS_GET_IID(nsISupports),
+                                          aRetval);
     }
 
     JS::RootedObject obj(aCx, wrappedObj->GetJSObject());
     if (!obj) {
         return NS_OK;
     }
 
     // Most users of XPCWrappedJS don't need to worry about
     // re-wrapping because things are implicitly rewrapped by
     // xpcconvert. However, because we're doing this directly
     // through the native call context, we need to call
     // JS_WrapObject().
     if (!JS_WrapObject(aCx, &obj)) {
         return NS_ERROR_FAILURE;
     }
 
-    *aRetval = OBJECT_TO_JSVAL(obj);
+    aRetval.setObject(*obj);
     return NS_OK;
 }
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -580,17 +580,17 @@ Blob(JSContext *cx, unsigned argc, jsval
   if (NS_FAILED(rv)) {
     JS_ReportError(cx, "Could not get XPConnent service!");
     return false;
   }
 
   JSObject* global = JS::CurrentGlobalOrNull(cx);
   rv = xpc->WrapNativeToJSVal(cx, global, native, nullptr,
                               &NS_GET_IID(nsISupports), true,
-                              args.rval().address());
+                              args.rval());
   if (NS_FAILED(rv)) {
     JS_ReportError(cx, "Could not wrap native object!");
     return false;
   }
 
   return true;
 }
 
@@ -619,17 +619,17 @@ File(JSContext *cx, unsigned argc, jsval
   if (NS_FAILED(rv)) {
     JS_ReportError(cx, "Could not get XPConnent service!");
     return false;
   }
 
   JSObject* global = JS::CurrentGlobalOrNull(cx);
   rv = xpc->WrapNativeToJSVal(cx, global, native, nullptr,
                               &NS_GET_IID(nsISupports), true,
-                              args.rval().address());
+                              args.rval());
   if (NS_FAILED(rv)) {
     JS_ReportError(cx, "Could not wrap native object!");
     return false;
   }
 
   return true;
 }
 
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -360,36 +360,35 @@ bool XPCVariant::InitializeData(JSContex
     const nsIID& iid = NS_GET_IID(nsISupports);
 
     return NS_SUCCEEDED(xpc->WrapJS(cx, jsobj,
                                     iid, getter_AddRefs(wrapper))) &&
            NS_SUCCEEDED(nsVariant::SetFromInterface(&mData, iid, wrapper));
 }
 
 NS_IMETHODIMP
-XPCVariant::GetAsJSVal(jsval* result)
+XPCVariant::GetAsJSVal(MutableHandleValue result)
 {
-  NS_PRECONDITION(result, "null result arg.");
-  *result = GetJSVal();
+  result.set(GetJSVal());
   return NS_OK;
 }
 
 // static
 bool
 XPCVariant::VariantDataToJS(nsIVariant* variant,
                             nsresult* pErr, MutableHandleValue pJSVal)
 {
     // Get the type early because we might need to spoof it below.
     uint16_t type;
     if (NS_FAILED(variant->GetDataType(&type)))
         return false;
 
     AutoJSContext cx;
     RootedValue realVal(cx);
-    nsresult rv = variant->GetAsJSVal(realVal.address());
+    nsresult rv = variant->GetAsJSVal(&realVal);
 
     if (NS_SUCCEEDED(rv) &&
         (JSVAL_IS_PRIMITIVE(realVal) ||
          type == nsIDataType::VTYPE_ARRAY ||
          type == nsIDataType::VTYPE_EMPTY_ARRAY ||
          type == nsIDataType::VTYPE_ID)) {
         if (!JS_WrapValue(cx, &realVal))
             return false;
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -574,29 +574,25 @@ nsXPConnect::WrapNative(JSContext * aJSC
 /* void wrapNativeToJSVal (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDPtr aIID, out jsval aVal, out nsIXPConnectJSObjectHolder aHolder); */
 NS_IMETHODIMP
 nsXPConnect::WrapNativeToJSVal(JSContext * aJSContext,
                                JSObject * aScopeArg,
                                nsISupports *aCOMObj,
                                nsWrapperCache *aCache,
                                const nsIID * aIID,
                                bool aAllowWrapping,
-                               jsval *aVal)
+                               MutableHandleValue aVal)
 {
     MOZ_ASSERT(aJSContext, "bad param");
     MOZ_ASSERT(aScopeArg, "bad param");
     MOZ_ASSERT(aCOMObj, "bad param");
 
     RootedObject aScope(aJSContext, aScopeArg);
-
-    RootedValue rval(aJSContext);
-    nsresult rv = NativeInterface2JSObject(aScope, aCOMObj, aCache, aIID,
-                                           aAllowWrapping, &rval, nullptr);
-    *aVal = rval;
-    return rv;
+    return NativeInterface2JSObject(aScope, aCOMObj, aCache, aIID,
+                                    aAllowWrapping, aVal, nullptr);
 }
 
 /* void wrapJS (in JSContextPtr aJSContext, in JSObjectPtr aJSObj, in nsIIDRef aIID, [iid_is (aIID), retval] out nsQIResult result); */
 NS_IMETHODIMP
 nsXPConnect::WrapJS(JSContext * aJSContext,
                     JSObject * aJSObjArg,
                     const nsIID & aIID,
                     void * *result)
@@ -614,23 +610,22 @@ nsXPConnect::WrapJS(JSContext * aJSConte
     if (!XPCConvert::JSObject2NativeInterface(result, aJSObj,
                                               &aIID, nullptr, &rv))
         return rv;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPConnect::JSValToVariant(JSContext *cx,
-                            jsval *aJSVal,
+                            HandleValue aJSVal,
                             nsIVariant ** aResult)
 {
-    NS_PRECONDITION(aJSVal, "bad param");
     NS_PRECONDITION(aResult, "bad param");
 
-    *aResult = XPCVariant::newVariant(cx, *aJSVal);
+    *aResult = XPCVariant::newVariant(cx, aJSVal);
     NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
 
     return NS_OK;
 }
 
 /* void wrapJSAggregatedToNative (in nsISupports aOuter, in JSContextPtr aJSContext, in JSObjectPtr aJSObj, in nsIIDRef aIID, [iid_is (aIID), retval] out nsQIResult result); */
 NS_IMETHODIMP
 nsXPConnect::WrapJSAggregatedToNative(nsISupports *aOuter,
@@ -892,29 +887,25 @@ nsXPConnect::CreateSandbox(JSContext *cx
     }
 
     return rv;
 }
 
 NS_IMETHODIMP
 nsXPConnect::EvalInSandboxObject(const nsAString& source, const char *filename,
                                  JSContext *cx, JSObject *sandboxArg,
-                                 bool returnStringOnly, JS::Value *rvalArg)
+                                 bool returnStringOnly, MutableHandleValue rval)
 {
     if (!sandboxArg)
         return NS_ERROR_INVALID_ARG;
 
     RootedObject sandbox(cx, sandboxArg);
-    RootedValue rval(cx);
-    nsresult rv = EvalInSandbox(cx, sandbox, source, filename ? filename :
-                                "x-bogus://XPConnect/Sandbox", 1, JSVERSION_DEFAULT,
-                                returnStringOnly, &rval);
-    NS_ENSURE_SUCCESS(rv, rv);
-    *rvalArg = rval;
-    return NS_OK;
+    return EvalInSandbox(cx, sandbox, source, filename ? filename :
+                         "x-bogus://XPConnect/Sandbox", 1, JSVERSION_DEFAULT,
+                         returnStringOnly, rval);
 }
 
 /* nsIXPConnectJSObjectHolder getWrappedNativePrototype (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsIClassInfo aClassInfo); */
 NS_IMETHODIMP
 nsXPConnect::GetWrappedNativePrototype(JSContext * aJSContext,
                                        JSObject * aScopeArg,
                                        nsIClassInfo *aClassInfo,
                                        nsIXPConnectJSObjectHolder **_retval)
@@ -1050,42 +1041,38 @@ nsXPConnect::DebugDumpEvalInJSStackFrame
         xpc_DumpEvalInJSStackFrame(cx, aFrameNumber, aSourceText);
 
     return NS_OK;
 }
 
 /* jsval variantToJS (in JSContextPtr ctx, in JSObjectPtr scope, in nsIVariant value); */
 NS_IMETHODIMP
 nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scopeArg, nsIVariant* value,
-                         jsval* _retval)
+                         MutableHandleValue _retval)
 {
     NS_PRECONDITION(ctx, "bad param");
     NS_PRECONDITION(scopeArg, "bad param");
     NS_PRECONDITION(value, "bad param");
-    NS_PRECONDITION(_retval, "bad param");
 
     RootedObject scope(ctx, scopeArg);
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, ctx));
 
     nsresult rv = NS_OK;
-    RootedValue rval(ctx);
-    if (!XPCVariant::VariantDataToJS(value, &rv, &rval)) {
+    if (!XPCVariant::VariantDataToJS(value, &rv, _retval)) {
         if (NS_FAILED(rv))
             return rv;
 
         return NS_ERROR_FAILURE;
     }
-
-    *_retval = rval;
     return NS_OK;
 }
 
 /* nsIVariant JSToVariant (in JSContextPtr ctx, in jsval value); */
 NS_IMETHODIMP
-nsXPConnect::JSToVariant(JSContext* ctx, const jsval &value, nsIVariant** _retval)
+nsXPConnect::JSToVariant(JSContext* ctx, HandleValue value, nsIVariant** _retval)
 {
     NS_PRECONDITION(ctx, "bad param");
     NS_PRECONDITION(_retval, "bad param");
 
     *_retval = XPCVariant::newVariant(ctx, value);
     if (!(*_retval))
         return NS_ERROR_FAILURE;
 
@@ -1413,17 +1400,17 @@ nsXPConnect::SetDebugModeWhenPossible(bo
 {
     gDesiredDebugMode = mode;
     if (!mode && allowSyncDisable)
         CheckForDebugMode(mRuntime->Runtime());
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPConnect::GetTelemetryValue(JSContext *cx, jsval *rval)
+nsXPConnect::GetTelemetryValue(JSContext *cx, MutableHandleValue rval)
 {
     RootedObject obj(cx, JS_NewObject(cx, nullptr, nullptr, nullptr));
     if (!obj)
         return NS_ERROR_OUT_OF_MEMORY;
 
     unsigned attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
 
     size_t i = JS_SetProtoCalled(cx);
@@ -1431,17 +1418,17 @@ nsXPConnect::GetTelemetryValue(JSContext
     if (!JS_DefineProperty(cx, obj, "setProto", v, nullptr, nullptr, attrs))
         return NS_ERROR_OUT_OF_MEMORY;
 
     i = JS_GetCustomIteratorCount(cx);
     v = DOUBLE_TO_JSVAL(i);
     if (!JS_DefineProperty(cx, obj, "customIter", v, nullptr, nullptr, attrs))
         return NS_ERROR_OUT_OF_MEMORY;
 
-    *rval = OBJECT_TO_JSVAL(obj);
+    rval.setObject(*obj);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPConnect::NotifyDidPaint()
 {
     JS::NotifyDidPaint(GetRuntime()->Runtime());
     return NS_OK;
--- a/js/xpconnect/src/qsgen.py
+++ b/js/xpconnect/src/qsgen.py
@@ -608,18 +608,18 @@ def writeResultDecl(f, type, varname):
     f.write("    !; // TODO - Declare out parameter `%s`.\n" % varname)
 
 def outParamForm(name, type):
     type = unaliasType(type)
     if type.kind == 'builtin':
         return '&' + name
     elif type.kind == 'native':
         if getBuiltinOrNativeTypeName(type) == '[jsval]':
-            return name + '.address()'
-        elif type.modifier == 'ref':
+            return '&' + name
+        if type.modifier == 'ref':
             return name
         else:
             return '&' + name
     else:
         return 'getter_AddRefs(%s)' % name
 
 # From NativeData2JS.
 resultConvTemplates = {
--- a/js/xpconnect/tests/components/native/xpctest_params.cpp
+++ b/js/xpconnect/tests/components/native/xpctest_params.cpp
@@ -192,21 +192,23 @@ NS_IMETHODIMP nsXPCTestParams::TestAUTF8
 }
 
 /* ACString testACString (in ACString a, inout ACString b); */
 NS_IMETHODIMP nsXPCTestParams::TestACString(const nsACString & a, nsACString & b, nsACString & _retval)
 {
     STRING_METHOD_IMPL;
 }
 
-/* jsval testJsval (in jsval a, inout jsval b); */
-NS_IMETHODIMP nsXPCTestParams::TestJsval(const jsval & a, jsval & b, jsval *_retval)
+/* jsval testJsval (in jsval a, in jsval b); */
+NS_IMETHODIMP nsXPCTestParams::TestJsval(JS::Handle<JS::Value> a,
+                                         JS::MutableHandle<JS::Value> b,
+                                         JS::MutableHandle<JS::Value> _retval)
 {
-    *_retval = b;
-    b = a;
+    _retval.set(b);
+    b.set(a);
     return NS_OK;
 }
 
 /* void testShortArray (in unsigned long aLength, [array, size_is (aLength)] in short a,
  *                      inout unsigned long bLength, [array, size_is (bLength)] inout short b,
  *                      out unsigned long rvLength, [array, size_is (rvLength), retval] out short rv); */
 NS_IMETHODIMP nsXPCTestParams::TestShortArray(uint32_t aLength, int16_t *a,
                                               uint32_t *bLength, int16_t **b,
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -277,18 +277,17 @@ WrapperFactory::PrepareForWrapping(JSCon
         }
     }
 
     // This public WrapNativeToJSVal API enters the compartment of 'wrapScope'
     // so we don't have to.
     RootedValue v(cx);
     nsresult rv =
         nsXPConnect::XPConnect()->WrapNativeToJSVal(cx, wrapScope, wn->Native(), nullptr,
-                                                    &NS_GET_IID(nsISupports), false,
-                                                    v.address());
+                                                    &NS_GET_IID(nsISupports), false, &v);
     NS_ENSURE_SUCCESS(rv, nullptr);
 
     obj = JSVAL_TO_OBJECT(v);
     MOZ_ASSERT(IS_WN_REFLECTOR(obj), "bad object");
 
     // Because the underlying native didn't have a PreCreate hook, we had
     // to a new (or possibly pre-existing) XPCWN in our compartment.
     // This could be a problem for chrome code that passes XPCOM objects
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -611,30 +611,29 @@ inDOMUtils::GetCSSValuesForProperty(cons
     ret[i] = ToNewUnicode(array[i]);
   }
   *aValues = ret;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 inDOMUtils::ColorNameToRGB(const nsAString& aColorName, JSContext* aCx,
-                           JS::Value* aValue)
+                           JS::MutableHandle<JS::Value> aValue)
 {
   nscolor color;
   if (!NS_ColorNameToRGB(aColorName, &color)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   InspectorRGBTriple triple;
   triple.mR = NS_GET_R(color);
   triple.mG = NS_GET_G(color);
   triple.mB = NS_GET_B(color);
 
-  if (!triple.ToObject(aCx, JS::NullPtr(),
-                       JS::MutableHandle<JS::Value>::fromMarkedLocation(aValue))) {
+  if (!triple.ToObject(aCx, JS::NullPtr(), aValue)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 inDOMUtils::RgbToColorName(uint8_t aR, uint8_t aG, uint8_t aB,
--- a/netwerk/base/src/ArrayBufferInputStream.cpp
+++ b/netwerk/base/src/ArrayBufferInputStream.cpp
@@ -25,17 +25,17 @@ ArrayBufferInputStream::ArrayBufferInput
 ArrayBufferInputStream::~ArrayBufferInputStream()
 {
   if (mRt) {
     JS_RemoveValueRootRT(mRt, &mArrayBuffer);
   }
 }
 
 NS_IMETHODIMP
-ArrayBufferInputStream::SetData(const JS::Value& aBuffer,
+ArrayBufferInputStream::SetData(JS::Handle<JS::Value> aBuffer,
                                 uint32_t aByteOffset,
                                 uint32_t aLength,
                                 JSContext* aCx)
 {
   if (!aBuffer.isObject()) {
     return NS_ERROR_FAILURE;
   }
   JS::RootedObject arrayBuffer(aCx, &aBuffer.toObject());
--- a/netwerk/protocol/app/AppProtocolHandler.cpp
+++ b/netwerk/protocol/app/AppProtocolHandler.cpp
@@ -361,17 +361,17 @@ AppProtocolHandler::NewChannel(nsIURI* a
   if (!mAppInfoCache.Get(host, &appInfo)) {
     nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
     if (!appsService) {
       return NS_ERROR_FAILURE;
     }
 
     mozilla::AutoSafeJSContext cx;
     JS::RootedValue jsInfo(cx);
-    rv = appsService->GetAppInfo(NS_ConvertUTF8toUTF16(host), jsInfo.address());
+    rv = appsService->GetAppInfo(NS_ConvertUTF8toUTF16(host), &jsInfo);
     if (NS_FAILED(rv) || !jsInfo.isObject()) {
       // Return a DummyChannel.
       printf_stderr("!! Creating a dummy channel for %s (no appInfo)\n", host.get());
       NS_IF_ADDREF(*aResult = new DummyChannel());
       return NS_OK;
     }
 
     appInfo = new mozilla::dom::AppInfo();
--- a/storage/src/Variant_inl.h
+++ b/storage/src/Variant_inl.h
@@ -215,15 +215,15 @@ NS_IMETHODIMP
 Variant_base::GetAsWStringWithSize(uint32_t *,
                                    char16_t **)
 {
   return NS_ERROR_CANNOT_CONVERT_DATA;
 }
 
 inline
 NS_IMETHODIMP
-Variant_base::GetAsJSVal(JS::Value *)
+Variant_base::GetAsJSVal(JS::MutableHandle<JS::Value>)
 {
   return NS_ERROR_CANNOT_CONVERT_DATA;
 }
 
 } // namespace storage
 } // namespace mozilla
--- a/toolkit/components/finalizationwitness/FinalizationWitnessService.cpp
+++ b/toolkit/components/finalizationwitness/FinalizationWitnessService.cpp
@@ -184,30 +184,29 @@ NS_IMPL_ISUPPORTS1(FinalizationWitnessSe
  * @param aValue The notification value. Converted to a string.
  *
  * @constructor
  */
 NS_IMETHODIMP
 FinalizationWitnessService::Make(const char* aTopic,
                                  const char16_t* aValue,
                                  JSContext* aCx,
-                                 JS::Value *aRetval) {
-  MOZ_ASSERT(aRetval);
-
+                                 JS::MutableHandle<JS::Value> aRetval)
+{
   JS::Rooted<JSObject*> objResult(aCx, JS_NewObject(aCx, &sWitnessClass, nullptr, nullptr));
   if (!objResult) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   if (!JS_DefineFunctions(aCx, objResult, sWitnessClassFunctions)) {
     return NS_ERROR_FAILURE;
   }
 
   nsRefPtr<FinalizationEvent> event = new FinalizationEvent(aTopic, aValue);
 
   // Transfer ownership of the addrefed |event| to |objResult|.
   JS_SetReservedSlot(objResult, WITNESS_SLOT_EVENT,
                      JS::PrivateValue(event.forget().get()));
 
-  aRetval->setObject(*objResult);
+  aRetval.setObject(*objResult);
   return NS_OK;
 }
 
 } // namespace mozilla
--- a/toolkit/components/places/History.cpp
+++ b/toolkit/components/places/History.cpp
@@ -2672,17 +2672,17 @@ History::RemoveAllDownloads()
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// mozIAsyncHistory
 
 NS_IMETHODIMP
-History::GetPlacesInfo(const JS::Value& aPlaceIdentifiers,
+History::GetPlacesInfo(JS::Handle<JS::Value> aPlaceIdentifiers,
                        mozIVisitInfoCallback* aCallback,
                        JSContext* aCtx) {
   nsNavHistory* navHistory = nsNavHistory::GetHistoryService();
   NS_ABORT_IF_FALSE(navHistory, "Could not get nsNavHistory?!");
 
   uint32_t placesIndentifiersLength;
   JS::Rooted<JSObject*> placesIndentifiers(aCtx);
   nsresult rv = GetJSArrayFromJSValue(aPlaceIdentifiers, aCtx,
@@ -2740,17 +2740,17 @@ History::GetPlacesInfo(const JS::Value& 
     nsCOMPtr<nsIRunnable> event = new NotifyCompletion(aCallback);
     return backgroundThread->Dispatch(event, NS_DISPATCH_NORMAL);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-History::UpdatePlaces(const JS::Value& aPlaceInfos,
+History::UpdatePlaces(JS::Handle<JS::Value> aPlaceInfos,
                       mozIVisitInfoCallback* aCallback,
                       JSContext* aCtx)
 {
   NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_UNEXPECTED);
   NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(aPlaceInfos), NS_ERROR_INVALID_ARG);
 
   uint32_t infosLength;
   JS::Rooted<JSObject*> infos(aCtx);
--- a/toolkit/components/places/PlaceInfo.cpp
+++ b/toolkit/components/places/PlaceInfo.cpp
@@ -83,23 +83,23 @@ NS_IMETHODIMP
 PlaceInfo::GetFrecency(int64_t* _frecency)
 {
   *_frecency = mFrecency;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PlaceInfo::GetVisits(JSContext* aContext,
-                     JS::Value* _visits)
+                     JS::MutableHandle<JS::Value> _visits)
 {
   // If the visits data was not provided, return null rather
   // than an empty array to distinguish this case from the case
   // of a place without any visit.
   if (!mVisitsAvailable) {
-    *_visits = JSVAL_NULL;
+    _visits.setNull();
     return NS_OK;
   }
 
   // TODO bug 625913 when we use this in situations that have more than one
   // visit here, we will likely want to make this cache the value.
   JS::Rooted<JSObject*> visits(aContext,
                                JS_NewArrayObject(aContext, 0, nullptr));
   NS_ENSURE_TRUE(visits, NS_ERROR_OUT_OF_MEMORY);
@@ -119,18 +119,17 @@ PlaceInfo::GetVisits(JSContext* aContext
     JS::Rooted<JSObject*> jsobj(aContext, wrapper->GetJSObject());
     NS_ENSURE_STATE(jsobj);
     JS::Rooted<JS::Value> wrappedVisit(aContext, OBJECT_TO_JSVAL(jsobj));
 
     bool rc = JS_SetElement(aContext, visits, idx, &wrappedVisit);
     NS_ENSURE_TRUE(rc, NS_ERROR_UNEXPECTED);
   }
 
-  *_visits = OBJECT_TO_JSVAL(visits);
-
+  _visits.setObject(*visits);
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsISupports
 
 NS_IMPL_ISUPPORTS1(
   PlaceInfo
--- a/toolkit/components/startup/nsAppStartup.cpp
+++ b/toolkit/components/startup/nsAppStartup.cpp
@@ -711,20 +711,20 @@ nsAppStartup::Observe(nsISupports *aSubj
   } else {
     NS_ERROR("Unexpected observer topic.");
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAppStartup::GetStartupInfo(JSContext* aCx, JS::Value* aRetval)
+nsAppStartup::GetStartupInfo(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval)
 {
   JS::Rooted<JSObject*> obj(aCx, JS_NewObject(aCx, nullptr, nullptr, nullptr));
-  *aRetval = OBJECT_TO_JSVAL(obj);
+  aRetval.setObject(*obj);
 
   TimeStamp procTime = StartupTimeline::Get(StartupTimeline::PROCESS_CREATION);
   TimeStamp now = TimeStamp::Now();
   PRTime absNow = PR_Now();
 
   if (procTime.IsNull()) {
     bool error = false;
 
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -285,17 +285,18 @@ private:
                                    JS::Handle<JSObject*> obj);
   static bool ReflectOtherThreadsSQL(SlowSQLEntryType *entry, JSContext *cx,
                                      JS::Handle<JSObject*> obj);
   static bool ReflectSQL(const SlowSQLEntryType *entry, const Stat *stat,
                          JSContext *cx, JS::Handle<JSObject*> obj);
 
   bool AddSQLInfo(JSContext *cx, JS::Handle<JSObject*> rootObj, bool mainThread,
                   bool privateSQL);
-  bool GetSQLStats(JSContext *cx, JS::Value *ret, bool includePrivateSql);
+  bool GetSQLStats(JSContext *cx, JS::MutableHandle<JS::Value> ret,
+                   bool includePrivateSql);
 
   // Like GetHistogramById, but returns the underlying C++ object, not the JS one.
   nsresult GetHistogramByName(const nsACString &name, Histogram **ret);
   bool ShouldReflectHistogram(Histogram *h);
   void IdentifyCorruptHistograms(StatisticsRecorder::Histograms &hs);
   typedef StatisticsRecorder::Histograms::iterator HistogramIterator;
 
   struct AddonHistogramInfo {
@@ -675,35 +676,35 @@ JSHistogram_Clear(JSContext *cx, unsigne
   }
 
   Histogram *h = static_cast<Histogram*>(JS_GetPrivate(obj));
   h->Clear();
   return true;
 }
 
 nsresult
-WrapAndReturnHistogram(Histogram *h, JSContext *cx, JS::Value *ret)
+WrapAndReturnHistogram(Histogram *h, JSContext *cx, JS::MutableHandle<JS::Value> ret)
 {
   static const JSClass JSHistogram_class = {
     "JSHistogram",  /* name */
     JSCLASS_HAS_PRIVATE, /* flags */
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
   };
 
   JS::Rooted<JSObject*> obj(cx, JS_NewObject(cx, &JSHistogram_class, nullptr, nullptr));
   if (!obj)
     return NS_ERROR_FAILURE;
   if (!(JS_DefineFunction(cx, obj, "add", JSHistogram_Add, 1, 0)
         && JS_DefineFunction(cx, obj, "snapshot", JSHistogram_Snapshot, 0, 0)
         && JS_DefineFunction(cx, obj, "clear", JSHistogram_Clear, 0, 0))) {
     return NS_ERROR_FAILURE;
   }
-  *ret = OBJECT_TO_JSVAL(obj);
   JS_SetPrivate(obj, h);
+  ret.setObject(*obj);
   return NS_OK;
 }
 
 static uint32_t
 ReadLastShutdownDuration(const char *filename) {
   FILE *f = fopen(filename, "r");
   if (!f) {
     return 0;
@@ -975,17 +976,17 @@ TelemetryImpl::~TelemetryImpl() {
 void
 TelemetryImpl::InitMemoryReporter() {
   RegisterWeakMemoryReporter(this);
 }
 
 NS_IMETHODIMP
 TelemetryImpl::NewHistogram(const nsACString &name, const nsACString &expiration, uint32_t min,
                             uint32_t max, uint32_t bucketCount, uint32_t histogramType,
-                            JSContext *cx, JS::Value *ret)
+                            JSContext *cx, JS::MutableHandle<JS::Value> ret)
 {
   Histogram *h;
   nsresult rv = HistogramGet(PromiseFlatCString(name).get(), PromiseFlatCString(expiration).get(),
                              min, max, bucketCount, histogramType, &h);
   if (NS_FAILED(rv))
     return rv;
   h->ClearFlags(Histogram::kUmaTargetedHistogramFlag);
   h->SetFlags(Histogram::kExtendedStatisticsFlag);
@@ -1095,17 +1096,17 @@ TelemetryImpl::GetHistogramByName(const 
   if (NS_FAILED(rv))
     return rv;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TelemetryImpl::HistogramFrom(const nsACString &name, const nsACString &existing_name,
-                             JSContext *cx, JS::Value *ret)
+                             JSContext *cx, JS::MutableHandle<JS::Value> ret)
 {
   Telemetry::ID id;
   nsresult rv = GetHistogramEnumId(PromiseFlatCString(existing_name).get(), &id);
   if (NS_FAILED(rv)) {
     return rv;
   }
   const TelemetryHistogram &p = gHistograms[id];
 
@@ -1238,17 +1239,17 @@ TelemetryImpl::RegisterAddonHistogram(co
   info.bucketCount = bucketCount;
   info.histogramType = histogramType;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TelemetryImpl::GetAddonHistogram(const nsACString &id, const nsACString &name,
-                                 JSContext *cx, JS::Value *ret)
+                                 JSContext *cx, JS::MutableHandle<JS::Value> ret)
 {
   AddonEntryType *addonEntry = mAddonMap.GetEntry(id);
   // The given id has not been registered.
   if (!addonEntry) {
     return NS_ERROR_INVALID_ARG;
   }
 
   AddonHistogramMapType *histogramMap = addonEntry->mData;
@@ -1281,22 +1282,22 @@ TelemetryImpl::UnregisterAddonHistograms
     delete addonEntry->mData;
     mAddonMap.RemoveEntry(id);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TelemetryImpl::GetHistogramSnapshots(JSContext *cx, JS::Value *ret)
+TelemetryImpl::GetHistogramSnapshots(JSContext *cx, JS::MutableHandle<JS::Value> ret)
 {
   JS::Rooted<JSObject*> root_obj(cx, JS_NewObject(cx, nullptr, nullptr, nullptr));
   if (!root_obj)
     return NS_ERROR_FAILURE;
-  *ret = OBJECT_TO_JSVAL(root_obj);
+  ret.setObject(*root_obj);
 
   // Ensure that all the HISTOGRAM_FLAG histograms have been created, so
   // that their values are snapshotted.
   for (size_t i = 0; i < Telemetry::HistogramCount; ++i) {
     if (gHistograms[i].histogramType == nsITelemetry::HISTOGRAM_FLAG) {
       Histogram *h;
       DebugOnly<nsresult> rv = GetHistogramByEnumId(Telemetry::ID(i), &h);
       MOZ_ASSERT(NS_SUCCEEDED(rv));
@@ -1423,87 +1424,86 @@ TelemetryImpl::AddonReflector(AddonEntry
                              OBJECT_TO_JSVAL(subobj), nullptr, nullptr,
                              JSPROP_ENUMERATE))) {
     return false;
   }
   return true;
 }
 
 NS_IMETHODIMP
-TelemetryImpl::GetAddonHistogramSnapshots(JSContext *cx, JS::Value *ret)
+TelemetryImpl::GetAddonHistogramSnapshots(JSContext *cx, JS::MutableHandle<JS::Value> ret)
 {
-  *ret = JSVAL_VOID;
   JS::Rooted<JSObject*> obj(cx, JS_NewObject(cx, nullptr, nullptr, nullptr));
   if (!obj) {
     return NS_ERROR_FAILURE;
   }
 
   if (!mAddonMap.ReflectIntoJS(AddonReflector, cx, obj)) {
     return NS_ERROR_FAILURE;
   }
-  *ret = OBJECT_TO_JSVAL(obj);
+  ret.setObject(*obj);
   return NS_OK;
 }
 
 bool
-TelemetryImpl::GetSQLStats(JSContext *cx, JS::Value *ret, bool includePrivateSql)
+TelemetryImpl::GetSQLStats(JSContext *cx, JS::MutableHandle<JS::Value> ret, bool includePrivateSql)
 {
   JS::Rooted<JSObject*> root_obj(cx, JS_NewObject(cx, nullptr, nullptr, nullptr));
   if (!root_obj)
     return false;
-  *ret = OBJECT_TO_JSVAL(root_obj);
+  ret.setObject(*root_obj);
 
   MutexAutoLock hashMutex(mHashMutex);
   // Add info about slow SQL queries on the main thread
   if (!AddSQLInfo(cx, root_obj, true, includePrivateSql))
     return false;
   // Add info about slow SQL queries on other threads
   if (!AddSQLInfo(cx, root_obj, false, includePrivateSql))
     return false;
 
   return true;
 }
 
 NS_IMETHODIMP
-TelemetryImpl::GetSlowSQL(JSContext *cx, JS::Value *ret)
+TelemetryImpl::GetSlowSQL(JSContext *cx, JS::MutableHandle<JS::Value> ret)
 {
   if (GetSQLStats(cx, ret, false))
     return NS_OK;
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-TelemetryImpl::GetDebugSlowSQL(JSContext *cx, JS::Value *ret)
+TelemetryImpl::GetDebugSlowSQL(JSContext *cx, JS::MutableHandle<JS::Value> ret)
 {
   bool revealPrivateSql =
     Preferences::GetBool("toolkit.telemetry.debugSlowSql", false);
   if (GetSQLStats(cx, ret, revealPrivateSql))
     return NS_OK;
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 TelemetryImpl::GetMaximalNumberOfConcurrentThreads(uint32_t *ret)
 {
   *ret = nsThreadManager::get()->GetHighestNumberOfThreads();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TelemetryImpl::GetChromeHangs(JSContext *cx, JS::Value *ret)
+TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle<JS::Value> ret)
 {
   MutexAutoLock hangReportMutex(mHangReportsMutex);
 
   const CombinedStacks& stacks = mHangReports.GetStacks();
   JS::Rooted<JSObject*> fullReportObj(cx, CreateJSStackObject(cx, stacks));
   if (!fullReportObj) {
     return NS_ERROR_FAILURE;
   }
 
-  *ret = OBJECT_TO_JSVAL(fullReportObj);
+  ret.setObject(*fullReportObj);
 
   JS::Rooted<JSObject*> durationArray(cx, JS_NewArrayObject(cx, 0, nullptr));
   if (!durationArray) {
     return NS_ERROR_FAILURE;
   }
   bool ok = JS_DefineProperty(cx, fullReportObj, "durations",
                               OBJECT_TO_JSVAL(durationArray),
                               nullptr, nullptr, JSPROP_ENUMERATE);
@@ -1850,50 +1850,50 @@ CreateJSThreadHangStats(JSContext* cx, c
   if (!JS_DefineProperty(cx, ret, "hangs", OBJECT_TO_JSVAL(hangs),
                          nullptr, nullptr, JSPROP_ENUMERATE)) {
     return nullptr;
   }
   return ret;
 }
 
 NS_IMETHODIMP
-TelemetryImpl::GetThreadHangStats(JSContext* cx, JS::Value* ret)
+TelemetryImpl::GetThreadHangStats(JSContext* cx, JS::MutableHandle<JS::Value> ret)
 {
   JS::RootedObject retObj(cx, JS_NewArrayObject(cx, 0, nullptr));
   if (!retObj) {
     return NS_ERROR_FAILURE;
   }
   size_t threadIndex = 0;
 
   /* First add active threads; we need to hold |iter| (and its lock)
      throughout this method to avoid a race condition where a thread can
      be recorded twice if the thread is destroyed while this method is
      running */
   BackgroundHangMonitor::ThreadHangStatsIterator iter;
   for (Telemetry::ThreadHangStats* histogram = iter.GetNext();
        histogram; histogram = iter.GetNext()) {
     JS::RootedObject obj(cx,
       CreateJSThreadHangStats(cx, *histogram));
-    JS::RootedValue thread(cx, OBJECT_TO_JSVAL(obj));
+    JS::RootedValue thread(cx, JS::ObjectValue(*obj));
     if (!JS_SetElement(cx, retObj, threadIndex++, &thread)) {
       return NS_ERROR_FAILURE;
     }
   }
 
   // Add saved threads next
   MutexAutoLock autoLock(mThreadHangStatsMutex);
   for (size_t i = 0; i < mThreadHangStats.length(); i++) {
     JS::RootedObject obj(cx,
       CreateJSThreadHangStats(cx, mThreadHangStats[i]));
-    JS::RootedValue thread(cx, OBJECT_TO_JSVAL(obj));
+    JS::RootedValue thread(cx, JS::ObjectValue(*obj));
     if (!JS_SetElement(cx, retObj, threadIndex++, &thread)) {
       return NS_ERROR_FAILURE;
     }
   }
-  *ret = OBJECT_TO_JSVAL(retObj);
+  ret.setObject(*retObj);
   return NS_OK;
 }
 
 void
 TelemetryImpl::ReadLateWritesStacks(nsIFile* aProfileDir)
 {
   nsAutoCString nativePath;
   nsresult rv = aProfileDir->GetNativePath(nativePath);
@@ -1926,17 +1926,17 @@ TelemetryImpl::ReadLateWritesStacks(nsIF
     }
     // Delete the file so that we don't report it again on the next run.
     PR_Delete(stackNativePath.get());
   }
   PR_CloseDir(dir);
 }
 
 NS_IMETHODIMP
-TelemetryImpl::GetLateWrites(JSContext *cx, JS::Value *ret)
+TelemetryImpl::GetLateWrites(JSContext *cx, JS::MutableHandle<JS::Value> ret)
 {
   // The user must call AsyncReadTelemetryData first. We return an empty list
   // instead of reporting a failure so that the rest of telemetry can uniformly
   // handle the read not being available yet.
 
   // FIXME: we allocate the js object again and again in the getter. We should
   // figure out a way to cache it. In order to do that we have to call
   // JS_AddNamedObjectRoot. A natural place to do so is in the TelemetryImpl
@@ -1953,17 +1953,17 @@ TelemetryImpl::GetLateWrites(JSContext *
   } else {
     report = CreateJSStackObject(cx, mLateWritesStacks);
   }
 
   if (report == nullptr) {
     return NS_ERROR_FAILURE;
   }
 
-  *ret = OBJECT_TO_JSVAL(report);
+  ret.setObject(*report);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TelemetryImpl::RegisteredHistograms(uint32_t *aCount, char*** aHistograms)
 {
   size_t count = ArrayLength(gHistograms);
   size_t offset = 0;
@@ -1981,17 +1981,18 @@ TelemetryImpl::RegisteredHistograms(uint
   }
 
   *aCount = count - offset;
   *aHistograms = histograms;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TelemetryImpl::GetHistogramById(const nsACString &name, JSContext *cx, JS::Value *ret)
+TelemetryImpl::GetHistogramById(const nsACString &name, JSContext *cx,
+                                JS::MutableHandle<JS::Value> ret)
 {
   Histogram *h;
   nsresult rv = GetHistogramByName(name, &h);
   if (NS_FAILED(rv))
     return rv;
 
   return WrapAndReturnHistogram(h, cx, ret);
 }
--- a/toolkit/devtools/server/nsJSInspector.cpp
+++ b/toolkit/devtools/server/nsJSInspector.cpp
@@ -60,17 +60,17 @@ nsJSInspector::nsJSInspector() : mNested
 nsJSInspector::~nsJSInspector()
 {
   MOZ_ASSERT(mRequestors.Length() == 0);
   MOZ_ASSERT(mLastRequestor.isNull());
   mozilla::DropJSObjects(this);
 }
 
 NS_IMETHODIMP
-nsJSInspector::EnterNestedEventLoop(const JS::Value& requestor, uint32_t *out)
+nsJSInspector::EnterNestedEventLoop(JS::Handle<JS::Value> requestor, uint32_t *out)
 {
   nsresult rv = NS_OK;
 
   mLastRequestor = requestor;
   mRequestors.AppendElement(requestor);
   mozilla::HoldJSObjects(this);
 
   mozilla::dom::AutoSystemCaller asc;
@@ -113,19 +113,19 @@ nsJSInspector::ExitNestedEventLoop(uint3
 NS_IMETHODIMP
 nsJSInspector::GetEventLoopNestLevel(uint32_t *out)
 {
   *out = mNestedLoopLevel;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsJSInspector::GetLastNestRequestor(JS::Value *out)
+nsJSInspector::GetLastNestRequestor(JS::MutableHandle<JS::Value> out)
 {
-  *out = mLastRequestor;
+  out.set(mLastRequestor);
   return NS_OK;
 }
 
 }
 }
 
 NS_DEFINE_NAMED_CID(JSINSPECTOR_CID);
 
--- a/tools/profiler/nsProfiler.cpp
+++ b/tools/profiler/nsProfiler.cpp
@@ -175,23 +175,24 @@ GetSharedLibraryInfoString()
 
 NS_IMETHODIMP
 nsProfiler::GetSharedLibraryInformation(nsAString& aOutString)
 {
   aOutString.Assign(NS_ConvertUTF8toUTF16(GetSharedLibraryInfoString().c_str()));
   return NS_OK;
 }
 
-NS_IMETHODIMP nsProfiler::GetProfileData(JSContext* aCx, JS::Value* aResult)
+NS_IMETHODIMP nsProfiler::GetProfileData(JSContext* aCx,
+                                         JS::MutableHandle<JS::Value> aResult)
 {
   JSObject *obj = profiler_get_profile_jsobject(aCx);
   if (!obj)
     return NS_ERROR_FAILURE;
 
-  *aResult = OBJECT_TO_JSVAL(obj);
+  aResult.setObject(*obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsProfiler::IsActive(bool *aIsActive)
 {
   *aIsActive = profiler_is_active();
   return NS_OK;
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -653,17 +653,17 @@ void nsExternalHelperAppService::LaunchV
   }
   jsVal.setObject(*msgObj);
 
   // Send the message.
   nsCOMPtr<nsIMessageSender> cpmm =
     do_GetService("@mozilla.org/childprocessmessagemanager;1");
   NS_ENSURE_TRUE_VOID(cpmm);
   cpmm->SendAsyncMessage(NS_LITERAL_STRING("content-handler"),
-    jsVal, JSVAL_NULL, principal, cx, 2);
+                         jsVal, JS::NullHandleValue, principal, cx, 2);
 }
 #endif
 
 NS_IMETHODIMP nsExternalHelperAppService::DoContent(const nsACString& aMimeContentType,
                                                     nsIRequest *aRequest,
                                                     nsIInterfaceRequestor *aWindowContext,
                                                     bool aForceSave,
                                                     nsIStreamListener ** aStreamListener)
--- a/widget/xpwidgets/GfxInfoBase.cpp
+++ b/widget/xpwidgets/GfxInfoBase.cpp
@@ -902,17 +902,17 @@ nsTArray<GfxInfoCollectorBase*> *sCollec
 
 static void
 InitCollectors()
 {
   if (!sCollectors)
     sCollectors = new nsTArray<GfxInfoCollectorBase*>;
 }
 
-nsresult GfxInfoBase::GetInfo(JSContext* aCx, jsval* aResult)
+nsresult GfxInfoBase::GetInfo(JSContext* aCx, JS::MutableHandle<JS::Value> aResult)
 {
   InitCollectors();
   InfoObject obj(aCx);
 
   for (uint32_t i = 0; i < sCollectors->Length(); i++) {
     (*sCollectors)[i]->GetInfo(obj);
   }
 
@@ -920,17 +920,17 @@ nsresult GfxInfoBase::GetInfo(JSContext*
   // obj.DefineProperty("wordCacheSize", gfxTextRunWordCache::Count());
   // obj.DefineProperty("renderer", mRendererIDsString);
   // obj.DefineProperty("five", 5);
 
   if (!obj.mOk) {
     return NS_ERROR_FAILURE;
   }
 
-  *aResult = OBJECT_TO_JSVAL(obj.mObj);
+  aResult.setObject(*obj.mObj);
   return NS_OK;
 }
 
 void
 GfxInfoBase::AddCollector(GfxInfoCollectorBase* collector)
 {
   InitCollectors();
   sCollectors->AppendElement(collector);
--- a/widget/xpwidgets/GfxInfoBase.h
+++ b/widget/xpwidgets/GfxInfoBase.h
@@ -46,17 +46,17 @@ public:
   // using GfxInfoBase::GetWebGLParameter;
   // to import the relevant methods into their namespace.
   NS_IMETHOD GetFeatureStatus(int32_t aFeature, int32_t *_retval);
   NS_IMETHOD GetFeatureSuggestedDriverVersion(int32_t aFeature, nsAString & _retval);
   NS_IMETHOD GetWebGLParameter(const nsAString & aParam, nsAString & _retval);
 
   NS_IMETHOD GetFailures(uint32_t *failureCount, char ***failures);
   NS_IMETHOD_(void) LogFailure(const nsACString &failure);
-  NS_IMETHOD GetInfo(JSContext*, jsval*);
+  NS_IMETHOD GetInfo(JSContext*, JS::MutableHandle<JS::Value>);
 
   // Initialization function. If you override this, you must call this class's
   // version of Init first.
   // We need Init to be called separately from the constructor so we can
   // register as an observer after all derived classes have been constructed
   // and we know we have a non-zero refcount.
   // Ideally, Init() would be void-return, but the rules of
   // NS_GENERIC_FACTORY_CONSTRUCTOR_INIT require it be nsresult return.
--- a/xpcom/ds/nsVariant.cpp
+++ b/xpcom/ds/nsVariant.cpp
@@ -1855,17 +1855,17 @@ NS_IMETHODIMP nsVariant::GetAsWString(ch
 
 /* nsISupports getAsISupports (); */
 NS_IMETHODIMP nsVariant::GetAsISupports(nsISupports **_retval)
 {
     return nsVariant::ConvertToISupports(mData, _retval);
 }
 
 /* jsval getAsJSVal() */
-NS_IMETHODIMP nsVariant::GetAsJSVal(JS::Value *_retval)
+NS_IMETHODIMP nsVariant::GetAsJSVal(JS::MutableHandleValue)
 {
     // Can only get the jsval from an XPCVariant.
     return NS_ERROR_CANNOT_CONVERT_DATA;
 }
 
 /* void getAsInterface (out nsIIDPtr iid, [iid_is (iid), retval] out nsQIResult iface); */
 NS_IMETHODIMP nsVariant::GetAsInterface(nsIID * *iid, void * *iface)
 {
--- a/xpcom/idl-parser/header.py
+++ b/xpcom/idl-parser/header.py
@@ -129,18 +129,18 @@ header = """/*
 """
 
 include = """
 #ifndef __gen_%(basename)s_h__
 #include "%(basename)s.h"
 #endif
 """
 
-jspubtd_include = """
-#include "jspubtd.h"
+jsvalue_include = """
+#include "js/Value.h"
 """
 
 infallible_includes = """
 #include "mozilla/Assertions.h"
 #include "mozilla/DebugOnly.h"
 """
 
 header_end = """/* For IDL files that don't want to include root IDL files. */
@@ -168,17 +168,17 @@ def print_header(idl, fd, filename):
     foundinc = False
     for inc in idl.includes():
         if not foundinc:
             foundinc = True
             fd.write('\n')
         fd.write(include % {'basename': idl_basename(inc.filename)})
 
     if idl.needsJSTypes():
-        fd.write(jspubtd_include)
+        fd.write(jsvalue_include)
 
     # Include some extra files if any attributes are infallible.
     for iface in [p for p in idl.productions if p.kind == 'interface']:
         for attr in [m for m in iface.members if isinstance(m, xpidl.Attribute)]:
             if attr.infallible:
                 fd.write(infallible_includes)
                 break
 
--- a/xpcom/idl-parser/xpidl.py
+++ b/xpcom/idl-parser/xpidl.py
@@ -424,30 +424,35 @@ class Native(object):
             return False
 
         if self.specialtype == 'nsid':
             return self.modifier is not None
 
         return self.modifier == 'ref'
 
     def isPtr(self, calltype):
-        return self.modifier == 'ptr' or (self.modifier == 'ref' and self.specialtype == 'jsval' and calltype == 'out')
+        return self.modifier == 'ptr'
 
     def isRef(self, calltype):
-        return self.modifier == 'ref' and not (self.specialtype == 'jsval' and calltype == 'out')
+        return self.modifier == 'ref'
 
     def nativeType(self, calltype, const=False, shared=False):
         if shared:
             if calltype != 'out':
                 raise IDLError("[shared] only applies to out parameters.")
             const = True
 
         if self.specialtype is not None and calltype == 'in':
             const = True
 
+        if self.specialtype == 'jsval':
+            if calltype == 'out' or calltype == 'inout':
+                return "JS::MutableHandleValue "
+            return "JS::HandleValue "
+
         if self.isRef(calltype):
             m = '& '
         elif self.isPtr(calltype):
             m = '*' + ((self.modifier == 'ptr' and calltype != 'in') and '*' or '')
         else:
             m = calltype != 'in' and '*' or ''
         return "%s%s %s" % (const and 'const ' or '', self.nativename, m)
 
--- a/xpcom/io/nsBinaryStream.cpp
+++ b/xpcom/io/nsBinaryStream.cpp
@@ -725,17 +725,17 @@ nsBinaryInputStream::ReadBytes(uint32_t 
 
 NS_IMETHODIMP
 nsBinaryInputStream::ReadByteArray(uint32_t aLength, uint8_t* *_rval)
 {
     return ReadBytes(aLength, reinterpret_cast<char **>(_rval));
 }
 
 NS_IMETHODIMP
-nsBinaryInputStream::ReadArrayBuffer(uint32_t aLength, const JS::Value& aBuffer, JSContext* cx)
+nsBinaryInputStream::ReadArrayBuffer(uint32_t aLength, JS::Handle<JS::Value> aBuffer, JSContext* cx)
 {
     if (!aBuffer.isObject()) {
         return NS_ERROR_FAILURE;
     }
     JS::RootedObject buffer(cx, &aBuffer.toObject());
     if (!JS_IsArrayBufferObject(buffer) ||
         JS_GetArrayBufferByteLength(buffer) < aLength) {
         return NS_ERROR_FAILURE;
--- a/xpfe/appshell/src/nsChromeTreeOwner.cpp
+++ b/xpfe/appshell/src/nsChromeTreeOwner.cpp
@@ -246,17 +246,17 @@ nsChromeTreeOwner::ContentShellRemoved(n
 
 NS_IMETHODIMP nsChromeTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell)
 {
    NS_ENSURE_STATE(mXULWindow);
    return mXULWindow->GetPrimaryContentShell(aShell);
 }
 
 NS_IMETHODIMP
-nsChromeTreeOwner::GetContentWindow(JSContext* aCx, JS::Value* aVal)
+nsChromeTreeOwner::GetContentWindow(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
 {
   NS_ENSURE_STATE(mXULWindow);
 
   nsCOMPtr<nsIDOMWindow> domWin;
   mXULWindow->GetWindowDOMWindow(getter_AddRefs(domWin));
   nsCOMPtr<nsIDOMChromeWindow> chromeWin = do_QueryInterface(domWin);
   if (!chromeWin)
     return NS_OK;
--- a/xpfe/appshell/src/nsContentTreeOwner.cpp
+++ b/xpfe/appshell/src/nsContentTreeOwner.cpp
@@ -299,17 +299,18 @@ nsContentTreeOwner::ContentShellRemoved(
 NS_IMETHODIMP
 nsContentTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell)
 {
    NS_ENSURE_STATE(mXULWindow);
    return mXULWindow->GetPrimaryContentShell(aShell);
 }
 
 NS_IMETHODIMP
-nsContentTreeOwner::GetContentWindow(JSContext* aCx, JS::Value* aVal)
+nsContentTreeOwner::GetContentWindow(JSContext* aCx,
+                                     JS::MutableHandle<JS::Value> aVal)
 {
   NS_ENSURE_STATE(mXULWindow);
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsContentTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem,
    int32_t aCX, int32_t aCY)
 {