Bug 1083611 - Use UniquePtr and fallible allocations. r=kamidphish, a=lmandel
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 15 Oct 2014 20:11:30 -0700
changeset 225779 42f43b1c896e
parent 225778 5c014e511661
child 225780 e84f980d638e
push id4014
push userryanvm@gmail.com
push date2014-10-22 23:37 +0000
treeherdermozilla-beta@27b0655c1385 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskamidphish, lmandel
bugs1083611
milestone34.0
Bug 1083611 - Use UniquePtr and fallible allocations. r=kamidphish, a=lmandel
dom/canvas/WebGLContextBuffers.cpp
dom/canvas/WebGLContextDraw.cpp
dom/canvas/WebGLContextGL.cpp
dom/canvas/WebGLTexture.cpp
--- a/dom/canvas/WebGLContextBuffers.cpp
+++ b/dom/canvas/WebGLContextBuffers.cpp
@@ -155,25 +155,24 @@ WebGLContext::BufferData(GLenum target, 
     if (!CheckedInt<GLsizeiptr>(size).isValid())
         return ErrorOutOfMemory("bufferData: bad size");
 
     WebGLBuffer* boundBuffer = bufferSlot->get();
 
     if (!boundBuffer)
         return ErrorInvalidOperation("bufferData: no buffer bound!");
 
-    void* zeroBuffer = calloc(size, 1);
+    UniquePtr<uint8_t> zeroBuffer((uint8_t*)moz_calloc(size, 1));
     if (!zeroBuffer)
         return ErrorOutOfMemory("bufferData: out of memory");
 
     MakeContextCurrent();
     InvalidateBufferFetching();
 
-    GLenum error = CheckedBufferData(target, size, zeroBuffer, usage);
-    free(zeroBuffer);
+    GLenum error = CheckedBufferData(target, size, zeroBuffer.get(), usage);
 
     if (error) {
         GenerateWarning("bufferData generated error %s", ErrorName(error));
         return;
     }
 
     boundBuffer->SetByteLength(size);
     if (!boundBuffer->ElementArrayCacheBufferData(nullptr, size)) {
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -552,24 +552,28 @@ WebGLContext::DoFakeVertexAttrib0(GLuint
         mFakeVertexAttrib0BufferObjectVector[2] = mVertexAttrib0Vector[2];
         mFakeVertexAttrib0BufferObjectVector[3] = mVertexAttrib0Vector[3];
 
         gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mFakeVertexAttrib0BufferObject);
 
         GetAndFlushUnderlyingGLErrors();
 
         if (mFakeVertexAttrib0BufferStatus == WebGLVertexAttrib0Status::EmulatedInitializedArray) {
-            nsAutoArrayPtr<GLfloat> array(new GLfloat[4 * vertexCount]);
+            UniquePtr<GLfloat[]> array(new ((fallible_t())) 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];
                 array[4 * i + 3] = mVertexAttrib0Vector[3];
             }
-            gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, array, LOCAL_GL_DYNAMIC_DRAW);
+            gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, array.get(), LOCAL_GL_DYNAMIC_DRAW);
         } else {
             gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, nullptr, LOCAL_GL_DYNAMIC_DRAW);
         }
         GLenum error = GetAndFlushUnderlyingGLErrors();
 
         gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0);
 
         // note that we do this error checking and early return AFTER having restored the buffer binding above
@@ -725,27 +729,26 @@ WebGLContext::FakeBlackTexture::FakeBlac
                    &formerBinding);
   gl->fGenTextures(1, &mGLName);
   gl->fBindTexture(target, mGLName);
 
   // we allocate our zeros on the heap, and we overallocate (16 bytes instead of 4)
   // to minimize the risk of running into a driver bug in texImage2D, as it is
   // a bit unusual maybe to create 1x1 textures, and the stack may not have the alignment
   // that texImage2D expects.
-  void* zeros = calloc(1, 16);
+  UniquePtr<uint8_t> zeros((uint8_t*)moz_xcalloc(1, 16));
   if (target == LOCAL_GL_TEXTURE_2D) {
       gl->fTexImage2D(target, 0, format, 1, 1,
-                      0, format, LOCAL_GL_UNSIGNED_BYTE, zeros);
+                      0, format, LOCAL_GL_UNSIGNED_BYTE, zeros.get());
   } else {
       for (GLuint i = 0; i < 6; ++i) {
           gl->fTexImage2D(LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, format, 1, 1,
-                          0, format, LOCAL_GL_UNSIGNED_BYTE, zeros);
+                          0, format, LOCAL_GL_UNSIGNED_BYTE, zeros.get());
       }
   }
