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

Side by Side Diff: src/parser.cc

Issue 5166006: Untemplated preparser.h and made it depend on virtual types. (Closed)
Patch Set: Created 10 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') | src/preparse-data.h » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 if (result.is_null()) { 349 if (result.is_null()) {
350 result = Factory::LookupSymbol(string); 350 result = Factory::LookupSymbol(string);
351 symbol_cache_.at(symbol_id) = result; 351 symbol_cache_.at(symbol_id) = result;
352 return result; 352 return result;
353 } 353 }
354 Counters::total_preparse_symbols_skipped.Increment(); 354 Counters::total_preparse_symbols_skipped.Increment();
355 return result; 355 return result;
356 } 356 }
357 357
358 358
359 Vector<unsigned> PartialParserRecorder::ExtractData() {
360 int function_size = function_store_.size();
361 int total_size = ScriptDataImpl::kHeaderSize + function_size;
362 Vector<unsigned> data = Vector<unsigned>::New(total_size);
363 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size;
364 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0;
365 memcpy(data.start(), preamble_, sizeof(preamble_));
366 int symbol_start = ScriptDataImpl::kHeaderSize + function_size;
367 if (function_size > 0) {
368 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize,
369 symbol_start));
370 }
371 return data;
372 }
373
374
375 void CompleteParserRecorder::LogSymbol(int start, Vector<const char> literal) {
376 if (!is_recording_) return;
377
378 int hash = vector_hash(literal);
379 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true);
380 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
381 if (id == 0) {
382 // Put (symbol_id_ + 1) into entry and increment it.
383 id = ++symbol_id_;
384 entry->value = reinterpret_cast<void*>(id);
385 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal);
386 entry->key = &symbol[0];
387 }
388 WriteNumber(id - 1);
389 }
390
391
392 Vector<unsigned> CompleteParserRecorder::ExtractData() {
393 int function_size = function_store_.size();
394 // Add terminator to symbols, then pad to unsigned size.
395 int symbol_size = symbol_store_.size();
396 int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned));
397 symbol_store_.AddBlock(padding, ScriptDataImpl::kNumberTerminator);
398 symbol_size += padding;
399 int total_size = ScriptDataImpl::kHeaderSize + function_size
400 + (symbol_size / sizeof(unsigned));
401 Vector<unsigned> data = Vector<unsigned>::New(total_size);
402 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size;
403 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_;
404 memcpy(data.start(), preamble_, sizeof(preamble_));
405 int symbol_start = ScriptDataImpl::kHeaderSize + function_size;
406 if (function_size > 0) {
407 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize,
408 symbol_start));
409 }
410 if (!has_error()) {
411 symbol_store_.WriteTo(
412 Vector<byte>::cast(data.SubVector(symbol_start, total_size)));
413 }
414 return data;
415 }
416
417
418 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { 359 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
419 // The current pre-data entry must be a FunctionEntry with the given 360 // The current pre-data entry must be a FunctionEntry with the given
420 // start position. 361 // start position.
421 if ((function_index_ + FunctionEntry::kSize <= store_.length()) 362 if ((function_index_ + FunctionEntry::kSize <= store_.length())
422 && (static_cast<int>(store_[function_index_]) == start)) { 363 && (static_cast<int>(store_[function_index_]) == start)) {
423 int index = function_index_; 364 int index = function_index_;
424 function_index_ += FunctionEntry::kSize; 365 function_index_ += FunctionEntry::kSize;
425 return FunctionEntry(store_.SubVector(index, 366 return FunctionEntry(store_.SubVector(index,
426 index + FunctionEntry::kSize)); 367 index + FunctionEntry::kSize));
427 } 368 }
428 return FunctionEntry(); 369 return FunctionEntry();
429 } 370 }
430 371
431 372
432 int ScriptDataImpl::GetSymbolIdentifier() { 373 int ScriptDataImpl::GetSymbolIdentifier() {
433 return ReadNumber(&symbol_data_); 374 return ReadNumber(&symbol_data_);
434 } 375 }
435 376
436 377
437 bool ScriptDataImpl::SanityCheck() { 378 bool ScriptDataImpl::SanityCheck() {
438 // Check that the header data is valid and doesn't specify 379 // Check that the header data is valid and doesn't specify
439 // point to positions outside the store. 380 // point to positions outside the store.
440 if (store_.length() < ScriptDataImpl::kHeaderSize) return false; 381 if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
441 if (magic() != ScriptDataImpl::kMagicNumber) return false; 382 if (magic() != PreparseDataConstants::kMagicNumber) return false;
442 if (version() != ScriptDataImpl::kCurrentVersion) return false; 383 if (version() != PreparseDataConstants::kCurrentVersion) return false;
443 if (has_error()) { 384 if (has_error()) {
444 // Extra sane sanity check for error message encoding. 385 // Extra sane sanity check for error message encoding.
445 if (store_.length() <= kHeaderSize + kMessageTextPos) return false; 386 if (store_.length() <= PreparseDataConstants::kHeaderSize
446 if (Read(kMessageStartPos) > Read(kMessageEndPos)) return false; 387 + PreparseDataConstants::kMessageTextPos) {
447 unsigned arg_count = Read(kMessageArgCountPos); 388 return false;
448 int pos = kMessageTextPos; 389 }
390 if (Read(PreparseDataConstants::kMessageStartPos) >
391 Read(PreparseDataConstants::kMessageEndPos)) {
392 return false;
393 }
394 unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
395 int pos = PreparseDataConstants::kMessageTextPos;
449 for (unsigned int i = 0; i <= arg_count; i++) { 396 for (unsigned int i = 0; i <= arg_count; i++) {
450 if (store_.length() <= kHeaderSize + pos) return false; 397 if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) {
398 return false;
399 }
451 int length = static_cast<int>(Read(pos)); 400 int length = static_cast<int>(Read(pos));
452 if (length < 0) return false; 401 if (length < 0) return false;
453 pos += 1 + length; 402 pos += 1 + length;
454 } 403 }
455 if (store_.length() < kHeaderSize + pos) return false; 404 if (store_.length() < PreparseDataConstants::kHeaderSize + pos) {
405 return false;
406 }
456 return true; 407 return true;
457 } 408 }
458 // Check that the space allocated for function entries is sane. 409 // Check that the space allocated for function entries is sane.
459 int functions_size = 410 int functions_size =
460 static_cast<int>(store_[ScriptDataImpl::kFunctionsSizeOffset]); 411 static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
461 if (functions_size < 0) return false; 412 if (functions_size < 0) return false;
462 if (functions_size % FunctionEntry::kSize != 0) return false; 413 if (functions_size % FunctionEntry::kSize != 0) return false;
463 // Check that the count of symbols is non-negative. 414 // Check that the count of symbols is non-negative.
464 int symbol_count = 415 int symbol_count =
465 static_cast<int>(store_[ScriptDataImpl::kSymbolCountOffset]); 416 static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]);
466 if (symbol_count < 0) return false; 417 if (symbol_count < 0) return false;
467 // Check that the total size has room for header and function entries. 418 // Check that the total size has room for header and function entries.
468 int minimum_size = 419 int minimum_size =
469 ScriptDataImpl::kHeaderSize + functions_size; 420 PreparseDataConstants::kHeaderSize + functions_size;
470 if (store_.length() < minimum_size) return false; 421 if (store_.length() < minimum_size) return false;
471 return true; 422 return true;
472 } 423 }
473 424
474 425
475 426
476 PartialParserRecorder::PartialParserRecorder()
477 : function_store_(0),
478 is_recording_(true),
479 pause_count_(0) {
480 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber;
481 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion;
482 preamble_[ScriptDataImpl::kHasErrorOffset] = false;
483 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = 0;
484 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0;
485 preamble_[ScriptDataImpl::kSizeOffset] = 0;
486 ASSERT_EQ(6, ScriptDataImpl::kHeaderSize);
487 #ifdef DEBUG
488 prev_start_ = -1;
489 #endif
490 }
491
492
493 CompleteParserRecorder::CompleteParserRecorder()
494 : PartialParserRecorder(),
495 symbol_store_(0),
496 symbol_entries_(0),
497 symbol_table_(vector_compare),
498 symbol_id_(0) {
499 }
500
501
502 void PartialParserRecorder::WriteString(Vector<const char> str) {
503 function_store_.Add(str.length());
504 for (int i = 0; i < str.length(); i++) {
505 function_store_.Add(str[i]);
506 }
507 }
508
509
510 void CompleteParserRecorder::WriteNumber(int number) {
511 ASSERT(number >= 0);
512
513 int mask = (1 << 28) - 1;
514 for (int i = 28; i > 0; i -= 7) {
515 if (number > mask) {
516 symbol_store_.Add(static_cast<byte>(number >> i) | 0x80u);
517 number &= mask;
518 }
519 mask >>= 7;
520 }
521 symbol_store_.Add(static_cast<byte>(number));
522 }
523
524
525
526 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { 427 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
527 int length = start[0]; 428 int length = start[0];
528 char* result = NewArray<char>(length + 1); 429 char* result = NewArray<char>(length + 1);
529 for (int i = 0; i < length; i++) { 430 for (int i = 0; i < length; i++) {
530 result[i] = start[i + 1]; 431 result[i] = start[i + 1];
531 } 432 }
532 result[length] = '\0'; 433 result[length] = '\0';
533 if (chars != NULL) *chars = length; 434 if (chars != NULL) *chars = length;
534 return result; 435 return result;
535 } 436 }
536 437
537
538 void PartialParserRecorder::LogMessage(Scanner::Location loc,
539 const char* message,
540 Vector<const char*> args) {
541 if (has_error()) return;
542 preamble_[ScriptDataImpl::kHasErrorOffset] = true;
543 function_store_.Reset();
544 STATIC_ASSERT(ScriptDataImpl::kMessageStartPos == 0);
545 function_store_.Add(loc.beg_pos);
546 STATIC_ASSERT(ScriptDataImpl::kMessageEndPos == 1);
547 function_store_.Add(loc.end_pos);
548 STATIC_ASSERT(ScriptDataImpl::kMessageArgCountPos == 2);
549 function_store_.Add(args.length());
550 STATIC_ASSERT(ScriptDataImpl::kMessageTextPos == 3);
551 WriteString(CStrVector(message));
552 for (int i = 0; i < args.length(); i++) {
553 WriteString(CStrVector(args[i]));
554 }
555 is_recording_ = false;
556 }
557
558
559 Scanner::Location ScriptDataImpl::MessageLocation() { 438 Scanner::Location ScriptDataImpl::MessageLocation() {
560 int beg_pos = Read(kMessageStartPos); 439 int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
561 int end_pos = Read(kMessageEndPos); 440 int end_pos = Read(PreparseDataConstants::kMessageEndPos);
562 return Scanner::Location(beg_pos, end_pos); 441 return Scanner::Location(beg_pos, end_pos);
563 } 442 }
564 443
565 444
566 const char* ScriptDataImpl::BuildMessage() { 445 const char* ScriptDataImpl::BuildMessage() {
567 unsigned* start = ReadAddress(kMessageTextPos); 446 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
568 return ReadString(start, NULL); 447 return ReadString(start, NULL);
569 } 448 }
570 449
571 450
572 Vector<const char*> ScriptDataImpl::BuildArgs() { 451 Vector<const char*> ScriptDataImpl::BuildArgs() {
573 int arg_count = Read(kMessageArgCountPos); 452 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
574 const char** array = NewArray<const char*>(arg_count); 453 const char** array = NewArray<const char*>(arg_count);
575 // Position after text found by skipping past length field and 454 // Position after text found by skipping past length field and
576 // length field content words. 455 // length field content words.
577 int pos = kMessageTextPos + 1 + Read(kMessageTextPos); 456 int pos = PreparseDataConstants::kMessageTextPos + 1
457 + Read(PreparseDataConstants::kMessageTextPos);
578 for (int i = 0; i < arg_count; i++) { 458 for (int i = 0; i < arg_count; i++) {
579 int count = 0; 459 int count = 0;
580 array[i] = ReadString(ReadAddress(pos), &count); 460 array[i] = ReadString(ReadAddress(pos), &count);
581 pos += count + 1; 461 pos += count + 1;
582 } 462 }
583 return Vector<const char*>(array, arg_count); 463 return Vector<const char*>(array, arg_count);
584 } 464 }
585 465
586 466
587 unsigned ScriptDataImpl::Read(int position) { 467 unsigned ScriptDataImpl::Read(int position) {
588 return store_[ScriptDataImpl::kHeaderSize + position]; 468 return store_[PreparseDataConstants::kHeaderSize + position];
589 } 469 }
590 470
591 471
592 unsigned* ScriptDataImpl::ReadAddress(int position) { 472 unsigned* ScriptDataImpl::ReadAddress(int position) {
593 return &store_[ScriptDataImpl::kHeaderSize + position]; 473 return &store_[PreparseDataConstants::kHeaderSize + position];
594 } 474 }
595 475
596 476
597 Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) { 477 Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) {
598 Scope* result = new Scope(parent, type); 478 Scope* result = new Scope(parent, type);
599 result->Initialize(inside_with); 479 result->Initialize(inside_with);
600 return result; 480 return result;
601 } 481 }
602 482
603 // ---------------------------------------------------------------------------- 483 // ----------------------------------------------------------------------------
(...skipping 3984 matching lines...) Expand 10 before | Expand all | Expand 10 after
4588 } 4468 }
4589 4469
4590 4470
4591 bool ScriptDataImpl::HasError() { 4471 bool ScriptDataImpl::HasError() {
4592 return has_error(); 4472 return has_error();
4593 } 4473 }
4594 4474
4595 4475
4596 void ScriptDataImpl::Initialize() { 4476 void ScriptDataImpl::Initialize() {
4597 // Prepares state for use. 4477 // Prepares state for use.
4598 if (store_.length() >= kHeaderSize) { 4478 if (store_.length() >= PreparseDataConstants::kHeaderSize) {
4599 function_index_ = kHeaderSize; 4479 function_index_ = PreparseDataConstants::kHeaderSize;
4600 int symbol_data_offset = kHeaderSize + store_[kFunctionsSizeOffset]; 4480 int symbol_data_offset = PreparseDataConstants::kHeaderSize
4481 + store_[PreparseDataConstants::kFunctionsSizeOffset];
4601 if (store_.length() > symbol_data_offset) { 4482 if (store_.length() > symbol_data_offset) {
4602 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); 4483 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
4603 } else { 4484 } else {
4604 // Partial preparse causes no symbol information. 4485 // Partial preparse causes no symbol information.
4605 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 4486 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
4606 } 4487 }
4607 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 4488 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
4608 } 4489 }
4609 } 4490 }
4610 4491
4611 4492
4612 int ScriptDataImpl::ReadNumber(byte** source) { 4493 int ScriptDataImpl::ReadNumber(byte** source) {
4613 // Reads a number from symbol_data_ in base 128. The most significant 4494 // Reads a number from symbol_data_ in base 128. The most significant
4614 // bit marks that there are more digits. 4495 // bit marks that there are more digits.
4615 // If the first byte is 0x80 (kNumberTerminator), it would normally 4496 // If the first byte is 0x80 (kNumberTerminator), it would normally
4616 // represent a leading zero. Since that is useless, and therefore won't 4497 // represent a leading zero. Since that is useless, and therefore won't
4617 // appear as the first digit of any actual value, it is used to 4498 // appear as the first digit of any actual value, it is used to
4618 // mark the end of the input stream. 4499 // mark the end of the input stream.
4619 byte* data = *source; 4500 byte* data = *source;
4620 if (data >= symbol_data_end_) return -1; 4501 if (data >= symbol_data_end_) return -1;
4621 byte input = *data; 4502 byte input = *data;
4622 if (input == kNumberTerminator) { 4503 if (input == PreparseDataConstants::kNumberTerminator) {
4623 // End of stream marker. 4504 // End of stream marker.
4624 return -1; 4505 return -1;
4625 } 4506 }
4626 int result = input & 0x7f; 4507 int result = input & 0x7f;
4627 data++; 4508 data++;
4628 while ((input & 0x80u) != 0) { 4509 while ((input & 0x80u) != 0) {
4629 if (data >= symbol_data_end_) return -1; 4510 if (data >= symbol_data_end_) return -1;
4630 input = *data; 4511 input = *data;
4631 result = (result << 7) | (input & 0x7f); 4512 result = (result << 7) | (input & 0x7f);
4632 data++; 4513 data++;
4633 } 4514 }
4634 *source = data; 4515 *source = data;
4635 return result; 4516 return result;
4636 } 4517 }
4637 4518
4638 4519
4639 // Create a Scanner for the preparser to use as input, and preparse the source. 4520 // Create a Scanner for the preparser to use as input, and preparse the source.
4640 static ScriptDataImpl* DoPreParse(Handle<String> source, 4521 static ScriptDataImpl* DoPreParse(Handle<String> source,
4641 unibrow::CharacterStream* stream, 4522 unibrow::CharacterStream* stream,
4642 bool allow_lazy, 4523 bool allow_lazy,
4643 PartialParserRecorder* recorder, 4524 ParserRecorder* recorder,
4644 int literal_flags) { 4525 int literal_flags) {
4645 V8JavaScriptScanner scanner; 4526 V8JavaScriptScanner scanner;
4646 scanner.Initialize(source, stream, literal_flags); 4527 scanner.Initialize(source, stream, literal_flags);
4647 preparser::PreParser<JavaScriptScanner, PartialParserRecorder> preparser; 4528 preparser::PreParser preparser;
4648 if (!preparser.PreParseProgram(&scanner, recorder, allow_lazy)) { 4529 if (!preparser.PreParseProgram(&scanner, recorder, allow_lazy)) {
4649 Top::StackOverflow(); 4530 Top::StackOverflow();
4650 return NULL; 4531 return NULL;
4651 } 4532 }
4652 4533
4653 // Extract the accumulated data from the recorder as a single 4534 // Extract the accumulated data from the recorder as a single
4654 // contiguous vector that we are responsible for disposing. 4535 // contiguous vector that we are responsible for disposing.
4655 Vector<unsigned> store = recorder->ExtractData(); 4536 Vector<unsigned> store = recorder->ExtractData();
4656 return new ScriptDataImpl(store); 4537 return new ScriptDataImpl(store);
4657 } 4538 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4737 Handle<String> source = Handle<String>(String::cast(script->source())); 4618 Handle<String> source = Handle<String>(String::cast(script->source()));
4738 result = parser.ParseProgram(source, info->is_global()); 4619 result = parser.ParseProgram(source, info->is_global());
4739 } 4620 }
4740 } 4621 }
4741 4622
4742 info->SetFunction(result); 4623 info->SetFunction(result);
4743 return (result != NULL); 4624 return (result != NULL);
4744 } 4625 }
4745 4626
4746 } } // namespace v8::internal 4627 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparse-data.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698