Bug 969114: Avoid allocation slop in MediaCacheStream.
authorBen Kelly <ben@wanderview.com>
Mon, 10 Feb 2014 22:31:40 -0800
changeset 168105 76e72417a9d71b9c7aa344d25c1dde4dfc98f5c0
parent 168104 3f2add0255e40478a8f2c518a13425db4c7009a5
child 168106 b3150ee1da4ded525aa5501b82bc815d33ba9abf
push id26197
push userryanvm@gmail.com
push dateTue, 11 Feb 2014 19:57:30 +0000
treeherdermozilla-central@802d87c77e76 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs969114
milestone30.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 969114: Avoid allocation slop in MediaCacheStream.
content/media/MediaCache.cpp
content/media/MediaCache.h
--- a/content/media/MediaCache.cpp
+++ b/content/media/MediaCache.cpp
@@ -376,17 +376,18 @@ MediaCacheStream::MediaCacheStream(Chann
     mCacheSuspended(false),
     mChannelEnded(false),
     mChannelOffset(0),
     mStreamLength(-1),
     mStreamOffset(0),
     mPlaybackBytesPerSecond(10000),
     mPinCount(0),
     mCurrentMode(MODE_PLAYBACK),
-    mMetadataInPartialBlockBuffer(false)
+    mMetadataInPartialBlockBuffer(false),
+    mPartialBlockBuffer(new int64_t[BLOCK_SIZE/sizeof(int64_t)])
 {
 }
 
 void MediaCacheStream::BlockList::AddFirstBlock(int32_t aBlock)
 {
   NS_ASSERTION(!mEntries.GetEntry(aBlock), "Block already in list");
   Entry* entry = mEntries.PutEntry(aBlock);
 
@@ -1730,22 +1731,22 @@ MediaCacheStream::NotifyDataReceived(int
       // mPartialBlockBuffer
       blockDataToStore = data;
     } else {
       if (blockOffset == 0) {
         // We've just started filling this buffer so now is a good time
         // to clear this flag.
         mMetadataInPartialBlockBuffer = false;
       }
-      memcpy(reinterpret_cast<char*>(mPartialBlockBuffer) + blockOffset,
+      memcpy(reinterpret_cast<char*>(mPartialBlockBuffer.get()) + blockOffset,
              data, chunkSize);
 
       if (blockOffset + chunkSize == BLOCK_SIZE) {
         // We completed a block, so lets write it out.
-        blockDataToStore = reinterpret_cast<char*>(mPartialBlockBuffer);
+        blockDataToStore = reinterpret_cast<char*>(mPartialBlockBuffer.get());
         if (mMetadataInPartialBlockBuffer) {
           mode = MODE_METADATA;
         }
       }
     }
 
     if (blockDataToStore) {
       gMediaCache->AllocateAndWriteBlock(this, blockDataToStore, mode);
@@ -1783,17 +1784,17 @@ MediaCacheStream::FlushPartialBlockInter
     CACHE_LOG(PR_LOG_DEBUG,
               ("Stream %p writing partial block: [%d] bytes; "
                "mStreamOffset [%lld] mChannelOffset[%lld] mStreamLength [%lld] "
                "notifying: [%s]",
                this, blockOffset, mStreamOffset, mChannelOffset, mStreamLength,
                aNotifyAll ? "yes" : "no"));
 
     // Write back the partial block
-    memset(reinterpret_cast<char*>(mPartialBlockBuffer) + blockOffset, 0,
+    memset(reinterpret_cast<char*>(mPartialBlockBuffer.get()) + blockOffset, 0,
            BLOCK_SIZE - blockOffset);
     gMediaCache->AllocateAndWriteBlock(this, mPartialBlockBuffer,
         mMetadataInPartialBlockBuffer ? MODE_METADATA : MODE_PLAYBACK);
     if (aNotifyAll) {
       // Wake up readers who may be waiting for this data
       mon.NotifyAll();
     }
   }
@@ -2177,17 +2178,17 @@ MediaCacheStream::Read(char* aBuffer, ui
         }
       }
       if (streamWithPartialBlock) {
         // We can just use the data in mPartialBlockBuffer. In fact we should
         // use it rather than waiting for the block to fill and land in
         // the cache.
         bytes = std::min<int64_t>(size, streamWithPartialBlock->mChannelOffset - mStreamOffset);
         memcpy(aBuffer,
-          reinterpret_cast<char*>(streamWithPartialBlock->mPartialBlockBuffer) + offsetInStreamBlock, bytes);
+          reinterpret_cast<char*>(streamWithPartialBlock->mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes);
         if (mCurrentMode == MODE_METADATA) {
           streamWithPartialBlock->mMetadataInPartialBlockBuffer = true;
         }
         mStreamOffset += bytes;
         count = bytes;
         break;
       }
 
@@ -2272,17 +2273,17 @@ MediaCacheStream::ReadFromCache(char* aB
     uint32_t channelBlock = uint32_t(mChannelOffset/BLOCK_SIZE);
     int32_t cacheBlock = streamBlock < mBlocks.Length() ? mBlocks[streamBlock] : -1;
     if (channelBlock == streamBlock && streamOffset < mChannelOffset) {
       // We can just use the data in mPartialBlockBuffer. In fact we should
       // use it rather than waiting for the block to fill and land in
       // the cache.
       bytes = std::min<int64_t>(size, mChannelOffset - streamOffset);
       memcpy(aBuffer + count,
-        reinterpret_cast<char*>(mPartialBlockBuffer) + offsetInStreamBlock, bytes);
+        reinterpret_cast<char*>(mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes);
     } else {
       if (cacheBlock < 0) {
         // We expect all blocks to be cached! Fail!
         return NS_ERROR_FAILURE;
       }
       int64_t offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock;
       NS_ABORT_IF_FALSE(size >= 0 && size <= INT32_MAX, "Size out of range.");
       nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, int32_t(size), &bytes);
--- a/content/media/MediaCache.h
+++ b/content/media/MediaCache.h
@@ -494,14 +494,16 @@ private:
   // The following field is protected by the cache's monitor but are
   // only written on the main thread.
 
   // Data received for the block containing mChannelOffset. Data needs
   // to wait here so we can write back a complete block. The first
   // mChannelOffset%BLOCK_SIZE bytes have been filled in with good data,
   // the rest are garbage.
   // Use int64_t so that the data is well-aligned.
-  int64_t           mPartialBlockBuffer[BLOCK_SIZE/sizeof(int64_t)];
+  // Heap allocate this buffer since the exact power-of-2 will cause allocation
+  // slop when combined with the rest of the object members.
+  nsAutoArrayPtr<int64_t> mPartialBlockBuffer;
 };
 
 } // namespace mozilla
 
 #endif