Chromium Code Reviews| 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..aaec3279f6b6283334f8a17e0224486a41169c39 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,14 @@ 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 |
| + allocateMemoryOrNull(sizeInBytes, initPolicy, data); |
|
binji
2015/10/16 22:12:39
since this is an enum, probably should assert that
Justin Novosad
2015/10/19 16:42:52
Acknowledged.
|
| m_data = data; |
| m_sizeInBytes = data ? sizeInBytes : 0; |
| m_isShared = isShared; |
| @@ -146,13 +169,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; |
|
binji
2015/10/16 22:12:39
shouldn't be necessary (it is asserted to be zero
Justin Novosad
2015/10/19 16:42:52
I disagree. The purpose of this function is to ove
|
| return; |
| + } |
| memcpy(other.m_data, m_data, m_sizeInBytes); |
| other.m_sizeInBytes = m_sizeInBytes; |
| } |