Reviewers: Dmitry Lomov (chromium), arv, rossberg,
Message:
PTAL --- as suggested in crrev.com/745233002, it changes the hashing
strategy to
build rolling hashes from each string component.
Tests pass on debug, so I think this should be a pretty trivial refactoring
(but
it does mean adding 2 static helpers to StringHasher).
Description:
Make TemplateLiteral hashing algorithm more memory efficient
Previously, a separate string to be hashed (in order to help determine the
need
to
use a cached Template Call Site) was built up by joining UTF8 spans within a
template.
Now, the hash key is generated from the original strings, removing the
allocate
a new
buffer and copy strings into it.
BUG=
Please review this at https://codereview.chromium.org/765473006/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+33, -17 lines):
M src/objects.h
M src/objects-inl.h
M src/parser.cc
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
03aea64736d818f456c748f76a31d583593dc664..fa6d3beb254c2ba15b5d94ba6709ff71970c27a7
100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -6722,6 +6722,28 @@ uint32_t StringHasher::GetHashCore(uint32_t
running_hash) {
}
+uint32_t StringHasher::ComputeRunningHash(uint32_t running_hash,
+ const uc16* chars, int length) {
+ DCHECK(chars && length > 0);
+ for (int i = 0; i < length; ++i) {
+ running_hash = AddCharacterCore(running_hash, *chars++);
+ }
+ return running_hash;
+}
+
+
+uint32_t StringHasher::ComputeRunningHashOneByte(uint32_t running_hash,
+ const char* chars,
+ int length) {
+ DCHECK(chars && length > 0);
+ for (int i = 0; i < length; ++i) {
+ uint16_t c = static_cast<uint16_t>(*chars++);
+ running_hash = AddCharacterCore(running_hash, c);
+ }
+ return running_hash;
+}
+
+
void StringHasher::AddCharacter(uint16_t c) {
// Use the Jenkins one-at-a-time hash function to update the hash
// for the given character.
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
746f88d1c4c0c10083e63263a005f79ec4378b9d..eaea38623fbc5fe58ee6cf9c4dbb08baa3fa834c
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -8489,6 +8489,11 @@ class StringHasher {
// Reusable parts of the hashing algorithm.
INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint16_t
c));
INLINE(static uint32_t GetHashCore(uint32_t running_hash));
+ INLINE(static uint32_t ComputeRunningHash(uint32_t running_hash,
+ const uc16* chars, int
length));
+ INLINE(static uint32_t ComputeRunningHashOneByte(uint32_t running_hash,
+ const char* chars,
+ int length));
protected:
// Returns the value to store in the hash field of a string with
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index
c2d6c5754849a1601b23569e6b1aef8f562a255b..819e5481a9c4de09a9d8d62f78478a1c3fee18c0
100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -5295,14 +5295,7 @@ ZoneList<Expression*>*
Parser::TemplateRawStrings(const TemplateLiteral* lit,
raw_strings = new (zone()) ZoneList<Expression*>(total, zone());
- int num_hash_chars = (total - 1) * 3;
- for (int index = 0; index < total; ++index) {
- // Allow about length * 4 to handle most UTF8 sequences.
- num_hash_chars += lengths->at(index) * 4;
- }
-
- Vector<uint8_t> hash_string = Vector<uint8_t>::New(num_hash_chars);
- num_hash_chars = 0;
+ uint32_t running_hash = 0;
for (int index = 0; index < total; ++index) {
int span_start = cooked_strings->at(index)->position() + 1;
@@ -5311,9 +5304,8 @@ ZoneList<Expression*>*
Parser::TemplateRawStrings(const TemplateLiteral* lit,
int to_index = 0;
if (index) {
- hash_string[num_hash_chars++] = '$';
- hash_string[num_hash_chars++] = '{';
- hash_string[num_hash_chars++] = '}';
+ running_hash = StringHasher::ComputeRunningHashOneByte(
+ running_hash, "${}", 3);
}
SmartArrayPointer<char> raw_chars =
@@ -5330,7 +5322,6 @@ ZoneList<Expression*>*
Parser::TemplateRawStrings(const TemplateLiteral* lit,
++from_index;
}
}
- hash_string[num_hash_chars++] = ch;
raw_chars[to_index++] = ch;
}
@@ -5342,6 +5333,8 @@ ZoneList<Expression*>*
Parser::TemplateRawStrings(const TemplateLiteral* lit,
if (utf16_length > 0) {
uc16* utf16_buffer = zone()->NewArray<uc16>(utf16_length);
to_index = decoder->WriteUtf16(utf16_buffer, utf16_length);
+ running_hash = StringHasher::ComputeRunningHash(
+ running_hash, utf16_buffer, to_index);
const uint16_t* data = reinterpret_cast<const
uint16_t*>(utf16_buffer);
const AstRawString* raw_str = ast_value_factory()->GetTwoByteString(
Vector<const uint16_t>(data, to_index));
@@ -5354,11 +5347,7 @@ ZoneList<Expression*>*
Parser::TemplateRawStrings(const TemplateLiteral* lit,
raw_strings->Add(raw_lit, zone());
}
- hash_string.Truncate(num_hash_chars);
- int utf16_length;
- *hash = StringHasher::ComputeUtf8Hash(Vector<const
char>::cast(hash_string),
- num_hash_chars, &utf16_length);
- hash_string.Dispose();
+ *hash = running_hash;
return raw_strings;
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.