Index: third_party/WebKit/Source/wtf/ArrayBufferContents.cpp |
diff --git a/third_party/WebKit/Source/wtf/ArrayBufferContents.cpp b/third_party/WebKit/Source/wtf/ArrayBufferContents.cpp |
index 6a75a5286cab13c5500cc63fc5ea893edf6dd0e7..b9c2f52ac3523a8d180f2061348a2c7979180db2 100644 |
--- a/third_party/WebKit/Source/wtf/ArrayBufferContents.cpp |
+++ b/third_party/WebKit/Source/wtf/ArrayBufferContents.cpp |
@@ -34,12 +34,13 @@ |
namespace WTF { |
+bool ArrayBufferContents::s_fakeAllocationFailureForTestingOneTime = false; |
AdjustAmountOfExternalAllocatedMemoryFunction ArrayBufferContents::s_adjustAmountOfExternalAllocatedMemoryFunction; |
ArrayBufferContents::ArrayBufferContents() |
: m_holder(adoptRef(new DataHolder())) { } |
-ArrayBufferContents::ArrayBufferContents(unsigned numElements, unsigned elementByteSize, SharingType isShared, ArrayBufferContents::InitializationPolicy policy) |
+ArrayBufferContents::ArrayBufferContents(unsigned numElements, unsigned elementByteSize, SharingType isShared, InitializationPolicy initPolicy, OutOfMemoryPolicy oomPolicy) |
: m_holder(adoptRef(new DataHolder())) |
{ |
// Do not allow 32-bit overflow of the total size. |
@@ -49,12 +50,11 @@ ArrayBufferContents::ArrayBufferContents(unsigned numElements, unsigned elementB |
return; |
} |
} |
- |
- m_holder->allocateNew(totalSize, isShared, policy); |
+ m_holder->allocateNew(totalSize, isShared, initPolicy, oomPolicy); |
} |
ArrayBufferContents::ArrayBufferContents( |
- void* data, unsigned sizeInBytes, SharingType isShared) |
+ void* data, unsigned sizeInBytes, SharingType isShared, OutOfMemoryPolicy oomPolicy) |
: m_holder(adoptRef(new DataHolder())) |
{ |
if (data) { |
@@ -64,7 +64,7 @@ ArrayBufferContents::ArrayBufferContents( |
sizeInBytes = 0; |
// Allow null data if size is 0 bytes, make sure data is valid pointer. |
// (PartitionAlloc guarantees valid pointer for size 0) |
- m_holder->allocateNew(sizeInBytes, isShared, ZeroInitialize); |
+ m_holder->allocateNew(sizeInBytes, isShared, ZeroInitialize, oomPolicy); |
} |
} |
@@ -92,21 +92,41 @@ void ArrayBufferContents::shareWith(ArrayBufferContents& other) |
other.m_holder = m_holder; |
} |
-void ArrayBufferContents::copyTo(ArrayBufferContents& other) |
+void ArrayBufferContents::copyTo(ArrayBufferContents& other, OutOfMemoryPolicy oomPolicy) |
{ |
ASSERT(!m_holder->isShared() && !other.m_holder->isShared()); |
- m_holder->copyMemoryTo(*other.m_holder); |
+ m_holder->copyMemoryTo(*other.m_holder, oomPolicy); |
} |
-void ArrayBufferContents::allocateMemory(size_t size, InitializationPolicy policy, void*& data) |
+void ArrayBufferContents::deprecatedAllocateMemoryOrCrash(size_t size, InitializationPolicy policy, void*& data) |
{ |
if (s_adjustAmountOfExternalAllocatedMemoryFunction) |
s_adjustAmountOfExternalAllocatedMemoryFunction(static_cast<int>(size)); |
+ if (s_fakeAllocationFailureForTestingOneTime) |
+ IMMEDIATE_CRASH(); |
data = partitionAllocGeneric(WTF::Partitions::bufferPartition(), size); |
- if (policy == ZeroInitialize && data) |
+ ASSERT(data); // Supposed to have crashed on alloc failure |
+ if (policy == ZeroInitialize) |
memset(data, '\0', size); |
} |
+void ArrayBufferContents::allocateMemoryOrNull(size_t size, InitializationPolicy policy, void*& data) |
+{ |
+ if (s_fakeAllocationFailureForTestingOneTime) { |
+ data = nullptr; |
+ s_fakeAllocationFailureForTestingOneTime = false; |
+ } else { |
+ data = partitionAllocGenericFlags(WTF::Partitions::bufferPartition(), WTF::PartitionAllocReturnNull, size); |
+ } |
+ |
+ if (data) { |
+ if (s_adjustAmountOfExternalAllocatedMemoryFunction) |
+ s_adjustAmountOfExternalAllocatedMemoryFunction(static_cast<int>(size)); |
+ if (policy == ZeroInitialize) |
+ memset(data, '\0', size); |
+ } |
+} |
+ |
void ArrayBufferContents::freeMemory(void* data, size_t size) |
{ |
Partitions::bufferFree(data); |
@@ -128,11 +148,16 @@ ArrayBufferContents::DataHolder::~DataHolder() |
m_isShared = NotShared; |
} |
-void ArrayBufferContents::DataHolder::allocateNew(unsigned sizeInBytes, SharingType isShared, InitializationPolicy policy) |
+void ArrayBufferContents::DataHolder::allocateNew(unsigned sizeInBytes, SharingType isShared, InitializationPolicy initPolicy, OutOfMemoryPolicy oomPolicy) |
{ |
ASSERT(!m_data); |
void* data = nullptr; |
- allocateMemory(sizeInBytes, policy, data); |
+ if (oomPolicy == CrashIfOutOfMemory_DEPRECATED) { |
+ deprecatedAllocateMemoryOrCrash(sizeInBytes, initPolicy, data); |
+ } else { |
+ ASSERT(oomPolicy == NullDataIfOutOfMemory); |
+ allocateMemoryOrNull(sizeInBytes, initPolicy, data); |
+ } |
m_data = data; |
m_sizeInBytes = data ? sizeInBytes : 0; |
m_isShared = isShared; |
@@ -146,13 +171,19 @@ void ArrayBufferContents::DataHolder::adopt(void* data, unsigned sizeInBytes, Sh |
m_isShared = isShared; |
} |
-void ArrayBufferContents::DataHolder::copyMemoryTo(DataHolder& other) |
+void ArrayBufferContents::DataHolder::copyMemoryTo(DataHolder& other, OutOfMemoryPolicy oomPolicy) |
{ |
ASSERT(!other.m_sizeInBytes); |
ArrayBufferContents::freeMemory(other.m_data, other.m_sizeInBytes); |
- ArrayBufferContents::allocateMemory(m_sizeInBytes, DontInitialize, other.m_data); |
- if (!other.m_data) |
+ if (oomPolicy == CrashIfOutOfMemory_DEPRECATED) |
+ ArrayBufferContents::deprecatedAllocateMemoryOrCrash(m_sizeInBytes, DontInitialize, other.m_data); |
+ else |
+ ArrayBufferContents::allocateMemoryOrNull(m_sizeInBytes, DontInitialize, other.m_data); |
+ |
+ if (!other.m_data) { |
+ other.m_sizeInBytes = 0; |
return; |
+ } |
memcpy(other.m_data, m_data, m_sizeInBytes); |
other.m_sizeInBytes = m_sizeInBytes; |
} |