Created
December 30, 2011 02:34
-
-
Save piscisaureus/1537383 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From db8adac19321504530e6794771ae534a238c1648 Mon Sep 17 00:00:00 2001 | |
From: Bert Belder <[email protected]> | |
Date: Fri, 30 Dec 2011 14:36:31 +0100 | |
Subject: [PATCH 1/1] Partial support for hash randomization | |
- Doesn't play nice with snapshots | |
- Breaks ARM and MIPS | |
--- | |
deps/v8/src/flag-definitions.h | 3 +++ | |
deps/v8/src/ia32/code-stubs-ia32.cc | 18 ++++++++++++++---- | |
deps/v8/src/isolate.cc | 8 +++++++- | |
deps/v8/src/isolate.h | 3 +++ | |
deps/v8/src/objects-inl.h | 6 ++++-- | |
deps/v8/src/objects.cc | 4 +++- | |
deps/v8/src/x64/code-stubs-x64.cc | 18 ++++++++++++++---- | |
7 files changed, 48 insertions(+), 12 deletions(-) | |
diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h | |
index 7df2b0b..e0b3989 100644 | |
--- a/deps/v8/src/flag-definitions.h | |
+++ b/deps/v8/src/flag-definitions.h | |
@@ -319,6 +319,9 @@ DEFINE_bool(trace_exception, false, | |
"print stack trace when throwing exceptions") | |
DEFINE_bool(preallocate_message_memory, false, | |
"preallocate some memory to build stack traces.") | |
+DEFINE_bool(randomize_string_hashes, | |
+ true, | |
+ "randomize string hashes to avoid predictable hash collisions") | |
// v8.cc | |
DEFINE_bool(preemption, false, | |
diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc | |
index 1009aaf..444fd28 100644 | |
--- a/deps/v8/src/ia32/code-stubs-ia32.cc | |
+++ b/deps/v8/src/ia32/code-stubs-ia32.cc | |
@@ -5606,10 +5606,20 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm, | |
Register hash, | |
Register character, | |
Register scratch) { | |
- // hash = character + (character << 10); | |
- __ mov(hash, character); | |
- __ shl(hash, 10); | |
- __ add(hash, Operand(character)); | |
+ int32_t seed = masm->isolate()->HasherSeed(); | |
+ if (seed != 0) { | |
+ ASSERT(FLAG_randomize_string_hashes); | |
+ // hash = (seed + character) + ((seed + character) << 10); | |
+ __ lea(scratch, Operand(character, seed)); | |
+ __ shl(scratch, 10); | |
+ __ lea(hash, Operand(hash, character, times_1, seed)); | |
+ } else { | |
+ ASSERT(!FLAG_randomize_string_hashes); | |
+ // hash = character + (character << 10); | |
+ __ mov(hash, character); | |
+ __ shl(hash, 10); | |
+ __ add(hash, Operand(character)); | |
+ } | |
// hash ^= hash >> 6; | |
__ mov(scratch, hash); | |
__ sar(scratch, 6); | |
diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc | |
index fd0f673..b24e474 100644 | |
--- a/deps/v8/src/isolate.cc | |
+++ b/deps/v8/src/isolate.cc | |
@@ -1410,7 +1410,8 @@ Isolate::Isolate() | |
thread_manager_(NULL), | |
string_tracker_(NULL), | |
regexp_stack_(NULL), | |
- embedder_data_(NULL) { | |
+ embedder_data_(NULL), | |
+ hasher_seed_(0) { | |
TRACE_ISOLATE(constructor); | |
memset(isolate_addresses_, 0, | |
@@ -1709,6 +1710,11 @@ bool Isolate::Init(Deserializer* des) { | |
regexp_stack_ = new RegExpStack(); | |
regexp_stack_->isolate_ = this; | |
+ // Setup the seed that is used to randomize the string hash function. | |
+ if (FLAG_randomize_string_hashes) { | |
+ hasher_seed_ = V8::RandomPrivate(this); | |
+ } | |
+ | |
// Enable logging before setting up the heap | |
logger_->Setup(); | |
diff --git a/deps/v8/src/isolate.h b/deps/v8/src/isolate.h | |
index 2582da6..a75342c 100644 | |
--- a/deps/v8/src/isolate.h | |
+++ b/deps/v8/src/isolate.h | |
@@ -897,6 +897,8 @@ class Isolate { | |
return &interp_canonicalize_mapping_; | |
} | |
+ uint32_t HasherSeed() { return hasher_seed_; } | |
+ | |
void* PreallocatedStorageNew(size_t size); | |
void PreallocatedStorageDelete(void* p); | |
void PreallocatedStorageInit(size_t size); | |
@@ -1149,6 +1151,7 @@ class Isolate { | |
RegExpStack* regexp_stack_; | |
unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_; | |
void* embedder_data_; | |
+ uint32_t hasher_seed_; | |
#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \ | |
defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__) | |
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h | |
index 8796865..af58572 100644 | |
--- a/deps/v8/src/objects-inl.h | |
+++ b/deps/v8/src/objects-inl.h | |
@@ -4237,11 +4237,13 @@ uint32_t String::Hash() { | |
StringHasher::StringHasher(int length) | |
: length_(length), | |
- raw_running_hash_(0), | |
+ raw_running_hash_(ISOLATE->HasherSeed()), | |
array_index_(0), | |
is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), | |
is_first_char_(true), | |
- is_valid_(true) { } | |
+ is_valid_(true) { | |
+ ASSERT(FLAG_randomize_string_hashes == (raw_running_hash_ != 0)); | |
+} | |
bool StringHasher::has_trivial_hash() { | |
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc | |
index 6085b4e..6f5f36d 100644 | |
--- a/deps/v8/src/objects.cc | |
+++ b/deps/v8/src/objects.cc | |
@@ -10482,7 +10482,9 @@ class TwoCharHashTableKey : public HashTableKey { | |
TwoCharHashTableKey(uint32_t c1, uint32_t c2) | |
: c1_(c1), c2_(c2) { | |
// Char 1. | |
- uint32_t hash = c1 + (c1 << 10); | |
+ uint32_t hash = ISOLATE->HasherSeed(); | |
+ hash += c1; | |
+ hash += hash << 10; | |
hash ^= hash >> 6; | |
// Char 2. | |
hash += c2; | |
diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc | |
index df4438b..1bba5e6 100644 | |
--- a/deps/v8/src/x64/code-stubs-x64.cc | |
+++ b/deps/v8/src/x64/code-stubs-x64.cc | |
@@ -4609,10 +4609,20 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm, | |
Register hash, | |
Register character, | |
Register scratch) { | |
- // hash = character + (character << 10); | |
- __ movl(hash, character); | |
- __ shll(hash, Immediate(10)); | |
- __ addl(hash, character); | |
+ int32_t seed = masm->isolate()->HasherSeed(); | |
+ if (seed != 0) { | |
+ ASSERT(FLAG_randomize_string_hashes); | |
+ // hash = (seed + character) + ((seed + character) << 10); | |
+ __ leal(scratch, Operand(character, seed)); | |
+ __ shll(scratch, Immediate(10)); | |
+ __ leal(hash, Operand(hash, character, times_1, seed)); | |
+ } else { | |
+ ASSERT(!FLAG_randomize_string_hashes); | |
+ // hash = character + (character << 10); | |
+ __ movl(hash, character); | |
+ __ shll(hash, Immediate(10)); | |
+ __ addl(hash, character); | |
+ } | |
// hash ^= hash >> 6; | |
__ movl(scratch, hash); | |
__ sarl(scratch, Immediate(6)); | |
-- | |
1.7.7.1.msysgit.0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment