Bug 1216611 - add mozilla::MakeUniqueFallible and convert uses throughout the tree; r=Waldo
authorNathan Froyd <froydnj@mozilla.com>
Thu, 05 Nov 2015 16:24:24 -0500
changeset 271447 9bfc35f6d7abc7c22dd6562b645d19238e12865d
parent 271446 7bd635612263828db738f3ac6cb73d2c8b0159b8
child 271448 bc5cd0dc3ff0912419294825d133337c3df33d45
push id29641
push usercbook@mozilla.com
push dateFri, 06 Nov 2015 12:44:48 +0000
treeherdermozilla-central@512caeeb5565 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs1216611
milestone45.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 1216611 - add mozilla::MakeUniqueFallible and convert uses throughout the tree; r=Waldo
dom/canvas/WebGLContextDraw.cpp
dom/canvas/WebGLContextGL.cpp
gfx/thebes/gfxUtils.cpp
image/encoders/bmp/nsBMPEncoder.cpp
media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
mfbt/UniquePtrExtensions.h
mfbt/moz.build
widget/gtk/nsWindow.cpp
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #include "WebGLContext.h"
 
 #include "GLContext.h"
 #include "mozilla/CheckedInt.h"
+#include "mozilla/UniquePtrExtensions.h"
 #include "WebGLBuffer.h"
 #include "WebGLContextUtils.h"
 #include "WebGLFramebuffer.h"
 #include "WebGLProgram.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLShader.h"
 #include "WebGLTexture.h"
 #include "WebGLVertexArray.h"
