| Index: src/parser.cc | 
| diff --git a/src/parser.cc b/src/parser.cc | 
| index 5e7530496bdbcac537a066c30598b21c9c9b9bb4..d83552960781789801bd300e16844815f19475b4 100644 | 
| --- a/src/parser.cc | 
| +++ b/src/parser.cc | 
| @@ -5231,7 +5231,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(); | 
| @@ -5247,6 +5248,11 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start, | 
| factory()->NewArrayLiteral( | 
| const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos), | 
| zone()); | 
| + | 
| +    // Ensure hash is suitable as an Smi value | 
| +    Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash))); | 
| +    args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone()); | 
| + | 
| this->CheckPossibleEvalCall(tag, scope_); | 
| Expression* call_site = factory()->NewCallRuntime( | 
| ast_value_factory()->get_template_callsite_string(), NULL, args, start); | 
| @@ -5261,7 +5267,8 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start, | 
| } | 
|  | 
|  | 
| -ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) { | 
| +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(); | 
| @@ -5281,12 +5288,27 @@ 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; | 
| + | 
| 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_hash_chars++] = '$'; | 
| +      hash_string[num_hash_chars++] = '{'; | 
| +      hash_string[num_hash_chars++] = '}'; | 
| +    } | 
| + | 
| SmartArrayPointer<char> raw_chars = | 
| source->ToCString(ALLOW_NULLS, FAST_STRING_TRAVERSAL, span_start, | 
| span_end, &length); | 
| @@ -5301,6 +5323,7 @@ ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) { | 
| ++from_index; | 
| } | 
| } | 
| +      hash_string[num_hash_chars++] = ch; | 
| raw_chars[to_index++] = ch; | 
| } | 
|  | 
| @@ -5310,6 +5333,12 @@ 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(); | 
| + | 
| return raw_strings; | 
| } | 
| } }  // namespace v8::internal | 
|  |