Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef ContiguousContainer_h | 5 #ifndef ContiguousContainer_h |
| 6 #define ContiguousContainer_h | 6 #define ContiguousContainer_h |
| 7 | 7 |
| 8 #include "platform/PlatformExport.h" | 8 #include "platform/PlatformExport.h" |
| 9 #include "wtf/Alignment.h" | 9 #include "wtf/Alignment.h" |
| 10 #include "wtf/Allocator.h" | 10 #include "wtf/Allocator.h" |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 // supported operations are limited to appending to, and removing from, the end | 34 // supported operations are limited to appending to, and removing from, the end |
| 35 // of the list. | 35 // of the list. |
| 36 // | 36 // |
| 37 // Clients should instantiate ContiguousContainer; ContiguousContainerBase is an | 37 // Clients should instantiate ContiguousContainer; ContiguousContainerBase is an |
| 38 // artifact of the implementation. | 38 // artifact of the implementation. |
| 39 | 39 |
| 40 class PLATFORM_EXPORT ContiguousContainerBase { | 40 class PLATFORM_EXPORT ContiguousContainerBase { |
| 41 DISALLOW_NEW(); | 41 DISALLOW_NEW(); |
| 42 WTF_MAKE_NONCOPYABLE(ContiguousContainerBase); | 42 WTF_MAKE_NONCOPYABLE(ContiguousContainerBase); |
| 43 protected: | 43 protected: |
| 44 explicit ContiguousContainerBase(size_t maxObjectSize, const char* typeName) ; | 44 explicit ContiguousContainerBase(size_t maxObjectSize); |
| 45 ContiguousContainerBase(size_t maxObjectSize, size_t initialSizeBytes, const char* typeName); | |
| 46 ~ContiguousContainerBase(); | 45 ~ContiguousContainerBase(); |
| 47 | 46 |
| 48 size_t size() const { return m_elements.size(); } | 47 size_t size() const { return m_elements.size(); } |
| 49 bool isEmpty() const { return !size(); } | 48 bool isEmpty() const { return !size(); } |
| 50 size_t capacityInBytes() const; | 49 size_t capacityInBytes() const; |
| 51 size_t usedCapacityInBytes() const; | 50 size_t usedCapacityInBytes() const; |
| 52 size_t memoryUsageInBytes() const; | 51 size_t memoryUsageInBytes() const; |
| 53 | 52 |
| 54 // These do not invoke constructors or destructors. | 53 // These do not invoke constructors or destructors. |
| 54 void reserveInitialCapacity(size_t, const char* typeName); | |
| 55 void* allocate(size_t objectSize, const char* typeName); | 55 void* allocate(size_t objectSize, const char* typeName); |
| 56 void removeLast(); | 56 void removeLast(); |
| 57 void clear(); | 57 void clear(); |
| 58 void swap(ContiguousContainerBase&); | 58 void swap(ContiguousContainerBase&); |
| 59 | 59 |
| 60 Vector<void*> m_elements; | 60 Vector<void*> m_elements; |
| 61 | 61 |
| 62 private: | 62 private: |
| 63 class Buffer; | 63 class Buffer; |
| 64 | 64 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 BaseIterator m_it; | 101 BaseIterator m_it; |
| 102 friend class ContiguousContainer; | 102 friend class ContiguousContainer; |
| 103 }; | 103 }; |
| 104 | 104 |
| 105 public: | 105 public: |
| 106 using iterator = IteratorWrapper<Vector<void*>::iterator, BaseElementType>; | 106 using iterator = IteratorWrapper<Vector<void*>::iterator, BaseElementType>; |
| 107 using const_iterator = IteratorWrapper<Vector<void*>::const_iterator, const BaseElementType>; | 107 using const_iterator = IteratorWrapper<Vector<void*>::const_iterator, const BaseElementType>; |
| 108 using reverse_iterator = IteratorWrapper<Vector<void*>::reverse_iterator, Ba seElementType>; | 108 using reverse_iterator = IteratorWrapper<Vector<void*>::reverse_iterator, Ba seElementType>; |
| 109 using const_reverse_iterator = IteratorWrapper<Vector<void*>::const_reverse_ iterator, const BaseElementType>; | 109 using const_reverse_iterator = IteratorWrapper<Vector<void*>::const_reverse_ iterator, const BaseElementType>; |
| 110 | 110 |
| 111 explicit ContiguousContainer(size_t maxObjectSize) | 111 explicit ContiguousContainer(size_t maxObjectSize) : ContiguousContainerBase (align(maxObjectSize)) {} |
| 112 : ContiguousContainerBase(align(maxObjectSize), WTF_HEAP_PROFILER_TYPE_N AME(BaseElementType)) {} | 112 |
| 113 ContiguousContainer(size_t maxObjectSize, size_t initialSizeBytes) | 113 ContiguousContainer(size_t maxObjectSize, size_t initialSizeBytes) |
| 114 : ContiguousContainerBase(align(maxObjectSize), initialSizeBytes, WTF_HE AP_PROFILER_TYPE_NAME(BaseElementType)) {} | 114 : ContiguousContainer(maxObjectSize) |
| 115 { | |
| 116 reserveInitialCapacity(std::max(maxObjectSize, initialSizeBytes), WTF_HE AP_PROFILER_TYPE_NAME(BaseElementType)); | |
| 117 } | |
| 115 | 118 |
| 116 ~ContiguousContainer() | 119 ~ContiguousContainer() |
| 117 { | 120 { |
| 118 for (auto& element : *this) { | 121 for (auto& element : *this) { |
| 119 (void)element; // MSVC incorrectly reports this variable as unused. | 122 (void)element; // MSVC incorrectly reports this variable as unused. |
| 120 element.~BaseElementType(); | 123 element.~BaseElementType(); |
| 121 } | 124 } |
| 122 } | 125 } |
| 123 | 126 |
| 124 using ContiguousContainerBase::size; | 127 using ContiguousContainerBase::size; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 144 const BaseElementType& operator[](size_t index) const { return *(begin() + i ndex); } | 147 const BaseElementType& operator[](size_t index) const { return *(begin() + i ndex); } |
| 145 | 148 |
| 146 template <class DerivedElementType, typename... Args> | 149 template <class DerivedElementType, typename... Args> |
| 147 DerivedElementType& allocateAndConstruct(Args&&... args) | 150 DerivedElementType& allocateAndConstruct(Args&&... args) |
| 148 { | 151 { |
| 149 static_assert(WTF::IsSubclass<DerivedElementType, BaseElementType>::valu e, | 152 static_assert(WTF::IsSubclass<DerivedElementType, BaseElementType>::valu e, |
| 150 "Must use subclass of BaseElementType."); | 153 "Must use subclass of BaseElementType."); |
| 151 static_assert(alignment % WTF_ALIGN_OF(DerivedElementType) == 0, | 154 static_assert(alignment % WTF_ALIGN_OF(DerivedElementType) == 0, |
| 152 "Derived type requires stronger alignment."); | 155 "Derived type requires stronger alignment."); |
| 153 size_t allocSize = align(sizeof(DerivedElementType)); | 156 size_t allocSize = align(sizeof(DerivedElementType)); |
| 154 return *new (allocate(allocSize, WTF_HEAP_PROFILER_TYPE_NAME(DerivedElem entType))) DerivedElementType(std::forward<Args>(args)...); | 157 return *new (allocate(allocSize)) DerivedElementType(std::forward<Args>( args)...); |
|
Ruud van Asseldonk
2016/01/21 10:23:23
So now instead of reporting the type as |DerivedEl
jbroman
2016/01/21 14:23:18
Right.
| |
| 155 } | 158 } |
| 156 | 159 |
| 157 void removeLast() | 160 void removeLast() |
| 158 { | 161 { |
| 159 ASSERT(!isEmpty()); | 162 ASSERT(!isEmpty()); |
| 160 last().~BaseElementType(); | 163 last().~BaseElementType(); |
| 161 ContiguousContainerBase::removeLast(); | 164 ContiguousContainerBase::removeLast(); |
| 162 } | 165 } |
| 163 | 166 |
| 164 void clear() | 167 void clear() |
| 165 { | 168 { |
| 166 for (auto& element : *this) { | 169 for (auto& element : *this) { |
| 167 (void)element; // MSVC incorrectly reports this variable as unused. | 170 (void)element; // MSVC incorrectly reports this variable as unused. |
| 168 element.~BaseElementType(); | 171 element.~BaseElementType(); |
| 169 } | 172 } |
| 170 ContiguousContainerBase::clear(); | 173 ContiguousContainerBase::clear(); |
| 171 } | 174 } |
| 172 | 175 |
| 173 void swap(ContiguousContainer& other) { ContiguousContainerBase::swap(other) ; } | 176 void swap(ContiguousContainer& other) { ContiguousContainerBase::swap(other) ; } |
| 174 | 177 |
| 175 // Appends a new element using memcpy, then default-constructs a base | 178 // Appends a new element using memcpy, then default-constructs a base |
| 176 // element in its place. Use with care. | 179 // element in its place. Use with care. |
| 177 BaseElementType& appendByMoving(BaseElementType& item, size_t size) | 180 BaseElementType& appendByMoving(BaseElementType& item, size_t size) |
| 178 { | 181 { |
| 179 ASSERT(size >= sizeof(BaseElementType)); | 182 ASSERT(size >= sizeof(BaseElementType)); |
| 180 void* newItem = allocate(size, WTF_HEAP_PROFILER_TYPE_NAME(BaseElementTy pe)); | 183 void* newItem = allocate(size); |
| 181 memcpy(newItem, static_cast<void*>(&item), size); | 184 memcpy(newItem, static_cast<void*>(&item), size); |
| 182 new (&item) BaseElementType; | 185 new (&item) BaseElementType; |
| 183 return *static_cast<BaseElementType*>(newItem); | 186 return *static_cast<BaseElementType*>(newItem); |
| 184 } | 187 } |
| 185 | 188 |
| 186 private: | 189 private: |
| 190 void* allocate(size_t objectSize) | |
| 191 { | |
| 192 return ContiguousContainerBase::allocate(objectSize, WTF_HEAP_PROFILER_T YPE_NAME(BaseElementType)); | |
| 193 } | |
| 194 | |
| 187 static size_t align(size_t size) | 195 static size_t align(size_t size) |
| 188 { | 196 { |
| 189 size_t alignedSize = alignment * ((size + alignment - 1) / alignment); | 197 size_t alignedSize = alignment * ((size + alignment - 1) / alignment); |
| 190 ASSERT(alignedSize % alignment == 0); | 198 ASSERT(alignedSize % alignment == 0); |
| 191 ASSERT(alignedSize >= size); | 199 ASSERT(alignedSize >= size); |
| 192 ASSERT(alignedSize < size + alignment); | 200 ASSERT(alignedSize < size + alignment); |
| 193 return alignedSize; | 201 return alignedSize; |
| 194 } | 202 } |
| 195 }; | 203 }; |
| 196 | 204 |
| 197 } // namespace blink | 205 } // namespace blink |
| 198 | 206 |
| 199 #endif // ContiguousContainer_h | 207 #endif // ContiguousContainer_h |
| OLD | NEW |