@@ -575,17 +576,17 @@ WebGLContext::DoFakeVertexAttrib0(GLuint
         mFakeVertexAttrib0BufferObjectVector[2] = mVertexAttrib0Vector[2];
         mFakeVertexAttrib0BufferObjectVector[3] = mVertexAttrib0Vector[3];
 
         gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mFakeVertexAttrib0BufferObject);
 
         GetAndFlushUnderlyingGLErrors();
 
         if (mFakeVertexAttrib0BufferStatus == WebGLVertexAttrib0Status::EmulatedInitializedArray) {
-            UniquePtr<GLfloat[]> array(new (fallible) GLfloat[4 * vertexCount]);
+            auto array = MakeUniqueFallible<GLfloat[]>(4 * vertexCount);
             if (!array) {
                 ErrorOutOfMemory("Fake attrib0 array.");
                 return false;
             }
             for(size_t i = 0; i < vertexCount; ++i) {
                 array[4 * i + 0] = mVertexAttrib0Vector[0];
                 array[4 * i + 1] = mVertexAttrib0Vector[1];
                 array[4 * i + 2] = mVertexAttrib0Vector[2];
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -47,16 +47,17 @@
 #endif
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/Endian.h"
 #include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtrExtensions.h"
 
 namespace mozilla {
 
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 
 static const WebGLRectangleObject*
@@ -1617,17 +1618,17 @@ WebGLContext::ReadPixels(GLint x, GLint 
         // no need to check again for integer overflow here, since we already know the sizes aren't greater than before
         uint32_t subrect_plainRowSize = subrect_width * bytesPerPixel;
     // There are checks above to ensure that this doesn't overflow.
         uint32_t subrect_alignedRowSize =
             RoundedToNextMultipleOf(subrect_plainRowSize, mPixelStorePackAlignment).value();
         uint32_t subrect_byteLength = (subrect_height-1)*subrect_alignedRowSize + subrect_plainRowSize;
 
         // create subrect buffer, call glReadPixels, copy pixels into destination buffer, delete subrect buffer
-        UniquePtr<GLubyte> subrect_data(new (fallible) GLubyte[subrect_byteLength]);
+        auto subrect_data = MakeUniqueFallible<GLubyte[]>(subrect_byteLength);
         if (!subrect_data)
             return ErrorOutOfMemory("readPixels: subrect_data");
 
         // Effectively: gl->fReadPixels(subrect_x, subrect_y, subrect_width,
         //                              subrect_height, format, type, subrect_data.get());
         ReadPixelsAndConvert(gl, subrect_x, subrect_y, subrect_width, subrect_height,
                              format, readType, mPixelStorePackAlignment, format, type,
                              subrect_data.get());
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -16,16 +16,17 @@
 #include "mozilla/dom/ImageEncoder.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtrExtensions.h"
 #include "mozilla/Vector.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIClipboardHelper.h"
 #include "nsIFile.h"
 #include "nsIGfxInfo.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsRegion.h"
@@ -1555,17 +1556,17 @@ gfxUtils::GetImageBuffer(gfx::DataSource
 {
     *outFormat = 0;
 
     DataSourceSurface::MappedSurface map;
     if (!aSurface->Map(DataSourceSurface::MapType::READ, &map))
         return nullptr;
 
     uint32_t bufferSize = aSurface->GetSize().width * aSurface->GetSize().height * 4;
-    UniquePtr<uint8_t[]> imageBuffer(new (fallible) uint8_t[bufferSize]);
+    auto imageBuffer = MakeUniqueFallible<uint8_t[]>(bufferSize);
     if (!imageBuffer) {
         aSurface->Unmap();
         return nullptr;
     }
     memcpy(imageBuffer.get(), map.mData, bufferSize);
 
     aSurface->Unmap();
 
--- a/image/encoders/bmp/nsBMPEncoder.cpp
+++ b/image/encoders/bmp/nsBMPEncoder.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #include "nsCRT.h"
 #include "mozilla/Endian.h"
+#include "mozilla/UniquePtrExtensions.h"
 #include "nsBMPEncoder.h"
 #include "prprf.h"
 #include "nsString.h"
 #include "nsStreamUtils.h"
 #include "nsTArray.h"
 
 using namespace mozilla;
 using namespace mozilla::image;
@@ -182,19 +183,18 @@ nsBMPEncoder::AddImageFrame(const uint8_
 
   // validate input format
   if (aInputFormat != INPUT_FORMAT_RGB &&
       aInputFormat != INPUT_FORMAT_RGBA &&
       aInputFormat != INPUT_FORMAT_HOSTARGB) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  UniquePtr<uint8_t[]> row(new (fallible)
-                           uint8_t[mBMPInfoHeader.width *
-                                   BytesPerPixel(mBMPInfoHeader.bpp)]);
+  auto row = MakeUniqueFallible<uint8_t[]>(mBMPInfoHeader.width *
+                                           BytesPerPixel(mBMPInfoHeader.bpp));
   if (!row) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   // write each row: if we add more input formats, we may want to
   // generalize the conversions
   if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
     // BMP requires RGBA with post-multiplied alpha, so we need to convert
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -40,16 +40,17 @@
 #include "runnable_utils.h"
 #include "libyuv/convert.h"
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "mozilla/PeerIdentity.h"
 #endif
 #include "mozilla/gfx/Point.h"
 #include "mozilla/gfx/Types.h"
 #include "mozilla/UniquePtr.h"
+#include "mozilla/UniquePtrExtensions.h"
 
 #include "logging.h"
 
 // Should come from MediaEngineWebRTC.h, but that's a pain to include here
 #define DEFAULT_SAMPLE_RATE 32000
 
 using namespace mozilla;
 using namespace mozilla::gfx;
@@ -1174,17 +1175,17 @@ void MediaPipelineTransmit::PipelineList
     return;
   }
 
   IntSize size = img->GetSize();
   int half_width = (size.width + 1) >> 1;
   int half_height = (size.height + 1) >> 1;
   int c_size = half_width * half_height;
   int buffer_size = YSIZE(size.width, size.height) + 2 * c_size;
-  UniquePtr<uint8[]> yuv_scoped(new (fallible) uint8[buffer_size]);
+  auto yuv_scoped = MakeUniqueFallible<uint8[]>(buffer_size);
   if (!yuv_scoped)
     return;
   uint8* yuv = yuv_scoped.get();
 
   DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ);
   if (!map.IsMapped()) {
     MOZ_MTLOG(ML_ERROR, "Reading DataSourceSurface from " << Stringify(format)
                         << " image with " << Stringify(surf->GetType()) << "("
new file mode 100644
--- /dev/null
+++ b/mfbt/UniquePtrExtensions.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+/* Useful extensions to UniquePtr. */
+
+#ifndef mozilla_UniquePtrExtensions_h
+#define mozilla_UniquePtrExtensions_h
+
+#include "mozilla/fallible.h"
+#include "mozilla/UniquePtr.h"
+
+namespace mozilla {
+
+/**
+ * MakeUniqueFallible works exactly like MakeUnique, except that the memory
+ * allocation performed is done fallibly, i.e. it can return nullptr.
+ */
+template<typename T, typename... Args>
+typename detail::UniqueSelector<T>::SingleObject
+MakeUniqueFallible(Args&&... aArgs)
+{
+  return UniquePtr<T>(new (fallible) T(Forward<Args>(aArgs)...));
+}
+
+template<typename T>
+typename detail::UniqueSelector<T>::UnknownBound
+MakeUniqueFallible(decltype(sizeof(int)) aN)
+{
+  typedef typename RemoveExtent<T>::Type ArrayType;
+  return UniquePtr<T>(new (fallible) ArrayType[aN]());
+}
+
+template<typename T, typename... Args>
+typename detail::UniqueSelector<T>::KnownBound
+MakeUniqueFallible(Args&&... aArgs) = delete;
+
+} // namespace mozilla
+
+#endif // mozilla_UniquePtrExtensions_h
--- a/mfbt/moz.build
+++ b/mfbt/moz.build
@@ -84,16 +84,17 @@ EXPORTS.mozilla = [
     'TemplateLib.h',
     'ThreadLocal.h',
     'ToString.h',
     'Tuple.h',
     'TypedEnumBits.h',
     'Types.h',
     'TypeTraits.h',
     'UniquePtr.h',
+    'UniquePtrExtensions.h',
     'Variant.h',
     'Vector.h',
     'WeakPtr.h',
     'XorShift128PlusRNG.h',
     'unused.h',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -6,16 +6,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
+#include "mozilla/UniquePtrExtensions.h"
 #include <algorithm>
 
 #include "GeckoProfiler.h"
 
 #include "prlink.h"
 #include "nsGTKToolkit.h"
 #include "nsIRollupListener.h"
 #include "nsIDOMNode.h"
@@ -2317,17 +2318,17 @@ nsWindow::OnExposeEvent(cairo_t *cr)
 void
 nsWindow::UpdateAlpha(gfxPattern* aPattern, nsIntRect aBoundsRect)
 {
     // We need to create our own buffer to force the stride to match the
     // expected stride.
     int32_t stride = GetAlignedStride<4>(BytesPerPixel(SurfaceFormat::A8) *
                                          aBoundsRect.width);
     int32_t bufferSize = stride * aBoundsRect.height;
-    UniquePtr<uint8_t[]> imageBuffer(new (std::nothrow) uint8_t[bufferSize]);
+    auto imageBuffer = MakeUniqueFallible<uint8_t[]>(bufferSize);
     RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
         CreateDrawTargetForData(imageBuffer.get(), aBoundsRect.Size(),
                                 stride, SurfaceFormat::A8);
 
     if (drawTarget) {
         Matrix transform = Matrix::Translation(-aBoundsRect.x, -aBoundsRect.y);
         drawTarget->SetTransform(transform);