Coverage Report

Created: 2018-09-25 14:53

/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 */