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

Side by Side Diff: third_party/WebKit/Source/wtf/HashTraits.h

Issue 2769603002: Move files in wtf/ to platform/wtf/ (Part 8). (Closed)
Patch Set: Rebase. Created 3 years, 9 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 unified diff | Download patch
OLDNEW
1 /* 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights 2 // Use of this source code is governed by a BSD-style license that can be
3 * reserved. 3 // found in the LICENSE file.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21 4
22 #ifndef WTF_HashTraits_h 5 #include "platform/wtf/HashTraits.h"
23 #define WTF_HashTraits_h
24 6
25 #include "wtf/Forward.h" 7 // The contents of this header was moved to platform/wtf as part of
26 #include "wtf/HashFunctions.h" 8 // WTF migration project. See the following post for details:
27 #include "wtf/HashTableDeletedValueType.h" 9 // https://groups.google.com/a/chromium.org/d/msg/blink-dev/tLdAZCTlcAA/bYXVT8gY CAAJ
28 #include "wtf/StdLibExtras.h"
29 #include "wtf/TypeTraits.h"
30 #include <limits>
31 #include <memory>
32 #include <string.h> // For memset.
33 #include <type_traits>
34 #include <utility>
35
36 namespace WTF {
37
38 template <bool isInteger, typename T>
39 struct GenericHashTraitsBase;
40 template <typename T>
41 struct HashTraits;
42
43 enum ShouldWeakPointersBeMarkedStrongly {
44 WeakPointersActStrong,
45 WeakPointersActWeak
46 };
47
48 template <typename T>
49 struct GenericHashTraitsBase<false, T> {
50 // The emptyValueIsZero flag is used to optimize allocation of empty hash
51 // tables with zeroed memory.
52 static const bool emptyValueIsZero = false;
53
54 // The hasIsEmptyValueFunction flag allows the hash table to automatically
55 // generate code to check for the empty value when it can be done with the
56 // equality operator, but allows custom functions for cases like String that
57 // need them.
58 static const bool hasIsEmptyValueFunction = false;
59
60 // The starting table size. Can be overridden when we know beforehand that a
61 // hash table will have at least N entries.
62 #if defined(MEMORY_SANITIZER_INITIAL_SIZE)
63 static const unsigned minimumTableSize = 1;
64 #else
65 static const unsigned minimumTableSize = 8;
66 #endif
67
68 // When a hash table backing store is traced, its elements will be
69 // traced if their class type has a trace method. However, weak-referenced
70 // elements should not be traced then, but handled by the weak processing
71 // phase that follows.
72 template <typename U = void>
73 struct IsTraceableInCollection {
74 static const bool value = IsTraceable<T>::value && !IsWeak<T>::value;
75 };
76
77 // The NeedsToForbidGCOnMove flag is used to make the hash table move
78 // operations safe when GC is enabled: if a move constructor invokes
79 // an allocation triggering the GC then it should be invoked within GC
80 // forbidden scope.
81 template <typename U = void>
82 struct NeedsToForbidGCOnMove {
83 // TODO(yutak): Consider using of std:::is_trivially_move_constructible
84 // when it is accessible.
85 static const bool value = !std::is_pod<T>::value;
86 };
87
88 static const WeakHandlingFlag weakHandlingFlag =
89 IsWeak<T>::value ? WeakHandlingInCollections
90 : NoWeakHandlingInCollections;
91 };
92
93 // Default integer traits disallow both 0 and -1 as keys (max value instead of
94 // -1 for unsigned).
95 template <typename T>
96 struct GenericHashTraitsBase<true, T> : GenericHashTraitsBase<false, T> {
97 static const bool emptyValueIsZero = true;
98 static void constructDeletedValue(T& slot, bool) {
99 slot = static_cast<T>(-1);
100 }
101 static bool isDeletedValue(T value) { return value == static_cast<T>(-1); }
102 };
103
104 template <typename T>
105 struct GenericHashTraits
106 : GenericHashTraitsBase<std::is_integral<T>::value, T> {
107 typedef T TraitType;
108 typedef T EmptyValueType;
109
110 static T emptyValue() { return T(); }
111
112 // Type for functions that do not take ownership, such as contains.
113 typedef const T& PeekInType;
114 typedef T* IteratorGetType;
115 typedef const T* IteratorConstGetType;
116 typedef T& IteratorReferenceType;
117 typedef const T& IteratorConstReferenceType;
118 static IteratorReferenceType getToReferenceConversion(IteratorGetType x) {
119 return *x;
120 }
121 static IteratorConstReferenceType getToReferenceConstConversion(
122 IteratorConstGetType x) {
123 return *x;
124 }
125
126 template <typename IncomingValueType>
127 static void store(IncomingValueType&& value, T& storage) {
128 storage = std::forward<IncomingValueType>(value);
129 }
130
131 // Type for return value of functions that do not transfer ownership, such
132 // as get.
133 // FIXME: We could change this type to const T& for better performance if we
134 // figured out a way to handle the return value from emptyValue, which is a
135 // temporary.
136 typedef T PeekOutType;
137 static const T& peek(const T& value) { return value; }
138 };
139
140 template <typename T>
141 struct HashTraits : GenericHashTraits<T> {};
142
143 template <typename T>
144 struct FloatHashTraits : GenericHashTraits<T> {
145 static T emptyValue() { return std::numeric_limits<T>::infinity(); }
146 static void constructDeletedValue(T& slot, bool) {
147 slot = -std::numeric_limits<T>::infinity();
148 }
149 static bool isDeletedValue(T value) {
150 return value == -std::numeric_limits<T>::infinity();
151 }
152 };
153
154 template <>
155 struct HashTraits<float> : FloatHashTraits<float> {};
156 template <>
157 struct HashTraits<double> : FloatHashTraits<double> {};
158
159 // Default unsigned traits disallow both 0 and max as keys -- use these traits
160 // to allow zero and disallow max - 1.
161 template <typename T>
162 struct UnsignedWithZeroKeyHashTraits : GenericHashTraits<T> {
163 static const bool emptyValueIsZero = false;
164 static T emptyValue() { return std::numeric_limits<T>::max(); }
165 static void constructDeletedValue(T& slot, bool) {
166 slot = std::numeric_limits<T>::max() - 1;
167 }
168 static bool isDeletedValue(T value) {
169 return value == std::numeric_limits<T>::max() - 1;
170 }
171 };
172
173 template <typename P>
174 struct HashTraits<P*> : GenericHashTraits<P*> {
175 static const bool emptyValueIsZero = true;
176 static void constructDeletedValue(P*& slot, bool) {
177 slot = reinterpret_cast<P*>(-1);
178 }
179 static bool isDeletedValue(P* value) {
180 return value == reinterpret_cast<P*>(-1);
181 }
182 };
183
184 template <typename T>
185 struct SimpleClassHashTraits : GenericHashTraits<T> {
186 static const bool emptyValueIsZero = true;
187 template <typename U = void>
188 struct NeedsToForbidGCOnMove {
189 static const bool value = false;
190 };
191 static void constructDeletedValue(T& slot, bool) {
192 new (NotNull, &slot) T(HashTableDeletedValue);
193 }
194 static bool isDeletedValue(const T& value) {
195 return value.isHashTableDeletedValue();
196 }
197 };
198
199 template <typename P>
200 struct HashTraits<RefPtr<P>> : SimpleClassHashTraits<RefPtr<P>> {
201 typedef std::nullptr_t EmptyValueType;
202 static EmptyValueType emptyValue() { return nullptr; }
203
204 static const bool hasIsEmptyValueFunction = true;
205 static bool isEmptyValue(const RefPtr<P>& value) { return !value; }
206
207 typedef RefPtrValuePeeker<P> PeekInType;
208 typedef RefPtr<P>* IteratorGetType;
209 typedef const RefPtr<P>* IteratorConstGetType;
210 typedef RefPtr<P>& IteratorReferenceType;
211 typedef const RefPtr<P>& IteratorConstReferenceType;
212 static IteratorReferenceType getToReferenceConversion(IteratorGetType x) {
213 return *x;
214 }
215 static IteratorConstReferenceType getToReferenceConstConversion(
216 IteratorConstGetType x) {
217 return *x;
218 }
219
220 static void store(PassRefPtr<P> value, RefPtr<P>& storage) {
221 storage = std::move(value);
222 }
223
224 typedef P* PeekOutType;
225 static PeekOutType peek(const RefPtr<P>& value) { return value.get(); }
226 static PeekOutType peek(std::nullptr_t) { return 0; }
227 };
228
229 template <typename T>
230 struct HashTraits<std::unique_ptr<T>>
231 : SimpleClassHashTraits<std::unique_ptr<T>> {
232 using EmptyValueType = std::nullptr_t;
233 static EmptyValueType emptyValue() { return nullptr; }
234
235 static const bool hasIsEmptyValueFunction = true;
236 static bool isEmptyValue(const std::unique_ptr<T>& value) { return !value; }
237
238 using PeekInType = T*;
239
240 static void store(std::unique_ptr<T>&& value, std::unique_ptr<T>& storage) {
241 storage = std::move(value);
242 }
243
244 using PeekOutType = T*;
245 static PeekOutType peek(const std::unique_ptr<T>& value) {
246 return value.get();
247 }
248 static PeekOutType peek(std::nullptr_t) { return nullptr; }
249
250 static void constructDeletedValue(std::unique_ptr<T>& slot, bool) {
251 // Dirty trick: implant an invalid pointer to unique_ptr. Destructor isn't
252 // called for deleted buckets, so this is okay.
253 new (NotNull, &slot) std::unique_ptr<T>(reinterpret_cast<T*>(1u));
254 }
255 static bool isDeletedValue(const std::unique_ptr<T>& value) {
256 return value.get() == reinterpret_cast<T*>(1u);
257 }
258 };
259
260 template <>
261 struct HashTraits<String> : SimpleClassHashTraits<String> {
262 static const bool hasIsEmptyValueFunction = true;
263 static bool isEmptyValue(const String&);
264 };
265
266 // This struct template is an implementation detail of the
267 // isHashTraitsEmptyValue function, which selects either the emptyValue function
268 // or the isEmptyValue function to check for empty values.
269 template <typename Traits, bool hasEmptyValueFunction>
270 struct HashTraitsEmptyValueChecker;
271 template <typename Traits>
272 struct HashTraitsEmptyValueChecker<Traits, true> {
273 template <typename T>
274 static bool isEmptyValue(const T& value) {
275 return Traits::isEmptyValue(value);
276 }
277 };
278 template <typename Traits>
279 struct HashTraitsEmptyValueChecker<Traits, false> {
280 template <typename T>
281 static bool isEmptyValue(const T& value) {
282 return value == Traits::emptyValue();
283 }
284 };
285 template <typename Traits, typename T>
286 inline bool isHashTraitsEmptyValue(const T& value) {
287 return HashTraitsEmptyValueChecker<
288 Traits, Traits::hasIsEmptyValueFunction>::isEmptyValue(value);
289 }
290
291 template <typename FirstTraitsArg, typename SecondTraitsArg>
292 struct PairHashTraits
293 : GenericHashTraits<std::pair<typename FirstTraitsArg::TraitType,
294 typename SecondTraitsArg::TraitType>> {
295 typedef FirstTraitsArg FirstTraits;
296 typedef SecondTraitsArg SecondTraits;
297 typedef std::pair<typename FirstTraits::TraitType,
298 typename SecondTraits::TraitType>
299 TraitType;
300 typedef std::pair<typename FirstTraits::EmptyValueType,
301 typename SecondTraits::EmptyValueType>
302 EmptyValueType;
303
304 static const bool emptyValueIsZero =
305 FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero;
306 static EmptyValueType emptyValue() {
307 return std::make_pair(FirstTraits::emptyValue(),
308 SecondTraits::emptyValue());
309 }
310
311 static const bool hasIsEmptyValueFunction =
312 FirstTraits::hasIsEmptyValueFunction ||
313 SecondTraits::hasIsEmptyValueFunction;
314 static bool isEmptyValue(const TraitType& value) {
315 return isHashTraitsEmptyValue<FirstTraits>(value.first) &&
316 isHashTraitsEmptyValue<SecondTraits>(value.second);
317 }
318
319 static const unsigned minimumTableSize = FirstTraits::minimumTableSize;
320
321 static void constructDeletedValue(TraitType& slot, bool zeroValue) {
322 FirstTraits::constructDeletedValue(slot.first, zeroValue);
323 // For GC collections the memory for the backing is zeroed when it is
324 // allocated, and the constructors may take advantage of that,
325 // especially if a GC occurs during insertion of an entry into the
326 // table. This slot is being marked deleted, but If the slot is reused
327 // at a later point, the same assumptions around memory zeroing must
328 // hold as they did at the initial allocation. Therefore we zero the
329 // value part of the slot here for GC collections.
330 if (zeroValue)
331 memset(reinterpret_cast<void*>(&slot.second), 0, sizeof(slot.second));
332 }
333 static bool isDeletedValue(const TraitType& value) {
334 return FirstTraits::isDeletedValue(value.first);
335 }
336 };
337
338 template <typename First, typename Second>
339 struct HashTraits<std::pair<First, Second>>
340 : public PairHashTraits<HashTraits<First>, HashTraits<Second>> {};
341
342 template <typename KeyTypeArg, typename ValueTypeArg>
343 struct KeyValuePair {
344 typedef KeyTypeArg KeyType;
345
346 template <typename IncomingKeyType, typename IncomingValueType>
347 KeyValuePair(IncomingKeyType&& key, IncomingValueType&& value)
348 : key(std::forward<IncomingKeyType>(key)),
349 value(std::forward<IncomingValueType>(value)) {}
350
351 template <typename OtherKeyType, typename OtherValueType>
352 KeyValuePair(KeyValuePair<OtherKeyType, OtherValueType>&& other)
353 : key(std::move(other.key)), value(std::move(other.value)) {}
354
355 KeyTypeArg key;
356 ValueTypeArg value;
357 };
358
359 template <typename KeyTraitsArg, typename ValueTraitsArg>
360 struct KeyValuePairHashTraits
361 : GenericHashTraits<KeyValuePair<typename KeyTraitsArg::TraitType,
362 typename ValueTraitsArg::TraitType>> {
363 typedef KeyTraitsArg KeyTraits;
364 typedef ValueTraitsArg ValueTraits;
365 typedef KeyValuePair<typename KeyTraits::TraitType,
366 typename ValueTraits::TraitType>
367 TraitType;
368 typedef KeyValuePair<typename KeyTraits::EmptyValueType,
369 typename ValueTraits::EmptyValueType>
370 EmptyValueType;
371
372 static const bool emptyValueIsZero =
373 KeyTraits::emptyValueIsZero && ValueTraits::emptyValueIsZero;
374 static EmptyValueType emptyValue() {
375 return KeyValuePair<typename KeyTraits::EmptyValueType,
376 typename ValueTraits::EmptyValueType>(
377 KeyTraits::emptyValue(), ValueTraits::emptyValue());
378 }
379
380 template <typename U = void>
381 struct IsTraceableInCollection {
382 static const bool value = IsTraceableInCollectionTrait<KeyTraits>::value ||
383 IsTraceableInCollectionTrait<ValueTraits>::value;
384 };
385
386 template <typename U = void>
387 struct NeedsToForbidGCOnMove {
388 static const bool value =
389 KeyTraits::template NeedsToForbidGCOnMove<>::value ||
390 ValueTraits::template NeedsToForbidGCOnMove<>::value;
391 };
392
393 static const WeakHandlingFlag weakHandlingFlag =
394 (KeyTraits::weakHandlingFlag == WeakHandlingInCollections ||
395 ValueTraits::weakHandlingFlag == WeakHandlingInCollections)
396 ? WeakHandlingInCollections
397 : NoWeakHandlingInCollections;
398
399 static const unsigned minimumTableSize = KeyTraits::minimumTableSize;
400
401 static void constructDeletedValue(TraitType& slot, bool zeroValue) {
402 KeyTraits::constructDeletedValue(slot.key, zeroValue);
403 // See similar code in this file for why we need to do this.
404 if (zeroValue)
405 memset(reinterpret_cast<void*>(&slot.value), 0, sizeof(slot.value));
406 }
407 static bool isDeletedValue(const TraitType& value) {
408 return KeyTraits::isDeletedValue(value.key);
409 }
410 };
411
412 template <typename Key, typename Value>
413 struct HashTraits<KeyValuePair<Key, Value>>
414 : public KeyValuePairHashTraits<HashTraits<Key>, HashTraits<Value>> {};
415
416 template <typename T>
417 struct NullableHashTraits : public HashTraits<T> {
418 static const bool emptyValueIsZero = false;
419 static T emptyValue() { return reinterpret_cast<T>(1); }
420 };
421
422 } // namespace WTF
423
424 using WTF::HashTraits;
425 using WTF::PairHashTraits;
426 using WTF::NullableHashTraits;
427 using WTF::SimpleClassHashTraits;
428
429 #endif // WTF_HashTraits_h
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/HashTable.cpp ('k') | third_party/WebKit/Source/wtf/LinkedHashSet.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698