Bug 1249389 - part 1 - change NewObjectInputStreamFromBuffer to take a UniquePtr argument; r=erahm
authorNathan Froyd <froydnj@mozilla.com>
Thu, 18 Feb 2016 11:14:02 -0500
changeset 321783 b688e63090589bcee8766ea557f1a74682c020d5
parent 321782 615be94be0865921a73a7d2f81fbdb6bb1640bc6
child 321784 14e29cda9552844c1bf593df50ab85c555d345b3
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerserahm
bugs1249389
milestone47.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 1249389 - part 1 - change NewObjectInputStreamFromBuffer to take a UniquePtr argument; r=erahm Because NewObjectInputStreamFromBuffer takes a raw pointer as input, the typical coding pattern to use it is: nsAutoArrayPtr<char> buf; // assign something to buf nsresult rv = NewObjectInputStreamFromBuffer(buf, ...); if (NS_FAILED(rv)) { ... return rv; } buf.forget(); Which is clumsy, error-prone, and obscures the ownership transfer of the pointer into the stream returned by NewObjectInputStreamFromBuffer. Let's address all of these concerns by changing the argument to a UniquePtr<char[]>.
dom/xbl/nsXBLDocumentInfo.cpp
dom/xul/nsXULPrototypeCache.cpp
startupcache/StartupCacheUtils.cpp
startupcache/StartupCacheUtils.h
startupcache/test/TestStartupCache.cpp
--- a/dom/xbl/nsXBLDocumentInfo.cpp
+++ b/dom/xbl/nsXBLDocumentInfo.cpp
@@ -201,19 +201,19 @@ nsXBLDocumentInfo::ReadPrototypeBindings
   nsAutoArrayPtr<char> buf;
   uint32_t len;
   rv = startupCache->GetBuffer(spec.get(), getter_Transfers(buf), &len);
   // GetBuffer will fail if the binding is not in the cache.
   if (NS_FAILED(rv))
     return rv;
 
   nsCOMPtr<nsIObjectInputStream> stream;
-  rv = NewObjectInputStreamFromBuffer(buf, len, getter_AddRefs(stream));
+  rv = NewObjectInputStreamFromBuffer(UniquePtr<char[]>(buf.forget()),
+                                      len, getter_AddRefs(stream));
   NS_ENSURE_SUCCESS(rv, rv);
