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 |