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

Side by Side Diff: src/parser.cc

Issue 733023003: Reland "Soft fail for invalid cache data." (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix leak 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') | src/serialize.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 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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 195
196 int ParseData::FunctionCount() { 196 int ParseData::FunctionCount() {
197 int functions_size = FunctionsSize(); 197 int functions_size = FunctionsSize();
198 if (functions_size < 0) return 0; 198 if (functions_size < 0) return 0;
199 if (functions_size % FunctionEntry::kSize != 0) return 0; 199 if (functions_size % FunctionEntry::kSize != 0) return 0;
200 return functions_size / FunctionEntry::kSize; 200 return functions_size / FunctionEntry::kSize;
201 } 201 }
202 202
203 203
204 bool ParseData::IsSane() { 204 bool ParseData::IsSane() {
205 if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
205 // Check that the header data is valid and doesn't specify 206 // Check that the header data is valid and doesn't specify
206 // point to positions outside the store. 207 // point to positions outside the store.
207 int data_length = Length(); 208 int data_length = Length();
208 if (data_length < PreparseDataConstants::kHeaderSize) return false; 209 if (data_length < PreparseDataConstants::kHeaderSize) return false;
209 if (Magic() != PreparseDataConstants::kMagicNumber) return false; 210 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
210 if (Version() != PreparseDataConstants::kCurrentVersion) return false; 211 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
211 if (HasError()) return false; 212 if (HasError()) return false;
212 // Check that the space allocated for function entries is sane. 213 // Check that the space allocated for function entries is sane.
213 int functions_size = FunctionsSize(); 214 int functions_size = FunctionsSize();
214 if (functions_size < 0) return false; 215 if (functions_size < 0) return false;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); 250 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
250 } 251 }
251 252
252 253
253 void Parser::SetCachedData() { 254 void Parser::SetCachedData() {
254 if (compile_options() == ScriptCompiler::kNoCompileOptions) { 255 if (compile_options() == ScriptCompiler::kNoCompileOptions) {
255 cached_parse_data_ = NULL; 256 cached_parse_data_ = NULL;
256 } else { 257 } else {
257 DCHECK(info_->cached_data() != NULL); 258 DCHECK(info_->cached_data() != NULL);
258 if (compile_options() == ScriptCompiler::kConsumeParserCache) { 259 if (compile_options() == ScriptCompiler::kConsumeParserCache) {
259 cached_parse_data_ = new ParseData(*info_->cached_data()); 260 cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data());
260 } 261 }
261 } 262 }
262 } 263 }
263 264
264 265
265 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { 266 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
266 DCHECK(ast_value_factory()); 267 DCHECK(ast_value_factory());
267 Scope* result = 268 Scope* result =
268 new (zone()) Scope(parent, scope_type, ast_value_factory(), zone()); 269 new (zone()) Scope(parent, scope_type, ast_value_factory(), zone());
269 result->Initialize(); 270 result->Initialize();
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 base::ElapsedTimer timer; 828 base::ElapsedTimer timer;
828 if (FLAG_trace_parse) { 829 if (FLAG_trace_parse) {
829 timer.Start(); 830 timer.Start();
830 } 831 }
831 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 832 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
832 833
833 // Initialize parser state. 834 // Initialize parser state.
834 CompleteParserRecorder recorder; 835 CompleteParserRecorder recorder;
835 836
836 debug_saved_compile_options_ = compile_options(); 837 debug_saved_compile_options_ = compile_options();
837 if (compile_options() == ScriptCompiler::kProduceParserCache) { 838 if (produce_cached_parse_data()) {
838 log_ = &recorder; 839 log_ = &recorder;
839 } else if (compile_options() == ScriptCompiler::kConsumeParserCache) { 840 } else if (consume_cached_parse_data()) {
840 cached_parse_data_->Initialize(); 841 cached_parse_data_->Initialize();
841 } 842 }
842 843
843 source = String::Flatten(source); 844 source = String::Flatten(source);
844 FunctionLiteral* result; 845 FunctionLiteral* result;
845 846
846 Scope* top_scope = NULL; 847 Scope* top_scope = NULL;
847 Scope* eval_scope = NULL; 848 Scope* eval_scope = NULL;
848 if (source->IsExternalTwoByteString()) { 849 if (source->IsExternalTwoByteString()) {
849 // Notice that the stream is destroyed at the end of the branch block. 850 // Notice that the stream is destroyed at the end of the branch block.
(...skipping 20 matching lines...) Expand all
870 PrintF("[parsing eval"); 871 PrintF("[parsing eval");
871 } else if (info()->script()->name()->IsString()) { 872 } else if (info()->script()->name()->IsString()) {
872 String* name = String::cast(info()->script()->name()); 873 String* name = String::cast(info()->script()->name());
873 SmartArrayPointer<char> name_chars = name->ToCString(); 874 SmartArrayPointer<char> name_chars = name->ToCString();
874 PrintF("[parsing script: %s", name_chars.get()); 875 PrintF("[parsing script: %s", name_chars.get());
875 } else { 876 } else {
876 PrintF("[parsing script"); 877 PrintF("[parsing script");
877 } 878 }
878 PrintF(" - took %0.3f ms]\n", ms); 879 PrintF(" - took %0.3f ms]\n", ms);
879 } 880 }
880 if (compile_options() == ScriptCompiler::kProduceParserCache) { 881 if (produce_cached_parse_data()) {
881 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 882 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
882 log_ = NULL; 883 log_ = NULL;
883 } 884 }
884 return result; 885 return result;
885 } 886 }
886 887
887 888
888 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, 889 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
889 Scope** eval_scope) { 890 Scope** eval_scope) {
890 DCHECK(scope_ == NULL); 891 DCHECK(scope_ == NULL);
(...skipping 2911 matching lines...) Expand 10 before | Expand all | Expand 10 after
3802 int* materialized_literal_count, 3803 int* materialized_literal_count,
3803 int* expected_property_count, 3804 int* expected_property_count,
3804 bool* ok) { 3805 bool* ok) {
3805 // Temporary debugging code for tracking down a mystery crash which should 3806 // Temporary debugging code for tracking down a mystery crash which should
3806 // never happen. The crash happens on the line where we log the function in 3807 // never happen. The crash happens on the line where we log the function in
3807 // the preparse data: log_->LogFunction(...). TODO(marja): remove this once 3808 // the preparse data: log_->LogFunction(...). TODO(marja): remove this once
3808 // done. 3809 // done.
3809 CHECK(materialized_literal_count); 3810 CHECK(materialized_literal_count);
3810 CHECK(expected_property_count); 3811 CHECK(expected_property_count);
3811 CHECK(debug_saved_compile_options_ == compile_options()); 3812 CHECK(debug_saved_compile_options_ == compile_options());
3812 if (compile_options() == ScriptCompiler::kProduceParserCache) { 3813 if (produce_cached_parse_data()) CHECK(log_);
3813 CHECK(log_);
3814 }
3815 3814
3816 int function_block_pos = position(); 3815 int function_block_pos = position();
3817 if (compile_options() == ScriptCompiler::kConsumeParserCache) { 3816 if (consume_cached_parse_data()) {
3818 // If we have cached data, we use it to skip parsing the function body. The 3817 // If we have cached data, we use it to skip parsing the function body. The
3819 // data contains the information we need to construct the lazy function. 3818 // data contains the information we need to construct the lazy function.
3820 FunctionEntry entry = 3819 FunctionEntry entry =
3821 cached_parse_data_->GetFunctionEntry(function_block_pos); 3820 cached_parse_data_->GetFunctionEntry(function_block_pos);
3822 // Check that cached data is valid. 3821 // Check that cached data is valid.
3823 CHECK(entry.is_valid()); 3822 CHECK(entry.is_valid());
3824 // End position greater than end of stream is safe, and hard to check. 3823 // End position greater than end of stream is safe, and hard to check.
3825 CHECK(entry.end_pos() > function_block_pos); 3824 CHECK(entry.end_pos() > function_block_pos);
3826 scanner()->SeekForward(entry.end_pos() - 1); 3825 scanner()->SeekForward(entry.end_pos() - 1);
3827 3826
(...skipping 27 matching lines...) Expand all
3855 } 3854 }
3856 scope_->set_end_position(logger.end()); 3855 scope_->set_end_position(logger.end());
3857 Expect(Token::RBRACE, ok); 3856 Expect(Token::RBRACE, ok);
3858 if (!*ok) { 3857 if (!*ok) {
3859 return; 3858 return;
3860 } 3859 }
3861 total_preparse_skipped_ += scope_->end_position() - function_block_pos; 3860 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3862 *materialized_literal_count = logger.literals(); 3861 *materialized_literal_count = logger.literals();
3863 *expected_property_count = logger.properties(); 3862 *expected_property_count = logger.properties();
3864 scope_->SetStrictMode(logger.strict_mode()); 3863 scope_->SetStrictMode(logger.strict_mode());
3865 if (compile_options() == ScriptCompiler::kProduceParserCache) { 3864 if (produce_cached_parse_data()) {
3866 DCHECK(log_); 3865 DCHECK(log_);
3867 // Position right after terminal '}'. 3866 // Position right after terminal '}'.
3868 int body_end = scanner()->location().end_pos; 3867 int body_end = scanner()->location().end_pos;
3869 log_->LogFunction(function_block_pos, body_end, 3868 log_->LogFunction(function_block_pos, body_end,
3870 *materialized_literal_count, 3869 *materialized_literal_count,
3871 *expected_property_count, 3870 *expected_property_count,
3872 scope_->strict_mode()); 3871 scope_->strict_mode());
3873 } 3872 }
3874 } 3873 }
3875 } 3874 }
(...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after
5116 } 5115 }
5117 5116
5118 5117
5119 void Parser::ParseOnBackground() { 5118 void Parser::ParseOnBackground() {
5120 DCHECK(info()->function() == NULL); 5119 DCHECK(info()->function() == NULL);
5121 FunctionLiteral* result = NULL; 5120 FunctionLiteral* result = NULL;
5122 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 5121 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
5123 5122
5124 CompleteParserRecorder recorder; 5123 CompleteParserRecorder recorder;
5125 debug_saved_compile_options_ = compile_options(); 5124 debug_saved_compile_options_ = compile_options();
5126 if (compile_options() == ScriptCompiler::kProduceParserCache) { 5125 if (produce_cached_parse_data()) log_ = &recorder;
5127 log_ = &recorder;
5128 }
5129 5126
5130 DCHECK(info()->source_stream() != NULL); 5127 DCHECK(info()->source_stream() != NULL);
5131 ExternalStreamingStream stream(info()->source_stream(), 5128 ExternalStreamingStream stream(info()->source_stream(),
5132 info()->source_stream_encoding()); 5129 info()->source_stream_encoding());
5133 scanner_.Initialize(&stream); 5130 scanner_.Initialize(&stream);
5134 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext()); 5131 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext());
5135 5132
5136 // When streaming, we don't know the length of the source until we have parsed 5133 // When streaming, we don't know the length of the source until we have parsed
5137 // it. The raw data can be UTF-8, so we wouldn't know the source length until 5134 // it. The raw data can be UTF-8, so we wouldn't know the source length until
5138 // we have decoded it anyway even if we knew the raw data length (which we 5135 // we have decoded it anyway even if we knew the raw data length (which we
5139 // don't). We work around this by storing all the scopes which need their end 5136 // don't). We work around this by storing all the scopes which need their end
5140 // position set at the end of the script (the top scope and possible eval 5137 // position set at the end of the script (the top scope and possible eval
5141 // scopes) and set their end position after we know the script length. 5138 // scopes) and set their end position after we know the script length.
5142 Scope* top_scope = NULL; 5139 Scope* top_scope = NULL;
5143 Scope* eval_scope = NULL; 5140 Scope* eval_scope = NULL;
5144 result = DoParseProgram(info(), &top_scope, &eval_scope); 5141 result = DoParseProgram(info(), &top_scope, &eval_scope);
5145 5142
5146 top_scope->set_end_position(scanner()->location().end_pos); 5143 top_scope->set_end_position(scanner()->location().end_pos);
5147 if (eval_scope != NULL) { 5144 if (eval_scope != NULL) {
5148 eval_scope->set_end_position(scanner()->location().end_pos); 5145 eval_scope->set_end_position(scanner()->location().end_pos);
5149 } 5146 }
5150 5147
5151 info()->SetFunction(result); 5148 info()->SetFunction(result);
5152 5149
5153 // We cannot internalize on a background thread; a foreground task will take 5150 // We cannot internalize on a background thread; a foreground task will take
5154 // care of calling Parser::Internalize just before compilation. 5151 // care of calling Parser::Internalize just before compilation.
5155 5152
5156 if (compile_options() == ScriptCompiler::kProduceParserCache) { 5153 if (produce_cached_parse_data()) {
5157 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 5154 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
5158 log_ = NULL; 5155 log_ = NULL;
5159 } 5156 }
5160 } 5157 }
5161 5158
5162 5159
5163 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { 5160 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
5164 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos); 5161 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
5165 } 5162 }
5166 5163
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
5289 5286
5290 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( 5287 const AstRawString* raw_str = ast_value_factory()->GetOneByteString(
5291 OneByteVector(raw_chars.get(), to_index)); 5288 OneByteVector(raw_chars.get(), to_index));
5292 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); 5289 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1);
5293 raw_strings->Add(raw_lit, zone()); 5290 raw_strings->Add(raw_lit, zone());
5294 } 5291 }
5295 5292
5296 return raw_strings; 5293 return raw_strings;
5297 } 5294 }
5298 } } // namespace v8::internal 5295 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/serialize.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698