| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index c6c72fefbba7cdbd9614e467d2942f2ba61dc9e4..a3c19735cecf85a3ac23345e454eb6cb1c5ddb4f 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -210,12 +210,19 @@ Handle<String> Parser::LookupSymbol(int symbol_id) {
|
| // that case, we'll just read the literal from Scanner. This also guards
|
| // against corrupt preparse data where the symbol id is larger than the symbol
|
| // count.
|
| - if (symbol_id < 0 ||
|
| - (pre_parse_data_ && symbol_id >= pre_parse_data_->symbol_count())) {
|
| + if (symbol_id < 0 || (cached_data_ && *cached_data_ &&
|
| + symbol_id >= (*cached_data_)->symbol_count())) {
|
| if (scanner()->is_literal_ascii()) {
|
| + if (log_) {
|
| + log_->LogAsciiSymbol(position(), scanner()->literal_ascii_string());
|
| + }
|
| return isolate()->factory()->InternalizeOneByteString(
|
| Vector<const uint8_t>::cast(scanner()->literal_ascii_string()));
|
| +
|
| } else {
|
| + if (log_) {
|
| + log_->LogUtf16Symbol(position(), scanner()->literal_utf16_string());
|
| + }
|
| return isolate()->factory()->InternalizeTwoByteString(
|
| scanner()->literal_utf16_string());
|
| }
|
| @@ -493,8 +500,8 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
|
|
|
| Handle<String> ParserTraits::GetSymbol(Scanner* scanner) {
|
| int symbol_id = -1;
|
| - if (parser_->pre_parse_data() != NULL) {
|
| - symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier();
|
| + if (parser_->cached_data_ != NULL && *(parser_->cached_data_) != NULL) {
|
| + symbol_id = (*parser_->cached_data_)->GetSymbolIdentifier();
|
| }
|
| return parser_->LookupSymbol(symbol_id);
|
| }
|
| @@ -604,6 +611,7 @@ Parser::Parser(CompilationInfo* info)
|
| : ParserBase<ParserTraits>(&scanner_,
|
| info->isolate()->stack_guard()->real_climit(),
|
| info->extension(),
|
| + NULL,
|
| info->zone(),
|
| this),
|
| isolate_(info->isolate()),
|
| @@ -613,7 +621,7 @@ Parser::Parser(CompilationInfo* info)
|
| reusable_preparser_(NULL),
|
| original_scope_(NULL),
|
| target_stack_(NULL),
|
| - pre_parse_data_(NULL),
|
| + cached_data_(NULL),
|
| info_(info) {
|
| ASSERT(!script_.is_null());
|
| isolate_->set_ast_node_id(0);
|
| @@ -628,6 +636,11 @@ Parser::Parser(CompilationInfo* info)
|
|
|
|
|
| FunctionLiteral* Parser::ParseProgram() {
|
| + CompleteParserRecorder recorder;
|
| + if (cached_data_ != NULL && *cached_data_ == NULL) {
|
| + // We're asked to generate data to cache.
|
| + log_ = &recorder;
|
| + }
|
| // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
|
| // see comment for HistogramTimerScope class.
|
| HistogramTimerScope timer_scope(isolate()->counters()->parse(), true);
|
| @@ -669,6 +682,11 @@ FunctionLiteral* Parser::ParseProgram() {
|
| }
|
| PrintF(" - took %0.3f ms]\n", ms);
|
| }
|
| + if (cached_data_ != NULL && *cached_data_ == NULL) {
|
| + Vector<unsigned> store = recorder.ExtractData();
|
| + *cached_data_ = new ScriptDataImpl(store);
|
| + log_ = NULL;
|
| + }
|
| return result;
|
| }
|
|
|
| @@ -677,7 +695,9 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
|
| Handle<String> source) {
|
| ASSERT(scope_ == NULL);
|
| ASSERT(target_stack_ == NULL);
|
| - if (pre_parse_data_ != NULL) pre_parse_data_->Initialize();
|
| + if (cached_data_ != NULL && *cached_data_ != NULL) {
|
| + (*cached_data_)->Initialize();
|
| + }
|
|
|
| Handle<String> no_name = isolate()->factory()->empty_string();
|
|
|
| @@ -3796,11 +3816,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| if (is_lazily_parsed) {
|
| int function_block_pos = position();
|
| FunctionEntry entry;
|
| - if (pre_parse_data_ != NULL) {
|
| - // If we have pre_parse_data_, we use it to skip parsing the function
|
| - // body. The preparser data contains the information we need to
|
| + if (cached_data_ != NULL && *cached_data_ != NULL) {
|
| + // If we have cached_data_, we use it to skip parsing the function
|
| + // body. The data contains the information we need to
|
| // construct the lazy function.
|
| - entry = pre_parse_data()->GetFunctionEntry(function_block_pos);
|
| + entry = (*cached_data_)->GetFunctionEntry(function_block_pos);
|
| if (entry.is_valid()) {
|
| if (entry.end_pos() <= function_block_pos) {
|
| // End position greater than end of stream is safe, and hard
|
| @@ -3833,6 +3853,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| is_lazily_parsed = false;
|
| }
|
| } else {
|
| + if (log_) log_->PauseRecording();
|
| // With no preparser data, we partially parse the function, without
|
| // building an AST. This gathers the data needed to build a lazy
|
| // function.
|
| @@ -3864,6 +3885,15 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| materialized_literal_count = logger.literals();
|
| expected_property_count = logger.properties();
|
| scope_->SetStrictMode(logger.strict_mode());
|
| + if (log_) {
|
| + log_->ResumeRecording();
|
| + // Position right after terminal '}'.
|
| + int body_end = scanner()->location().end_pos;
|
| + log_->LogFunction(function_block_pos, body_end,
|
| + materialized_literal_count,
|
| + expected_property_count,
|
| + scope_->strict_mode());
|
| + }
|
| }
|
| }
|
|
|
| @@ -5163,12 +5193,13 @@ bool Parser::Parse() {
|
| result = ParseProgram();
|
| }
|
| } else {
|
| - ScriptDataImpl* pre_parse_data = info()->pre_parse_data();
|
| - set_pre_parse_data(pre_parse_data);
|
| - if (pre_parse_data != NULL && pre_parse_data->has_error()) {
|
| - Scanner::Location loc = pre_parse_data->MessageLocation();
|
| - const char* message = pre_parse_data->BuildMessage();
|
| - Vector<const char*> args = pre_parse_data->BuildArgs();
|
| + ScriptDataImpl** cached_data = info()->cached_data();
|
| + set_cached_data(cached_data);
|
| + if (cached_data != NULL && *cached_data != NULL &&
|
| + (*cached_data)->has_error()) {
|
| + Scanner::Location loc = (*cached_data)->MessageLocation();
|
| + const char* message = (*cached_data)->BuildMessage();
|
| + Vector<const char*> args = (*cached_data)->BuildArgs();
|
| ParserTraits::ReportMessageAt(loc, message, args);
|
| DeleteArray(message);
|
| for (int i = 0; i < args.length(); i++) {
|
|
|