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

Side by Side Diff: src/parser.cc

Issue 742643003: Cache template literal callSiteObj (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Ensure hash is a valid Smi literal 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 unified diff | Download patch
« no previous file with comments | « src/parser.h ('k') | test/mjsunit/harmony/templates.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 5213 matching lines...) Expand 10 before | Expand all | Expand 10 after
5224 Token::ADD, cooked_str, expressions->at(i), 5224 Token::ADD, cooked_str, expressions->at(i),
5225 cooked_str->position()), 5225 cooked_str->position()),
5226 cooked_str->position()); 5226 cooked_str->position());
5227 } 5227 }
5228 cooked_str = cooked_strings->at(i); 5228 cooked_str = cooked_strings->at(i);
5229 expr = factory()->NewBinaryOperation(Token::ADD, expr, cooked_str, 5229 expr = factory()->NewBinaryOperation(Token::ADD, expr, cooked_str,
5230 cooked_str->position()); 5230 cooked_str->position());
5231 } 5231 }
5232 return expr; 5232 return expr;
5233 } else { 5233 } else {
5234 ZoneList<Expression*>* raw_strings = TemplateRawStrings(lit); 5234 uint32_t hash;
5235 ZoneList<Expression*>* raw_strings = TemplateRawStrings(lit, &hash);
5235 Handle<String> source(String::cast(script()->source())); 5236 Handle<String> source(String::cast(script()->source()));
5236 5237
5237 int cooked_idx = function_state_->NextMaterializedLiteralIndex(); 5238 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
5238 int raw_idx = function_state_->NextMaterializedLiteralIndex(); 5239 int raw_idx = function_state_->NextMaterializedLiteralIndex();
5239 5240
5240 // GetTemplateCallSite 5241 // GetTemplateCallSite
5241 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone()); 5242 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
5242 args->Add(factory()->NewArrayLiteral( 5243 args->Add(factory()->NewArrayLiteral(
5243 const_cast<ZoneList<Expression*>*>(cooked_strings), 5244 const_cast<ZoneList<Expression*>*>(cooked_strings),
5244 cooked_idx, pos), 5245 cooked_idx, pos),
5245 zone()); 5246 zone());
5246 args->Add( 5247 args->Add(
5247 factory()->NewArrayLiteral( 5248 factory()->NewArrayLiteral(
5248 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos), 5249 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
5249 zone()); 5250 zone());
5251
5252 // Ensure hash is suitable as an Smi value
5253 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
5254 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
5255
5250 this->CheckPossibleEvalCall(tag, scope_); 5256 this->CheckPossibleEvalCall(tag, scope_);
5251 Expression* call_site = factory()->NewCallRuntime( 5257 Expression* call_site = factory()->NewCallRuntime(
5252 ast_value_factory()->get_template_callsite_string(), NULL, args, start); 5258 ast_value_factory()->get_template_callsite_string(), NULL, args, start);
5253 5259
5254 // Call TagFn 5260 // Call TagFn
5255 ZoneList<Expression*>* call_args = 5261 ZoneList<Expression*>* call_args =
5256 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone()); 5262 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
5257 call_args->Add(call_site, zone()); 5263 call_args->Add(call_site, zone());
5258 call_args->AddAll(*expressions, zone()); 5264 call_args->AddAll(*expressions, zone());
5259 return factory()->NewCall(tag, call_args, pos); 5265 return factory()->NewCall(tag, call_args, pos);
5260 } 5266 }
5261 } 5267 }
5262 5268
5263 5269
5264 ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) { 5270 ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit,
5271 uint32_t* hash) {
5265 const ZoneList<int>* lengths = lit->lengths(); 5272 const ZoneList<int>* lengths = lit->lengths();
5266 const ZoneList<Expression*>* cooked_strings = lit->cooked(); 5273 const ZoneList<Expression*>* cooked_strings = lit->cooked();
5267 int total = lengths->length(); 5274 int total = lengths->length();
5268 ZoneList<Expression*>* raw_strings; 5275 ZoneList<Expression*>* raw_strings;
5269 5276
5270 // Given a TemplateLiteral, produce a list of raw strings, used for generating 5277 // Given a TemplateLiteral, produce a list of raw strings, used for generating
5271 // a CallSite object for a tagged template invocations. 5278 // a CallSite object for a tagged template invocations.
5272 // 5279 //
5273 // A raw string will consist of the unescaped characters of a template span, 5280 // A raw string will consist of the unescaped characters of a template span,
5274 // with end-of-line sequences normalized to U+000A LINE FEEDs, and without 5281 // with end-of-line sequences normalized to U+000A LINE FEEDs, and without
5275 // leading or trailing template delimiters. 5282 // leading or trailing template delimiters.
5276 // 5283 //
5277 5284
5278 DCHECK(total); 5285 DCHECK(total);
5279 5286
5280 Handle<String> source(String::cast(script()->source())); 5287 Handle<String> source(String::cast(script()->source()));
5281 5288
5282 raw_strings = new (zone()) ZoneList<Expression*>(total, zone()); 5289 raw_strings = new (zone()) ZoneList<Expression*>(total, zone());
5283 5290
5291 int num_hash_chars = (total - 1) * 3;
5292 for (int index = 0; index < total; ++index) {
5293 // Allow about length * 4 to handle most UTF8 sequences.
5294 num_hash_chars += lengths->at(index) * 4;
5295 }
5296
5297 Vector<uint8_t> hash_string = Vector<uint8_t>::New(num_hash_chars);
5298 num_hash_chars = 0;
5299
5284 for (int index = 0; index < total; ++index) { 5300 for (int index = 0; index < total; ++index) {
5285 int span_start = cooked_strings->at(index)->position() + 1; 5301 int span_start = cooked_strings->at(index)->position() + 1;
5286 int span_end = lengths->at(index) - 1; 5302 int span_end = lengths->at(index) - 1;
5287 int length; 5303 int length;
5288 int to_index = 0; 5304 int to_index = 0;
5289 5305
5306 if (index) {
5307 hash_string[num_hash_chars++] = '$';
5308 hash_string[num_hash_chars++] = '{';
5309 hash_string[num_hash_chars++] = '}';
5310 }
5311
5290 SmartArrayPointer<char> raw_chars = 5312 SmartArrayPointer<char> raw_chars =
5291 source->ToCString(ALLOW_NULLS, FAST_STRING_TRAVERSAL, span_start, 5313 source->ToCString(ALLOW_NULLS, FAST_STRING_TRAVERSAL, span_start,
5292 span_end, &length); 5314 span_end, &length);
5293 5315
5294 // Normalize raw line-feeds. [U+000D U+000A] (CRLF) and [U+000D] (CR) must 5316 // Normalize raw line-feeds. [U+000D U+000A] (CRLF) and [U+000D] (CR) must
5295 // be translated into U+000A (LF). 5317 // be translated into U+000A (LF).
5296 for (int from_index = 0; from_index < length; ++from_index) { 5318 for (int from_index = 0; from_index < length; ++from_index) {
5297 char ch = raw_chars[from_index]; 5319 char ch = raw_chars[from_index];
5298 if (ch == '\r') { 5320 if (ch == '\r') {
5299 ch = '\n'; 5321 ch = '\n';
5300 if (from_index + 1 < length && raw_chars[from_index + 1] == '\n') { 5322 if (from_index + 1 < length && raw_chars[from_index + 1] == '\n') {
5301 ++from_index; 5323 ++from_index;
5302 } 5324 }
5303 } 5325 }
5326 hash_string[num_hash_chars++] = ch;
5304 raw_chars[to_index++] = ch; 5327 raw_chars[to_index++] = ch;
5305 } 5328 }
5306 5329
5307 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( 5330 const AstRawString* raw_str = ast_value_factory()->GetOneByteString(
5308 OneByteVector(raw_chars.get(), to_index)); 5331 OneByteVector(raw_chars.get(), to_index));
5309 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); 5332 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1);
5310 raw_strings->Add(raw_lit, zone()); 5333 raw_strings->Add(raw_lit, zone());
5311 } 5334 }
5312 5335
5336 hash_string.Truncate(num_hash_chars);
5337 int utf16_length;
5338 *hash = StringHasher::ComputeUtf8Hash(Vector<const char>::cast(hash_string),
5339 num_hash_chars, &utf16_length);
5340 hash_string.Dispose();
5341
5313 return raw_strings; 5342 return raw_strings;
5314 } 5343 }
5315 } } // namespace v8::internal 5344 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | test/mjsunit/harmony/templates.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698