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

Side by Side Diff: src/parser.cc

Issue 376223002: Refactor ScriptData class for cached compile data. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 months 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 | Annotate | Revision Log
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/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 // Only call immediately after adding an atom or character! 175 // Only call immediately after adding an atom or character!
176 UNREACHABLE(); 176 UNREACHABLE();
177 return; 177 return;
178 } 178 }
179 terms_.Add( 179 terms_.Add(
180 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); 180 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
181 LAST(ADD_TERM); 181 LAST(ADD_TERM);
182 } 182 }
183 183
184 184
185 ScriptData* ScriptData::New(const char* data, int length, bool owns_store) { 185 FunctionEntry ParseData::GetFunctionEntry(int start) {
186 // The length is obviously invalid.
187 if (length % sizeof(unsigned) != 0) {
188 return NULL;
189 }
190
191 int deserialized_data_length = length / sizeof(unsigned);
192 unsigned* deserialized_data;
193 owns_store =
194 owns_store || reinterpret_cast<intptr_t>(data) % sizeof(unsigned) != 0;
195 if (owns_store) {
196 // Copy the data to align it.
197 deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
198 i::CopyBytes(reinterpret_cast<char*>(deserialized_data),
199 data, static_cast<size_t>(length));
200 } else {
201 // If aligned, don't create a copy of the data.
202 deserialized_data = reinterpret_cast<unsigned*>(const_cast<char*>(data));
203 }
204 return new ScriptData(
205 Vector<unsigned>(deserialized_data, deserialized_data_length),
206 owns_store);
207 }
208
209
210 FunctionEntry ScriptData::GetFunctionEntry(int start) {
211 // The current pre-data entry must be a FunctionEntry with the given 186 // The current pre-data entry must be a FunctionEntry with the given
212 // start position. 187 // start position.
213 if ((function_index_ + FunctionEntry::kSize <= store_.length()) 188 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
214 && (static_cast<int>(store_[function_index_]) == start)) { 189 (static_cast<int>(Data()[function_index_]) == start)) {
215 int index = function_index_; 190 int index = function_index_;
216 function_index_ += FunctionEntry::kSize; 191 function_index_ += FunctionEntry::kSize;
217 return FunctionEntry(store_.SubVector(index, 192 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
218 index + FunctionEntry::kSize)); 193 return FunctionEntry(subvector);
219 } 194 }
220 return FunctionEntry(); 195 return FunctionEntry();
221 } 196 }
222 197
223 198
224 int ScriptData::GetSymbolIdentifier() { 199 int ParseData::GetSymbolIdentifier() { return ReadNumber(&symbol_data_); }
225 return ReadNumber(&symbol_data_); 200
201
202 int ParseData::FunctionCount() {
203 int functions_size = FunctionsSize();
204 if (functions_size < 0) return 0;
205 if (functions_size % FunctionEntry::kSize != 0) return 0;
206 return functions_size / FunctionEntry::kSize;
226 } 207 }
227 208
228 209
229 bool ScriptData::SanityCheck() { 210 bool ParseData::Sanity() {
230 // Check that the header data is valid and doesn't specify 211 // Check that the header data is valid and doesn't specify
231 // point to positions outside the store. 212 // point to positions outside the store.
232 if (store_.length() < PreparseDataConstants::kHeaderSize) return false; 213 int data_length = Length();
233 if (magic() != PreparseDataConstants::kMagicNumber) return false; 214 if (data_length < PreparseDataConstants::kHeaderSize) return false;
234 if (version() != PreparseDataConstants::kCurrentVersion) return false; 215 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
235 if (has_error()) { 216 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
217 if (HasError()) {
marja 2014/07/09 14:42:30 Afaics we'll never have an error in normal operati
Yang 2014/07/10 08:28:46 Done. But if that's the case, couldn't we just re
236 // Extra sane sanity check for error message encoding. 218 // Extra sane sanity check for error message encoding.
237 if (store_.length() <= PreparseDataConstants::kHeaderSize 219 if (data_length <= PreparseDataConstants::kHeaderSize +
238 + PreparseDataConstants::kMessageTextPos) { 220 PreparseDataConstants::kMessageTextPos) {
239 return false; 221 return false;
240 } 222 }
241 if (Read(PreparseDataConstants::kMessageStartPos) > 223 if (Read(PreparseDataConstants::kMessageStartPos) >
242 Read(PreparseDataConstants::kMessageEndPos)) { 224 Read(PreparseDataConstants::kMessageEndPos)) {
243 return false; 225 return false;
244 } 226 }
245 unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos); 227 unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
246 int pos = PreparseDataConstants::kMessageTextPos; 228 int pos = PreparseDataConstants::kMessageTextPos;
247 for (unsigned int i = 0; i <= arg_count; i++) { 229 for (unsigned int i = 0; i <= arg_count; i++) {
248 if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) { 230 if (data_length <= PreparseDataConstants::kHeaderSize + pos) {
249 return false; 231 return false;
250 } 232 }
251 int length = static_cast<int>(Read(pos)); 233 int length = static_cast<int>(Read(pos));
252 if (length < 0) return false; 234 if (length < 0) return false;
253 pos += 1 + length; 235 pos += 1 + length;
254 } 236 }
255 if (store_.length() < PreparseDataConstants::kHeaderSize + pos) { 237 if (data_length < PreparseDataConstants::kHeaderSize + pos) {
256 return false; 238 return false;
257 } 239 }
258 return true; 240 return true;
259 } 241 }
260 // Check that the space allocated for function entries is sane. 242 // Check that the space allocated for function entries is sane.
261 int functions_size = 243 int functions_size = FunctionsSize();
262 static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
263 if (functions_size < 0) return false; 244 if (functions_size < 0) return false;
264 if (functions_size % FunctionEntry::kSize != 0) return false; 245 if (functions_size % FunctionEntry::kSize != 0) return false;
265 // Check that the total size has room for header and function entries. 246 // Check that the total size has room for header and function entries.
266 int minimum_size = 247 int minimum_size =
267 PreparseDataConstants::kHeaderSize + functions_size; 248 PreparseDataConstants::kHeaderSize + functions_size;
268 if (store_.length() < minimum_size) return false; 249 if (data_length < minimum_size) return false;
269 return true; 250 return true;
270 } 251 }
271 252
272 253
254 void ParseData::Initialize() {
255 // Prepares state for use.
256 int data_length = Length();
257 if (data_length >= PreparseDataConstants::kHeaderSize) {
258 function_index_ = PreparseDataConstants::kHeaderSize;
259 int symbol_data_offset =
marja 2014/07/09 14:42:30 Omg, this is messier than I thought. We don't have
Yang 2014/07/10 08:28:46 Done.
260 PreparseDataConstants::kHeaderSize + FunctionsSize();
261 unsigned* data = Data();
262 if (data_length > symbol_data_offset) {
263 symbol_data_ = reinterpret_cast<byte*>(data[symbol_data_offset]);
264 } else {
265 // Partial preparse causes no symbol information.
266 symbol_data_ = reinterpret_cast<byte*>(data + data_length);
267 }
vogelheim 2014/07/09 17:23:36 nitpick, and not your code, but... this duplicates
Yang 2014/07/10 08:28:45 All gone now anyways.
268 symbol_data_end_ = reinterpret_cast<byte*>(data + data_length);
269 }
270 }
273 271
274 const char* ScriptData::ReadString(unsigned* start, int* chars) { 272
275 int length = start[0]; 273 int ParseData::ReadNumber(byte** source) {
276 char* result = NewArray<char>(length + 1); 274 // Reads a number from symbol_data_ in base 128. The most significant
277 for (int i = 0; i < length; i++) { 275 // bit marks that there are more digits.
278 result[i] = start[i + 1]; 276 // If the first byte is 0x80 (kNumberTerminator), it would normally
277 // represent a leading zero. Since that is useless, and therefore won't
278 // appear as the first digit of any actual value, it is used to
279 // mark the end of the input stream.
280 byte* data = *source;
281 if (data >= symbol_data_end_) return -1;
282 byte input = *data;
283 if (input == PreparseDataConstants::kNumberTerminator) {
284 // End of stream marker.
285 return -1;
279 } 286 }
280 result[length] = '\0'; 287 int result = input & 0x7f;
281 if (chars != NULL) *chars = length; 288 data++;
289 while ((input & 0x80u) != 0) {
290 if (data >= symbol_data_end_) return -1;
291 input = *data;
292 result = (result << 7) | (input & 0x7f);
293 data++;
294 }
295 *source = data;
282 return result; 296 return result;
283 } 297 }
284 298
285 299
286 Scanner::Location ScriptData::MessageLocation() const { 300 Scanner::Location ParseData::MessageLocation() const {
287 int beg_pos = Read(PreparseDataConstants::kMessageStartPos); 301 int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
288 int end_pos = Read(PreparseDataConstants::kMessageEndPos); 302 int end_pos = Read(PreparseDataConstants::kMessageEndPos);
289 return Scanner::Location(beg_pos, end_pos); 303 return Scanner::Location(beg_pos, end_pos);
290 } 304 }
291 305
292 306
293 bool ScriptData::IsReferenceError() const { 307 bool ParseData::IsReferenceError() const {
294 return Read(PreparseDataConstants::kIsReferenceErrorPos); 308 return Read(PreparseDataConstants::kIsReferenceErrorPos);
295 } 309 }
296 310
297 311
298 const char* ScriptData::BuildMessage() const { 312 const char* ParseData::BuildMessage() {
299 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos); 313 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
300 return ReadString(start, NULL); 314 return ReadString(start, NULL);
301 } 315 }
302 316
303 317
304 const char* ScriptData::BuildArg() const { 318 const char* ParseData::BuildArg() {
305 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos); 319 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
306 ASSERT(arg_count == 0 || arg_count == 1); 320 ASSERT(arg_count == 0 || arg_count == 1);
307 if (arg_count == 0) { 321 if (arg_count == 0) {
308 return NULL; 322 return NULL;
309 } 323 }
310 // Position after text found by skipping past length field and 324 // Position after text found by skipping past length field and
311 // length field content words. 325 // length field content words.
312 int pos = PreparseDataConstants::kMessageTextPos + 1 326 int pos = PreparseDataConstants::kMessageTextPos + 1
313 + Read(PreparseDataConstants::kMessageTextPos); 327 + Read(PreparseDataConstants::kMessageTextPos);
314 int count = 0; 328 int count = 0;
315 return ReadString(ReadAddress(pos), &count); 329 return ReadString(ReadAddress(pos), &count);
316 } 330 }
317 331
318 332
319 unsigned ScriptData::Read(int position) const { 333 const char* ParseData::ReadString(unsigned* start, int* chars) {
320 return store_[PreparseDataConstants::kHeaderSize + position]; 334 int length = start[0];
335 char* result = NewArray<char>(length + 1);
336 for (int i = 0; i < length; i++) {
337 result[i] = start[i + 1];
338 }
339 result[length] = '\0';
340 if (chars != NULL) *chars = length;
341 return result;
321 } 342 }
322 343
323 344
324 unsigned* ScriptData::ReadAddress(int position) const { 345 bool ParseData::HasError() const {
325 return &store_[PreparseDataConstants::kHeaderSize + position]; 346 return Data()[PreparseDataConstants::kHasErrorOffset];
347 }
348
349 unsigned ParseData::Magic() const {
350 return Data()[PreparseDataConstants::kMagicOffset];
351 }
352
353 unsigned ParseData::Version() const {
354 return Data()[PreparseDataConstants::kVersionOffset];
355 }
356
357 int ParseData::FunctionsSize() const {
358 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
359 }
360
361 unsigned ParseData::Read(int position) const {
362 return Data()[PreparseDataConstants::kHeaderSize + position];
363 }
364
365 unsigned* ParseData::ReadAddress(int position) const {
366 return &(Data()[PreparseDataConstants::kHeaderSize + position]);
326 } 367 }
327 368
328 369
370 void Parser::SetCachedData() {
371 if (cached_data_mode() == NO_CACHED_DATA) {
372 cached_parse_data_ = NULL;
373 } else {
374 ASSERT(info_->cached_data() != NULL);
375 if (cached_data_mode() == CONSUME_CACHED_DATA) {
376 cached_parse_data_ = new ParseData(*info_->cached_data());
377 }
378 }
379 }
380
381
329 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { 382 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
330 ASSERT(ast_value_factory_); 383 ASSERT(ast_value_factory_);
331 Scope* result = 384 Scope* result =
332 new (zone()) Scope(parent, scope_type, ast_value_factory_, zone()); 385 new (zone()) Scope(parent, scope_type, ast_value_factory_, zone());
333 result->Initialize(); 386 result->Initialize();
334 return result; 387 return result;
335 } 388 }
336 389
337 390
338 // ---------------------------------------------------------------------------- 391 // ----------------------------------------------------------------------------
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 return parser_->ParseFunctionLiteral(name, function_name_location, 803 return parser_->ParseFunctionLiteral(name, function_name_location,
751 name_is_strict_reserved, is_generator, 804 name_is_strict_reserved, is_generator,
752 function_token_position, type, 805 function_token_position, type,
753 arity_restriction, ok); 806 arity_restriction, ok);
754 } 807 }
755 808
756 809
757 Parser::Parser(CompilationInfo* info) 810 Parser::Parser(CompilationInfo* info)
758 : ParserBase<ParserTraits>(&scanner_, 811 : ParserBase<ParserTraits>(&scanner_,
759 info->isolate()->stack_guard()->real_climit(), 812 info->isolate()->stack_guard()->real_climit(),
760 info->extension(), 813 info->extension(), NULL, info->zone(), this),
761 NULL,
762 info->zone(),
763 this),
764 isolate_(info->isolate()), 814 isolate_(info->isolate()),
765 script_(info->script()), 815 script_(info->script()),
766 scanner_(isolate_->unicode_cache()), 816 scanner_(isolate_->unicode_cache()),
767 reusable_preparser_(NULL), 817 reusable_preparser_(NULL),
768 original_scope_(NULL), 818 original_scope_(NULL),
769 target_stack_(NULL), 819 target_stack_(NULL),
770 cached_data_(NULL), 820 cached_parse_data_(NULL),
771 cached_data_mode_(NO_CACHED_DATA),
772 ast_value_factory_(NULL), 821 ast_value_factory_(NULL),
773 info_(info), 822 info_(info),
774 has_pending_error_(false), 823 has_pending_error_(false),
775 pending_error_message_(NULL), 824 pending_error_message_(NULL),
776 pending_error_arg_(NULL), 825 pending_error_arg_(NULL),
777 pending_error_char_arg_(NULL) { 826 pending_error_char_arg_(NULL) {
778 ASSERT(!script_.is_null()); 827 ASSERT(!script_.is_null());
779 isolate_->set_ast_node_id(0); 828 isolate_->set_ast_node_id(0);
780 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); 829 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
781 set_allow_modules(!info->is_native() && FLAG_harmony_modules); 830 set_allow_modules(!info->is_native() && FLAG_harmony_modules);
(...skipping 16 matching lines...) Expand all
798 Handle<String> source(String::cast(script_->source())); 847 Handle<String> source(String::cast(script_->source()));
799 isolate()->counters()->total_parse_size()->Increment(source->length()); 848 isolate()->counters()->total_parse_size()->Increment(source->length());
800 base::ElapsedTimer timer; 849 base::ElapsedTimer timer;
801 if (FLAG_trace_parse) { 850 if (FLAG_trace_parse) {
802 timer.Start(); 851 timer.Start();
803 } 852 }
804 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); 853 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone());
805 854
806 // Initialize parser state. 855 // Initialize parser state.
807 CompleteParserRecorder recorder; 856 CompleteParserRecorder recorder;
808 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { 857 if (cached_data_mode() == PRODUCE_CACHED_DATA) {
809 log_ = &recorder; 858 log_ = &recorder;
810 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { 859 } else if (cached_data_mode() == CONSUME_CACHED_DATA) {
811 (*cached_data_)->Initialize(); 860 cached_parse_data_->Initialize();
812 } 861 }
813 862
814 source = String::Flatten(source); 863 source = String::Flatten(source);
815 FunctionLiteral* result; 864 FunctionLiteral* result;
816 if (source->IsExternalTwoByteString()) { 865 if (source->IsExternalTwoByteString()) {
817 // Notice that the stream is destroyed at the end of the branch block. 866 // Notice that the stream is destroyed at the end of the branch block.
818 // The last line of the blocks can't be moved outside, even though they're 867 // The last line of the blocks can't be moved outside, even though they're
819 // identical calls. 868 // identical calls.
820 ExternalTwoByteStringUtf16CharacterStream stream( 869 ExternalTwoByteStringUtf16CharacterStream stream(
821 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 870 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
(...skipping 11 matching lines...) Expand all
833 PrintF("[parsing eval"); 882 PrintF("[parsing eval");
834 } else if (info()->script()->name()->IsString()) { 883 } else if (info()->script()->name()->IsString()) {
835 String* name = String::cast(info()->script()->name()); 884 String* name = String::cast(info()->script()->name());
836 SmartArrayPointer<char> name_chars = name->ToCString(); 885 SmartArrayPointer<char> name_chars = name->ToCString();
837 PrintF("[parsing script: %s", name_chars.get()); 886 PrintF("[parsing script: %s", name_chars.get());
838 } else { 887 } else {
839 PrintF("[parsing script"); 888 PrintF("[parsing script");
840 } 889 }
841 PrintF(" - took %0.3f ms]\n", ms); 890 PrintF(" - took %0.3f ms]\n", ms);
842 } 891 }
843 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { 892 if (cached_data_mode() == PRODUCE_CACHED_DATA) {
844 if (result != NULL) { 893 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
845 Vector<unsigned> store = recorder.ExtractData();
846 *cached_data_ = new ScriptData(store);
847 }
848 log_ = NULL; 894 log_ = NULL;
849 } 895 }
850 return result; 896 return result;
851 } 897 }
852 898
853 899
854 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, 900 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
855 Handle<String> source) { 901 Handle<String> source) {
856 ASSERT(scope_ == NULL); 902 ASSERT(scope_ == NULL);
857 ASSERT(target_stack_ == NULL); 903 ASSERT(target_stack_ == NULL);
(...skipping 2428 matching lines...) Expand 10 before | Expand all | Expand 10 after
3286 // DebuggerStatement :: 3332 // DebuggerStatement ::
3287 // 'debugger' ';' 3333 // 'debugger' ';'
3288 3334
3289 int pos = peek_position(); 3335 int pos = peek_position();
3290 Expect(Token::DEBUGGER, CHECK_OK); 3336 Expect(Token::DEBUGGER, CHECK_OK);
3291 ExpectSemicolon(CHECK_OK); 3337 ExpectSemicolon(CHECK_OK);
3292 return factory()->NewDebuggerStatement(pos); 3338 return factory()->NewDebuggerStatement(pos);
3293 } 3339 }
3294 3340
3295 3341
3296 void Parser::ReportInvalidCachedData(const AstRawString* name, bool* ok) {
3297 ParserTraits::ReportMessage("invalid_cached_data_function", name);
3298 *ok = false;
3299 }
3300
3301
3302 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { 3342 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3303 if (expression->IsLiteral()) return true; 3343 if (expression->IsLiteral()) return true;
3304 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); 3344 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3305 return lit != NULL && lit->is_simple(); 3345 return lit != NULL && lit->is_simple();
3306 } 3346 }
3307 3347
3308 3348
3309 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, 3349 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3310 Expression* expression) { 3350 Expression* expression) {
3311 Factory* factory = isolate->factory(); 3351 Factory* factory = isolate->factory();
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
3608 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 3648 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
3609 return function_literal; 3649 return function_literal;
3610 } 3650 }
3611 3651
3612 3652
3613 void Parser::SkipLazyFunctionBody(const AstRawString* function_name, 3653 void Parser::SkipLazyFunctionBody(const AstRawString* function_name,
3614 int* materialized_literal_count, 3654 int* materialized_literal_count,
3615 int* expected_property_count, 3655 int* expected_property_count,
3616 bool* ok) { 3656 bool* ok) {
3617 int function_block_pos = position(); 3657 int function_block_pos = position();
3618 if (cached_data_mode_ == CONSUME_CACHED_DATA) { 3658 if (cached_data_mode() == CONSUME_CACHED_DATA) {
3619 // If we have cached data, we use it to skip parsing the function body. The 3659 // If we have cached data, we use it to skip parsing the function body. The
3620 // data contains the information we need to construct the lazy function. 3660 // data contains the information we need to construct the lazy function.
3621 FunctionEntry entry = 3661 FunctionEntry entry =
3622 (*cached_data())->GetFunctionEntry(function_block_pos); 3662 cached_parse_data_->GetFunctionEntry(function_block_pos);
3623 if (entry.is_valid()) { 3663 // Invalid cached data if checks fail.
vogelheim 2014/07/09 17:23:36 I can't really parse the comment.
Yang 2014/07/10 08:28:45 Changed.
3624 if (entry.end_pos() <= function_block_pos) { 3664 CHECK(entry.is_valid());
3625 // End position greater than end of stream is safe, and hard to check. 3665 // End position greater than end of stream is safe, and hard to check.
3626 ReportInvalidCachedData(function_name, ok); 3666 CHECK(entry.end_pos() > function_block_pos);
3627 if (!*ok) { 3667 scanner()->SeekForward(entry.end_pos() - 1);
3628 return;
3629 }
3630 }
3631 scanner()->SeekForward(entry.end_pos() - 1);
3632 3668
3633 scope_->set_end_position(entry.end_pos()); 3669 scope_->set_end_position(entry.end_pos());
3634 Expect(Token::RBRACE, ok); 3670 Expect(Token::RBRACE, ok);
3635 if (!*ok) { 3671 if (!*ok) {
3636 return;
3637 }
3638 isolate()->counters()->total_preparse_skipped()->Increment(
3639 scope_->end_position() - function_block_pos);
3640 *materialized_literal_count = entry.literal_count();
3641 *expected_property_count = entry.property_count();
3642 scope_->SetStrictMode(entry.strict_mode());
3643 } else {
3644 // This case happens when we have preparse data but it doesn't contain an
3645 // entry for the function. Fail the compilation.
3646 ReportInvalidCachedData(function_name, ok);
3647 return; 3672 return;
3648 } 3673 }
3674 isolate()->counters()->total_preparse_skipped()->Increment(
3675 scope_->end_position() - function_block_pos);
3676 *materialized_literal_count = entry.literal_count();
3677 *expected_property_count = entry.property_count();
3678 scope_->SetStrictMode(entry.strict_mode());
3649 } else { 3679 } else {
3650 // With no cached data, we partially parse the function, without building an 3680 // With no cached data, we partially parse the function, without building an
3651 // AST. This gathers the data needed to build a lazy function. 3681 // AST. This gathers the data needed to build a lazy function.
3652 SingletonLogger logger; 3682 SingletonLogger logger;
3653 PreParser::PreParseResult result = 3683 PreParser::PreParseResult result =
3654 ParseLazyFunctionBodyWithPreParser(&logger); 3684 ParseLazyFunctionBodyWithPreParser(&logger);
3655 if (result == PreParser::kPreParseStackOverflow) { 3685 if (result == PreParser::kPreParseStackOverflow) {
3656 // Propagate stack overflow. 3686 // Propagate stack overflow.
3657 set_stack_overflow(); 3687 set_stack_overflow();
3658 *ok = false; 3688 *ok = false;
3659 return; 3689 return;
3660 } 3690 }
3661 if (logger.has_error()) { 3691 if (logger.has_error()) {
3662 ParserTraits::ReportMessageAt( 3692 ParserTraits::ReportMessageAt(
3663 Scanner::Location(logger.start(), logger.end()), 3693 Scanner::Location(logger.start(), logger.end()),
3664 logger.message(), logger.argument_opt(), logger.is_reference_error()); 3694 logger.message(), logger.argument_opt(), logger.is_reference_error());
3665 *ok = false; 3695 *ok = false;
3666 return; 3696 return;
3667 } 3697 }
3668 scope_->set_end_position(logger.end()); 3698 scope_->set_end_position(logger.end());
3669 Expect(Token::RBRACE, ok); 3699 Expect(Token::RBRACE, ok);
3670 if (!*ok) { 3700 if (!*ok) {
3671 return; 3701 return;
3672 } 3702 }
3673 isolate()->counters()->total_preparse_skipped()->Increment( 3703 isolate()->counters()->total_preparse_skipped()->Increment(
3674 scope_->end_position() - function_block_pos); 3704 scope_->end_position() - function_block_pos);
3675 *materialized_literal_count = logger.literals(); 3705 *materialized_literal_count = logger.literals();
3676 *expected_property_count = logger.properties(); 3706 *expected_property_count = logger.properties();
3677 scope_->SetStrictMode(logger.strict_mode()); 3707 scope_->SetStrictMode(logger.strict_mode());
3678 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { 3708 if (cached_data_mode() == PRODUCE_CACHED_DATA) {
3679 ASSERT(log_); 3709 ASSERT(log_);
3680 // Position right after terminal '}'. 3710 // Position right after terminal '}'.
3681 int body_end = scanner()->location().end_pos; 3711 int body_end = scanner()->location().end_pos;
3682 log_->LogFunction(function_block_pos, body_end, 3712 log_->LogFunction(function_block_pos, body_end,
3683 *materialized_literal_count, 3713 *materialized_literal_count,
3684 *expected_property_count, 3714 *expected_property_count,
3685 scope_->strict_mode()); 3715 scope_->strict_mode());
3686 } 3716 }
3687 } 3717 }
3688 } 3718 }
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after
4760 ranges->Add(CharacterRange::Everything(), zone()); 4790 ranges->Add(CharacterRange::Everything(), zone());
4761 is_negated = !is_negated; 4791 is_negated = !is_negated;
4762 } 4792 }
4763 return new(zone()) RegExpCharacterClass(ranges, is_negated); 4793 return new(zone()) RegExpCharacterClass(ranges, is_negated);
4764 } 4794 }
4765 4795
4766 4796
4767 // ---------------------------------------------------------------------------- 4797 // ----------------------------------------------------------------------------
4768 // The Parser interface. 4798 // The Parser interface.
4769 4799
4770 ScriptData::~ScriptData() {
4771 if (owns_store_) store_.Dispose();
4772 }
4773
4774
4775 int ScriptData::Length() {
4776 return store_.length() * sizeof(unsigned);
4777 }
4778
4779
4780 const char* ScriptData::Data() {
4781 return reinterpret_cast<const char*>(store_.start());
4782 }
4783
4784
4785 bool ScriptData::HasError() {
4786 return has_error();
4787 }
4788
4789
4790 void ScriptData::Initialize() {
4791 // Prepares state for use.
4792 if (store_.length() >= PreparseDataConstants::kHeaderSize) {
4793 function_index_ = PreparseDataConstants::kHeaderSize;
4794 int symbol_data_offset = PreparseDataConstants::kHeaderSize
4795 + store_[PreparseDataConstants::kFunctionsSizeOffset];
4796 if (store_.length() > symbol_data_offset) {
4797 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
4798 } else {
4799 // Partial preparse causes no symbol information.
4800 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
4801 }
4802 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
4803 }
4804 }
4805
4806
4807 int ScriptData::ReadNumber(byte** source) {
4808 // Reads a number from symbol_data_ in base 128. The most significant
4809 // bit marks that there are more digits.
4810 // If the first byte is 0x80 (kNumberTerminator), it would normally
4811 // represent a leading zero. Since that is useless, and therefore won't
4812 // appear as the first digit of any actual value, it is used to
4813 // mark the end of the input stream.
4814 byte* data = *source;
4815 if (data >= symbol_data_end_) return -1;
4816 byte input = *data;
4817 if (input == PreparseDataConstants::kNumberTerminator) {
4818 // End of stream marker.
4819 return -1;
4820 }
4821 int result = input & 0x7f;
4822 data++;
4823 while ((input & 0x80u) != 0) {
4824 if (data >= symbol_data_end_) return -1;
4825 input = *data;
4826 result = (result << 7) | (input & 0x7f);
4827 data++;
4828 }
4829 *source = data;
4830 return result;
4831 }
4832
4833
4834 bool RegExpParser::ParseRegExp(FlatStringReader* input, 4800 bool RegExpParser::ParseRegExp(FlatStringReader* input,
4835 bool multiline, 4801 bool multiline,
4836 RegExpCompileData* result, 4802 RegExpCompileData* result,
4837 Zone* zone) { 4803 Zone* zone) {
4838 ASSERT(result != NULL); 4804 ASSERT(result != NULL);
4839 RegExpParser parser(input, &result->error, multiline, zone); 4805 RegExpParser parser(input, &result->error, multiline, zone);
4840 RegExpTree* tree = parser.ParsePattern(); 4806 RegExpTree* tree = parser.ParsePattern();
4841 if (parser.failed()) { 4807 if (parser.failed()) {
4842 ASSERT(tree == NULL); 4808 ASSERT(tree == NULL);
4843 ASSERT(!result->error.is_null()); 4809 ASSERT(!result->error.is_null());
(...skipping 26 matching lines...) Expand all
4870 } 4836 }
4871 4837
4872 if (info()->is_lazy()) { 4838 if (info()->is_lazy()) {
4873 ASSERT(!info()->is_eval()); 4839 ASSERT(!info()->is_eval());
4874 if (info()->shared_info()->is_function()) { 4840 if (info()->shared_info()->is_function()) {
4875 result = ParseLazy(); 4841 result = ParseLazy();
4876 } else { 4842 } else {
4877 result = ParseProgram(); 4843 result = ParseProgram();
4878 } 4844 }
4879 } else { 4845 } else {
4880 SetCachedData(info()->cached_data(), info()->cached_data_mode()); 4846 SetCachedData();
4881 result = ParseProgram(); 4847 result = ParseProgram();
4882 } 4848 }
4883 info()->SetFunction(result); 4849 info()->SetFunction(result);
4884 ASSERT(ast_value_factory_->IsInternalized()); 4850 ASSERT(ast_value_factory_->IsInternalized());
4885 // info takes ownership of ast_value_factory_. 4851 // info takes ownership of ast_value_factory_.
4886 if (info()->ast_value_factory() == NULL) { 4852 if (info()->ast_value_factory() == NULL) {
4887 info()->SetAstValueFactory(ast_value_factory_); 4853 info()->SetAstValueFactory(ast_value_factory_);
4888 } 4854 }
4889 ast_value_factory_ = NULL; 4855 ast_value_factory_ = NULL;
4890 4856
4891 InternalizeUseCounts(); 4857 InternalizeUseCounts();
4892 4858
4893 return (result != NULL); 4859 return (result != NULL);
4894 } 4860 }
4895 4861
4896 } } // namespace v8::internal 4862 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698