/work/obj-fuzz/dist/include/mozilla/HashFunctions.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | /* Utilities for hashing. */ |
8 | | |
9 | | /* |
10 | | * This file exports functions for hashing data down to a uint32_t (a.k.a. |
11 | | * mozilla::HashNumber), including: |
12 | | * |
13 | | * - HashString Hash a char* or char16_t/wchar_t* of known or unknown |
14 | | * length. |
15 | | * |
16 | | * - HashBytes Hash a byte array of known length. |
17 | | * |
18 | | * - HashGeneric Hash one or more values. Currently, we support uint32_t, |
19 | | * types which can be implicitly cast to uint32_t, data |
20 | | * pointers, and function pointers. |
21 | | * |
22 | | * - AddToHash Add one or more values to the given hash. This supports the |
23 | | * same list of types as HashGeneric. |
24 | | * |
25 | | * |
26 | | * You can chain these functions together to hash complex objects. For example: |
27 | | * |
28 | | * class ComplexObject |
29 | | * { |
30 | | * char* mStr; |
31 | | * uint32_t mUint1, mUint2; |
32 | | * void (*mCallbackFn)(); |
33 | | * |
34 | | * public: |
35 | | * HashNumber hash() |
36 | | * { |
37 | | * HashNumber hash = HashString(mStr); |
38 | | * hash = AddToHash(hash, mUint1, mUint2); |
39 | | * return AddToHash(hash, mCallbackFn); |
40 | | * } |
41 | | * }; |
42 | | * |
43 | | * If you want to hash an nsAString or nsACString, use the HashString functions |
44 | | * in nsHashKeys.h. |
45 | | */ |
46 | | |
47 | | #ifndef mozilla_HashFunctions_h |
48 | | #define mozilla_HashFunctions_h |
49 | | |
50 | | #include "mozilla/Assertions.h" |
51 | | #include "mozilla/Attributes.h" |
52 | | #include "mozilla/Char16.h" |
53 | | #include "mozilla/MathAlgorithms.h" |
54 | | #include "mozilla/Types.h" |
55 | | #include "mozilla/WrappingOperations.h" |
56 | | |
57 | | #include <stdint.h> |
58 | | |
59 | | namespace mozilla { |
60 | | |
61 | | using HashNumber = uint32_t; |
62 | | static const uint32_t kHashNumberBits = 32; |
63 | | |
64 | | /** |
65 | | * The golden ratio as a 32-bit fixed-point value. |
66 | | */ |
67 | | static const HashNumber kGoldenRatioU32 = 0x9E3779B9U; |
68 | | |
69 | | /* |
70 | | * Given a raw hash code, h, return a number that can be used to select a hash |
71 | | * bucket. |
72 | | * |
73 | | * This function aims to produce as uniform an output distribution as possible, |
74 | | * especially in the most significant (leftmost) bits, even though the input |
75 | | * distribution may be highly nonrandom, given the constraints that this must |
76 | | * be deterministic and quick to compute. |
77 | | * |
78 | | * Since the leftmost bits of the result are best, the hash bucket index is |
79 | | * computed by doing ScrambleHashCode(h) / (2^32/N) or the equivalent |
80 | | * right-shift, not ScrambleHashCode(h) % N or the equivalent bit-mask. |
81 | | * |
82 | | * FIXME: OrderedHashTable uses a bit-mask; see bug 775896. |
83 | | */ |
84 | | constexpr HashNumber |
85 | | ScrambleHashCode(HashNumber h) |
86 | | { |
87 | | /* |
88 | | * Simply returning h would not cause any hash tables to produce wrong |
89 | | * answers. But it can produce pathologically bad performance: The caller |
90 | | * right-shifts the result, keeping only the highest bits. The high bits of |
91 | | * hash codes are very often completely entropy-free. (So are the lowest |
92 | | * bits.) |
93 | | * |
94 | | * So we use Fibonacci hashing, as described in Knuth, The Art of Computer |
95 | | * Programming, 6.4. This mixes all the bits of the input hash code h. |
96 | | * |
97 | | * The value of goldenRatio is taken from the hex expansion of the golden |
98 | | * ratio, which starts 1.9E3779B9.... This value is especially good if |
99 | | * values with consecutive hash codes are stored in a hash table; see Knuth |
100 | | * for details. |
101 | | */ |
102 | | return mozilla::WrappingMultiply(h, kGoldenRatioU32); |
103 | | } |
104 | | |
105 | | namespace detail { |
106 | | |
107 | | MOZ_NO_SANITIZE_UNSIGNED_OVERFLOW |
108 | | constexpr HashNumber |
109 | | RotateLeft5(HashNumber aValue) |
110 | 482M | { |
111 | 482M | return (aValue << 5) | (aValue >> 27); |
112 | 482M | } |
113 | | |
114 | | constexpr HashNumber |
115 | | AddU32ToHash(HashNumber aHash, uint32_t aValue) |
116 | 482M | { |
117 | 482M | /* |
118 | 482M | * This is the meat of all our hash routines. This hash function is not |
119 | 482M | * particularly sophisticated, but it seems to work well for our mostly |
120 | 482M | * plain-text inputs. Implementation notes follow. |
121 | 482M | * |
122 | 482M | * Our use of the golden ratio here is arbitrary; we could pick almost any |
123 | 482M | * number which: |
124 | 482M | * |
125 | 482M | * * is odd (because otherwise, all our hash values will be even) |
126 | 482M | * |
127 | 482M | * * has a reasonably-even mix of 1's and 0's (consider the extreme case |
128 | 482M | * where we multiply by 0x3 or 0xeffffff -- this will not produce good |
129 | 482M | * mixing across all bits of the hash). |
130 | 482M | * |
131 | 482M | * The rotation length of 5 is also arbitrary, although an odd number is again |
132 | 482M | * preferable so our hash explores the whole universe of possible rotations. |
133 | 482M | * |
134 | 482M | * Finally, we multiply by the golden ratio *after* xor'ing, not before. |
135 | 482M | * Otherwise, if |aHash| is 0 (as it often is for the beginning of a |
136 | 482M | * message), the expression |
137 | 482M | * |
138 | 482M | * mozilla::WrappingMultiply(kGoldenRatioU32, RotateLeft5(aHash)) |
139 | 482M | * |xor| |
140 | 482M | * aValue |
141 | 482M | * |
142 | 482M | * evaluates to |aValue|. |
143 | 482M | * |
144 | 482M | * (Number-theoretic aside: Because any odd number |m| is relatively prime to |
145 | 482M | * our modulus (2**32), the list |
146 | 482M | * |
147 | 482M | * [x * m (mod 2**32) for 0 <= x < 2**32] |
148 | 482M | * |
149 | 482M | * has no duplicate elements. This means that multiplying by |m| does not |
150 | 482M | * cause us to skip any possible hash values. |
151 | 482M | * |
152 | 482M | * It's also nice if |m| has large-ish order mod 2**32 -- that is, if the |
153 | 482M | * smallest k such that m**k == 1 (mod 2**32) is large -- so we can safely |
154 | 482M | * multiply our hash value by |m| a few times without negating the |
155 | 482M | * multiplicative effect. Our golden ratio constant has order 2**29, which is |
156 | 482M | * more than enough for our purposes.) |
157 | 482M | */ |
158 | 482M | return mozilla::WrappingMultiply(kGoldenRatioU32, |
159 | 482M | RotateLeft5(aHash) ^ aValue); |
160 | 482M | } |
161 | | |
162 | | /** |
163 | | * AddUintptrToHash takes sizeof(uintptr_t) as a template parameter. |
164 | | */ |
165 | | template<size_t PtrSize> |
166 | | constexpr HashNumber |
167 | | AddUintptrToHash(HashNumber aHash, uintptr_t aValue) |
168 | 238M | { |
169 | 238M | return AddU32ToHash(aHash, static_cast<uint32_t>(aValue)); |
170 | 238M | } unsigned int mozilla::detail::AddUintptrToHash<1ul>(unsigned int, unsigned long) Line | Count | Source | 168 | 200M | { | 169 | 200M | return AddU32ToHash(aHash, static_cast<uint32_t>(aValue)); | 170 | 200M | } |
unsigned int mozilla::detail::AddUintptrToHash<4ul>(unsigned int, unsigned long) Line | Count | Source | 168 | 37.6M | { | 169 | 37.6M | return AddU32ToHash(aHash, static_cast<uint32_t>(aValue)); | 170 | 37.6M | } |
|
171 | | |
172 | | template<> |
173 | | inline HashNumber |
174 | | AddUintptrToHash<8>(HashNumber aHash, uintptr_t aValue) |
175 | 117M | { |
176 | 117M | uint32_t v1 = static_cast<uint32_t>(aValue); |
177 | 117M | uint32_t v2 = static_cast<uint32_t>(static_cast<uint64_t>(aValue) >> 32); |
178 | 117M | return AddU32ToHash(AddU32ToHash(aHash, v1), v2); |
179 | 117M | } |
180 | | |
181 | | } /* namespace detail */ |
182 | | |
183 | | /** |
184 | | * AddToHash takes a hash and some values and returns a new hash based on the |
185 | | * inputs. |
186 | | * |
187 | | * Currently, we support hashing uint32_t's, values which we can implicitly |
188 | | * convert to uint32_t, data pointers, and function pointers. |
189 | | */ |
190 | | template<typename T, |
191 | | bool TypeIsNotIntegral = !mozilla::IsIntegral<T>::value, |
192 | | typename U = typename mozilla::EnableIf<TypeIsNotIntegral>::Type> |
193 | | MOZ_MUST_USE inline HashNumber |
194 | | AddToHash(HashNumber aHash, T aA) |
195 | 8.16M | { |
196 | 8.16M | /* |
197 | 8.16M | * Try to convert |A| to uint32_t implicitly. If this works, great. If not, |
198 | 8.16M | * we'll error out. |
199 | 8.16M | */ |
200 | 8.16M | return detail::AddU32ToHash(aHash, aA); |
201 | 8.16M | } Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::URLPreloader::CacheKey::EntryType, true, void>(unsigned int, mozilla::URLPreloader::CacheKey::EntryType) Unexecuted instantiation: unsigned int mozilla::AddToHash<float, true, void>(unsigned int, float) Unexecuted instantiation: unsigned int mozilla::AddToHash<double, true, void>(unsigned int, double) Unexecuted instantiation: unsigned int mozilla::AddToHash<js::jit::SimdConstant::Type, true, void>(unsigned int, js::jit::SimdConstant::Type) unsigned int mozilla::AddToHash<JSProtoKey, true, void>(unsigned int, JSProtoKey) Line | Count | Source | 195 | 8.16M | { | 196 | 8.16M | /* | 197 | 8.16M | * Try to convert |A| to uint32_t implicitly. If this works, great. If not, | 198 | 8.16M | * we'll error out. | 199 | 8.16M | */ | 200 | 8.16M | return detail::AddU32ToHash(aHash, aA); | 201 | 8.16M | } |
unsigned int mozilla::AddToHash<js::jit::MaybeTailCall, true, void>(unsigned int, js::jit::MaybeTailCall) Line | Count | Source | 195 | 1.66k | { | 196 | 1.66k | /* | 197 | 1.66k | * Try to convert |A| to uint32_t implicitly. If this works, great. If not, | 198 | 1.66k | * we'll error out. | 199 | 1.66k | */ | 200 | 1.66k | return detail::AddU32ToHash(aHash, aA); | 201 | 1.66k | } |
|
202 | | |
203 | | template<typename A> |
204 | | MOZ_MUST_USE inline HashNumber |
205 | | AddToHash(HashNumber aHash, A* aA) |
206 | 47.0M | { |
207 | 47.0M | /* |
208 | 47.0M | * You might think this function should just take a void*. But then we'd only |
209 | 47.0M | * catch data pointers and couldn't handle function pointers. |
210 | 47.0M | */ |
211 | 47.0M | |
212 | 47.0M | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); |
213 | 47.0M | |
214 | 47.0M | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); |
215 | 47.0M | } Unexecuted instantiation: unsigned int mozilla::AddToHash<bool (mozilla::dom::Element*, mozilla::dom::Element*, void*)>(unsigned int, bool (*)(mozilla::dom::Element*, mozilla::dom::Element*, void*)) unsigned int mozilla::AddToHash<void>(unsigned int, void*) Line | Count | Source | 206 | 1.66k | { | 207 | 1.66k | /* | 208 | 1.66k | * You might think this function should just take a void*. But then we'd only | 209 | 1.66k | * catch data pointers and couldn't handle function pointers. | 210 | 1.66k | */ | 211 | 1.66k | | 212 | 1.66k | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 1.66k | | 214 | 1.66k | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 1.66k | } |
unsigned int mozilla::AddToHash<void const>(unsigned int, void const*) Line | Count | Source | 206 | 27.4M | { | 207 | 27.4M | /* | 208 | 27.4M | * You might think this function should just take a void*. But then we'd only | 209 | 27.4M | * catch data pointers and couldn't handle function pointers. | 210 | 27.4M | */ | 211 | 27.4M | | 212 | 27.4M | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 27.4M | | 214 | 27.4M | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 27.4M | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<nsINode>(unsigned int, nsINode*) Unexecuted instantiation: unsigned int mozilla::AddToHash<bool (mozilla::dom::Element*, int, nsAtom*, void*)>(unsigned int, bool (*)(mozilla::dom::Element*, int, nsAtom*, void*)) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::dom::Element>(unsigned int, mozilla::dom::Element*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsINode const>(unsigned int, nsINode const*) unsigned int mozilla::AddToHash<nsIMemoryReporter const>(unsigned int, nsIMemoryReporter const*) Line | Count | Source | 206 | 85 | { | 207 | 85 | /* | 208 | 85 | * You might think this function should just take a void*. But then we'd only | 209 | 85 | * catch data pointers and couldn't handle function pointers. | 210 | 85 | */ | 211 | 85 | | 212 | 85 | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 85 | | 214 | 85 | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 85 | } |
unsigned int mozilla::AddToHash<PRThread const>(unsigned int, PRThread const*) Line | Count | Source | 206 | 46 | { | 207 | 46 | /* | 208 | 46 | * You might think this function should just take a void*. But then we'd only | 209 | 46 | * catch data pointers and couldn't handle function pointers. | 210 | 46 | */ | 211 | 46 | | 212 | 46 | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 46 | | 214 | 46 | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 46 | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<gfxFontEntry const>(unsigned int, gfxFontEntry const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<gfxCharacterMap const>(unsigned int, gfxCharacterMap const*) unsigned int mozilla::AddToHash<nsISupports>(unsigned int, nsISupports*) Line | Count | Source | 206 | 71 | { | 207 | 71 | /* | 208 | 71 | * You might think this function should just take a void*. But then we'd only | 209 | 71 | * catch data pointers and couldn't handle function pointers. | 210 | 71 | */ | 211 | 71 | | 212 | 71 | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 71 | | 214 | 71 | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 71 | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::net::nsAHttpTransaction const>(unsigned int, mozilla::net::nsAHttpTransaction const*) unsigned int mozilla::AddToHash<nsAtom const>(unsigned int, nsAtom const*) Line | Count | Source | 206 | 600 | { | 207 | 600 | /* | 208 | 600 | * You might think this function should just take a void*. But then we'd only | 209 | 600 | * catch data pointers and couldn't handle function pointers. | 210 | 600 | */ | 211 | 600 | | 212 | 600 | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 600 | | 214 | 600 | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 600 | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<nsIFrame>(unsigned int, nsIFrame*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::layers::Layer const>(unsigned int, mozilla::layers::Layer const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::layers::LayerMLGPU const>(unsigned int, mozilla::layers::LayerMLGPU const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::image::IProgressObserver const>(unsigned int, mozilla::image::IProgressObserver const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::image::Image const>(unsigned int, mozilla::image::Image const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsIFrame const>(unsigned int, nsIFrame const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsXBLPrototypeHandler const>(unsigned int, nsXBLPrototypeHandler const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::dom::Element const>(unsigned int, mozilla::dom::Element const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<imgIRequest const>(unsigned int, imgIRequest const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<RawServoStyleRule const>(unsigned int, RawServoStyleRule const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsAtom>(unsigned int, nsAtom*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsIContent const>(unsigned int, nsIContent const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<void (nsMappedAttributes const*, mozilla::MappedDeclarations&)>(unsigned int, void (*)(nsMappedAttributes const*, mozilla::MappedDeclarations&)) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::dom::HTMLCanvasElement>(unsigned int, mozilla::dom::HTMLCanvasElement*) Unexecuted instantiation: unsigned int mozilla::AddToHash<imgIContainer>(unsigned int, imgIContainer*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::dom::BlobImpl const>(unsigned int, mozilla::dom::BlobImpl const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsPIDOMWindowInner>(unsigned int, nsPIDOMWindowInner*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::SVGAnimatedLengthList const>(unsigned int, mozilla::SVGAnimatedLengthList const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::SVGAnimatedNumberList const>(unsigned int, mozilla::SVGAnimatedNumberList const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsSVGLength2 const>(unsigned int, nsSVGLength2 const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::SVGStringList const>(unsigned int, mozilla::SVGStringList const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::SVGAnimatedPreserveAspectRatio const>(unsigned int, mozilla::SVGAnimatedPreserveAspectRatio const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::nsSVGAnimatedTransformList const>(unsigned int, mozilla::nsSVGAnimatedTransformList const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::dom::SVGTransform const>(unsigned int, mozilla::dom::SVGTransform const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsSVGAngle const>(unsigned int, nsSVGAngle const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsSVGBoolean const>(unsigned int, nsSVGBoolean const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsSVGEnum const>(unsigned int, nsSVGEnum const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsSVGInteger const>(unsigned int, nsSVGInteger const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsSVGIntegerPair const>(unsigned int, nsSVGIntegerPair const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsSVGNumber2 const>(unsigned int, nsSVGNumber2 const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsSVGNumberPair const>(unsigned int, nsSVGNumberPair const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsSVGString const>(unsigned int, nsSVGString const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsSVGViewBox const>(unsigned int, nsSVGViewBox const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<_NPP>(unsigned int, _NPP*) Unexecuted instantiation: unsigned int mozilla::AddToHash<_NPAsyncSurface const>(unsigned int, _NPAsyncSurface const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<NPObject const>(unsigned int, NPObject const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsPIDOMWindowInner const>(unsigned int, nsPIDOMWindowInner const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<_GdkEventSequence const>(unsigned int, _GdkEventSequence const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<gfxFontFaceSrc const>(unsigned int, gfxFontFaceSrc const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<RawServoFontFaceRule const>(unsigned int, RawServoFontFaceRule const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsIDocument const>(unsigned int, nsIDocument const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::DisplayItemClipChain const>(unsigned int, mozilla::DisplayItemClipChain const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<AnimatedGeometryRoot const>(unsigned int, AnimatedGeometryRoot const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::ActiveScrolledRoot const>(unsigned int, mozilla::ActiveScrolledRoot const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::layers::KnowsCompositor>(unsigned int, mozilla::layers::KnowsCompositor*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsDisplayItem const>(unsigned int, nsDisplayItem const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsPresContext const>(unsigned int, nsPresContext const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::a11y::DocAccessible const>(unsigned int, mozilla::a11y::DocAccessible const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::a11y::DocAccessibleParent const>(unsigned int, mozilla::a11y::DocAccessibleParent const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::a11y::Accessible const>(unsigned int, mozilla::a11y::Accessible const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<_GtkWidget const>(unsigned int, _GtkWidget const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::extensions::DocumentObserver const>(unsigned int, mozilla::extensions::DocumentObserver const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsPerformanceGroup const>(unsigned int, nsPerformanceGroup const*) unsigned int mozilla::AddToHash<js::gc::Cell*>(unsigned int, js::gc::Cell**) Line | Count | Source | 206 | 5 | { | 207 | 5 | /* | 208 | 5 | * You might think this function should just take a void*. But then we'd only | 209 | 5 | * catch data pointers and couldn't handle function pointers. | 210 | 5 | */ | 211 | 5 | | 212 | 5 | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 5 | | 214 | 5 | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 5 | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<JS::Value>(unsigned int, JS::Value*) unsigned int mozilla::AddToHash<js::Class const>(unsigned int, js::Class const*) Line | Count | Source | 206 | 19.5M | { | 207 | 19.5M | /* | 208 | 19.5M | * You might think this function should just take a void*. But then we'd only | 209 | 19.5M | * catch data pointers and couldn't handle function pointers. | 210 | 19.5M | */ | 211 | 19.5M | | 212 | 19.5M | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 19.5M | | 214 | 19.5M | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 19.5M | } |
unsigned int mozilla::AddToHash<js::UnownedBaseShape>(unsigned int, js::UnownedBaseShape*) Line | Count | Source | 206 | 412 | { | 207 | 412 | /* | 208 | 412 | * You might think this function should just take a void*. But then we'd only | 209 | 412 | * catch data pointers and couldn't handle function pointers. | 210 | 412 | */ | 211 | 412 | | 212 | 412 | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 412 | | 214 | 412 | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 412 | } |
unsigned int mozilla::AddToHash<bool (JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>)>(unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>)) Line | Count | Source | 206 | 412 | { | 207 | 412 | /* | 208 | 412 | * You might think this function should just take a void*. But then we'd only | 209 | 412 | * catch data pointers and couldn't handle function pointers. | 210 | 412 | */ | 211 | 412 | | 212 | 412 | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 412 | | 214 | 412 | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 412 | } |
unsigned int mozilla::AddToHash<bool (JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)>(unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)) Line | Count | Source | 206 | 412 | { | 207 | 412 | /* | 208 | 412 | * You might think this function should just take a void*. But then we'd only | 209 | 412 | * catch data pointers and couldn't handle function pointers. | 210 | 412 | */ | 211 | 412 | | 212 | 412 | static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); | 213 | 412 | | 214 | 412 | return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA)); | 215 | 412 | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<js::gc::Cell>(unsigned int, js::gc::Cell*) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned char>(unsigned int, unsigned char*) Unexecuted instantiation: unsigned int mozilla::AddToHash<JSScript>(unsigned int, JSScript*) Unexecuted instantiation: unsigned int mozilla::AddToHash<JSAtom>(unsigned int, JSAtom*) Unexecuted instantiation: unsigned int mozilla::AddToHash<js::PropertyName>(unsigned int, js::PropertyName*) |
216 | | |
217 | | // We use AddUintptrToHash() for hashing all integral types. 8-byte integral types |
218 | | // are treated the same as 64-bit pointers, and smaller integral types are first |
219 | | // implicitly converted to 32 bits and then passed to AddUintptrToHash() to be hashed. |
220 | | template<typename T, |
221 | | typename U = typename mozilla::EnableIf<mozilla::IsIntegral<T>::value>::Type> |
222 | | MOZ_MUST_USE constexpr HashNumber |
223 | | AddToHash(HashNumber aHash, T aA) |
224 | 108M | { |
225 | 108M | return detail::AddUintptrToHash<sizeof(T)>(aHash, aA); |
226 | 108M | } unsigned int mozilla::AddToHash<char, void>(unsigned int, char) Line | Count | Source | 224 | 6.87k | { | 225 | 6.87k | return detail::AddUintptrToHash<sizeof(T)>(aHash, aA); | 226 | 6.87k | } |
unsigned int mozilla::AddToHash<unsigned long, void>(unsigned int, unsigned long) Line | Count | Source | 224 | 70.4M | { | 225 | 70.4M | return detail::AddUintptrToHash<sizeof(T)>(aHash, aA); | 226 | 70.4M | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<long, void>(unsigned int, long) unsigned int mozilla::AddToHash<unsigned int, void>(unsigned int, unsigned int) Line | Count | Source | 224 | 37.6M | { | 225 | 37.6M | return detail::AddUintptrToHash<sizeof(T)>(aHash, aA); | 226 | 37.6M | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned short, void>(unsigned int, unsigned short) unsigned int mozilla::AddToHash<int, void>(unsigned int, int) Line | Count | Source | 224 | 11.0k | { | 225 | 11.0k | return detail::AddUintptrToHash<sizeof(T)>(aHash, aA); | 226 | 11.0k | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<bool, void>(unsigned int, bool) |
227 | | |
228 | | template<typename A, typename... Args> |
229 | | MOZ_MUST_USE HashNumber |
230 | | AddToHash(HashNumber aHash, A aArg, Args... aArgs) |
231 | 13.1M | { |
232 | 13.1M | return AddToHash(AddToHash(aHash, aArg), aArgs...); |
233 | 13.1M | } unsigned int mozilla::AddToHash<unsigned long, unsigned long>(unsigned int, unsigned long, unsigned long) Line | Count | Source | 231 | 3.32M | { | 232 | 3.32M | return AddToHash(AddToHash(aHash, aArg), aArgs...); | 233 | 3.32M | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned long, unsigned int, unsigned long>(unsigned int, unsigned long, unsigned int, unsigned long) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, unsigned long>(unsigned int, unsigned int, unsigned long) Unexecuted instantiation: unsigned int mozilla::AddToHash<bool (*)(mozilla::dom::Element*, mozilla::dom::Element*, void*), void*>(unsigned int, bool (*)(mozilla::dom::Element*, mozilla::dom::Element*, void*), void*) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned char, unsigned short, unsigned char>(unsigned int, unsigned char, unsigned short, unsigned char) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned short, unsigned char>(unsigned int, unsigned short, unsigned char) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsINode*, int, bool>(unsigned int, nsINode*, int, bool) Unexecuted instantiation: unsigned int mozilla::AddToHash<int, bool>(unsigned int, int, bool) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsINode*, bool (*)(mozilla::dom::Element*, int, nsAtom*, void*)>(unsigned int, nsINode*, bool (*)(mozilla::dom::Element*, int, nsAtom*, void*)) Unexecuted instantiation: unsigned int mozilla::AddToHash<int, void*>(unsigned int, int, void*) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::dom::Element*, unsigned char>(unsigned int, mozilla::dom::Element*, unsigned char) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::URLPreloader::CacheKey::EntryType, unsigned int>(unsigned int, mozilla::URLPreloader::CacheKey::EntryType, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned char, unsigned char>(unsigned int, unsigned char, unsigned char) unsigned int mozilla::AddToHash<unsigned int, unsigned int>(unsigned int, unsigned int, unsigned int) Line | Count | Source | 231 | 39 | { | 232 | 39 | return AddToHash(AddToHash(aHash, aArg), aArgs...); | 233 | 39 | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, unsigned int, unsigned int>(unsigned int, unsigned int, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<int, int>(unsigned int, int, int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, gfxFontEntry const*, gfxCharacterMap const*>(unsigned int, unsigned int, gfxFontEntry const*, gfxCharacterMap const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<gfxFontEntry const*, gfxCharacterMap const*>(unsigned int, gfxFontEntry const*, gfxCharacterMap const*) Unexecuted instantiation: unsigned int mozilla::AddToHash<char16_t, char16_t>(unsigned int, char16_t, char16_t) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, int>(unsigned int, unsigned int, int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned short, int, unsigned short, unsigned int>(unsigned int, unsigned short, int, unsigned short, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<int, unsigned short, unsigned int>(unsigned int, int, unsigned short, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned short, unsigned int>(unsigned int, unsigned short, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<nsIFrame*, unsigned int>(unsigned int, nsIFrame*, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, unsigned int, unsigned int, unsigned int, unsigned int>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, unsigned int, unsigned int, unsigned int>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<float, float>(unsigned int, float, float) Unexecuted instantiation: unsigned int mozilla::AddToHash<bool, unsigned short, unsigned short, unsigned short, double, int, unsigned int>(unsigned int, bool, unsigned short, unsigned short, unsigned short, double, int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned short, unsigned short, unsigned short, double, int, unsigned int>(unsigned int, unsigned short, unsigned short, unsigned short, double, int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned short, unsigned short, double, int, unsigned int>(unsigned int, unsigned short, unsigned short, double, int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned short, double, int, unsigned int>(unsigned int, unsigned short, double, int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<double, int, unsigned int>(unsigned int, double, int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<int, unsigned int>(unsigned int, int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned long, unsigned int>(unsigned int, unsigned long, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned char, unsigned int>(unsigned int, unsigned char, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<imgIContainer*, mozilla::dom::HTMLCanvasElement*, bool>(unsigned int, imgIContainer*, mozilla::dom::HTMLCanvasElement*, bool) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::dom::HTMLCanvasElement*, bool>(unsigned int, mozilla::dom::HTMLCanvasElement*, bool) Unexecuted instantiation: unsigned int mozilla::AddToHash<imgIContainer*, bool>(unsigned int, imgIContainer*, bool) Unexecuted instantiation: unsigned int mozilla::AddToHash<int, int, nsAtom*>(unsigned int, int, int, nsAtom*) Unexecuted instantiation: unsigned int mozilla::AddToHash<int, nsAtom*>(unsigned int, int, nsAtom*) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, float>(unsigned int, unsigned int, float) Unexecuted instantiation: unsigned int mozilla::AddToHash<mozilla::ActiveScrolledRoot const*, unsigned int>(unsigned int, mozilla::ActiveScrolledRoot const*, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<int, int, int, int>(unsigned int, int, int, int, int) Unexecuted instantiation: unsigned int mozilla::AddToHash<int, int, int>(unsigned int, int, int, int) unsigned int mozilla::AddToHash<unsigned long, unsigned int, unsigned int>(unsigned int, unsigned long, unsigned int, unsigned int) Line | Count | Source | 231 | 39 | { | 232 | 39 | return AddToHash(AddToHash(aHash, aArg), aArgs...); | 233 | 39 | } |
unsigned int mozilla::AddToHash<unsigned int, js::Class const*>(unsigned int, unsigned int, js::Class const*) Line | Count | Source | 231 | 1.62M | { | 232 | 1.62M | return AddToHash(AddToHash(aHash, aArg), aArgs...); | 233 | 1.62M | } |
unsigned int mozilla::AddToHash<js::Class const*, unsigned int>(unsigned int, js::Class const*, unsigned int) Line | Count | Source | 231 | 8.16M | { | 232 | 8.16M | return AddToHash(AddToHash(aHash, aArg), aArgs...); | 233 | 8.16M | } |
unsigned int mozilla::AddToHash<js::UnownedBaseShape*, unsigned char, unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>), bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)>(unsigned int, js::UnownedBaseShape*, unsigned char, unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>), bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)) Line | Count | Source | 231 | 412 | { | 232 | 412 | return AddToHash(AddToHash(aHash, aArg), aArgs...); | 233 | 412 | } |
unsigned int mozilla::AddToHash<unsigned char, unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>), bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)>(unsigned int, unsigned char, unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>), bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)) Line | Count | Source | 231 | 412 | { | 232 | 412 | return AddToHash(AddToHash(aHash, aArg), aArgs...); | 233 | 412 | } |
unsigned int mozilla::AddToHash<unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>), bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)>(unsigned int, unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>), bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)) Line | Count | Source | 231 | 412 | { | 232 | 412 | return AddToHash(AddToHash(aHash, aArg), aArgs...); | 233 | 412 | } |
unsigned int mozilla::AddToHash<bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>), bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)>(unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>), bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)) Line | Count | Source | 231 | 412 | { | 232 | 412 | return AddToHash(AddToHash(aHash, aArg), aArgs...); | 233 | 412 | } |
Unexecuted instantiation: unsigned int mozilla::AddToHash<JSScript*, unsigned char*>(unsigned int, JSScript*, unsigned char*) Unexecuted instantiation: unsigned int mozilla::AddToHash<unsigned int, JSAtom*, JSAtom*, JSAtom*, unsigned int, unsigned int>(unsigned int, unsigned int, JSAtom*, JSAtom*, JSAtom*, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<JSAtom*, JSAtom*, JSAtom*, unsigned int, unsigned int>(unsigned int, JSAtom*, JSAtom*, JSAtom*, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<JSAtom*, JSAtom*, unsigned int, unsigned int>(unsigned int, JSAtom*, JSAtom*, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<JSAtom*, unsigned int, unsigned int>(unsigned int, JSAtom*, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::AddToHash<js::PropertyName*, unsigned int>(unsigned int, js::PropertyName*, unsigned int) |
234 | | |
235 | | /** |
236 | | * The HashGeneric class of functions let you hash one or more values. |
237 | | * |
238 | | * If you want to hash together two values x and y, calling HashGeneric(x, y) is |
239 | | * much better than calling AddToHash(x, y), because AddToHash(x, y) assumes |
240 | | * that x has already been hashed. |
241 | | */ |
242 | | template<typename... Args> |
243 | | MOZ_MUST_USE inline HashNumber |
244 | | HashGeneric(Args... aArgs) |
245 | 110M | { |
246 | 110M | return AddToHash(0, aArgs...); |
247 | 110M | } Unexecuted instantiation: unsigned int mozilla::HashGeneric<long>(long) Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned long, unsigned int, unsigned long>(unsigned long, unsigned int, unsigned long) Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned long, unsigned long>(unsigned long, unsigned long) Unexecuted instantiation: unsigned int mozilla::HashGeneric<bool (*)(mozilla::dom::Element*, mozilla::dom::Element*, void*), void*>(bool (*)(mozilla::dom::Element*, mozilla::dom::Element*, void*), void*) unsigned int mozilla::HashGeneric<void const*>(void const*) Line | Count | Source | 245 | 27.4M | { | 246 | 27.4M | return AddToHash(0, aArgs...); | 247 | 27.4M | } |
Unexecuted instantiation: unsigned int mozilla::HashGeneric<int, void*>(int, void*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::dom::Element*, unsigned char>(mozilla::dom::Element*, unsigned char) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsINode const*>(nsINode const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<void*>(void*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::URLPreloader::CacheKey::EntryType, unsigned int>(mozilla::URLPreloader::CacheKey::EntryType, unsigned int) unsigned int mozilla::HashGeneric<nsIMemoryReporter const*>(nsIMemoryReporter const*) Line | Count | Source | 245 | 85 | { | 246 | 85 | return AddToHash(0, aArgs...); | 247 | 85 | } |
Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned char, unsigned char>(unsigned char, unsigned char) Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned int, unsigned int>(unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned int, unsigned int, unsigned int>(unsigned int, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::HashGeneric<int, int>(int, int) unsigned int mozilla::HashGeneric<PRThread const*>(PRThread const*) Line | Count | Source | 245 | 46 | { | 246 | 46 | return AddToHash(0, aArgs...); | 247 | 46 | } |
Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned int, gfxFontEntry const*, gfxCharacterMap const*>(unsigned int, gfxFontEntry const*, gfxCharacterMap const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::net::nsAHttpTransaction const*>(mozilla::net::nsAHttpTransaction const*) unsigned int mozilla::HashGeneric<nsAtom const*>(nsAtom const*) Line | Count | Source | 245 | 600 | { | 246 | 600 | return AddToHash(0, aArgs...); | 247 | 600 | } |
unsigned int mozilla::HashGeneric<unsigned long>(unsigned long) Line | Count | Source | 245 | 63.7M | { | 246 | 63.7M | return AddToHash(0, aArgs...); | 247 | 63.7M | } |
Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsIFrame*, unsigned int>(nsIFrame*, unsigned int) Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned int, int>(unsigned int, int) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::layers::Layer const*>(mozilla::layers::Layer const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::layers::LayerMLGPU const*>(mozilla::layers::LayerMLGPU const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned long, unsigned int>(unsigned long, unsigned int) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::image::IProgressObserver const*>(mozilla::image::IProgressObserver const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::image::Image const*>(mozilla::image::Image const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsIFrame const*>(nsIFrame const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsXBLPrototypeHandler const*>(nsXBLPrototypeHandler const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::dom::Element const*>(mozilla::dom::Element const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<imgIRequest const*>(imgIRequest const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<RawServoStyleRule const*>(RawServoStyleRule const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsIContent const*>(nsIContent const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<void (*)(nsMappedAttributes const*, mozilla::MappedDeclarations&)>(void (*)(nsMappedAttributes const*, mozilla::MappedDeclarations&)) Unexecuted instantiation: unsigned int mozilla::HashGeneric<gfxFontEntry const*>(gfxFontEntry const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<imgIContainer*, mozilla::dom::HTMLCanvasElement*, bool>(imgIContainer*, mozilla::dom::HTMLCanvasElement*, bool) Unexecuted instantiation: unsigned int mozilla::HashGeneric<imgIContainer*, bool>(imgIContainer*, bool) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::dom::BlobImpl const*>(mozilla::dom::BlobImpl const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::SVGAnimatedLengthList const*>(mozilla::SVGAnimatedLengthList const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::SVGAnimatedNumberList const*>(mozilla::SVGAnimatedNumberList const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsSVGLength2 const*>(nsSVGLength2 const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::SVGStringList const*>(mozilla::SVGStringList const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::SVGAnimatedPreserveAspectRatio const*>(mozilla::SVGAnimatedPreserveAspectRatio const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::nsSVGAnimatedTransformList const*>(mozilla::nsSVGAnimatedTransformList const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::dom::SVGTransform const*>(mozilla::dom::SVGTransform const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsSVGAngle const*>(nsSVGAngle const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsSVGBoolean const*>(nsSVGBoolean const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsSVGEnum const*>(nsSVGEnum const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsSVGInteger const*>(nsSVGInteger const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsSVGIntegerPair const*>(nsSVGIntegerPair const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsSVGNumber2 const*>(nsSVGNumber2 const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsSVGNumberPair const*>(nsSVGNumberPair const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsSVGString const*>(nsSVGString const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsSVGViewBox const*>(nsSVGViewBox const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<_NPP*>(_NPP*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<_NPAsyncSurface const*>(_NPAsyncSurface const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<NPObject const*>(NPObject const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsPIDOMWindowInner const*>(nsPIDOMWindowInner const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<int, int, nsAtom*>(int, int, nsAtom*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<_GdkEventSequence const*>(_GdkEventSequence const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<gfxFontFaceSrc const*>(gfxFontFaceSrc const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<RawServoFontFaceRule const*>(RawServoFontFaceRule const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsIDocument const*>(nsIDocument const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::DisplayItemClipChain const*>(mozilla::DisplayItemClipChain const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned int, float>(unsigned int, float) Unexecuted instantiation: unsigned int mozilla::HashGeneric<AnimatedGeometryRoot const*>(AnimatedGeometryRoot const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::ActiveScrolledRoot const*, unsigned int>(mozilla::ActiveScrolledRoot const*, unsigned int) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsDisplayItem const*>(nsDisplayItem const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsPresContext const*>(nsPresContext const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::a11y::DocAccessible const*>(mozilla::a11y::DocAccessible const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::a11y::DocAccessibleParent const*>(mozilla::a11y::DocAccessibleParent const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::a11y::Accessible const*>(mozilla::a11y::Accessible const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<unsigned int>(unsigned int) Unexecuted instantiation: unsigned int mozilla::HashGeneric<_GtkWidget const*>(_GtkWidget const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<mozilla::extensions::DocumentObserver const*>(mozilla::extensions::DocumentObserver const*) Unexecuted instantiation: unsigned int mozilla::HashGeneric<nsPerformanceGroup const*>(nsPerformanceGroup const*) unsigned int mozilla::HashGeneric<js::gc::Cell**>(js::gc::Cell**) Line | Count | Source | 245 | 5 | { | 246 | 5 | return AddToHash(0, aArgs...); | 247 | 5 | } |
unsigned int mozilla::HashGeneric<unsigned long, unsigned int, unsigned int>(unsigned long, unsigned int, unsigned int) Line | Count | Source | 245 | 39 | { | 246 | 39 | return AddToHash(0, aArgs...); | 247 | 39 | } |
Unexecuted instantiation: unsigned int mozilla::HashGeneric<JS::Value*>(JS::Value*) unsigned int mozilla::HashGeneric<unsigned int, js::Class const*>(unsigned int, js::Class const*) Line | Count | Source | 245 | 1.62M | { | 246 | 1.62M | return AddToHash(0, aArgs...); | 247 | 1.62M | } |
unsigned int mozilla::HashGeneric<js::Class const*, unsigned int>(js::Class const*, unsigned int) Line | Count | Source | 245 | 8.16M | { | 246 | 8.16M | return AddToHash(0, aArgs...); | 247 | 8.16M | } |
unsigned int mozilla::HashGeneric<js::UnownedBaseShape*, unsigned char, unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>), bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)>(js::UnownedBaseShape*, unsigned char, unsigned int, bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>), bool (*)(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::Handle<JS::Value>, JS::ObjectOpResult&)) Line | Count | Source | 245 | 412 | { | 246 | 412 | return AddToHash(0, aArgs...); | 247 | 412 | } |
Unexecuted instantiation: unsigned int mozilla::HashGeneric<js::gc::Cell*>(js::gc::Cell*) unsigned int mozilla::HashGeneric<js::Class const*>(js::Class const*) Line | Count | Source | 245 | 9.78M | { | 246 | 9.78M | return AddToHash(0, aArgs...); | 247 | 9.78M | } |
Unexecuted instantiation: unsigned int mozilla::HashGeneric<js::PropertyName*, unsigned int>(js::PropertyName*, unsigned int) |
248 | | |
249 | | namespace detail { |
250 | | |
251 | | template<typename T> |
252 | | constexpr HashNumber |
253 | | HashUntilZero(const T* aStr) |
254 | 0 | { |
255 | 0 | HashNumber hash = 0; |
256 | 0 | for (; T c = *aStr; aStr++) { |
257 | 0 | hash = AddToHash(hash, c); |
258 | 0 | } |
259 | 0 | return hash; |
260 | 0 | } |
261 | | |
262 | | template<typename T> |
263 | | HashNumber |
264 | | HashKnownLength(const T* aStr, size_t aLength) |
265 | | { |
266 | | HashNumber hash = 0; |
267 | | for (size_t i = 0; i < aLength; i++) { |
268 | | hash = AddToHash(hash, aStr[i]); |
269 | | } |
270 | | return hash; |
271 | | } |
272 | | |
273 | | } /* namespace detail */ |
274 | | |
275 | | /** |
276 | | * The HashString overloads below do just what you'd expect. |
277 | | * |
278 | | * If you have the string's length, you might as well call the overload which |
279 | | * includes the length. It may be marginally faster. |
280 | | */ |
281 | | MOZ_MUST_USE inline HashNumber |
282 | | HashString(const char* aStr) |
283 | | { |
284 | | return detail::HashUntilZero(reinterpret_cast<const unsigned char*>(aStr)); |
285 | | } |
286 | | |
287 | | MOZ_MUST_USE inline HashNumber |
288 | | HashString(const char* aStr, size_t aLength) |
289 | | { |
290 | | return detail::HashKnownLength(reinterpret_cast<const unsigned char*>(aStr), aLength); |
291 | | } |
292 | | |
293 | | MOZ_MUST_USE |
294 | | inline HashNumber |
295 | | HashString(const unsigned char* aStr, size_t aLength) |
296 | | { |
297 | | return detail::HashKnownLength(aStr, aLength); |
298 | | } |
299 | | |
300 | | // You may need to use the |
301 | | // MOZ_{PUSH,POP}_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING macros if you use |
302 | | // this function. See the comment on those macros' definitions for more detail. |
303 | | MOZ_MUST_USE constexpr HashNumber |
304 | | HashString(const char16_t* aStr) |
305 | 0 | { |
306 | 0 | return detail::HashUntilZero(aStr); |
307 | 0 | } |
308 | | |
309 | | MOZ_MUST_USE inline HashNumber |
310 | | HashString(const char16_t* aStr, size_t aLength) |
311 | | { |
312 | | return detail::HashKnownLength(aStr, aLength); |
313 | | } |
314 | | |
315 | | /* |
316 | | * On Windows, wchar_t is not the same as char16_t, even though it's |
317 | | * the same width! |
318 | | */ |
319 | | #ifdef WIN32 |
320 | | MOZ_MUST_USE inline HashNumber |
321 | | HashString(const wchar_t* aStr) |
322 | | { |
323 | | return detail::HashUntilZero(aStr); |
324 | | } |
325 | | |
326 | | MOZ_MUST_USE inline HashNumber |
327 | | HashString(const wchar_t* aStr, size_t aLength) |
328 | | { |
329 | | return detail::HashKnownLength(aStr, aLength); |
330 | | } |
331 | | #endif |
332 | | |
333 | | /** |
334 | | * Hash some number of bytes. |
335 | | * |
336 | | * This hash walks word-by-word, rather than byte-by-byte, so you won't get the |
337 | | * same result out of HashBytes as you would out of HashString. |
338 | | */ |
339 | | MOZ_MUST_USE extern MFBT_API HashNumber |
340 | | HashBytes(const void* bytes, size_t aLength); |
341 | | |
342 | | /** |
343 | | * A pseudorandom function mapping 32-bit integers to 32-bit integers. |
344 | | * |
345 | | * This is for when you're feeding private data (like pointer values or credit |
346 | | * card numbers) to a non-crypto hash function (like HashBytes) and then using |
347 | | * the hash code for something that untrusted parties could observe (like a JS |
348 | | * Map). Plug in a HashCodeScrambler before that last step to avoid leaking the |
349 | | * private data. |
350 | | * |
351 | | * By itself, this does not prevent hash-flooding DoS attacks, because an |
352 | | * attacker can still generate many values with exactly equal hash codes by |
353 | | * attacking the non-crypto hash function alone. Equal hash codes will, of |
354 | | * course, still be equal however much you scramble them. |
355 | | * |
356 | | * The algorithm is SipHash-1-3. See <https://131002.net/siphash/>. |
357 | | */ |
358 | | class HashCodeScrambler |
359 | | { |
360 | | struct SipHasher; |
361 | | |
362 | | uint64_t mK0, mK1; |
363 | | |
364 | | public: |
365 | | /** Creates a new scrambler with the given 128-bit key. */ |
366 | 0 | constexpr HashCodeScrambler(uint64_t aK0, uint64_t aK1) : mK0(aK0), mK1(aK1) {} |
367 | | |
368 | | /** |
369 | | * Scramble a hash code. Always produces the same result for the same |
370 | | * combination of key and hash code. |
371 | | */ |
372 | | HashNumber scramble(HashNumber aHashCode) const |
373 | 0 | { |
374 | 0 | SipHasher hasher(mK0, mK1); |
375 | 0 | return HashNumber(hasher.sipHash(aHashCode)); |
376 | 0 | } |
377 | | |
378 | | private: |
379 | | struct SipHasher |
380 | | { |
381 | | SipHasher(uint64_t aK0, uint64_t aK1) |
382 | 0 | { |
383 | 0 | // 1. Initialization. |
384 | 0 | mV0 = aK0 ^ UINT64_C(0x736f6d6570736575); |
385 | 0 | mV1 = aK1 ^ UINT64_C(0x646f72616e646f6d); |
386 | 0 | mV2 = aK0 ^ UINT64_C(0x6c7967656e657261); |
387 | 0 | mV3 = aK1 ^ UINT64_C(0x7465646279746573); |
388 | 0 | } |
389 | | |
390 | | uint64_t sipHash(uint64_t aM) |
391 | 0 | { |
392 | 0 | // 2. Compression. |
393 | 0 | mV3 ^= aM; |
394 | 0 | sipRound(); |
395 | 0 | mV0 ^= aM; |
396 | 0 |
|
397 | 0 | // 3. Finalization. |
398 | 0 | mV2 ^= 0xff; |
399 | 0 | for (int i = 0; i < 3; i++) |
400 | 0 | sipRound(); |
401 | 0 | return mV0 ^ mV1 ^ mV2 ^ mV3; |
402 | 0 | } |
403 | | |
404 | | void sipRound() |
405 | 0 | { |
406 | 0 | mV0 = WrappingAdd(mV0, mV1); |
407 | 0 | mV1 = RotateLeft(mV1, 13); |
408 | 0 | mV1 ^= mV0; |
409 | 0 | mV0 = RotateLeft(mV0, 32); |
410 | 0 | mV2 = WrappingAdd(mV2, mV3); |
411 | 0 | mV3 = RotateLeft(mV3, 16); |
412 | 0 | mV3 ^= mV2; |
413 | 0 | mV0 = WrappingAdd(mV0, mV3); |
414 | 0 | mV3 = RotateLeft(mV3, 21); |
415 | 0 | mV3 ^= mV0; |
416 | 0 | mV2 = WrappingAdd(mV2, mV1); |
417 | 0 | mV1 = RotateLeft(mV1, 17); |
418 | 0 | mV1 ^= mV2; |
419 | 0 | mV2 = RotateLeft(mV2, 32); |
420 | 0 | } |
421 | | |
422 | | uint64_t mV0, mV1, mV2, mV3; |
423 | | }; |
424 | | }; |
425 | | |
426 | | } /* namespace mozilla */ |
427 | | |
428 | | #endif /* mozilla_HashFunctions_h */ |