Bug 1022773 - Return value rooting for content/, r=smaug, a=abillings
authorSteve Fink <sfink@mozilla.com>
Tue, 01 Jul 2014 14:23:28 -0700
changeset 207553 adec0f46578219ea3289060dffefb8b1085fe1cc
parent 207552 ac90b02a034acec302fd095debaf177daff54eda
child 207554 87216353f2dc4cc7665e2ae3d233300777b34406
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, abillings
bugs1022773
milestone32.0a2
Bug 1022773 - Return value rooting for content/, r=smaug, a=abillings
content/base/src/Element.cpp
content/media/webaudio/AudioDestinationNode.cpp
content/media/webaudio/AudioProcessingEvent.cpp
content/media/webaudio/MediaBufferDecoder.cpp
content/media/webaudio/ScriptProcessorNode.cpp
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -474,26 +474,29 @@ Element::WrapObject(JSContext *aCx)
   bool dummy;
 
   nsXBLService* xblService = nsXBLService::GetInstance();
   if (!xblService) {
     dom::Throw(aCx, NS_ERROR_NOT_AVAILABLE);
     return nullptr;
   }
 
-  nsRefPtr<nsXBLBinding> binding;
-  xblService->LoadBindings(this, uri, principal, getter_AddRefs(binding), &dummy);
-  
-  if (binding) {
-    if (nsContentUtils::IsSafeToRunScript()) {
-      binding->ExecuteAttachedHandler();
-    }
-    else {
-      nsContentUtils::AddScriptRunner(
-        NS_NewRunnableMethod(binding, &nsXBLBinding::ExecuteAttachedHandler));
+  {
+    // Make a scope so that ~nsRefPtr can GC before returning obj.
+    nsRefPtr<nsXBLBinding> binding;
+    xblService->LoadBindings(this, uri, principal, getter_AddRefs(binding), &dummy);
+
+    if (binding) {
+      if (nsContentUtils::IsSafeToRunScript()) {
+        binding->ExecuteAttachedHandler();
+      }
+      else {
+        nsContentUtils::AddScriptRunner(
+          NS_NewRunnableMethod(binding, &nsXBLBinding::ExecuteAttachedHandler));
+      }
     }
   }
 
   return obj;
 }
 
 nsDOMTokenList*
 Element::ClassList()
--- a/content/media/webaudio/AudioDestinationNode.cpp
+++ b/content/media/webaudio/AudioDestinationNode.cpp
@@ -121,24 +121,24 @@ public:
   void FireOfflineCompletionEvent(AudioDestinationNode* aNode)
   {
     AudioContext* context = aNode->Context();
     context->Shutdown();
     // Shutdown drops self reference, but the context is still referenced by aNode,
     // which is strongly referenced by the runnable that called
     // AudioDestinationNode::FireOfflineCompletionEvent.
 
+    AutoJSAPI jsapi;
+    JSContext* cx = jsapi.cx();
+
     // We need the global for the context so that we can enter its compartment.
-    JSObject* global = context->GetGlobalJSObject();
+    JS::Rooted<JSObject*> global(cx, context->GetGlobalJSObject());
     if (NS_WARN_IF(!global)) {
       return;
     }
-
-    AutoJSAPI jsapi;
-    JSContext* cx = jsapi.cx();
     JSAutoCompartment ac(cx, global);
 
     // Create the input buffer
     ErrorResult rv;
     nsRefPtr<AudioBuffer> renderedBuffer =
       AudioBuffer::Create(context, mInputChannels.Length(),
                           mLength, mSampleRate, cx, rv);
     if (rv.Failed()) {
--- a/content/media/webaudio/AudioProcessingEvent.cpp
+++ b/content/media/webaudio/AudioProcessingEvent.cpp
@@ -36,25 +36,25 @@ AudioProcessingEvent::WrapObject(JSConte
 {
   return AudioProcessingEventBinding::Wrap(aCx, this);
 }
 
 already_AddRefed<AudioBuffer>
 AudioProcessingEvent::LazilyCreateBuffer(uint32_t aNumberOfChannels,
                                          ErrorResult& aRv)
 {
+  AutoJSAPI jsapi;
+  JSContext* cx = jsapi.cx();
+
   // We need the global for the context so that we can enter its compartment.
-  JSObject* global = mNode->Context()->GetGlobalJSObject();
+  JS::Rooted<JSObject*> global(cx, mNode->Context()->GetGlobalJSObject());
   if (NS_WARN_IF(!global)) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
-
-  AutoJSAPI jsapi;
-  JSContext* cx = jsapi.cx();
   JSAutoCompartment ac(cx, global);
 
   nsRefPtr<AudioBuffer> buffer =
     AudioBuffer::Create(mNode->Context(), aNumberOfChannels,
                         mNode->BufferSize(),
                         mNode->Context()->SampleRate(), cx, aRv);
   MOZ_ASSERT(buffer || aRv.ErrorCode() == NS_ERROR_OUT_OF_MEMORY);
   return buffer.forget();
--- a/content/media/webaudio/MediaBufferDecoder.cpp
+++ b/content/media/webaudio/MediaBufferDecoder.cpp
@@ -394,24 +394,24 @@ MediaDecodeTask::CallbackTheResult()
 }
 
 bool
 WebAudioDecodeJob::AllocateBuffer()
 {
   MOZ_ASSERT(!mOutput);
   MOZ_ASSERT(NS_IsMainThread());
 
+  AutoJSAPI jsapi;
+  JSContext* cx = jsapi.cx();
+
   // We need the global for the context so that we can enter its compartment.
-  JSObject* global = mContext->GetGlobalJSObject();
+  JS::Rooted<JSObject*> global(cx, mContext->GetGlobalJSObject());
   if (NS_WARN_IF(!global)) {
     return false;
   }
-
-  AutoJSAPI jsapi;
-  JSContext* cx = jsapi.cx();
   JSAutoCompartment ac(cx, global);
 
   // Now create the AudioBuffer
   ErrorResult rv;
   mOutput = AudioBuffer::Create(mContext, mChannelBuffers.Length(),
                                 mWriteIndex, mContext->SampleRate(), cx, rv);
   if (rv.Failed()) {
     return false;
--- a/content/media/webaudio/ScriptProcessorNode.cpp
+++ b/content/media/webaudio/ScriptProcessorNode.cpp
@@ -397,24 +397,24 @@ private:
           // this function.
           MutexAutoLock lock(mStream->Engine()->NodeMutex());
           node = static_cast<ScriptProcessorNode*>(mStream->Engine()->Node());
         }
         if (!node || !node->Context()) {
           return NS_OK;
         }
 
+        AutoJSAPI jsapi;
+        JSContext* cx = jsapi.cx();
+
         // Get the global for the context so that we can enter its compartment.
-        JSObject* global = node->Context()->GetGlobalJSObject();
+        JS::Rooted<JSObject*> global(cx, node->Context()->GetGlobalJSObject());
         if (NS_WARN_IF(!global)) {
           return NS_OK;
         }
-
-        AutoJSAPI jsapi;
-        JSContext* cx = jsapi.cx();
         JSAutoCompartment ac(cx, global);
 
         // Create the input buffer
         nsRefPtr<AudioBuffer> inputBuffer;
         if (!mNullInput) {
           ErrorResult rv;
           inputBuffer =
             AudioBuffer::Create(node->Context(), mInputChannels.Length(),