Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.