diff options
-rw-r--r-- | include/private/SkMalloc.h | 90 | ||||
-rw-r--r-- | include/private/SkTArray.h | 6 | ||||
-rw-r--r-- | include/private/SkTemplates.h | 21 | ||||
-rw-r--r-- | public.bzl | 1 | ||||
-rw-r--r-- | src/codec/SkBmpBaseCodec.cpp | 2 | ||||
-rw-r--r-- | src/codec/SkIcoCodec.cpp | 5 | ||||
-rw-r--r-- | src/core/SkAutoMalloc.h | 2 | ||||
-rw-r--r-- | src/core/SkAutoPixmapStorage.cpp | 2 | ||||
-rw-r--r-- | src/core/SkBitmapCache.cpp | 2 | ||||
-rw-r--r-- | src/core/SkMallocPixelRef.cpp | 31 | ||||
-rw-r--r-- | src/core/SkRegion_path.cpp | 7 | ||||
-rw-r--r-- | src/gpu/GrBuffer.cpp | 2 | ||||
-rw-r--r-- | src/lazy/SkDiscardableMemoryPool.cpp | 2 | ||||
-rw-r--r-- | src/ports/SkMemory_malloc.cpp | 22 | ||||
-rw-r--r-- | src/ports/SkMemory_mozalloc.cpp | 20 |
15 files changed, 146 insertions, 69 deletions
diff --git a/include/private/SkMalloc.h b/include/private/SkMalloc.h index ba14d465c1..53c3d99a8f 100644 --- a/include/private/SkMalloc.h +++ b/include/private/SkMalloc.h @@ -17,26 +17,52 @@ memory wrappers to be implemented by the porting layer (platform) */ + +/** Free memory returned by sk_malloc(). It is safe to pass null. */ +SK_API extern void sk_free(void*); + +/** + * Called internally if we run out of memory. The platform implementation must + * not return, but should either throw an exception or otherwise exit. + */ +SK_API extern void sk_out_of_memory(void); + enum { - SK_MALLOC_TEMP = 0x01, //!< hint to sk_malloc that the requested memory will be freed in the scope of the stack frame - SK_MALLOC_THROW = 0x02 //!< instructs sk_malloc to not return normally if the memory cannot be allocated. +#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER + SK_MALLOC_TEMP = 1, +#else + /** + * If this bit is set, the returned buffer must be zero-initialized. If this bit is not set + * the buffer can be uninitialized. + */ + SK_MALLOC_ZERO_INITIALIZE = 1 << 0, +#endif + + /** + * If this bit is set, the implementation must throw/crash/quit if the request cannot + * be fulfilled. If this bit is not set, then it should return nullptr on failure. + */ + SK_MALLOC_THROW = 1 << 1, }; -/** Return a block of memory (at least 4-byte aligned) of at least the - specified size. If the requested memory cannot be returned, either - return null (if SK_MALLOC_TEMP bit is clear) or throw an exception - (if SK_MALLOC_TEMP bit is set). To free the memory, call sk_free(). -*/ +/** + * Return a block of memory (at least 4-byte aligned) of at least the specified size. + * If the requested memory cannot be returned, either return nullptr or throw/exit, depending + * on the SK_MALLOC_THROW bit. If the allocation succeeds, the memory will be zero-initialized + * if the SK_MALLOC_ZERO_INITIALIZE bit was set. + * + * To free the memory, call sk_free() + */ SK_API extern void* sk_malloc_flags(size_t size, unsigned flags); -/** Same as sk_malloc(), but hard coded to pass SK_MALLOC_THROW as the flag -*/ -SK_API extern void* sk_malloc_throw(size_t size); + /** Same as standard realloc(), but this one never returns null on failure. It will throw - an exception if it fails. -*/ + * an exception if it fails. + */ SK_API extern void* sk_realloc_throw(void* buffer, size_t size); -/** Free memory returned by sk_malloc(). It is safe to pass null. -*/ -SK_API extern void sk_free(void*); + +#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER + +/** Same as sk_malloc_flags(), but hard coded to pass SK_MALLOC_THROW as the flag */ +SK_API extern void* sk_malloc_throw(size_t size); /** Much like calloc: returns a pointer to at least size zero bytes, or NULL on failure. */ @@ -46,10 +72,36 @@ SK_API extern void* sk_calloc(size_t size); */ SK_API extern void* sk_calloc_throw(size_t size); -/** Called internally if we run out of memory. The platform implementation must - not return, but should either throw an exception or otherwise exit. -*/ -SK_API extern void sk_out_of_memory(void); +#else +static inline void* sk_malloc_throw(size_t size) { + return sk_malloc_flags(size, SK_MALLOC_THROW); +} + +static inline void* sk_calloc_throw(size_t size) { + return sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_ZERO_INITIALIZE); +} +#endif + +static inline void* sk_calloc_canfail(size_t size) { +#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER + return sk_calloc(size); +#else + return sk_malloc_flags(size, SK_MALLOC_ZERO_INITIALIZE); +#endif +} + +// Performs a safe multiply count * elemSize, checking for overflow +SK_API extern void* sk_calloc_throw(size_t count, size_t elemSize); +SK_API extern void* sk_malloc_throw(size_t count, size_t elemSize); +SK_API extern void* sk_realloc_throw(void* buffer, size_t count, size_t elemSize); + +/** + * These variants return nullptr on failure + */ +static inline void* sk_malloc_canfail(size_t size) { + return sk_malloc_flags(size, 0); +} +SK_API extern void* sk_malloc_canfail(size_t count, size_t elemSize); // bzero is safer than memset, but we can't rely on it, so... sk_bzero() static inline void sk_bzero(void* buffer, size_t size) { diff --git a/include/private/SkTArray.h b/include/private/SkTArray.h index 3f4cc429b4..68dab9a33a 100644 --- a/include/private/SkTArray.h +++ b/include/private/SkTArray.h @@ -445,7 +445,7 @@ private: fReserved = false; } else { fAllocCount = SkTMax(count, SkTMax(kMinHeapAllocCount, reserveCount)); - fMemArray = sk_malloc_throw(fAllocCount * sizeof(T)); + fMemArray = sk_malloc_throw(fAllocCount, sizeof(T)); fOwnMemory = true; fReserved = reserveCount > 0; } @@ -460,7 +460,7 @@ private: fReserved = false; if (count > preallocCount) { fAllocCount = SkTMax(count, kMinHeapAllocCount); - fMemArray = sk_malloc_throw(fAllocCount * sizeof(T)); + fMemArray = sk_malloc_throw(fAllocCount, sizeof(T)); fOwnMemory = true; } else { fAllocCount = preallocCount; @@ -537,7 +537,7 @@ private: return; } fAllocCount = newAllocCount; - void* newMemArray = sk_malloc_throw(fAllocCount * sizeof(T)); + void* newMemArray = sk_malloc_throw(fAllocCount, sizeof(T)); this->move(newMemArray); if (fOwnMemory) { sk_free(fMemArray); diff --git a/include/private/SkTemplates.h b/include/private/SkTemplates.h index 8a605fbd02..3f70203555 100644 --- a/include/private/SkTemplates.h +++ b/include/private/SkTemplates.h @@ -175,12 +175,7 @@ public: } if (count > kCount) { - const uint64_t size64 = sk_64_mul(count, sizeof(T)); - const size_t size = static_cast<size_t>(size64); - if (size != size64) { - sk_out_of_memory(); - } - fArray = (T*) sk_malloc_throw(size); + fArray = (T*) sk_malloc_throw(count, sizeof(T)); } else if (count > 0) { fArray = (T*) fStorage; } else { @@ -250,7 +245,7 @@ public: /** Allocates space for 'count' Ts. */ explicit SkAutoTMalloc(size_t count) { - fPtr = count ? (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW) : nullptr; + fPtr = count ? (T*)sk_malloc_throw(count, sizeof(T)) : nullptr; } SkAutoTMalloc(SkAutoTMalloc<T>&& that) : fPtr(that.release()) {} @@ -271,7 +266,7 @@ public: /** Resize the memory area pointed to by the current ptr without preserving contents. */ T* reset(size_t count = 0) { sk_free(fPtr); - fPtr = count ? (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW) : nullptr; + fPtr = count ? (T*)sk_malloc_throw(count, sizeof(T)) : nullptr; return fPtr; } @@ -322,7 +317,7 @@ public: SkAutoSTMalloc(size_t count) { if (count > kCount) { - fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP); + fPtr = (T*)sk_malloc_throw(count, sizeof(T)); } else if (count) { fPtr = fTStorage; } else { @@ -342,7 +337,7 @@ public: sk_free(fPtr); } if (count > kCount) { - fPtr = (T*)sk_malloc_throw(count * sizeof(T)); + fPtr = (T*)sk_malloc_throw(count, sizeof(T)); } else if (count) { fPtr = fTStorage; } else { @@ -373,14 +368,14 @@ public: void realloc(size_t count) { if (count > kCount) { if (fPtr == fTStorage) { - fPtr = (T*)sk_malloc_throw(count * sizeof(T)); + fPtr = (T*)sk_malloc_throw(count, sizeof(T)); memcpy(fPtr, fTStorage, kCount * sizeof(T)); } else { - fPtr = (T*)sk_realloc_throw(fPtr, count * sizeof(T)); + fPtr = (T*)sk_realloc_throw(fPtr, count, sizeof(T)); } } else if (count) { if (fPtr != fTStorage) { - fPtr = (T*)sk_realloc_throw(fPtr, count * sizeof(T)); + fPtr = (T*)sk_realloc_throw(fPtr, count, sizeof(T)); } } else { this->reset(0); diff --git a/public.bzl b/public.bzl index 1e2894058a..d856db20b0 100644 --- a/public.bzl +++ b/public.bzl @@ -586,6 +586,7 @@ def base_defines(os_conditions): "SK_JUMPER_DISABLE_8BIT", # JPEG is in codec_limited "SK_HAS_JPEG_LIBRARY", + "SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER", ] + skia_select( os_conditions, [ diff --git a/src/codec/SkBmpBaseCodec.cpp b/src/codec/SkBmpBaseCodec.cpp index 1071ff38e7..c548514057 100644 --- a/src/codec/SkBmpBaseCodec.cpp +++ b/src/codec/SkBmpBaseCodec.cpp @@ -13,5 +13,5 @@ SkBmpBaseCodec::SkBmpBaseCodec(int width, int height, const SkEncodedInfo& info, std::unique_ptr<SkStream> stream, uint16_t bitsPerPixel, SkCodec::SkScanlineOrder rowOrder) : INHERITED(width, height, info, std::move(stream), bitsPerPixel, rowOrder) - , fSrcBuffer(sk_malloc_flags(this->srcRowBytes(), 0)) + , fSrcBuffer(sk_malloc_canfail(this->srcRowBytes())) {} diff --git a/src/codec/SkIcoCodec.cpp b/src/codec/SkIcoCodec.cpp index 1b9321c3ea..af9125565a 100644 --- a/src/codec/SkIcoCodec.cpp +++ b/src/codec/SkIcoCodec.cpp @@ -55,8 +55,7 @@ std::unique_ptr<SkCodec> SkIcoCodec::MakeFromStream(std::unique_ptr<SkStream> st uint32_t offset; uint32_t size; }; - SkAutoFree dirEntryBuffer(sk_malloc_flags(sizeof(Entry) * numImages, - SK_MALLOC_TEMP)); + SkAutoFree dirEntryBuffer(sk_malloc_canfail(sizeof(Entry) * numImages)); if (!dirEntryBuffer) { SkCodecPrintf("Error: OOM allocating ICO directory for %i images.\n", numImages); @@ -131,7 +130,7 @@ std::unique_ptr<SkCodec> SkIcoCodec::MakeFromStream(std::unique_ptr<SkStream> st bytesRead = offset; // Create a new stream for the embedded codec - SkAutoFree buffer(sk_malloc_flags(size, 0)); + SkAutoFree buffer(sk_malloc_canfail(size)); if (!buffer) { SkCodecPrintf("Warning: OOM trying to create embedded stream.\n"); break; diff --git a/src/core/SkAutoMalloc.h b/src/core/SkAutoMalloc.h index 03cbf79ea6..f5c872954d 100644 --- a/src/core/SkAutoMalloc.h +++ b/src/core/SkAutoMalloc.h @@ -144,7 +144,7 @@ public: SkASSERT(fPtr != fStorage); // otherwise we lied when setting didChangeAlloc. fPtr = fStorage; } else { - fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP); + fPtr = sk_malloc_throw(size); } fSize = size; diff --git a/src/core/SkAutoPixmapStorage.cpp b/src/core/SkAutoPixmapStorage.cpp index 47f41e7b92..72194233a8 100644 --- a/src/core/SkAutoPixmapStorage.cpp +++ b/src/core/SkAutoPixmapStorage.cpp @@ -40,7 +40,7 @@ bool SkAutoPixmapStorage::tryAlloc(const SkImageInfo& info) { if (SkImageInfo::ByteSizeOverflowed(size)) { return false; } - void* pixels = sk_malloc_flags(size, 0); + void* pixels = sk_malloc_canfail(size); if (nullptr == pixels) { return false; } diff --git a/src/core/SkBitmapCache.cpp b/src/core/SkBitmapCache.cpp index 210787e47d..cb88070ba4 100644 --- a/src/core/SkBitmapCache.cpp +++ b/src/core/SkBitmapCache.cpp @@ -301,7 +301,7 @@ SkBitmapCache::RecPtr SkBitmapCache::Alloc(const SkBitmapCacheDesc& desc, const if (factory) { dm.reset(factory(size)); } else { - block = sk_malloc_flags(size, 0); + block = sk_malloc_canfail(size); } if (!dm && !block) { return nullptr; diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp index 6e402c98f7..2933e48cc4 100644 --- a/src/core/SkMallocPixelRef.cpp +++ b/src/core/SkMallocPixelRef.cpp @@ -8,8 +8,27 @@ #include "SkMallocPixelRef.h" #include "SkBitmap.h" #include "SkReadBuffer.h" +#include "SkSafeMath.h" #include "SkWriteBuffer.h" +void* sk_calloc_throw(size_t count, size_t elemSize) { + return sk_calloc_throw(SkSafeMath::Mul(count, elemSize)); +} + +void* sk_malloc_throw(size_t count, size_t elemSize) { + return sk_malloc_throw(SkSafeMath::Mul(count, elemSize)); +} + +void* sk_realloc_throw(void* buffer, size_t count, size_t elemSize) { + return sk_realloc_throw(buffer, SkSafeMath::Mul(count, elemSize)); +} + +void* sk_malloc_canfail(size_t count, size_t elemSize) { + return sk_malloc_canfail(SkSafeMath::Mul(count, elemSize)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + // assumes ptr was allocated via sk_malloc static void sk_free_releaseproc(void* ptr, void*) { sk_free(ptr); @@ -63,15 +82,13 @@ sk_sp<SkPixelRef> SkMallocPixelRef::MakeUsing(void*(*allocProc)(size_t), sk_free_releaseproc, nullptr)); } -sk_sp<SkPixelRef> SkMallocPixelRef::MakeAllocate(const SkImageInfo& info, - size_t rowBytes) { - auto sk_malloc_nothrow = [](size_t size) { return sk_malloc_flags(size, 0); }; - return MakeUsing(sk_malloc_nothrow, info, rowBytes); +sk_sp<SkPixelRef> SkMallocPixelRef::MakeAllocate(const SkImageInfo& info, size_t rowBytes) { + return MakeUsing(sk_malloc_canfail, info, rowBytes); } sk_sp<SkPixelRef> SkMallocPixelRef::MakeZeroed(const SkImageInfo& info, size_t rowBytes) { - return MakeUsing(sk_calloc, info, rowBytes); + return MakeUsing(sk_calloc_canfail, info, rowBytes); } static void sk_data_releaseproc(void*, void* dataPtr) { @@ -93,8 +110,8 @@ sk_sp<SkPixelRef> SkMallocPixelRef::MakeWithProc(const SkImageInfo& info, } sk_sp<SkPixelRef> SkMallocPixelRef::MakeWithData(const SkImageInfo& info, - size_t rowBytes, - sk_sp<SkData> data) { + size_t rowBytes, + sk_sp<SkData> data) { SkASSERT(data != nullptr); if (!is_valid(info)) { return nullptr; diff --git a/src/core/SkRegion_path.cpp b/src/core/SkRegion_path.cpp index fec78256b3..e6af059c8e 100644 --- a/src/core/SkRegion_path.cpp +++ b/src/core/SkRegion_path.cpp @@ -144,12 +144,7 @@ bool SkRgnBuilder::init(int maxHeight, int maxTransitions, bool pathIsInverse) { } fStorageCount = sk_64_asS32(count); - int64_t size = sk_64_mul(fStorageCount, sizeof(SkRegion::RunType)); - if (size < 0 || !sk_64_isS32(size)) { - return false; - } - - fStorage = (SkRegion::RunType*)sk_malloc_flags(sk_64_asS32(size), 0); + fStorage = (SkRegion::RunType*)sk_malloc_canfail(fStorageCount, sizeof(SkRegion::RunType)); if (nullptr == fStorage) { return false; } diff --git a/src/gpu/GrBuffer.cpp b/src/gpu/GrBuffer.cpp index c92b2968b9..cd7862a226 100644 --- a/src/gpu/GrBuffer.cpp +++ b/src/gpu/GrBuffer.cpp @@ -16,7 +16,7 @@ GrBuffer* GrBuffer::CreateCPUBacked(GrGpu* gpu, size_t sizeInBytes, GrBufferType if (gpu->caps()->mustClearUploadedBufferData()) { cpuData = sk_calloc_throw(sizeInBytes); } else { - cpuData = sk_malloc_flags(sizeInBytes, SK_MALLOC_THROW); + cpuData = sk_malloc_throw(sizeInBytes); } if (data) { memcpy(cpuData, data, sizeInBytes); diff --git a/src/lazy/SkDiscardableMemoryPool.cpp b/src/lazy/SkDiscardableMemoryPool.cpp index 6e5582a494..394e325707 100644 --- a/src/lazy/SkDiscardableMemoryPool.cpp +++ b/src/lazy/SkDiscardableMemoryPool.cpp @@ -164,7 +164,7 @@ void DiscardableMemoryPool::dumpDownTo(size_t budget) { } std::unique_ptr<SkDiscardableMemory> DiscardableMemoryPool::make(size_t bytes) { - SkAutoFree addr(sk_malloc_flags(bytes, 0)); + SkAutoFree addr(sk_malloc_canfail(bytes)); if (nullptr == addr) { return nullptr; } diff --git a/src/ports/SkMemory_malloc.cpp b/src/ports/SkMemory_malloc.cpp index 05c69d53ae..aa1cfacb47 100644 --- a/src/ports/SkMemory_malloc.cpp +++ b/src/ports/SkMemory_malloc.cpp @@ -54,10 +54,6 @@ void sk_out_of_memory(void) { #endif } -void* sk_malloc_throw(size_t size) { - return sk_malloc_flags(size, SK_MALLOC_THROW); -} - void* sk_realloc_throw(void* addr, size_t size) { return throw_on_failure(size, realloc(addr, size)); } @@ -69,7 +65,16 @@ void sk_free(void* p) { } void* sk_malloc_flags(size_t size, unsigned flags) { - void* p = malloc(size); + void* p; +#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER + p = malloc(size); +#else + if (flags & SK_MALLOC_ZERO_INITIALIZE) { + p = calloc(size, 1); + } else { + p = malloc(size); + } +#endif if (flags & SK_MALLOC_THROW) { return throw_on_failure(size, p); } else { @@ -77,10 +82,15 @@ void* sk_malloc_flags(size_t size, unsigned flags) { } } +#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER +void* sk_malloc_throw(size_t size) { + return sk_malloc_flags(size, SK_MALLOC_THROW); +} void* sk_calloc(size_t size) { return calloc(size, 1); } - void* sk_calloc_throw(size_t size) { return throw_on_failure(size, sk_calloc(size)); } +#endif + diff --git a/src/ports/SkMemory_mozalloc.cpp b/src/ports/SkMemory_mozalloc.cpp index bf5971ba07..e13b94612a 100644 --- a/src/ports/SkMemory_mozalloc.cpp +++ b/src/ports/SkMemory_mozalloc.cpp @@ -22,22 +22,28 @@ void sk_out_of_memory(void) { mozalloc_handle_oom(0); } -void* sk_malloc_throw(size_t size) { - return sk_malloc_flags(size, SK_MALLOC_THROW); +void sk_free(void* p) { + free(p); } void* sk_realloc_throw(void* addr, size_t size) { return moz_xrealloc(addr, size); } -void sk_free(void* p) { - free(p); -} - void* sk_malloc_flags(size_t size, unsigned flags) { +#ifndef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER + if (flags & SK_MALLOC_ZERO_INITIALIZE) { + return (flags & SK_MALLOC_THROW) ? moz_xcalloc(size, 1) : calloc(size, 1); + } +#endif return (flags & SK_MALLOC_THROW) ? moz_xmalloc(size) : malloc(size); } +#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER +void* sk_malloc_throw(size_t size) { + return sk_malloc_flags(size, SK_MALLOC_THROW); +} + void* sk_calloc(size_t size) { return calloc(size, 1); } @@ -45,3 +51,5 @@ void* sk_calloc(size_t size) { void* sk_calloc_throw(size_t size) { return moz_xcalloc(size, 1); } +#endif + |