Bug 882543 - Retain storage for media streams accross iterations instead of reallocating. r=jlebar,roc
authorPaul Adenot <paul@paul.cx>
Fri, 19 Jul 2013 16:40:56 +0200
changeset 140187 2aa33cb78665591b5244c36b111b67507af0e293
parent 140186 adeb3608cd4114359cc0eff753f704ed578deb11
child 140188 11ab5b6a918103e8f8fa0f3ae3d68212c8c7b25b
push id1945
push userryanvm@gmail.com
push dateSat, 27 Jul 2013 02:27:26 +0000
treeherderfx-team@4874fa438b1c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar, roc
bugs882543
milestone25.0a1
Bug 882543 - Retain storage for media streams accross iterations instead of reallocating. r=jlebar,roc
content/media/MediaStreamGraph.cpp
content/media/MediaStreamGraphImpl.h
xpcom/glue/nsTArray.h
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -484,33 +484,33 @@ MediaStreamGraphImpl::UpdateStreamOrderF
 
   stream->mHasBeenOrdered = true;
   *mStreams.AppendElement() = stream.forget();
 }
 
 void
 MediaStreamGraphImpl::UpdateStreamOrder()
 {
-  nsTArray<nsRefPtr<MediaStream> > oldStreams;
-  oldStreams.SwapElements(mStreams);
-  for (uint32_t i = 0; i < oldStreams.Length(); ++i) {
-    MediaStream* stream = oldStreams[i];
+  mOldStreams.SwapElements(mStreams);
+  mStreams.ClearAndRetainStorage();
+  for (uint32_t i = 0; i < mOldStreams.Length(); ++i) {
+    MediaStream* stream = mOldStreams[i];
     stream->mHasBeenOrdered = false;
     stream->mIsConsumed = false;
     stream->mIsOnOrderingStack = false;
     stream->mInBlockingSet = false;
     ProcessedMediaStream* ps = stream->AsProcessedStream();
     if (ps) {
       ps->mInCycle = false;
     }
   }
 
   nsAutoTArray<MediaStream*,10> stack;
-  for (uint32_t i = 0; i < oldStreams.Length(); ++i) {
-    nsRefPtr<MediaStream>& s = oldStreams[i];
+  for (uint32_t i = 0; i < mOldStreams.Length(); ++i) {
+    nsRefPtr<MediaStream>& s = mOldStreams[i];
     if (!s->mAudioOutputs.IsEmpty() || !s->mVideoOutputs.IsEmpty()) {
       MarkConsumed(s);
     }
     if (!s->mHasBeenOrdered) {
       UpdateStreamOrderForStream(&stack, s.forget());
     }
   }
 }
--- a/content/media/MediaStreamGraphImpl.h
+++ b/content/media/MediaStreamGraphImpl.h
@@ -366,16 +366,21 @@ public:
   nsCOMPtr<nsIThread> mThread;
 
   // The following state is managed on the graph thread only, unless
   // mLifecycleState > LIFECYCLE_RUNNING in which case the graph thread
   // is not running and this state can be used from the main thread.
 
   nsTArray<nsRefPtr<MediaStream> > mStreams;
   /**
+   * mOldStreams is used as temporary storage for streams when computing the
+   * order in which we compute them.
+   */
+  nsTArray<nsRefPtr<MediaStream> > mOldStreams;
+  /**
    * The current graph time for the current iteration of the RunThread control
    * loop.
    */
   GraphTime mCurrentTime;
   /**
    * Blocking decisions and all stream contents have been computed up to this
    * time. The next batch of updates from the main thread will be processed
    * at this time. Always >= mCurrentTime.
--- a/xpcom/glue/nsTArray.h
+++ b/xpcom/glue/nsTArray.h
@@ -1037,16 +1037,30 @@ public:
   template<class Item>
   index_type BinaryIndexOf(const Item& item) const {
     return BinaryIndexOf(item, nsDefaultComparator<elem_type, Item>());
   }
 
   //
   // Mutation methods
   //
+  // This method call the destructor on each element of the array, empties it,
+  // but does not shrink the array's capacity.
+  //
+  // Make sure to call Compact() if needed to avoid keeping a huge array
+  // around.
+  void ClearAndRetainStorage() {
+    if (base_type::mHdr == EmptyHdr()) {
+      return;
+    }
+
+    DestructRange(0, Length());
+    base_type::mHdr->mLength = 0;
+  }
+
 
   // This method replaces a range of elements in this array.
   // @param start     The starting index of the elements to replace.
   // @param count     The number of elements to replace.  This may be zero to
   //                  insert elements without removing any existing elements.
   // @param array     The values to copy into this array.  Must be non-null,
   //                  and these elements must not already exist in the array
   //                  being modified.