Bug 1091986 (part 2) - Change nsStreamLoader::mData to a mozilla::Vector. r=mcmanus.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 30 Oct 2014 19:48:30 -0700
changeset 240444 4be4cf0afc2950232fd5d84e4edcf8a0a429c8dc
parent 240443 b24680cc584c68eefd8dd5f75d177fa8d6464410
child 240445 d95e85773aa64e8efec26b623cbaf34e48d2aa8f
push id660
push userraliiev@mozilla.com
push dateWed, 18 Feb 2015 20:30:48 +0000
treeherdermozilla-release@49e493494178 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs1091986
milestone36.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 1091986 (part 2) - Change nsStreamLoader::mData to a mozilla::Vector. r=mcmanus.
netwerk/base/src/nsStreamLoader.cpp
netwerk/base/src/nsStreamLoader.h
--- a/netwerk/base/src/nsStreamLoader.cpp
+++ b/netwerk/base/src/nsStreamLoader.cpp
@@ -4,26 +4,25 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsStreamLoader.h"
 #include "nsIInputStream.h"
 #include "nsIChannel.h"
 #include "nsError.h"
 #include "GeckoProfiler.h"
 
+#include <limits>
+
 nsStreamLoader::nsStreamLoader()
-  : mData(nullptr),
-    mAllocated(0),
-    mLength(0)
+  : mData()
 {
 }
 
 nsStreamLoader::~nsStreamLoader()
 {
-  ReleaseData();
 }
 
 NS_IMETHODIMP
 nsStreamLoader::Init(nsIStreamLoaderObserver* observer)
 {
   NS_ENSURE_ARG_POINTER(observer);
   mObserver = observer;
   return NS_OK;
@@ -44,70 +43,68 @@ nsStreamLoader::Create(nsISupports *aOut
 }
 
 NS_IMPL_ISUPPORTS(nsStreamLoader, nsIStreamLoader,
                   nsIRequestObserver, nsIStreamListener)
 
 NS_IMETHODIMP 
 nsStreamLoader::GetNumBytesRead(uint32_t* aNumBytes)
 {
-  *aNumBytes = mLength;
+  *aNumBytes = mData.length();
   return NS_OK;
 }
 
 /* readonly attribute nsIRequest request; */
 NS_IMETHODIMP 
 nsStreamLoader::GetRequest(nsIRequest **aRequest)
 {
   NS_IF_ADDREF(*aRequest = mRequest);
   return NS_OK;
 }
 
-NS_IMETHODIMP 
+NS_IMETHODIMP
 nsStreamLoader::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
 {
   nsCOMPtr<nsIChannel> chan( do_QueryInterface(request) );
   if (chan) {
     int64_t contentLength = -1;
     chan->GetContentLength(&contentLength);
     if (contentLength >= 0) {
-      if (contentLength > UINT32_MAX) {
-        // Too big to fit into uint32, so let's bail.
-        // XXX we should really make mAllocated and mLength 64-bit instead.
+      if (uint64_t(contentLength) > std::numeric_limits<size_t>::max()) {
+        // Too big to fit into size_t, so let's bail.
         return NS_ERROR_OUT_OF_MEMORY;
       }
-      uint32_t contentLength32 = uint32_t(contentLength);
       // preallocate buffer
-      mData = static_cast<uint8_t*>(moz_malloc(contentLength32));
-      if (!mData) {
+      if (!mData.initCapacity(contentLength)) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
-      mAllocated = contentLength32;
     }
   }
   mContext = ctxt;
   return NS_OK;
 }
 
-NS_IMETHODIMP 
+NS_IMETHODIMP
 nsStreamLoader::OnStopRequest(nsIRequest* request, nsISupports *ctxt,
                               nsresult aStatus)
 {
   PROFILER_LABEL("nsStreamLoader", "OnStopRequest",
     js::ProfileEntry::Category::NETWORK);
 
   if (mObserver) {
     // provide nsIStreamLoader::request during call to OnStreamComplete
     mRequest = request;
+    size_t length = mData.length();
+    uint8_t* elems = mData.extractRawBuffer();
     nsresult rv = mObserver->OnStreamComplete(this, mContext, aStatus,
-                                              mLength, mData);
-    if (rv == NS_SUCCESS_ADOPTED_DATA) {
-      // the observer now owns the data buffer, and the loader must
-      // not deallocate it
-      mData = nullptr;
+                                              length, elems);
+    if (rv != NS_SUCCESS_ADOPTED_DATA) {
+      // The observer didn't take ownership of the extracted data buffer, so
+      // put it back into mData.
+      mData.replaceRawBuffer(elems, length);
     }
     // done.. cleanup
     ReleaseData();
     mRequest = 0;
     mObserver = 0;
     mContext = 0;
   }
   return NS_OK;
@@ -118,33 +115,21 @@ nsStreamLoader::WriteSegmentFun(nsIInput
                                 void *closure,
                                 const char *fromSegment,
                                 uint32_t toOffset,
                                 uint32_t count,
                                 uint32_t *writeCount)
 {
   nsStreamLoader *self = (nsStreamLoader *) closure;
 
-  if (count > UINT32_MAX - self->mLength) {
-    return NS_ERROR_ILLEGAL_VALUE; // is there a better error to use here?
+  if (!self->mData.append(fromSegment, count)) {
+    self->mData.clearAndFree();
+    return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  if (self->mLength + count > self->mAllocated) {
-    self->mData = static_cast<uint8_t*>(moz_realloc(self->mData,
-                                                    self->mLength + count));
-    if (!self->mData) {
-      self->ReleaseData();
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    self->mAllocated = self->mLength + count;
-  }
-
-  ::memcpy(self->mData + self->mLength, fromSegment, count);
-  self->mLength += count;
-
   *writeCount = count;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsStreamLoader::OnDataAvailable(nsIRequest* request, nsISupports *ctxt, 
                                 nsIInputStream *inStr, 
@@ -152,15 +137,10 @@ nsStreamLoader::OnDataAvailable(nsIReque
 {
   uint32_t countRead;
   return inStr->ReadSegments(WriteSegmentFun, this, count, &countRead);
 }
 
 void
 nsStreamLoader::ReleaseData()
 {
-  if (mData) {
-    moz_free(mData);
-    mData = nullptr;
-  }
-  mLength = 0;
-  mAllocated = 0;
+  mData.clearAndFree();
 }
--- a/netwerk/base/src/nsStreamLoader.h
+++ b/netwerk/base/src/nsStreamLoader.h
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsStreamLoader_h__
 #define nsStreamLoader_h__
 
 #include "nsIStreamLoader.h"
 #include "nsCOMPtr.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/Vector.h"
 
 class nsIRequest;
 
 class nsStreamLoader MOZ_FINAL : public nsIStreamLoader
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTREAMLOADER
@@ -34,16 +35,14 @@ protected:
   // Utility method to free mData, if present, and update other state to
   // reflect that no data has been allocated.
   void ReleaseData();
 
   nsCOMPtr<nsIStreamLoaderObserver> mObserver;
   nsCOMPtr<nsISupports>             mContext;  // the observer's context
   nsCOMPtr<nsIRequest>              mRequest;
 
-  uint8_t  *mData;      // buffer to accumulate incoming data
-  uint32_t  mAllocated; // allocated size of data buffer (we preallocate if
-                        //   contentSize is available)
-  uint32_t  mLength;    // actual length of data in buffer
-                        //   (must be <= mAllocated)
+  // Buffer to accumulate incoming data. We preallocate if contentSize is
+  // available.
+  mozilla::Vector<uint8_t, 0> mData;
 };
 
 #endif // nsStreamLoader_h__