From 7aef2d4a7cb3ddc242561c542a38a446acd41a54 Mon Sep 17 00:00:00 2001 From: Yang Guo Date: Fri, 5 Oct 2018 12:35:05 +0200 Subject: [PATCH] deps: V8: cherry-pick 64-bit hash seed commits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This serves as mitigation for the so-called HashWick vulnerability. Original commit messages: commit d5686a74d56fbb6985b22663ddadd66eb7b91519 Author: Yang Guo Date: Mon Jul 16 11:19:42 2018 Extend hash seed to 64 bits R=bmeurer@chromium.org, ulan@chromium.org Bug: chromium:680662 Change-Id: I5e1486ad2a42db2998d5485a0c4e711378678e6c Reviewed-on: https://chromium-review.googlesource.com/1136034 Reviewed-by: Marja Hölttä Reviewed-by: Ulan Degenbaev Reviewed-by: Benedikt Meurer Commit-Queue: Yang Guo Cr-Commit-Position: refs/heads/master@{#54460} commit 3833fef57368c53c6170559ffa524c8c69f16ee5 Author: Yang Guo Date: Thu Sep 20 11:43:13 2018 Refactor integer hashing function names We now clearly differentiate between: - unseeded hash for 32-bit integers - unseeded hash for 64-bit integers - seeded hash for 32-bit integers - seeded hash for strings R=bmeurer@chromium.org Bug: chromium:680662 Change-Id: I7459958c4158ee3501c962943dff8f33258bb5ce Reviewed-on: https://chromium-review.googlesource.com/1235973 Commit-Queue: Yang Guo Reviewed-by: Benedikt Meurer Cr-Commit-Position: refs/heads/master@{#56068} commit 95a979e02d7154e45b293261a6998c99d71fc238 Author: Yang Guo Date: Thu Sep 20 14:34:48 2018 Call into C++ to compute seeded integer hash R=bmeurer@chromium.org Bug: chromium:680662 Change-Id: I8dace89d576dfcc5833fd539ce698a9ade1cb5a0 Reviewed-on: https://chromium-review.googlesource.com/1235928 Commit-Queue: Yang Guo Reviewed-by: Benedikt Meurer Cr-Commit-Position: refs/heads/master@{#56091} commit 2c2af0022d5feb9e525a00a76cb15db9f3e38dba Author: Yang Guo Date: Thu Sep 27 16:37:57 2018 Use 64-bit for seeded integer hashes R=petermarshall@chromium.org Bug: chromium:680662 Change-Id: If48d1043dbe1e1bb695ec890c23e103a6cacf2d4 Reviewed-on: https://chromium-review.googlesource.com/1244220 Commit-Queue: Yang Guo Reviewed-by: Peter Marshall Cr-Commit-Position: refs/heads/master@{#56271} Refs: https://github.com/nodejs/node/issues/23259 --- deps/v8/include/v8-version.h | 2 +- deps/v8/src/assembler.cc | 10 +++++ deps/v8/src/assembler.h | 2 +- deps/v8/src/ast/ast-value-factory.cc | 1 - deps/v8/src/ast/ast-value-factory.h | 10 ++--- .../src/builtins/builtins-collections-gen.cc | 11 +++-- deps/v8/src/code-stub-assembler.cc | 44 ++++++++++++------- deps/v8/src/code-stub-assembler.h | 5 +-- deps/v8/src/external-reference-table.cc | 2 + deps/v8/src/flag-definitions.h | 7 +-- deps/v8/src/flags.cc | 39 ++++++++++++++++ deps/v8/src/frames.cc | 3 +- deps/v8/src/heap/heap-inl.h | 6 +-- deps/v8/src/heap/heap.cc | 15 ++++--- deps/v8/src/heap/heap.h | 5 ++- deps/v8/src/json-parser.cc | 4 +- deps/v8/src/objects-inl.h | 11 +++-- deps/v8/src/objects.cc | 16 +++---- deps/v8/src/objects/hash-table.h | 2 +- deps/v8/src/objects/string-inl.h | 8 ++-- deps/v8/src/parsing/parse-info.h | 6 +-- deps/v8/src/profiler/allocation-tracker.cc | 2 +- deps/v8/src/profiler/heap-profiler.cc | 4 +- .../src/profiler/heap-snapshot-generator.cc | 2 +- .../v8/src/profiler/heap-snapshot-generator.h | 4 +- deps/v8/src/profiler/profile-generator.cc | 18 ++++---- deps/v8/src/profiler/profile-generator.h | 2 +- deps/v8/src/profiler/profiler-listener.cc | 3 +- deps/v8/src/profiler/strings-storage.cc | 5 +-- deps/v8/src/profiler/strings-storage.h | 3 +- deps/v8/src/string-hasher-inl.h | 10 ++--- deps/v8/src/string-hasher.h | 10 ++--- deps/v8/src/utils.h | 19 ++++---- deps/v8/test/cctest/heap/test-heap.cc | 2 +- .../test/cctest/test-code-stub-assembler.cc | 12 +++-- deps/v8/test/cctest/test-serialize.cc | 3 +- 36 files changed, 180 insertions(+), 128 deletions(-) diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index f2531abb21f0aa..1e44f2b4a266a9 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 6 #define V8_MINOR_VERSION 2 #define V8_BUILD_NUMBER 414 -#define V8_PATCH_LEVEL 68 +#define V8_PATCH_LEVEL 69 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/assembler.cc b/deps/v8/src/assembler.cc index 35238081f9864f..cb5fc84500506d 100644 --- a/deps/v8/src/assembler.cc +++ b/deps/v8/src/assembler.cc @@ -1432,6 +1432,16 @@ ExternalReference ExternalReference::check_object_type(Isolate* isolate) { return ExternalReference(Redirect(isolate, FUNCTION_ADDR(CheckObjectType))); } +static uint32_t ComputeSeededIntegerHash(Isolate* isolate, uint32_t key) { + DisallowHeapAllocation no_gc; + return ComputeSeededHash(key, isolate->heap()->HashSeed()); +} + +ExternalReference ExternalReference::compute_integer_hash(Isolate* isolate) { + return ExternalReference( + Redirect(isolate, FUNCTION_ADDR(ComputeSeededIntegerHash))); +} + #ifdef V8_INTL_SUPPORT ExternalReference ExternalReference::intl_convert_one_byte_to_lower( Isolate* isolate) { diff --git a/deps/v8/src/assembler.h b/deps/v8/src/assembler.h index aeecaa167c94de..17c8d1115478f0 100644 --- a/deps/v8/src/assembler.h +++ b/deps/v8/src/assembler.h @@ -979,7 +979,7 @@ class ExternalReference BASE_EMBEDDED { static ExternalReference try_internalize_string_function(Isolate* isolate); static ExternalReference check_object_type(Isolate* isolate); - + static ExternalReference compute_integer_hash(Isolate* isolate); #ifdef V8_INTL_SUPPORT static ExternalReference intl_convert_one_byte_to_lower(Isolate* isolate); static ExternalReference intl_to_latin1_lower_table(Isolate* isolate); diff --git a/deps/v8/src/ast/ast-value-factory.cc b/deps/v8/src/ast/ast-value-factory.cc index c9c89d7745adde..b7bcb84e18e9ae 100644 --- a/deps/v8/src/ast/ast-value-factory.cc +++ b/deps/v8/src/ast/ast-value-factory.cc @@ -202,7 +202,6 @@ bool AstValue::BooleanValue() const { UNREACHABLE(); } - void AstValue::Internalize(Isolate* isolate) { switch (type_) { case STRING: diff --git a/deps/v8/src/ast/ast-value-factory.h b/deps/v8/src/ast/ast-value-factory.h index b72e34a36c17e8..9f10307555d9d4 100644 --- a/deps/v8/src/ast/ast-value-factory.h +++ b/deps/v8/src/ast/ast-value-factory.h @@ -361,7 +361,7 @@ class AstValue : public ZoneObject { class AstStringConstants final { public: - AstStringConstants(Isolate* isolate, uint32_t hash_seed) + AstStringConstants(Isolate* isolate, uint64_t hash_seed) : zone_(isolate->allocator(), ZONE_NAME), string_table_(AstRawString::Compare), hash_seed_(hash_seed) { @@ -391,7 +391,7 @@ class AstStringConstants final { STRING_CONSTANTS(F) #undef F - uint32_t hash_seed() const { return hash_seed_; } + uint64_t hash_seed() const { return hash_seed_; } const base::CustomMatcherHashMap* string_table() const { return &string_table_; } @@ -399,7 +399,7 @@ class AstStringConstants final { private: Zone zone_; base::CustomMatcherHashMap string_table_; - uint32_t hash_seed_; + uint64_t hash_seed_; #define F(name, str) AstRawString* name##_string_; STRING_CONSTANTS(F) @@ -418,7 +418,7 @@ class AstStringConstants final { class AstValueFactory { public: AstValueFactory(Zone* zone, const AstStringConstants* string_constants, - uint32_t hash_seed) + uint64_t hash_seed) : string_table_(string_constants->string_table()), values_(nullptr), strings_(nullptr), @@ -535,7 +535,7 @@ class AstValueFactory { Zone* zone_; - uint32_t hash_seed_; + uint64_t hash_seed_; #define F(name) AstValue* name##_; OTHER_CONSTANTS(F) diff --git a/deps/v8/src/builtins/builtins-collections-gen.cc b/deps/v8/src/builtins/builtins-collections-gen.cc index acb4c949ae11a8..9c8ce5ab1d4d6e 100644 --- a/deps/v8/src/builtins/builtins-collections-gen.cc +++ b/deps/v8/src/builtins/builtins-collections-gen.cc @@ -92,7 +92,7 @@ class CollectionsBuiltinsAssembler : public CodeStubAssembler { Node* key_tagged, Variable* result, Label* entry_found, Label* not_found); - Node* ComputeIntegerHashForString(Node* context, Node* string_key); + Node* ComputeStringHash(Node* context, Node* string_key); void SameValueZeroString(Node* context, Node* key_string, Node* candidate_key, Label* if_same, Label* if_not_same); @@ -515,8 +515,7 @@ void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForSmiKey( Node* table, Node* smi_key, Variable* result, Label* entry_found, Label* not_found) { Node* const key_untagged = SmiUntag(smi_key); - Node* const hash = - ChangeInt32ToIntPtr(ComputeIntegerHash(key_untagged, Int32Constant(0))); + Node* const hash = ChangeInt32ToIntPtr(ComputeUnseededHash(key_untagged)); CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0))); result->Bind(hash); FindOrderedHashTableEntry( @@ -531,7 +530,7 @@ template void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForStringKey( Node* context, Node* table, Node* key_tagged, Variable* result, Label* entry_found, Label* not_found) { - Node* const hash = ComputeIntegerHashForString(context, key_tagged); + Node* const hash = ComputeStringHash(context, key_tagged); CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0))); result->Bind(hash); FindOrderedHashTableEntry( @@ -573,8 +572,8 @@ void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForOtherKey( result, entry_found, not_found); } -Node* CollectionsBuiltinsAssembler::ComputeIntegerHashForString( - Node* context, Node* string_key) { +Node* CollectionsBuiltinsAssembler::ComputeStringHash(Node* context, + Node* string_key) { VARIABLE(var_result, MachineType::PointerRepresentation()); Label hash_not_computed(this), done(this, &var_result); diff --git a/deps/v8/src/code-stub-assembler.cc b/deps/v8/src/code-stub-assembler.cc index 915f507b12689c..b48e1afae5274f 100644 --- a/deps/v8/src/code-stub-assembler.cc +++ b/deps/v8/src/code-stub-assembler.cc @@ -200,10 +200,6 @@ HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR); HEAP_CONSTANT_LIST(HEAP_CONSTANT_TEST); #undef HEAP_CONSTANT_TEST -Node* CodeStubAssembler::HashSeed() { - return LoadAndUntagToWord32Root(Heap::kHashSeedRootIndex); -} - Node* CodeStubAssembler::StaleRegisterConstant() { return LoadRoot(Heap::kStaleRegisterRootIndex); } @@ -5389,22 +5385,32 @@ template void CodeStubAssembler::NameDictionaryLookup( template void CodeStubAssembler::NameDictionaryLookup( Node*, Node*, Label*, Variable*, Label*, int, LookupMode); -Node* CodeStubAssembler::ComputeIntegerHash(Node* key) { - return ComputeIntegerHash(key, IntPtrConstant(kZeroHashSeed)); -} - -Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) { - // See v8::internal::ComputeIntegerHash() +Node* CodeStubAssembler::ComputeUnseededHash(Node* key) { + // See v8::internal::ComputeUnseededHash() Node* hash = TruncateWordToWord32(key); - hash = Word32Xor(hash, seed); - hash = Int32Add(Word32Xor(hash, Int32Constant(0xffffffff)), + hash = Int32Add(Word32Xor(hash, Int32Constant(0xFFFFFFFF)), Word32Shl(hash, Int32Constant(15))); hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12))); hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2))); hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4))); hash = Int32Mul(hash, Int32Constant(2057)); hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); - return Word32And(hash, Int32Constant(0x3fffffff)); + return Word32And(hash, Int32Constant(0x3FFFFFFF)); +} + +Node* CodeStubAssembler::ComputeSeededHash(Node* key) { + Node* const function_addr = + ExternalConstant(ExternalReference::compute_integer_hash(isolate())); + Node* const isolate_ptr = + ExternalConstant(ExternalReference::isolate_address(isolate())); + + MachineType type_ptr = MachineType::Pointer(); + MachineType type_uint32 = MachineType::Uint32(); + + Node* const result = + CallCFunction2(type_uint32, type_ptr, type_uint32, function_addr, + isolate_ptr, TruncateWordToWord32(key)); + return result; } template @@ -5420,10 +5426,14 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, Node* capacity = SmiUntag(GetCapacity(dictionary)); Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); - Node* int32_seed = std::is_same::value - ? HashSeed() - : Int32Constant(kZeroHashSeed); - Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed)); + Node* hash; + + if (std::is_same::value) { + hash = ChangeUint32ToWord(ComputeSeededHash(intptr_index)); + } else { + hash = ChangeUint32ToWord(ComputeUnseededHash(intptr_index)); + } + Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index); // See Dictionary::FirstProbe(). diff --git a/deps/v8/src/code-stub-assembler.h b/deps/v8/src/code-stub-assembler.h index 8379663297d6e7..4ee6fd8c1f5bb5 100644 --- a/deps/v8/src/code-stub-assembler.h +++ b/deps/v8/src/code-stub-assembler.h @@ -170,7 +170,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { HEAP_CONSTANT_LIST(HEAP_CONSTANT_TEST) #undef HEAP_CONSTANT_TEST - Node* HashSeed(); Node* StaleRegisterConstant(); Node* IntPtrOrSmiConstant(int value, ParameterMode mode); @@ -1276,8 +1275,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { int inlined_probes = kInlinedDictionaryProbes, LookupMode mode = kFindExisting); - Node* ComputeIntegerHash(Node* key); - Node* ComputeIntegerHash(Node* key, Node* seed); + Node* ComputeUnseededHash(Node* key); + Node* ComputeSeededHash(Node* key); template void NumberDictionaryLookup(Node* dictionary, Node* intptr_index, diff --git a/deps/v8/src/external-reference-table.cc b/deps/v8/src/external-reference-table.cc index 18edc4289bf04b..b9a49524d0840e 100644 --- a/deps/v8/src/external-reference-table.cc +++ b/deps/v8/src/external-reference-table.cc @@ -232,6 +232,8 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) { "try_internalize_string_function"); Add(ExternalReference::check_object_type(isolate).address(), "check_object_type"); + Add(ExternalReference::compute_integer_hash(isolate).address(), + "ComputeSeededHash"); #ifdef V8_INTL_SUPPORT Add(ExternalReference::intl_convert_one_byte_to_lower(isolate).address(), "intl_convert_one_byte_to_lower"); diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h index 7fc25bcc91b66e..1576202c9a031e 100644 --- a/deps/v8/src/flag-definitions.h +++ b/deps/v8/src/flag-definitions.h @@ -160,6 +160,7 @@ struct MaybeBoolFlag { FLAG(MAYBE_BOOL, MaybeBoolFlag, nam, {false COMMA false}, cmt) #define DEFINE_INT(nam, def, cmt) FLAG(INT, int, nam, def, cmt) #define DEFINE_UINT(nam, def, cmt) FLAG(UINT, unsigned int, nam, def, cmt) +#define DEFINE_UINT64(nam, def, cmt) FLAG(UINT64, uint64_t, nam, def, cmt) #define DEFINE_FLOAT(nam, def, cmt) FLAG(FLOAT, double, nam, def, cmt) #define DEFINE_STRING(nam, def, cmt) FLAG(STRING, const char*, nam, def, cmt) #define DEFINE_ARGS(nam, cmt) FLAG(ARGS, JSArguments, nam, {0 COMMA NULL}, cmt) @@ -914,9 +915,9 @@ DEFINE_BOOL(randomize_hashes, true, "(with snapshots this option cannot override the baked-in seed)") DEFINE_BOOL(rehash_snapshot, true, "rehash strings from the snapshot to override the baked-in seed") -DEFINE_INT(hash_seed, 0, - "Fixed seed to use to hash property keys (0 means random)" - "(with snapshots this option cannot override the baked-in seed)") +DEFINE_UINT64(hash_seed, 0, + "Fixed seed to use to hash property keys (0 means random)" + "(with snapshots this option cannot override the baked-in seed)") DEFINE_INT(random_seed, 0, "Default seed for initializing random generator " "(0, the default, means to use system random).") diff --git a/deps/v8/src/flags.cc b/deps/v8/src/flags.cc index 9fdc5d04be84dd..edf0d4681253a3 100644 --- a/deps/v8/src/flags.cc +++ b/deps/v8/src/flags.cc @@ -39,6 +39,7 @@ struct Flag { TYPE_MAYBE_BOOL, TYPE_INT, TYPE_UINT, + TYPE_UINT64, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS @@ -77,6 +78,11 @@ struct Flag { return reinterpret_cast(valptr_); } + uint64_t* uint64_variable() const { + DCHECK(type_ == TYPE_UINT64); + return reinterpret_cast(valptr_); + } + double* float_variable() const { DCHECK(type_ == TYPE_FLOAT); return reinterpret_cast(valptr_); @@ -115,6 +121,11 @@ struct Flag { return *reinterpret_cast(defptr_); } + uint64_t uint64_default() const { + DCHECK(type_ == TYPE_UINT64); + return *reinterpret_cast(defptr_); + } + double float_default() const { DCHECK(type_ == TYPE_FLOAT); return *reinterpret_cast(defptr_); @@ -141,6 +152,8 @@ struct Flag { return *int_variable() == int_default(); case TYPE_UINT: return *uint_variable() == uint_default(); + case TYPE_UINT64: + return *uint64_variable() == uint64_default(); case TYPE_FLOAT: return *float_variable() == float_default(); case TYPE_STRING: { @@ -171,6 +184,9 @@ struct Flag { case TYPE_UINT: *uint_variable() = uint_default(); break; + case TYPE_UINT64: + *uint64_variable() = uint64_default(); + break; case TYPE_FLOAT: *float_variable() = float_default(); break; @@ -201,6 +217,8 @@ static const char* Type2String(Flag::FlagType type) { case Flag::TYPE_INT: return "int"; case Flag::TYPE_UINT: return "uint"; + case Flag::TYPE_UINT64: + return "uint64"; case Flag::TYPE_FLOAT: return "float"; case Flag::TYPE_STRING: return "string"; case Flag::TYPE_ARGS: return "arguments"; @@ -225,6 +243,9 @@ std::ostream& operator<<(std::ostream& os, const Flag& flag) { // NOLINT case Flag::TYPE_UINT: os << *flag.uint_variable(); break; + case Flag::TYPE_UINT64: + os << *flag.uint64_variable(); + break; case Flag::TYPE_FLOAT: os << *flag.float_variable(); break; @@ -443,6 +464,24 @@ int FlagList::SetFlagsFromCommandLine(int* argc, *flag->uint_variable() = static_cast(val); break; } + case Flag::TYPE_UINT64: { + // We do not use strtoul because it accepts negative numbers. + int64_t val = static_cast(strtoll(value, &endp, 10)); + if (val < 0 || val > std::numeric_limits::max()) { + PrintF(stderr, + "Error: Value for flag %s of type %s is out of bounds " + "[0-%" PRIu64 + "]\n" + "Try --help for options\n", + arg, Type2String(flag->type()), + static_cast( + std::numeric_limits::max())); + return_code = j; + break; + } + *flag->uint64_variable() = static_cast(val); + break; + } case Flag::TYPE_FLOAT: *flag->float_variable() = strtod(value, &endp); break; diff --git a/deps/v8/src/frames.cc b/deps/v8/src/frames.cc index 37f5b4d9cf1673..665cd04d3e4d02 100644 --- a/deps/v8/src/frames.cc +++ b/deps/v8/src/frames.cc @@ -2132,7 +2132,8 @@ InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) { isolate_->counters()->pc_to_code()->Increment(); DCHECK(base::bits::IsPowerOfTwo(kInnerPointerToCodeCacheSize)); - uint32_t hash = ComputeIntegerHash(ObjectAddressForHashing(inner_pointer)); + uint32_t hash = ComputeUnseededHash( + ObjectAddressForHashing(reinterpret_cast(inner_pointer))); uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1); InnerPointerToCodeCacheEntry* entry = cache(index); if (entry->inner_pointer == inner_pointer) { diff --git a/deps/v8/src/heap/heap-inl.h b/deps/v8/src/heap/heap-inl.h index 49d69c80e23642..7abad16bf98cba 100644 --- a/deps/v8/src/heap/heap-inl.h +++ b/deps/v8/src/heap/heap-inl.h @@ -614,13 +614,13 @@ Oddball* Heap::ToBoolean(bool condition) { return condition ? true_value() : false_value(); } -uint32_t Heap::HashSeed() { - uint32_t seed = static_cast(hash_seed()->value()); +uint64_t Heap::HashSeed() { + uint64_t seed; + hash_seed()->copy_out(0, reinterpret_cast(&seed), kInt64Size); DCHECK(FLAG_randomize_hashes || seed == 0); return seed; } - int Heap::NextScriptId() { int last_id = last_script_id()->value(); if (last_id == Smi::kMaxValue) { diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc index f736977d227e7e..502b679dd80030 100644 --- a/deps/v8/src/heap/heap.cc +++ b/deps/v8/src/heap/heap.cc @@ -2825,6 +2825,9 @@ void Heap::CreateInitialObjects() { set_minus_infinity_value( *factory->NewHeapNumber(-V8_INFINITY, IMMUTABLE, TENURED)); + set_hash_seed(*factory->NewByteArray(kInt64Size, TENURED)); + InitializeHashSeed(); + // Allocate initial string table. set_string_table(*StringTable::New(isolate(), kInitialStringTableSize)); @@ -5929,10 +5932,6 @@ bool Heap::SetUp() { space_[LO_SPACE] = lo_space_ = new LargeObjectSpace(this, LO_SPACE); if (!lo_space_->SetUp()) return false; - // Set up the seed that is used to randomize the string hash function. - DCHECK(hash_seed() == 0); - if (FLAG_randomize_hashes) InitializeHashSeed(); - for (int i = 0; i < static_cast(v8::Isolate::kUseCounterFeatureCount); i++) { deferred_counters_[i] = 0; @@ -5970,12 +5969,14 @@ bool Heap::SetUp() { } void Heap::InitializeHashSeed() { + uint64_t new_hash_seed; if (FLAG_hash_seed == 0) { - int rnd = isolate()->random_number_generator()->NextInt(); - set_hash_seed(Smi::FromInt(rnd & Name::kHashBitMask)); + int64_t rnd = isolate()->random_number_generator()->NextInt64(); + new_hash_seed = static_cast(rnd); } else { - set_hash_seed(Smi::FromInt(FLAG_hash_seed)); + new_hash_seed = static_cast(FLAG_hash_seed); } + hash_seed()->copy_in(0, reinterpret_cast(&new_hash_seed), kInt64Size); } bool Heap::CreateHeapObjects() { diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h index 9b0bbc6293ff73..bcae0e5130cbfb 100644 --- a/deps/v8/src/heap/heap.h +++ b/deps/v8/src/heap/heap.h @@ -228,6 +228,8 @@ using v8::MemoryPressureLevel; V(FixedArray, serialized_templates, SerializedTemplates) \ V(FixedArray, serialized_global_proxy_sizes, SerializedGlobalProxySizes) \ V(TemplateList, message_listeners, MessageListeners) \ + /* Hash seed */ \ + V(ByteArray, hash_seed, HashSeed) \ /* per-Isolate map for JSPromiseCapability. */ \ /* TODO(caitp): Make this a Struct */ \ V(Map, js_promise_capability_map, JSPromiseCapabilityMap) \ @@ -240,7 +242,6 @@ using v8::MemoryPressureLevel; V(Smi, stack_limit, StackLimit) \ V(Smi, real_stack_limit, RealStackLimit) \ V(Smi, last_script_id, LastScriptId) \ - V(Smi, hash_seed, HashSeed) \ /* To distinguish the function templates, so that we can find them in the */ \ /* function cache of the native context. */ \ V(Smi, next_template_serial_number, NextTemplateSerialNumber) \ @@ -814,7 +815,7 @@ class Heap { void IncrementDeferredCount(v8::Isolate::UseCounterFeature feature); - inline uint32_t HashSeed(); + inline uint64_t HashSeed(); inline int NextScriptId(); diff --git a/deps/v8/src/json-parser.cc b/deps/v8/src/json-parser.cc index 32e4187c8edb3d..f5b0363f290301 100644 --- a/deps/v8/src/json-parser.cc +++ b/deps/v8/src/json-parser.cc @@ -793,9 +793,11 @@ Handle JsonParser::ScanJsonString() { // We intentionally use local variables instead of fields, compute hash // while we are iterating a string and manually inline StringTable lookup // here. - uint32_t running_hash = isolate()->heap()->HashSeed(); + uint32_t running_hash = + static_cast(isolate()->heap()->HashSeed()); int position = position_; uc32 c0 = c0_; + do { if (c0 == '\\') { c0_ = c0; diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index 91fd08a2dd58c8..b02f59bbe7d79a 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -5844,13 +5844,13 @@ bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) { } uint32_t UnseededNumberDictionaryShape::Hash(Isolate* isolate, uint32_t key) { - return ComputeIntegerHash(key); + return ComputeUnseededHash(key); } uint32_t UnseededNumberDictionaryShape::HashForObject(Isolate* isolate, Object* other) { DCHECK(other->IsNumber()); - return ComputeIntegerHash(static_cast(other->Number())); + return ComputeUnseededHash(static_cast(other->Number())); } Map* UnseededNumberDictionaryShape::GetMap(Isolate* isolate) { @@ -5858,14 +5858,14 @@ Map* UnseededNumberDictionaryShape::GetMap(Isolate* isolate) { } uint32_t SeededNumberDictionaryShape::Hash(Isolate* isolate, uint32_t key) { - return ComputeIntegerHash(key, isolate->heap()->HashSeed()); + return ComputeSeededHash(key, isolate->heap()->HashSeed()); } uint32_t SeededNumberDictionaryShape::HashForObject(Isolate* isolate, Object* other) { DCHECK(other->IsNumber()); - return ComputeIntegerHash(static_cast(other->Number()), - isolate->heap()->HashSeed()); + return ComputeSeededHash(static_cast(other->Number()), + isolate->heap()->HashSeed()); } @@ -5936,7 +5936,6 @@ uint32_t ObjectHashTableShape::HashForObject(Isolate* isolate, Object* other) { return Smi::ToInt(other->GetHash()); } - Handle ObjectHashTableShape::AsHandle(Isolate* isolate, Handle key) { return key; diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index 25bf0650245626..3dabc3cf0bd72d 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -2305,7 +2305,7 @@ Object* GetSimpleHash(Object* object) { // The object is either a Smi, a HeapNumber, a name, an odd-ball, a real JS // object, or a Harmony proxy. if (object->IsSmi()) { - uint32_t hash = ComputeIntegerHash(Smi::ToInt(object)); + uint32_t hash = ComputeUnseededHash(Smi::ToInt(object)); return Smi::FromInt(hash & Smi::kMaxValue); } if (object->IsHeapNumber()) { @@ -2313,7 +2313,7 @@ Object* GetSimpleHash(Object* object) { if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue); if (i::IsMinusZero(num)) num = 0; if (IsSmiDouble(num)) { - return Smi::FromInt(FastD2I(num))->GetHash(); + return Smi::FromInt(ComputeUnseededHash(FastD2I(num))); } uint32_t hash = ComputeLongHash(double_to_uint64(num)); return Smi::FromInt(hash & Smi::kMaxValue); @@ -12152,9 +12152,7 @@ uint32_t StringHasher::GetHashField() { } } - -uint32_t StringHasher::ComputeUtf8Hash(Vector chars, - uint32_t seed, +uint32_t StringHasher::ComputeUtf8Hash(Vector chars, uint64_t seed, int* utf16_length_out) { int vector_length = chars.length(); // Handle some edge cases @@ -16838,7 +16836,7 @@ Handle JSGlobalObject::EnsureEmptyPropertyCell( // algorithm. class TwoCharHashTableKey : public StringTableKey { public: - TwoCharHashTableKey(uint16_t c1, uint16_t c2, uint32_t seed) + TwoCharHashTableKey(uint16_t c1, uint16_t c2, uint64_t seed) : StringTableKey(ComputeHashField(c1, c2, seed)), c1_(c1), c2_(c2) {} bool IsMatch(Object* o) override { @@ -16855,9 +16853,9 @@ class TwoCharHashTableKey : public StringTableKey { } private: - uint32_t ComputeHashField(uint16_t c1, uint16_t c2, uint32_t seed) { + uint32_t ComputeHashField(uint16_t c1, uint16_t c2, uint64_t seed) { // Char 1. - uint32_t hash = seed; + uint32_t hash = static_cast(seed); hash += c1; hash += hash << 10; hash ^= hash >> 6; @@ -17030,7 +17028,7 @@ namespace { class StringTableNoAllocateKey : public StringTableKey { public: - StringTableNoAllocateKey(String* string, uint32_t seed) + StringTableNoAllocateKey(String* string, uint64_t seed) : StringTableKey(0), string_(string) { StringShape shape(string); one_byte_ = shape.HasOnlyOneByteChars(); diff --git a/deps/v8/src/objects/hash-table.h b/deps/v8/src/objects/hash-table.h index 6b5682535ab4ce..68ea45115f9e79 100644 --- a/deps/v8/src/objects/hash-table.h +++ b/deps/v8/src/objects/hash-table.h @@ -466,7 +466,7 @@ class OrderedHashTable : public OrderedHashTableBase { // This special cases for Smi, so that we avoid the HandleScope // creation below. if (key->IsSmi()) { - uint32_t hash = ComputeIntegerHash(Smi::ToInt(key)); + uint32_t hash = ComputeUnseededHash(Smi::ToInt(key)); return HashToEntry(hash & Smi::kMaxValue); } HandleScope scope(isolate); diff --git a/deps/v8/src/objects/string-inl.h b/deps/v8/src/objects/string-inl.h index a30b65da956c62..7208ef28dcc9f0 100644 --- a/deps/v8/src/objects/string-inl.h +++ b/deps/v8/src/objects/string-inl.h @@ -195,7 +195,7 @@ Char FlatStringReader::Get(int index) { template class SequentialStringKey : public StringTableKey { public: - explicit SequentialStringKey(Vector string, uint32_t seed) + explicit SequentialStringKey(Vector string, uint64_t seed) : StringTableKey(StringHasher::HashSequentialString( string.start(), string.length(), seed)), string_(string) {} @@ -205,7 +205,7 @@ class SequentialStringKey : public StringTableKey { class OneByteStringKey : public SequentialStringKey { public: - OneByteStringKey(Vector str, uint32_t seed) + OneByteStringKey(Vector str, uint64_t seed) : SequentialStringKey(str, seed) {} bool IsMatch(Object* string) override { @@ -250,7 +250,7 @@ class SeqOneByteSubStringKey : public StringTableKey { class TwoByteStringKey : public SequentialStringKey { public: - explicit TwoByteStringKey(Vector str, uint32_t seed) + explicit TwoByteStringKey(Vector str, uint64_t seed) : SequentialStringKey(str, seed) {} bool IsMatch(Object* string) override { @@ -263,7 +263,7 @@ class TwoByteStringKey : public SequentialStringKey { // Utf8StringKey carries a vector of chars as key. class Utf8StringKey : public StringTableKey { public: - explicit Utf8StringKey(Vector string, uint32_t seed) + explicit Utf8StringKey(Vector string, uint64_t seed) : StringTableKey(StringHasher::ComputeUtf8Hash(string, seed, &chars_)), string_(string) {} diff --git a/deps/v8/src/parsing/parse-info.h b/deps/v8/src/parsing/parse-info.h index 909f4c58e008bb..8aa0dfd700793b 100644 --- a/deps/v8/src/parsing/parse-info.h +++ b/deps/v8/src/parsing/parse-info.h @@ -148,8 +148,8 @@ class V8_EXPORT_PRIVATE ParseInfo { uintptr_t stack_limit() const { return stack_limit_; } void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } - uint32_t hash_seed() const { return hash_seed_; } - void set_hash_seed(uint32_t hash_seed) { hash_seed_ = hash_seed; } + uint64_t hash_seed() const { return hash_seed_; } + void set_hash_seed(uint64_t hash_seed) { hash_seed_ = hash_seed; } int compiler_hints() const { return compiler_hints_; } void set_compiler_hints(int compiler_hints) { @@ -266,7 +266,7 @@ class V8_EXPORT_PRIVATE ParseInfo { DeclarationScope* asm_function_scope_; UnicodeCache* unicode_cache_; uintptr_t stack_limit_; - uint32_t hash_seed_; + uint64_t hash_seed_; int compiler_hints_; int start_position_; int end_position_; diff --git a/deps/v8/src/profiler/allocation-tracker.cc b/deps/v8/src/profiler/allocation-tracker.cc index 8d8a3c7e1d4429..8d14031f640ccb 100644 --- a/deps/v8/src/profiler/allocation-tracker.cc +++ b/deps/v8/src/profiler/allocation-tracker.cc @@ -252,7 +252,7 @@ void AllocationTracker::AllocationEvent(Address addr, int size) { static uint32_t SnapshotObjectIdHash(SnapshotObjectId id) { - return ComputeIntegerHash(static_cast(id)); + return ComputeUnseededHash(static_cast(id)); } diff --git a/deps/v8/src/profiler/heap-profiler.cc b/deps/v8/src/profiler/heap-profiler.cc index f587adda497daf..61ffb84e8e0446 100644 --- a/deps/v8/src/profiler/heap-profiler.cc +++ b/deps/v8/src/profiler/heap-profiler.cc @@ -16,7 +16,7 @@ namespace internal { HeapProfiler::HeapProfiler(Heap* heap) : ids_(new HeapObjectsMap(heap)), - names_(new StringsStorage(heap->HashSeed())), + names_(new StringsStorage()), is_tracking_object_moves_(false), get_retainer_infos_callback_(nullptr) {} @@ -34,7 +34,7 @@ HeapProfiler::~HeapProfiler() { void HeapProfiler::DeleteAllSnapshots() { snapshots_.Iterate(DeleteHeapSnapshot); snapshots_.Clear(); - names_.reset(new StringsStorage(heap()->HashSeed())); + names_.reset(new StringsStorage()); } diff --git a/deps/v8/src/profiler/heap-snapshot-generator.cc b/deps/v8/src/profiler/heap-snapshot-generator.cc index 98e4600cd39893..0674a58cd6c511 100644 --- a/deps/v8/src/profiler/heap-snapshot-generator.cc +++ b/deps/v8/src/profiler/heap-snapshot-generator.cc @@ -526,7 +526,7 @@ SnapshotObjectId HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) { heap_->HashSeed()); intptr_t element_count = info->GetElementCount(); if (element_count != -1) { - id ^= ComputeIntegerHash(static_cast(element_count)); + id ^= ComputeUnseededHash(static_cast(element_count)); } return id << 1; } diff --git a/deps/v8/src/profiler/heap-snapshot-generator.h b/deps/v8/src/profiler/heap-snapshot-generator.h index b40400aa7d45df..6baaca2cb4f8e9 100644 --- a/deps/v8/src/profiler/heap-snapshot-generator.h +++ b/deps/v8/src/profiler/heap-snapshot-generator.h @@ -288,7 +288,7 @@ class HeapEntriesMap { private: static uint32_t Hash(HeapThing thing) { - return ComputeIntegerHash( + return ComputeUnseededHash( static_cast(reinterpret_cast(thing))); } @@ -497,7 +497,7 @@ class NativeObjectsExplorer { void VisitSubtreeWrapper(Object** p, uint16_t class_id); static uint32_t InfoHash(v8::RetainedObjectInfo* info) { - return ComputeIntegerHash(static_cast(info->GetHash())); + return ComputeUnseededHash(static_cast(info->GetHash())); } static bool RetainedInfosMatch(void* key1, void* key2) { return key1 == key2 || diff --git a/deps/v8/src/profiler/profile-generator.cc b/deps/v8/src/profiler/profile-generator.cc index c01904b77801b1..23bf67a8d2ee5d 100644 --- a/deps/v8/src/profiler/profile-generator.cc +++ b/deps/v8/src/profiler/profile-generator.cc @@ -83,16 +83,16 @@ CodeEntry* CodeEntry::UnresolvedEntryCreateTrait::Create() { } uint32_t CodeEntry::GetHash() const { - uint32_t hash = ComputeIntegerHash(tag()); + uint32_t hash = ComputeUnseededHash(tag()); if (script_id_ != v8::UnboundScript::kNoScriptId) { - hash ^= ComputeIntegerHash(static_cast(script_id_)); - hash ^= ComputeIntegerHash(static_cast(position_)); + hash ^= ComputeUnseededHash(static_cast(script_id_)); + hash ^= ComputeUnseededHash(static_cast(position_)); } else { - hash ^= ComputeIntegerHash( + hash ^= ComputeUnseededHash( static_cast(reinterpret_cast(name_))); - hash ^= ComputeIntegerHash( + hash ^= ComputeUnseededHash( static_cast(reinterpret_cast(resource_name_))); - hash ^= ComputeIntegerHash(line_number_); + hash ^= ComputeUnseededHash(line_number_); } return hash; } @@ -533,7 +533,7 @@ void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) { ClearCodesInRange(addr, addr + size); unsigned index = AddCodeEntry(addr, entry); code_map_.emplace(addr, CodeEntryMapInfo{index, size}); - DCHECK(entry->instruction_start() == kNullAddress || + DCHECK(entry->instruction_start() == 0 || addr == entry->instruction_start()); } @@ -605,9 +605,7 @@ void CodeMap::Print() { } CpuProfilesCollection::CpuProfilesCollection(Isolate* isolate) - : resource_names_(isolate->heap()->HashSeed()), - profiler_(nullptr), - current_profiles_semaphore_(1) {} + : profiler_(nullptr), current_profiles_semaphore_(1) {} static void DeleteCpuProfile(CpuProfile** profile_ptr) { delete *profile_ptr; diff --git a/deps/v8/src/profiler/profile-generator.h b/deps/v8/src/profiler/profile-generator.h index f5b8ef39f26e67..740e9f27ea5077 100644 --- a/deps/v8/src/profiler/profile-generator.h +++ b/deps/v8/src/profiler/profile-generator.h @@ -241,7 +241,7 @@ class ProfileNode { }; struct Hasher { std::size_t operator()(CodeEntryAndLineNumber pair) const { - return pair.code_entry->GetHash() ^ ComputeIntegerHash(pair.line_number); + return pair.code_entry->GetHash() ^ ComputeUnseededHash(pair.line_number); } }; diff --git a/deps/v8/src/profiler/profiler-listener.cc b/deps/v8/src/profiler/profiler-listener.cc index 0feb16dc875346..cba4e018d4717a 100644 --- a/deps/v8/src/profiler/profiler-listener.cc +++ b/deps/v8/src/profiler/profiler-listener.cc @@ -16,8 +16,7 @@ namespace internal { ProfilerListener::ProfilerListener(Isolate* isolate, CodeEventObserver* observer) : isolate_(isolate), - observer_(observer), - function_and_resource_names_(isolate->heap()->HashSeed()) {} + observer_(observer) {} ProfilerListener::~ProfilerListener() = default; diff --git a/deps/v8/src/profiler/strings-storage.cc b/deps/v8/src/profiler/strings-storage.cc index cce5ad176560e5..bc79c48250cf42 100644 --- a/deps/v8/src/profiler/strings-storage.cc +++ b/deps/v8/src/profiler/strings-storage.cc @@ -17,8 +17,7 @@ bool StringsStorage::StringsMatch(void* key1, void* key2) { 0; } -StringsStorage::StringsStorage(uint32_t hash_seed) - : hash_seed_(hash_seed), names_(StringsMatch) {} +StringsStorage::StringsStorage() : names_(StringsMatch) {} StringsStorage::~StringsStorage() { for (base::HashMap::Entry* p = names_.Start(); p != NULL; @@ -116,7 +115,7 @@ const char* StringsStorage::GetFunctionName(const char* name) { } base::HashMap::Entry* StringsStorage::GetEntry(const char* str, int len) { - uint32_t hash = StringHasher::HashSequentialString(str, len, hash_seed_); + uint32_t hash = StringHasher::HashSequentialString(str, len, kZeroHashSeed); return names_.LookupOrInsert(const_cast(str), hash); } diff --git a/deps/v8/src/profiler/strings-storage.h b/deps/v8/src/profiler/strings-storage.h index 246a4033d5ee57..88d12c02b4fe3c 100644 --- a/deps/v8/src/profiler/strings-storage.h +++ b/deps/v8/src/profiler/strings-storage.h @@ -19,7 +19,7 @@ class Name; // forever, even if they disappear from JS heap or external storage. class StringsStorage { public: - explicit StringsStorage(uint32_t hash_seed); + StringsStorage(); ~StringsStorage(); const char* GetCopy(const char* src); @@ -39,7 +39,6 @@ class StringsStorage { const char* AddOrDisposeString(char* str, int len); base::CustomMatcherHashMap::Entry* GetEntry(const char* str, int len); - uint32_t hash_seed_; base::CustomMatcherHashMap names_; DISALLOW_COPY_AND_ASSIGN(StringsStorage); diff --git a/deps/v8/src/string-hasher-inl.h b/deps/v8/src/string-hasher-inl.h index 7d1f106e0227bd..62f50f050a33ee 100644 --- a/deps/v8/src/string-hasher-inl.h +++ b/deps/v8/src/string-hasher-inl.h @@ -12,9 +12,9 @@ namespace v8 { namespace internal { -StringHasher::StringHasher(int length, uint32_t seed) +StringHasher::StringHasher(int length, uint64_t seed) : length_(length), - raw_running_hash_(seed), + raw_running_hash_(static_cast(seed)), array_index_(0), is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), is_first_char_(true) { @@ -113,16 +113,16 @@ inline void StringHasher::AddCharacters(const Char* chars, int length) { template uint32_t StringHasher::HashSequentialString(const schar* chars, int length, - uint32_t seed) { + uint64_t seed) { StringHasher hasher(length, seed); if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length); return hasher.GetHashField(); } -IteratingStringHasher::IteratingStringHasher(int len, uint32_t seed) +IteratingStringHasher::IteratingStringHasher(int len, uint64_t seed) : StringHasher(len, seed) {} -uint32_t IteratingStringHasher::Hash(String* string, uint32_t seed) { +uint32_t IteratingStringHasher::Hash(String* string, uint64_t seed) { IteratingStringHasher hasher(string->length(), seed); // Nothing to do. if (hasher.has_trivial_hash()) return hasher.GetHashField(); diff --git a/deps/v8/src/string-hasher.h b/deps/v8/src/string-hasher.h index 867a480a4187c1..35cca259294d21 100644 --- a/deps/v8/src/string-hasher.h +++ b/deps/v8/src/string-hasher.h @@ -18,14 +18,14 @@ class Vector; class V8_EXPORT_PRIVATE StringHasher { public: - explicit inline StringHasher(int length, uint32_t seed); + explicit inline StringHasher(int length, uint64_t seed); template static inline uint32_t HashSequentialString(const schar* chars, int length, - uint32_t seed); + uint64_t seed); // Reads all the data, even for long strings and computes the utf16 length. - static uint32_t ComputeUtf8Hash(Vector chars, uint32_t seed, + static uint32_t ComputeUtf8Hash(Vector chars, uint64_t seed, int* utf16_length_out); // Calculated hash value for a string consisting of 1 to @@ -74,12 +74,12 @@ class V8_EXPORT_PRIVATE StringHasher { class IteratingStringHasher : public StringHasher { public: - static inline uint32_t Hash(String* string, uint32_t seed); + static inline uint32_t Hash(String* string, uint64_t seed); inline void VisitOneByteString(const uint8_t* chars, int length); inline void VisitTwoByteString(const uint16_t* chars, int length); private: - inline IteratingStringHasher(int len, uint32_t seed); + inline IteratingStringHasher(int len, uint64_t seed); void VisitConsString(ConsString* cons_string); DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher); }; diff --git a/deps/v8/src/utils.h b/deps/v8/src/utils.h index 292ff535cb5700..20ef89d8ebcfcc 100644 --- a/deps/v8/src/utils.h +++ b/deps/v8/src/utils.h @@ -393,13 +393,12 @@ class BitSetComputer { // ---------------------------------------------------------------------------- // Hash function. -static const uint32_t kZeroHashSeed = 0; +static const uint64_t kZeroHashSeed = 0; // Thomas Wang, Integer Hash Functions. -// http://www.concentric.net/~Ttwang/tech/inthash.htm -inline uint32_t ComputeIntegerHash(uint32_t key, uint32_t seed) { +// http://www.concentric.net/~Ttwang/tech/inthash.htm` +inline uint32_t ComputeUnseededHash(uint32_t key) { uint32_t hash = key; - hash = hash ^ seed; hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1; hash = hash ^ (hash >> 12); hash = hash + (hash << 2); @@ -409,10 +408,6 @@ inline uint32_t ComputeIntegerHash(uint32_t key, uint32_t seed) { return hash & 0x3fffffff; } -inline uint32_t ComputeIntegerHash(uint32_t key) { - return ComputeIntegerHash(key, kZeroHashSeed); -} - inline uint32_t ComputeLongHash(uint64_t key) { uint64_t hash = key; hash = ~hash + (hash << 18); // hash = (hash << 18) - hash - 1; @@ -421,16 +416,18 @@ inline uint32_t ComputeLongHash(uint64_t key) { hash = hash ^ (hash >> 11); hash = hash + (hash << 6); hash = hash ^ (hash >> 22); - return static_cast(hash); + return static_cast(hash & 0x3fffffff); } +inline uint32_t ComputeSeededHash(uint32_t key, uint64_t seed) { + return ComputeLongHash(static_cast(key) ^ seed); +} inline uint32_t ComputePointerHash(void* ptr) { - return ComputeIntegerHash( + return ComputeUnseededHash( static_cast(reinterpret_cast(ptr))); } - // ---------------------------------------------------------------------------- // Generated memcpy/memmove diff --git a/deps/v8/test/cctest/heap/test-heap.cc b/deps/v8/test/cctest/heap/test-heap.cc index 46927cdc887554..74a44f7371d2c6 100644 --- a/deps/v8/test/cctest/heap/test-heap.cc +++ b/deps/v8/test/cctest/heap/test-heap.cc @@ -6094,7 +6094,7 @@ UNINITIALIZED_TEST(ReinitializeStringHashSeed) { v8::Isolate* isolate = v8::Isolate::New(create_params); { v8::Isolate::Scope isolate_scope(isolate); - CHECK_EQ(1337 * i, + CHECK_EQ(static_cast(1337 * i), reinterpret_cast(isolate)->heap()->HashSeed()); v8::HandleScope handle_scope(isolate); v8::Local context = v8::Context::New(isolate); diff --git a/deps/v8/test/cctest/test-code-stub-assembler.cc b/deps/v8/test/cctest/test-code-stub-assembler.cc index e34b2322449756..af4116ae059985 100644 --- a/deps/v8/test/cctest/test-code-stub-assembler.cc +++ b/deps/v8/test/cctest/test-code-stub-assembler.cc @@ -262,15 +262,13 @@ TEST(JSFunction) { TEST(ComputeIntegerHash) { Isolate* isolate(CcTest::InitIsolateOnce()); - const int kNumParams = 2; + const int kNumParams = 1; CodeAssemblerTester asm_tester(isolate, kNumParams); CodeStubAssembler m(asm_tester.state()); - m.Return(m.SmiFromWord32(m.ComputeIntegerHash( - m.SmiUntag(m.Parameter(0)), m.SmiToWord32(m.Parameter(1))))); - FunctionTester ft(asm_tester.GenerateCode(), kNumParams); + m.Return(m.SmiFromWord32(m.ComputeSeededHash(m.SmiUntag(m.Parameter(0))))); - Handle hash_seed = isolate->factory()->hash_seed(); + FunctionTester ft(asm_tester.GenerateCode(), kNumParams); base::RandomNumberGenerator rand_gen(FLAG_random_seed); @@ -278,9 +276,9 @@ TEST(ComputeIntegerHash) { int k = rand_gen.NextInt(Smi::kMaxValue); Handle key(Smi::FromInt(k), isolate); - Handle result = ft.Call(key, hash_seed).ToHandleChecked(); + Handle result = ft.Call(key).ToHandleChecked(); - uint32_t hash = ComputeIntegerHash(k, hash_seed->value()); + uint32_t hash = ComputeSeededHash(k, isolate->heap()->HashSeed()); Smi* expected = Smi::FromInt(hash & Smi::kMaxValue); CHECK_EQ(expected, Smi::cast(*result)); } diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 1f1d3e6010f1d6..5a3b9fc1b16c91 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -2465,7 +2465,8 @@ UNINITIALIZED_TEST(ReinitializeStringHashSeedNotRehashable) { v8::Isolate* isolate = v8::Isolate::New(create_params); { // Check that no rehashing has been performed. - CHECK_EQ(42, reinterpret_cast(isolate)->heap()->HashSeed()); + CHECK_EQ(static_cast(42), + reinterpret_cast(isolate)->heap()->HashSeed()); v8::Isolate::Scope isolate_scope(isolate); v8::HandleScope handle_scope(isolate); v8::Local context = v8::Context::New(isolate);