-  buf.forget();
 
   // The file compatibility.ini stores the build id. This is checked in
   // nsAppRunner.cpp and will delete the cache if a different build is
   // present. However, we check that the version matches here to be safe. 
   uint32_t version;
   rv = stream->Read32(&version);
   NS_ENSURE_SUCCESS(rv, rv);
   if (version != XBLBinding_Serialize_Version) {
--- a/dom/xul/nsXULPrototypeCache.cpp
+++ b/dom/xul/nsXULPrototypeCache.cpp
@@ -340,19 +340,19 @@ nsXULPrototypeCache::GetInputStream(nsIU
     StartupCache* sc = StartupCache::GetSingleton();
     if (!sc)
         return NS_ERROR_NOT_AVAILABLE;
 
     rv = sc->GetBuffer(spec.get(), getter_Transfers(buf), &len);
     if (NS_FAILED(rv))
         return NS_ERROR_NOT_AVAILABLE;
 
-    rv = NewObjectInputStreamFromBuffer(buf, len, getter_AddRefs(ois));
+    rv = NewObjectInputStreamFromBuffer(UniquePtr<char[]>(buf.forget()),
+                                        len, getter_AddRefs(ois));
     NS_ENSURE_SUCCESS(rv, rv);
-    buf.forget();
 
     mInputStreamTable.Put(uri, ois);
 
     ois.forget(stream);
     return NS_OK;
 }
 
 nsresult
@@ -495,20 +495,20 @@ nsXULPrototypeCache::BeginCaching(nsIURI
 
     nsAutoArrayPtr<char> buf;
     uint32_t len, amtRead;
     nsCOMPtr<nsIObjectInputStream> objectInput;
 
     rv = startupCache->GetBuffer(kXULCacheInfoKey, getter_Transfers(buf),
                                  &len);
     if (NS_SUCCEEDED(rv))
-        rv = NewObjectInputStreamFromBuffer(buf, len, getter_AddRefs(objectInput));
+        rv = NewObjectInputStreamFromBuffer(UniquePtr<char[]>(buf.forget()),
+                                            len, getter_AddRefs(objectInput));
 
     if (NS_SUCCEEDED(rv)) {
-        buf.forget();
         rv = objectInput->ReadCString(fileLocale);
         tmp = objectInput->ReadCString(fileChromePath);
         if (NS_FAILED(tmp)) {
           rv = tmp;
         }
         if (NS_FAILED(rv) ||
             (!fileChromePath.Equals(chromePath) ||
              !fileLocale.Equals(locale))) {
--- a/startupcache/StartupCacheUtils.cpp
+++ b/startupcache/StartupCacheUtils.cpp
@@ -14,25 +14,25 @@
 #include "StartupCacheUtils.h"
 #include "mozilla/scache/StartupCache.h"
 #include "mozilla/Omnijar.h"
 
 namespace mozilla {
 namespace scache {
 
 NS_EXPORT nsresult
-NewObjectInputStreamFromBuffer(char* buffer, uint32_t len, 
+NewObjectInputStreamFromBuffer(UniquePtr<char[]> buffer, uint32_t len, 
                                nsIObjectInputStream** stream)
 {
   nsCOMPtr<nsIStringInputStream> stringStream
     = do_CreateInstance("@mozilla.org/io/string-input-stream;1");
   nsCOMPtr<nsIObjectInputStream> objectInput 
     = do_CreateInstance("@mozilla.org/binaryinputstream;1");
   
-  stringStream->AdoptData(buffer, len);
+  stringStream->AdoptData(buffer.release(), len);
   objectInput->SetInputStream(stringStream);
   
   objectInput.forget(stream);
   return NS_OK;
 }
 
 NS_EXPORT nsresult
 NewObjectOutputWrappedStorageStream(nsIObjectOutputStream **wrapperStream,
--- a/startupcache/StartupCacheUtils.h
+++ b/startupcache/StartupCacheUtils.h
@@ -3,22 +3,23 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsStartupCacheUtils_h_
 #define nsStartupCacheUtils_h_
 
 #include "nsIStorageStream.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
+#include "mozilla/UniquePtr.h"
 
 namespace mozilla {
 namespace scache {
 
 NS_EXPORT nsresult
-NewObjectInputStreamFromBuffer(char* buffer, uint32_t len, 
+NewObjectInputStreamFromBuffer(UniquePtr<char[]> buffer, uint32_t len, 
                                nsIObjectInputStream** stream);
 
 // We can't retrieve the wrapped stream from the objectOutputStream later,
 // so we return it here. We give callers in debug builds the option 
 // to wrap the outputstream in a debug stream, which will detect if
 // non-singleton objects are written out multiple times during a serialization.
 // This could cause them to be deserialized incorrectly (as multiple copies
 // instead of references).
--- a/startupcache/test/TestStartupCache.cpp
+++ b/startupcache/test/TestStartupCache.cpp
@@ -18,39 +18,41 @@
 #include "nsIObjectOutputStream.h"
 #include "nsIURI.h"
 #include "nsStringAPI.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsIXPConnect.h"
 #include "prio.h"
 #include "mozilla/Maybe.h"
+#include "mozilla/UniquePtr.h"
 
 using namespace JS;
 
 namespace mozilla {
 namespace scache {
 
 NS_IMPORT nsresult
-NewObjectInputStreamFromBuffer(char* buffer, uint32_t len, 
+NewObjectInputStreamFromBuffer(UniquePtr<char[]> buffer, uint32_t len, 
                                nsIObjectInputStream** stream);
 
 // We can't retrieve the wrapped stream from the objectOutputStream later,
 // so we return it here.
 NS_IMPORT nsresult
 NewObjectOutputWrappedStorageStream(nsIObjectOutputStream **wrapperStream,
                                     nsIStorageStream** stream);
 
 NS_IMPORT nsresult
 NewBufferFromStorageStream(nsIStorageStream *storageStream, 
                            char** buffer, uint32_t* len);
 } // namespace scache
 } // namespace mozilla
 
 using namespace mozilla::scache;
+using mozilla::UniquePtr;
 
 #define NS_ENSURE_STR_MATCH(str1, str2, testname)  \
 PR_BEGIN_MACRO                                     \
 if (0 != strcmp(str1, str2)) {                     \
   fail("failed " testname);                        \
   return NS_ERROR_FAILURE;                         \
 }                                                  \
 passed("passed " testname);                        \
@@ -211,22 +213,22 @@ TestWriteObject() {
   uint32_t len2;
   nsCOMPtr<nsIObjectInputStream> objectInput;
   rv = sc->GetBuffer(id, getter_Transfers(buf2), &len2);
   if (NS_FAILED(rv)) {
     fail("failed to retrieve buffer");
     return rv;
   }
 
-  rv = NewObjectInputStreamFromBuffer(buf2, len2, getter_AddRefs(objectInput));
+  rv = NewObjectInputStreamFromBuffer(UniquePtr<char[]>(buf2.forget()), len2,
+                                      getter_AddRefs(objectInput));
   if (NS_FAILED(rv)) {
     fail("failed to created input stream");
     return rv;
   }  
-  buf2.forget();
 
   nsCOMPtr<nsISupports> deserialized;
   rv = objectInput->ReadObject(true, getter_AddRefs(deserialized));
   if (NS_FAILED(rv)) {
     fail("failed to read object");
     return rv;
   }