Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(654)

Unified Diff: third_party/WebKit/Source/platform/graphics/ContiguousContainer.cpp

Issue 2119033003: Fix alignment issue of ContiguousContainer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/graphics/ContiguousContainer.cpp
diff --git a/third_party/WebKit/Source/platform/graphics/ContiguousContainer.cpp b/third_party/WebKit/Source/platform/graphics/ContiguousContainer.cpp
index cb42fefa480b0aa32f03d22131e9d8205945ed00..82959c78bb0f180620b1a97d6171d69508d6da16 100644
--- a/third_party/WebKit/Source/platform/graphics/ContiguousContainer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ContiguousContainer.cpp
@@ -18,6 +18,16 @@ namespace blink {
// initial buffer.
static const unsigned kDefaultInitialBufferSize = 32;
+static inline char* alignAddress(char* address, unsigned log2Alignment)
+{
+ char* aligned = reinterpret_cast<char*>(
+ (((reinterpret_cast<size_t>(address) - 1) >> log2Alignment) + 1) << log2Alignment);
jbroman 2016/07/04 19:21:35 why size_t and not uintptr_t?
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(aligned) % (1 << log2Alignment));
+ DCHECK(aligned >= address);
+ DCHECK(aligned < address + (1 << log2Alignment));
+ return aligned;
+}
+
class ContiguousContainerBase::Buffer {
WTF_MAKE_NONCOPYABLE(Buffer);
USING_FAST_MALLOC(Buffer);
@@ -38,17 +48,25 @@ public:
size_t capacity() const { return m_capacity; }
size_t usedCapacity() const { return m_end - m_begin; }
- size_t unusedCapacity() const { return capacity() - usedCapacity(); }
bool isEmpty() const { return usedCapacity() == 0; }
- void* allocate(size_t objectSize)
+ void* allocate(size_t objectSize, unsigned log2Alignment)
{
- ASSERT(unusedCapacity() >= objectSize);
+ char* alignedAddress;
+ if (isEmpty()) {
+ // m_begin's alignment must be suitable for all possible types.
+ DCHECK(m_begin == alignAddress(m_begin, log2Alignment));
+ DCHECK(objectSize <= m_capacity);
+ alignedAddress = m_begin;
+ } else {
+ alignedAddress = alignAddress(m_end, log2Alignment);
+ if (alignedAddress - m_begin + objectSize > m_capacity)
+ return nullptr;
+ }
ANNOTATE_CHANGE_SIZE(
- m_begin, m_capacity, usedCapacity(), usedCapacity() + objectSize);
- void* result = m_end;
- m_end += objectSize;
- return result;
+ m_begin, m_capacity, usedCapacity(), usedCapacity() + (alignedAddress - m_end) + objectSize);
+ m_end = alignedAddress + objectSize;
+ return alignedAddress;
}
void deallocateLastObject(void* object)
@@ -57,6 +75,8 @@ public:
ANNOTATE_CHANGE_SIZE(
m_begin, m_capacity, usedCapacity(), static_cast<char*>(object) - m_begin);
m_end = static_cast<char*>(object);
+ // We may leave a gap between the end of the previous object (which we don't know)
+ // and m_end because of alignment of the deallocated object.
jbroman 2016/07/04 19:21:35 ...which seems weird to me.
}
private:
@@ -115,27 +135,24 @@ void ContiguousContainerBase::reserveInitialCapacity(size_t bufferSize, const ch
allocateNewBufferForNextAllocation(bufferSize, typeName);
}
-void* ContiguousContainerBase::allocate(size_t objectSize, const char* typeName)
+void* ContiguousContainerBase::allocate(size_t objectSize, unsigned log2Alignment, const char* typeName)
{
- ASSERT(objectSize <= m_maxObjectSize);
-
- Buffer* bufferForAlloc = nullptr;
- if (!m_buffers.isEmpty()) {
- Buffer* endBuffer = m_buffers[m_endIndex].get();
- if (endBuffer->unusedCapacity() >= objectSize)
- bufferForAlloc = endBuffer;
- else if (m_endIndex + 1 < m_buffers.size())
- bufferForAlloc = m_buffers[++m_endIndex].get();
- }
+ DCHECK(objectSize <= m_maxObjectSize);
- if (!bufferForAlloc) {
- size_t newBufferSize = m_buffers.isEmpty()
- ? kDefaultInitialBufferSize * m_maxObjectSize
- : 2 * m_buffers.last()->capacity();
- bufferForAlloc = allocateNewBufferForNextAllocation(newBufferSize, typeName);
+ void* element = m_buffers.isEmpty() ? nullptr : m_buffers[m_endIndex]->allocate(objectSize, log2Alignment);
+ if (!element) {
+ Buffer* bufferForAlloc;
+ if (m_endIndex + 1 < m_buffers.size()) {
+ bufferForAlloc = m_buffers[++m_endIndex].get();
+ } else {
+ size_t newBufferSize = m_buffers.isEmpty()
+ ? kDefaultInitialBufferSize * m_maxObjectSize
+ : 2 * m_buffers.last()->capacity();
+ bufferForAlloc = allocateNewBufferForNextAllocation(newBufferSize, typeName);
+ }
+ element = bufferForAlloc->allocate(objectSize, log2Alignment);
+ DCHECK(element);
}
-
- void* element = bufferForAlloc->allocate(objectSize);
m_elements.append(element);
return element;
}

Powered by Google App Engine
This is Rietveld 408576698