summaryrefslogtreecommitdiff
path: root/deps/v8/src/strings/string-hasher-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/strings/string-hasher-inl.h')
-rw-r--r--deps/v8/src/strings/string-hasher-inl.h81
1 files changed, 81 insertions, 0 deletions
diff --git a/deps/v8/src/strings/string-hasher-inl.h b/deps/v8/src/strings/string-hasher-inl.h
new file mode 100644
index 0000000000..b547d0a78d
--- /dev/null
+++ b/deps/v8/src/strings/string-hasher-inl.h
@@ -0,0 +1,81 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_STRINGS_STRING_HASHER_INL_H_
+#define V8_STRINGS_STRING_HASHER_INL_H_
+
+#include "src/strings/string-hasher.h"
+
+#include "src/objects/objects.h"
+#include "src/objects/string-inl.h"
+#include "src/strings/char-predicates-inl.h"
+#include "src/utils/utils-inl.h"
+
+namespace v8 {
+namespace internal {
+
+uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint16_t c) {
+ running_hash += c;
+ running_hash += (running_hash << 10);
+ running_hash ^= (running_hash >> 6);
+ return running_hash;
+}
+
+uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
+ running_hash += (running_hash << 3);
+ running_hash ^= (running_hash >> 11);
+ running_hash += (running_hash << 15);
+ int32_t hash = static_cast<int32_t>(running_hash & String::kHashBitMask);
+ int32_t mask = (hash - 1) >> 31;
+ return running_hash | (kZeroHash & mask);
+}
+
+uint32_t StringHasher::GetTrivialHash(int length) {
+ DCHECK_GT(length, String::kMaxHashCalcLength);
+ // String hash of a large string is simply the length.
+ return (length << String::kHashShift) | String::kIsNotArrayIndexMask;
+}
+
+template <typename schar>
+uint32_t StringHasher::HashSequentialString(const schar* chars, int length,
+ uint64_t seed) {
+ // Check whether the string is a valid array index. In that case, compute the
+ // array index hash. It'll fall through to compute a regular string hash from
+ // the start if it turns out that the string isn't a valid array index.
+ if (IsInRange(length, 1, String::kMaxArrayIndexSize)) {
+ if (IsDecimalDigit(chars[0]) && (length == 1 || chars[0] != '0')) {
+ uint32_t index = chars[0] - '0';
+ int i = 1;
+ do {
+ if (i == length) {
+ return MakeArrayIndexHash(index, length);
+ }
+ } while (TryAddIndexChar(&index, chars[i++]));
+ }
+ } else if (length > String::kMaxHashCalcLength) {
+ return GetTrivialHash(length);
+ }
+
+ // Non-array-index hash.
+ DCHECK_LE(0, length);
+ DCHECK_IMPLIES(0 < length, chars != nullptr);
+ uint32_t running_hash = static_cast<uint32_t>(seed);
+ const schar* end = &chars[length];
+ while (chars != end) {
+ running_hash = AddCharacterCore(running_hash, *chars++);
+ }
+
+ return (GetHashCore(running_hash) << String::kHashShift) |
+ String::kIsNotArrayIndexMask;
+}
+
+std::size_t SeededStringHasher::operator()(const char* name) const {
+ return StringHasher::HashSequentialString(
+ name, static_cast<int>(strlen(name)), hashseed_);
+}
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_STRINGS_STRING_HASHER_INL_H_