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

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

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.h
diff --git a/third_party/WebKit/Source/platform/graphics/ContiguousContainer.h b/third_party/WebKit/Source/platform/graphics/ContiguousContainer.h
index a50431becefb31c3ab4a231c74212f66ea67bf33..ca8349e07eeabb716f90d56ca857a162b336cf97 100644
--- a/third_party/WebKit/Source/platform/graphics/ContiguousContainer.h
+++ b/third_party/WebKit/Source/platform/graphics/ContiguousContainer.h
@@ -19,6 +19,28 @@
namespace blink {
+namespace internal {
+template <size_t input> struct Log2 { };
+template<> struct Log2<1> {
+ static const unsigned value = 0;
+};
+template<> struct Log2<2> {
+ static const unsigned value = 1;
+};
+template<> struct Log2<4> {
+ static const unsigned value = 2;
+};
+template<> struct Log2<8> {
+ static const unsigned value = 3;
+};
+template<> struct Log2<16> {
+ static const unsigned value = 4;
+};
+}
+
+template<typename T>
+unsigned log2Alignment() { return internal::Log2<WTF_ALIGN_OF(T)>::value; }
+
// ContiguousContainer is a container which stores a list of heterogeneous
// objects (in particular, of varying sizes), packed next to one another in
// memory. Objects are never relocated, so it is safe to store pointers to them
@@ -55,7 +77,7 @@ protected:
// These do not invoke constructors or destructors.
void reserveInitialCapacity(size_t, const char* typeName);
- void* allocate(size_t objectSize, const char* typeName);
+ void* allocate(size_t objectSize, unsigned log2Alignment, const char* typeName);
void removeLast();
void clear();
void swap(ContiguousContainerBase&);
@@ -72,13 +94,7 @@ private:
size_t m_maxObjectSize;
};
-// For most cases, no alignment stricter than pointer alignment is required. If
-// one of the derived classes has stronger alignment requirements (and the
-// static_assert fires), set alignment to the LCM of the derived class
-// alignments. For small structs without pointers, it may be possible to reduce
-// alignment for tighter packing.
-
-template <class BaseElementType, unsigned alignment = sizeof(void*)>
+template <class BaseElementType>
class ContiguousContainer : public ContiguousContainerBase {
private:
// Declares itself as a forward iterator, but also supports a few more
@@ -108,7 +124,7 @@ public:
using reverse_iterator = IteratorWrapper<Vector<void*>::reverse_iterator, BaseElementType>;
using const_reverse_iterator = IteratorWrapper<Vector<void*>::const_reverse_iterator, const BaseElementType>;
- explicit ContiguousContainer(size_t maxObjectSize) : ContiguousContainerBase(align(maxObjectSize)) {}
+ explicit ContiguousContainer(size_t maxObjectSize) : ContiguousContainerBase(maxObjectSize) {}
ContiguousContainer(size_t maxObjectSize, size_t initialSizeBytes)
: ContiguousContainer(maxObjectSize)
@@ -164,10 +180,8 @@ public:
{
static_assert(WTF::IsSubclass<DerivedElementType, BaseElementType>::value,
"Must use subclass of BaseElementType.");
- static_assert(alignment % WTF_ALIGN_OF(DerivedElementType) == 0,
- "Derived type requires stronger alignment.");
- size_t allocSize = align(sizeof(DerivedElementType));
- return *new (allocate(allocSize)) DerivedElementType(std::forward<Args>(args)...);
+ return *new (allocate(sizeof(DerivedElementType), log2Alignment<DerivedElementType>()))
+ DerivedElementType(std::forward<Args>(args)...);
}
void removeLast()
@@ -190,28 +204,21 @@ public:
// Appends a new element using memcpy, then default-constructs a base
// element in its place. Use with care.
- BaseElementType& appendByMoving(BaseElementType& item, size_t size)
+ BaseElementType& appendByMoving(BaseElementType& item, size_t size, unsigned log2Alignment)
{
ASSERT(size >= sizeof(BaseElementType));
- void* newItem = allocate(size);
+ void* newItem = allocate(size, log2Alignment);
memcpy(newItem, static_cast<void*>(&item), size);
new (&item) BaseElementType;
return *static_cast<BaseElementType*>(newItem);
}
private:
- void* allocate(size_t objectSize)
- {
- return ContiguousContainerBase::allocate(objectSize, WTF_HEAP_PROFILER_TYPE_NAME(BaseElementType));
- }
+ FRIEND_TEST_ALL_PREFIXES(ContiguousContainerTest, Alignment);
- static size_t align(size_t size)
+ void* allocate(size_t objectSize, size_t log2Alignment)
{
- size_t alignedSize = alignment * ((size + alignment - 1) / alignment);
- ASSERT(alignedSize % alignment == 0);
- ASSERT(alignedSize >= size);
- ASSERT(alignedSize < size + alignment);
- return alignedSize;
+ return ContiguousContainerBase::allocate(objectSize, log2Alignment, WTF_HEAP_PROFILER_TYPE_NAME(BaseElementType));
}
};

Powered by Google App Engine
This is Rietveld 408576698