Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Unified Diff: src/parser.cc

Issue 742643003: Cache template literal callSiteObj (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index f9fdf28ef19f7e3700bf44e1bc3b7583f8164462..c05f22b6c5ede8118f3802c95de1f87ed6951b87 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -5214,7 +5214,8 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
}
return expr;
} else {
- ZoneList<Expression*>* raw_strings = TemplateRawStrings(lit);
+ uint32_t hash;
+ ZoneList<Expression*>* raw_strings = TemplateRawStrings(lit, &hash);
Handle<String> source(String::cast(script()->source()));
int cooked_idx = function_state_->NextMaterializedLiteralIndex();
@@ -5230,6 +5231,7 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
factory()->NewArrayLiteral(
const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
zone());
+ args->Add(factory()->NewSmiLiteral(hash, pos), zone());
this->CheckPossibleEvalCall(tag, scope_);
Expression* call_site = factory()->NewCallRuntime(
ast_value_factory()->get_template_callsite_string(), NULL, args, start);
@@ -5244,7 +5246,66 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
}
-ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) {
+// MurmurHash (Public Domain)
+// TODO(caitp): use std::hash if available?
+static uint32_t MurmurHash(Vector<uint8_t> chars, int length) {
+ // TODO(caitp): Do we want to seed this to improve randomness? I'm not sure
+ // it matters.
+ uint32_t hash = 0;
+
+ Vector<const uint32_t> chunks = Vector<const uint32_t>::cast(chars);
+ int num_chunks = chunks.length();
+
+ // MurmurHash magic numbers
+ static const uint32_t c1 = 0xcc9e2d51;
+ static const uint32_t c2 = 0x1b873593;
+ static const uint32_t r1 = 15;
+ static const uint32_t r2 = 13;
+ static const uint32_t m = 5;
+ static const uint32_t n = 0xe6546b64;
+ static const uint32_t f1 = 0x85ebca6b;
+ static const uint32_t f2 = 0xc2b2ae35;
+
+ for (int i = 0; i < num_chunks; ++i) {
+ uint32_t k = chunks[i];
+
+ k *= c1;
+ k = (k << r1) | (k >> (32 - r1));
+ k *= c2;
+
+ hash ^= k;
+ hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
+ }
+
+ const uint8_t *tail = chars.start() + num_chunks * 4;
+ uint32_t k1 = 0;
+
+ switch (length & 3) {
+ case 3:
+ k1 ^= tail[2] << 16;
+ case 2:
+ k1 ^= tail[1] << 8;
+ case 1:
+ k1 ^= tail[0];
+ k1 *= c1;
+ k1 = (k1 << r1) | (k1 >> (32 - r1));
+ k1 *= c2;
+ hash ^= k1;
+ }
+
+ hash ^= length;
+ hash ^= (hash >> 16);
+ hash *= f1;
+ hash ^= (hash >> 13);
+ hash *= f2;
+ hash ^= (hash >> 16);
+
+ return hash;
+}
+
+
+ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit,
+ uint32_t* hash) {
const ZoneList<int>* lengths = lit->lengths();
const ZoneList<Expression*>* cooked_strings = lit->cooked();
int total = lengths->length();
@@ -5264,12 +5325,27 @@ ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) {
raw_strings = new (zone()) ZoneList<Expression*>(total, zone());
+ int num_dummy_chars = (total - 1) * 4;
+ for (int index = 0; index < total; ++index) {
+ num_dummy_chars += lengths->at(index);
+ }
+
+ Vector<uint8_t> hash_string = Vector<uint8_t>::New(num_dummy_chars);
arv (Not doing code reviews) 2014/11/19 06:09:11 What about two byte strings? Can we use StringHas
caitp (gmail) 2014/11/19 07:15:05 String::ToCString claims to return a UTF8 represen
+ num_dummy_chars = 0;
+
for (int index = 0; index < total; ++index) {
int span_start = cooked_strings->at(index)->position() + 1;
int span_end = lengths->at(index) - 1;
int length;
int to_index = 0;
+ if (index) {
+ hash_string[num_dummy_chars++] = '$';
+ hash_string[num_dummy_chars++] = '{';
+ hash_string[num_dummy_chars++] = '.';
+ hash_string[num_dummy_chars++] = '}';
+ }
+
SmartArrayPointer<char> raw_chars =
source->ToCString(ALLOW_NULLS, FAST_STRING_TRAVERSAL, span_start,
span_end, &length);
@@ -5284,6 +5360,7 @@ ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) {
++from_index;
}
}
+ hash_string[num_dummy_chars++] = ch;
raw_chars[to_index++] = ch;
}
@@ -5293,6 +5370,9 @@ ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) {
raw_strings->Add(raw_lit, zone());
}
+ *hash = MurmurHash(hash_string, num_dummy_chars);
+ hash_string.Dispose();
+
return raw_strings;
}
} } // namespace v8::internal

Powered by Google App Engine
This is Rietveld 408576698