| 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));
|
| }
|
| };
|
|
|
|
|