-  free(zeros);
 
   gl->fBindTexture(target, formerBinding);
 }
 
 WebGLContext::FakeBlackTexture::~FakeBlackTexture()
 {
   if (mGL) {
       mGL->MakeCurrent();
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -2247,30 +2247,33 @@ 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
-        GLubyte *subrect_data = new GLubyte[subrect_byteLength];
-        gl->fReadPixels(subrect_x, subrect_y, subrect_width, subrect_height, format, type, subrect_data);
+        UniquePtr<GLubyte> subrect_data(new ((fallible_t())) GLubyte[subrect_byteLength]);
+        if (!subrect_data)
+            return ErrorOutOfMemory("readPixels: subrect_data");
+
+        gl->fReadPixels(subrect_x, subrect_y, subrect_width, subrect_height,
+                        format, type, subrect_data.get());
 
         // notice that this for loop terminates because we already checked that subrect_height is at most height
         for (GLint y_inside_subrect = 0; y_inside_subrect < subrect_height; ++y_inside_subrect) {
             GLint subrect_x_in_dest_buffer = subrect_x - x;
             GLint subrect_y_in_dest_buffer = subrect_y - y;
             memcpy(static_cast<GLubyte*>(data)
                      + checked_alignedRowSize.value() * (subrect_y_in_dest_buffer + y_inside_subrect)
                      + bytesPerPixel * subrect_x_in_dest_buffer, // destination
-                   subrect_data + subrect_alignedRowSize * y_inside_subrect, // source
+                   subrect_data.get() + subrect_alignedRowSize * y_inside_subrect, // source
                    subrect_plainRowSize); // size
         }
-        delete [] subrect_data;
     }
 
     // if we're reading alpha, we may need to do fixup.  Note that we don't allow
     // GL_ALPHA to readpixels currently, but we had the code written for it already.
     if (format == LOCAL_GL_ALPHA ||
         format == LOCAL_GL_RGBA)
     {
         bool needAlphaFixup;
@@ -3658,17 +3661,17 @@ WebGLContext::TexImage2D_base(GLenum tar
             !mPixelStoreFlipY)
         {
             // no conversion, no flipping, so we avoid copying anything and just pass the source pointer
             pixels = data;
         }
         else
         {
             size_t convertedDataSize = height * dstStride;
-            convertedData = (uint8_t*)moz_malloc(convertedDataSize);
+            convertedData = new ((fallible_t())) uint8_t[convertedDataSize];
             if (!convertedData) {
                 ErrorOutOfMemory("texImage2D: Ran out of memory when allocating"
                                  " a buffer for doing format conversion.");
                 return;
             }
             ConvertImage(width, height, srcStride, dstStride,
                         static_cast<uint8_t*>(data), convertedData,
                         actualSrcFormat, srcPremultiplied,
@@ -3815,17 +3818,17 @@ WebGLContext::TexSubImage2D_base(GLenum 
     // no conversion, no flipping, so we avoid copying anything and just pass the source pointer
     bool noConversion = (actualSrcFormat == dstFormat &&
                          srcPremultiplied == mPixelStorePremultiplyAlpha &&
                          srcStride == dstStride &&
                          !mPixelStoreFlipY);
 
     if (!noConversion) {
         size_t convertedDataSize = height * dstStride;
-        convertedData = (uint8_t*)moz_malloc(convertedDataSize);
+        convertedData = new ((fallible_t())) uint8_t[convertedDataSize];
         if (!convertedData) {
             ErrorOutOfMemory("texImage2D: Ran out of memory when allocating"
                              " a buffer for doing format conversion.");
             return;
         }
         ConvertImage(width, height, srcStride, dstStride,
                     static_cast<const uint8_t*>(data), convertedData,
                     actualSrcFormat, srcPremultiplied,
--- a/dom/canvas/WebGLTexture.cpp
+++ b/dom/canvas/WebGLTexture.cpp
@@ -568,30 +568,30 @@ WebGLTexture::DoDeferredImageInitializat
     uint32_t texelsize = WebGLTexelConversions::TexelBytesForFormat(texelformat);
     CheckedUint32 checked_byteLength
         = WebGLContext::GetImageSize(
                         imageInfo.mHeight,
                         imageInfo.mWidth,
                         texelsize,
                         mContext->mPixelStoreUnpackAlignment);
     MOZ_ASSERT(checked_byteLength.isValid()); // should have been checked earlier
-    ScopedFreePtr<void> zeros;
-    zeros = calloc(1, checked_byteLength.value());
+
+    UniquePtr<uint8_t> zeros((uint8_t*)moz_xcalloc(1, checked_byteLength.value())); // Infallible for now.
 
     gl::GLContext* gl = mContext->gl;
     GLenum driverType = DriverTypeFromType(gl, type);
     GLenum driverInternalFormat = LOCAL_GL_NONE;
     GLenum driverFormat = LOCAL_GL_NONE;
     DriverFormatsFromFormatAndType(gl, format, type, &driverInternalFormat, &driverFormat);
 
     mContext->GetAndFlushUnderlyingGLErrors();
     gl->fTexImage2D(imageTarget, level, driverInternalFormat,
                     imageInfo.mWidth, imageInfo.mHeight,
                     0, driverFormat, driverType,
-                    zeros);
+                    zeros.get());
     GLenum error = mContext->GetAndFlushUnderlyingGLErrors();
     if (error) {
         // Should only be OUT_OF_MEMORY. Anyway, there's no good way to recover from this here.
         printf_stderr("Error: 0x%4x\n", error);
         MOZ_CRASH(); // errors on texture upload have been related to video memory exposure in the past.
     }
 
     SetImageDataStatus(imageTarget, level, WebGLImageDataStatus::InitializedImageData);