Chromium Code Reviews| Index: Source/wtf/ArrayBufferContents.cpp |
| diff --git a/Source/wtf/ArrayBufferContents.cpp b/Source/wtf/ArrayBufferContents.cpp |
| index c71d829a4617c865d62bfcc4337d9cfafc69e840..dd5a12f4b38f3158d7d36977fabac46bcccc2512 100644 |
| --- a/Source/wtf/ArrayBufferContents.cpp |
| +++ b/Source/wtf/ArrayBufferContents.cpp |
| @@ -35,74 +35,61 @@ |
| namespace WTF { |
| ArrayBufferContents::ArrayBufferContents() |
| - : m_data(0) |
| - , m_sizeInBytes(0) |
| - , m_deallocationObserver(0) { } |
| + : m_holder(adoptRef(new DataHolder())) { } |
| -ArrayBufferContents::ArrayBufferContents(unsigned numElements, unsigned elementByteSize, ArrayBufferContents::InitializationPolicy policy) |
| - : m_data(0) |
| - , m_sizeInBytes(0) |
| - , m_deallocationObserver(0) |
| +ArrayBufferContents::ArrayBufferContents(unsigned numElements, unsigned elementByteSize, SharingType isShared, ArrayBufferContents::InitializationPolicy policy) |
| + : m_holder(adoptRef(new DataHolder())) |
| { |
| // Do not allow 32-bit overflow of the total size. |
| + unsigned totalSize = numElements * elementByteSize; |
| if (numElements) { |
| - unsigned totalSize = numElements * elementByteSize; |
| if (totalSize / numElements != elementByteSize) { |
| - m_data = 0; |
| return; |
| } |
| } |
| - allocateMemory(numElements * elementByteSize, policy, m_data); |
| - m_sizeInBytes = numElements * elementByteSize; |
| + |
| + m_holder->allocateNew(totalSize, isShared, policy, nullptr); |
| } |
| ArrayBufferContents::ArrayBufferContents( |
| - void* data, unsigned sizeInBytes, ArrayBufferDeallocationObserver* observer) |
| - : m_data(data) |
| - , m_sizeInBytes(sizeInBytes) |
| - , m_deallocationObserver(observer) |
| + void* data, unsigned sizeInBytes, SharingType isShared, ArrayBufferDeallocationObserver* observer) |
| + : m_holder(adoptRef(new DataHolder())) |
| { |
| - if (!m_data) { |
| - ASSERT(!m_sizeInBytes); |
| - m_sizeInBytes = 0; |
| - // Allow null data if size is 0 bytes, make sure m_data is valid pointer. |
| + if (!data) { |
| + ASSERT(!sizeInBytes); |
| + sizeInBytes = 0; |
| + // Allow null data if size is 0 bytes, make sure data is valid pointer. |
| // (partitionAllocGeneric guarantees valid pointer for size 0) |
| - allocateMemory(0, ZeroInitialize, m_data); |
| + m_holder->allocateNew(sizeInBytes, isShared, ZeroInitialize, observer); |
| + } else { |
| + m_holder->adopt(data, sizeInBytes, isShared, observer); |
| } |
| } |
| ArrayBufferContents::~ArrayBufferContents() |
| { |
| - freeMemory(m_data, m_sizeInBytes); |
| clear(); |
| } |
| void ArrayBufferContents::clear() |
| { |
| - if (m_data && m_deallocationObserver) |
| - m_deallocationObserver->arrayBufferDeallocated(m_sizeInBytes); |
| - m_data = 0; |
| - m_sizeInBytes = 0; |
| - m_deallocationObserver = 0; |
| + m_holder.clear(); |
| } |
| void ArrayBufferContents::transfer(ArrayBufferContents& other) |
| { |
| - ASSERT(!other.m_data); |
| - other.m_data = m_data; |
| - other.m_sizeInBytes = m_sizeInBytes; |
| - clear(); |
| + ASSERT(!other.m_holder->data()); |
| + other.m_holder = m_holder; |
| + if (!m_holder->isShared()) |
| + clear(); |
| } |
| void ArrayBufferContents::copyTo(ArrayBufferContents& other) |
| { |
| - ASSERT(!other.m_sizeInBytes); |
| - other.freeMemory(other.m_data, other.m_sizeInBytes); |
| - allocateMemory(m_sizeInBytes, DontInitialize, other.m_data); |
| - if (!other.m_data) |
| - return; |
| - memcpy(other.m_data, m_data, m_sizeInBytes); |
| - other.m_sizeInBytes = m_sizeInBytes; |
| + // TODO(binji): where is this function used? It probably shouldn't be used |
|
haraken
2015/06/11 05:59:29
If it's unused, we can remove the function.
|
| + // for shared array buffers. |
| + ASSERT(!m_holder->isShared() && !other.m_holder->isShared()); |
| + m_holder->copyMemoryTo(*other.m_holder); |
| } |
| void ArrayBufferContents::allocateMemory(size_t size, InitializationPolicy policy, void*& data) |
| @@ -117,4 +104,69 @@ void ArrayBufferContents::freeMemory(void* data, size_t) |
| partitionFreeGeneric(WTF::Partitions::getBufferPartition(), data); |
| } |
| +ArrayBufferContents::DataHolder::DataHolder() |
| + : m_data(nullptr) |
| + , m_sizeInBytes(0) |
| + , m_isShared(NotShared) |
| + , m_deallocationObserver(nullptr) { } |
| + |
| +ArrayBufferContents::DataHolder::~DataHolder() |
| +{ |
| + ArrayBufferContents::freeMemory(m_data, m_sizeInBytes); |
| + |
| + if (m_data && m_deallocationObserver) |
|
haraken
2015/06/11 05:59:29
Is it possible that we have m_deallocationObserver
|
| + m_deallocationObserver->arrayBufferDeallocated(m_sizeInBytes); |
| + |
| + m_data = nullptr; |
| + m_sizeInBytes = 0; |
| + m_isShared = NotShared; |
| + m_deallocationObserver = nullptr; |
| +} |
| + |
| +void ArrayBufferContents::DataHolder::allocateNew(unsigned sizeInBytes, SharingType isShared, InitializationPolicy policy, ArrayBufferDeallocationObserver* observer) |
| +{ |
| + ASSERT(!m_data); |
| + void* data = nullptr; |
| + allocateMemory(sizeInBytes, policy, data); |
|
Yuki
2015/06/11 05:16:14
nit: Better to be consistent with the same style.
|
| + m_data = data; |
| + m_sizeInBytes = sizeInBytes; |
| + m_isShared = isShared; |
| + m_deallocationObserver = observer; |
| +} |
| + |
| +void ArrayBufferContents::DataHolder::adopt(void* data, unsigned sizeInBytes, SharingType isShared, ArrayBufferDeallocationObserver* observer) |
| +{ |
| + ASSERT(!m_data); |
| + m_data = data; |
| + m_sizeInBytes = sizeInBytes; |
| + m_isShared = isShared; |
| + m_deallocationObserver = observer; |
| +} |
| + |
| +void ArrayBufferContents::DataHolder::copyMemoryTo(DataHolder& other) |
| +{ |
| + ASSERT(!other.m_sizeInBytes); |
| + ArrayBufferContents::freeMemory(other.m_data, other.m_sizeInBytes); |
| + ArrayBufferContents::allocateMemory(m_sizeInBytes, DontInitialize, other.m_data); |
| + if (!other.m_data) |
| + return; |
| + memcpy(other.m_data, m_data, m_sizeInBytes); |
| + other.m_sizeInBytes = m_sizeInBytes; |
| +} |
| + |
| +void ArrayBufferContents::DataHolder::setDeallocationObserver(ArrayBufferDeallocationObserver& observer) |
| +{ |
| + if (!m_deallocationObserver) { |
| + m_deallocationObserver = &observer; |
| + m_deallocationObserver->blinkAllocatedMemory(m_sizeInBytes); |
| + } |
| +} |
| + |
| +void ArrayBufferContents::DataHolder::setDeallocationObserverWithoutAllocationNotification(ArrayBufferDeallocationObserver& observer) |
| +{ |
| + if (!m_deallocationObserver) { |
| + m_deallocationObserver = &observer; |
| + } |
| +} |
| + |
| } // namespace WTF |