From db8adac19321504530e6794771ae534a238c1648 Mon Sep 17 00:00:00 2001 | |
From: Bert Belder <bertbelder@gmail.com> | |
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