Commit 93cd816c authored by caitpotter88's avatar caitpotter88 Committed by Commit bot

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 spans, removing the need to allocate a new
buffer and copy bytes into it.

BUG=

Review URL: https://codereview.chromium.org/765473006

Cr-Commit-Position: refs/heads/master@{#25549}
parent 5081f4cc
......@@ -6736,6 +6736,30 @@ uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
}
uint32_t StringHasher::ComputeRunningHash(uint32_t running_hash,
const uc16* chars, int length) {
DCHECK_NOT_NULL(chars);
DCHECK(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_NOT_NULL(chars);
DCHECK(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.
......
......@@ -8493,6 +8493,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
......
......@@ -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,10 @@ 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 key is used exclusively by template call site caching. There are no
// real security implications for unseeded hashes, and no issues with changing
// the hashing algorithm to improve performance or entropy.
*hash = running_hash;
return raw_strings;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment