Index: Source/wtf/ArrayBufferContents.cpp |
diff --git a/Source/wtf/ArrayBufferContents.cpp b/Source/wtf/ArrayBufferContents.cpp |
index 71f4bf99e84c63f460579f5417e955bda5fcd73f..7c6177923d6d57be77588decbafa9b37d33ce50f 100644 |
--- a/Source/wtf/ArrayBufferContents.cpp |
+++ b/Source/wtf/ArrayBufferContents.cpp |
@@ -34,75 +34,101 @@ |
namespace WTF { |
-ArrayBufferContents::ArrayBufferContents() |
+ |
+DataHolder::DataHolder() |
: m_data(0) |
, m_sizeInBytes(0) |
+ , m_shared(false) { } |
+ |
+DataHolder::~DataHolder() |
+{ |
+ // if (m_data) { |
+ // printf("Destroy data: %p size: %d shared: %d refs: %d\n", m_data, m_sizeInBytes, m_shared, refCount()); |
+ // } |
+ partitionFreeGeneric(WTF::Partitions::getBufferPartition(), m_data); |
+ m_data = 0; |
+ m_sizeInBytes = 0; |
+ m_shared = false; |
+} |
+ |
+void DataHolder::adopt(void* data, unsigned sizeInBytes, bool shared) |
+{ |
+ ASSERT(!m_data); |
+ m_data = data; |
+ m_sizeInBytes = sizeInBytes; |
+ m_shared = shared; |
+ // printf("Adopt data: %p size: %d shared: %d refs: %d\n", m_data, m_sizeInBytes, m_shared, refCount()); |
+} |
+ |
+ArrayBufferContents::ArrayBufferContents() |
+ : m_holder(adoptRef(new DataHolder())) |
, m_deallocationObserver(0) { } |
ArrayBufferContents::ArrayBufferContents(unsigned numElements, unsigned elementByteSize, ArrayBufferContents::InitializationPolicy policy) |
- : m_data(0) |
- , m_sizeInBytes(0) |
+ : m_holder(adoptRef(new DataHolder())) |
, m_deallocationObserver(0) |
{ |
+ unsigned totalSize = numElements * elementByteSize; |
// Do not allow 32-bit overflow of the total size. |
if (numElements) { |
- unsigned totalSize = numElements * elementByteSize; |
if (totalSize / numElements != elementByteSize) { |
- m_data = 0; |
return; |
} |
} |
- allocateMemory(numElements * elementByteSize, policy, m_data); |
- m_sizeInBytes = numElements * elementByteSize; |
+ void* data = 0; |
+ allocateMemory(totalSize, policy, data); |
+ m_holder->adopt(data, totalSize, false); |
} |
ArrayBufferContents::ArrayBufferContents( |
- void* data, unsigned sizeInBytes, ArrayBufferDeallocationObserver* observer) |
- : m_data(data) |
- , m_sizeInBytes(sizeInBytes) |
+ void* data, unsigned sizeInBytes, bool shared, ArrayBufferDeallocationObserver* observer) |
+ : m_holder(adoptRef(new DataHolder())) |
, m_deallocationObserver(observer) |
{ |
- if (!m_data) { |
- ASSERT(!m_sizeInBytes); |
- m_sizeInBytes = 0; |
+ if (!data) { |
+ ASSERT(!sizeInBytes); |
+ sizeInBytes = 0; |
// Allow null data if size is 0 bytes, make sure m_data is valid pointer. |
// (partitionAllocGeneric guarantees valid pointer for size 0) |
- allocateMemory(0, ZeroInitialize, m_data); |
+ allocateMemory(0, ZeroInitialize, data); |
} |
+ m_holder->adopt(data, sizeInBytes, shared); |
} |
ArrayBufferContents::~ArrayBufferContents() |
{ |
- freeMemory(m_data, m_sizeInBytes); |
+ // 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; |
+ if (m_holder->m_data && m_deallocationObserver) |
+ m_deallocationObserver->arrayBufferDeallocated(m_holder->m_sizeInBytes); |
+ m_holder = adoptRef(new DataHolder()); |
m_deallocationObserver = 0; |
} |
void ArrayBufferContents::transfer(ArrayBufferContents& other) |
{ |
- ASSERT(!other.m_data); |
- other.m_data = m_data; |
- other.m_sizeInBytes = m_sizeInBytes; |
- clear(); |
+ ASSERT(!other.m_holder->m_data); |
+ // TODO mark the memory as allocated in new context? |
+ other.m_holder = m_holder; |
+ if (!m_holder->m_shared) { |
+ 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) |
+ ASSERT(!other.m_holder->m_sizeInBytes); |
+ other.m_holder = adoptRef(new DataHolder()); |
+ void* data = 0; |
+ allocateMemory(m_holder->m_sizeInBytes, DontInitialize, data); |
+ if (!data) |
return; |
- memcpy(other.m_data, m_data, m_sizeInBytes); |
- other.m_sizeInBytes = m_sizeInBytes; |
+ memcpy(data, m_holder->m_data, m_holder->m_sizeInBytes); |
+ other.m_holder->adopt(data, m_holder->m_sizeInBytes, false); |
} |
void ArrayBufferContents::allocateMemory(size_t size, InitializationPolicy policy, void*& data) |