OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 inline Zone* zone() const { return zone_; } | 154 inline Zone* zone() const { return zone_; } |
155 | 155 |
156 static const int kInitialSpecialStringLength = 1024; | 156 static const int kInitialSpecialStringLength = 1024; |
157 | 157 |
158 | 158 |
159 private: | 159 private: |
160 Handle<String> source_; | 160 Handle<String> source_; |
161 int source_length_; | 161 int source_length_; |
162 Handle<SeqAsciiString> seq_source_; | 162 Handle<SeqAsciiString> seq_source_; |
163 | 163 |
164 PretenureFlag tenure_; | |
Michael Starzinger
2012/10/22 16:44:28
Let's call that "pretenure_" to be in line with th
Toon Verwaest
2012/10/23 08:05:57
Done.
| |
164 Isolate* isolate_; | 165 Isolate* isolate_; |
165 Factory* factory_; | 166 Factory* factory_; |
166 Handle<JSFunction> object_constructor_; | 167 Handle<JSFunction> object_constructor_; |
167 uc32 c0_; | 168 uc32 c0_; |
168 int position_; | 169 int position_; |
169 Zone* zone_; | 170 Zone* zone_; |
170 }; | 171 }; |
171 | 172 |
172 template <bool seq_ascii> | 173 template <bool seq_ascii> |
173 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source, | 174 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source, |
174 Zone* zone) { | 175 Zone* zone) { |
175 isolate_ = source->map()->GetHeap()->isolate(); | 176 isolate_ = source->map()->GetHeap()->isolate(); |
176 factory_ = isolate_->factory(); | 177 factory_ = isolate_->factory(); |
177 object_constructor_ = | 178 object_constructor_ = |
178 Handle<JSFunction>(isolate()->native_context()->object_function()); | 179 Handle<JSFunction>(isolate()->native_context()->object_function()); |
179 zone_ = zone; | 180 zone_ = zone; |
180 FlattenString(source); | 181 FlattenString(source); |
181 source_ = source; | 182 source_ = source; |
182 source_length_ = source_->length(); | 183 source_length_ = source_->length(); |
184 static const int kJsonAllocatePretenured = 100 * 1024; | |
Michael Starzinger
2012/10/22 16:44:28
Can we move this constant out into the JsonParser
Toon Verwaest
2012/10/23 08:05:57
Done.
| |
185 tenure_ = (source_length_ >= kJsonAllocatePretenured) ? TENURED : NOT_TENURED; | |
183 | 186 |
184 // Optimized fast case where we only have ASCII characters. | 187 // Optimized fast case where we only have ASCII characters. |
185 if (seq_ascii) { | 188 if (seq_ascii) { |
186 seq_source_ = Handle<SeqAsciiString>::cast(source_); | 189 seq_source_ = Handle<SeqAsciiString>::cast(source_); |
187 } | 190 } |
188 | 191 |
189 // Set initial position right before the string. | 192 // Set initial position right before the string. |
190 position_ = -1; | 193 position_ = -1; |
191 // Advance to the first character (possibly EOS) | 194 // Advance to the first character (possibly EOS) |
192 AdvanceSkipWhitespace(); | 195 AdvanceSkipWhitespace(); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
274 } | 277 } |
275 return ReportUnexpectedCharacter(); | 278 return ReportUnexpectedCharacter(); |
276 } | 279 } |
277 | 280 |
278 | 281 |
279 // Parse a JSON object. Position must be right at '{'. | 282 // Parse a JSON object. Position must be right at '{'. |
280 template <bool seq_ascii> | 283 template <bool seq_ascii> |
281 Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() { | 284 Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() { |
282 Handle<Object> prototype; | 285 Handle<Object> prototype; |
283 Handle<JSObject> json_object = | 286 Handle<JSObject> json_object = |
284 factory()->NewJSObject(object_constructor()); | 287 factory()->NewJSObject(object_constructor(), tenure_); |
285 ASSERT_EQ(c0_, '{'); | 288 ASSERT_EQ(c0_, '{'); |
286 | 289 |
287 AdvanceSkipWhitespace(); | 290 AdvanceSkipWhitespace(); |
288 if (c0_ != '}') { | 291 if (c0_ != '}') { |
289 do { | 292 do { |
290 if (c0_ != '"') return ReportUnexpectedCharacter(); | 293 if (c0_ != '"') return ReportUnexpectedCharacter(); |
291 | 294 |
292 int start_position = position_; | 295 int start_position = position_; |
293 Advance(); | 296 Advance(); |
294 | 297 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 if (element.is_null()) return ReportUnexpectedCharacter(); | 361 if (element.is_null()) return ReportUnexpectedCharacter(); |
359 elements.Add(element, zone()); | 362 elements.Add(element, zone()); |
360 } while (MatchSkipWhiteSpace(',')); | 363 } while (MatchSkipWhiteSpace(',')); |
361 if (c0_ != ']') { | 364 if (c0_ != ']') { |
362 return ReportUnexpectedCharacter(); | 365 return ReportUnexpectedCharacter(); |
363 } | 366 } |
364 } | 367 } |
365 AdvanceSkipWhitespace(); | 368 AdvanceSkipWhitespace(); |
366 // Allocate a fixed array with all the elements. | 369 // Allocate a fixed array with all the elements. |
367 Handle<FixedArray> fast_elements = | 370 Handle<FixedArray> fast_elements = |
368 factory()->NewFixedArray(elements.length()); | 371 factory()->NewFixedArray(elements.length(), tenure_); |
369 for (int i = 0, n = elements.length(); i < n; i++) { | 372 for (int i = 0, n = elements.length(); i < n; i++) { |
370 fast_elements->set(i, *elements[i]); | 373 fast_elements->set(i, *elements[i]); |
371 } | 374 } |
372 return factory()->NewJSArrayWithElements(fast_elements); | 375 return factory()->NewJSArrayWithElements( |
376 fast_elements, FAST_ELEMENTS, tenure_); | |
373 } | 377 } |
374 | 378 |
375 | 379 |
376 template <bool seq_ascii> | 380 template <bool seq_ascii> |
377 Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() { | 381 Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() { |
378 bool negative = false; | 382 bool negative = false; |
379 int beg_pos = position_; | 383 int beg_pos = position_; |
380 if (c0_ == '-') { | 384 if (c0_ == '-') { |
381 Advance(); | 385 Advance(); |
382 negative = true; | 386 negative = true; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 Vector<const char> result = | 433 Vector<const char> result = |
430 Vector<const char>(reinterpret_cast<const char*>(buffer.start()), | 434 Vector<const char>(reinterpret_cast<const char*>(buffer.start()), |
431 length); | 435 length); |
432 number = StringToDouble(isolate()->unicode_cache(), | 436 number = StringToDouble(isolate()->unicode_cache(), |
433 result, | 437 result, |
434 NO_FLAGS, // Hex, octal or trailing junk. | 438 NO_FLAGS, // Hex, octal or trailing junk. |
435 0.0); | 439 0.0); |
436 buffer.Dispose(); | 440 buffer.Dispose(); |
437 } | 441 } |
438 SkipWhitespace(); | 442 SkipWhitespace(); |
439 return factory()->NewNumber(number); | 443 return factory()->NewNumber(number, tenure_); |
440 } | 444 } |
441 | 445 |
442 | 446 |
443 template <typename StringType> | 447 template <typename StringType> |
444 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); | 448 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); |
445 | 449 |
446 template <> | 450 template <> |
447 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { | 451 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { |
448 seq_str->SeqTwoByteStringSet(i, c); | 452 seq_str->SeqTwoByteStringSet(i, c); |
449 } | 453 } |
450 | 454 |
451 template <> | 455 template <> |
452 inline void SeqStringSet(Handle<SeqAsciiString> seq_str, int i, uc32 c) { | 456 inline void SeqStringSet(Handle<SeqAsciiString> seq_str, int i, uc32 c) { |
453 seq_str->SeqAsciiStringSet(i, c); | 457 seq_str->SeqAsciiStringSet(i, c); |
454 } | 458 } |
455 | 459 |
456 template <typename StringType> | 460 template <typename StringType> |
457 inline Handle<StringType> NewRawString(Factory* factory, int length); | 461 inline Handle<StringType> NewRawString(Factory* factory, |
462 int length, | |
463 PretenureFlag tenure); | |
Michael Starzinger
2012/10/22 16:44:28
Call the third argument "pretenure".
Toon Verwaest
2012/10/23 08:05:57
Done.
| |
458 | 464 |
459 template <> | 465 template <> |
460 inline Handle<SeqTwoByteString> NewRawString(Factory* factory, int length) { | 466 inline Handle<SeqTwoByteString> NewRawString(Factory* factory, |
461 return factory->NewRawTwoByteString(length, NOT_TENURED); | 467 int length, |
468 PretenureFlag tenure) { | |
Michael Starzinger
2012/10/22 16:44:28
Likewise.
Toon Verwaest
2012/10/23 08:05:57
Done.
| |
469 return factory->NewRawTwoByteString(length, tenure); | |
462 } | 470 } |
463 | 471 |
464 template <> | 472 template <> |
465 inline Handle<SeqAsciiString> NewRawString(Factory* factory, int length) { | 473 inline Handle<SeqAsciiString> NewRawString(Factory* factory, |
466 return factory->NewRawAsciiString(length, NOT_TENURED); | 474 int length, |
475 PretenureFlag tenure) { | |
Michael Starzinger
2012/10/22 16:44:28
Likewise.
Toon Verwaest
2012/10/23 08:05:57
Done.
| |
476 return factory->NewRawAsciiString(length, tenure); | |
467 } | 477 } |
468 | 478 |
469 | 479 |
470 // Scans the rest of a JSON string starting from position_ and writes | 480 // Scans the rest of a JSON string starting from position_ and writes |
471 // prefix[start..end] along with the scanned characters into a | 481 // prefix[start..end] along with the scanned characters into a |
472 // sequential string of type StringType. | 482 // sequential string of type StringType. |
473 template <bool seq_ascii> | 483 template <bool seq_ascii> |
474 template <typename StringType, typename SinkChar> | 484 template <typename StringType, typename SinkChar> |
475 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString( | 485 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString( |
476 Handle<String> prefix, int start, int end) { | 486 Handle<String> prefix, int start, int end) { |
477 int count = end - start; | 487 int count = end - start; |
478 int max_length = count + source_length_ - position_; | 488 int max_length = count + source_length_ - position_; |
479 int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count)); | 489 int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count)); |
480 Handle<StringType> seq_str = NewRawString<StringType>(factory(), length); | 490 Handle<StringType> seq_str = |
491 NewRawString<StringType>(factory(), length, tenure_); | |
481 // Copy prefix into seq_str. | 492 // Copy prefix into seq_str. |
482 SinkChar* dest = seq_str->GetChars(); | 493 SinkChar* dest = seq_str->GetChars(); |
483 String::WriteToFlat(*prefix, dest, start, end); | 494 String::WriteToFlat(*prefix, dest, start, end); |
484 | 495 |
485 while (c0_ != '"') { | 496 while (c0_ != '"') { |
486 // Check for control character (0x00-0x1f) or unterminated string (<0). | 497 // Check for control character (0x00-0x1f) or unterminated string (<0). |
487 if (c0_ < 0x20) return Handle<String>::null(); | 498 if (c0_ < 0x20) return Handle<String>::null(); |
488 if (count >= length) { | 499 if (count >= length) { |
489 // We need to create a longer sequential string for the result. | 500 // We need to create a longer sequential string for the result. |
490 return SlowScanJsonString<StringType, SinkChar>(seq_str, 0, count); | 501 return SlowScanJsonString<StringType, SinkChar>(seq_str, 0, count); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
649 } else { | 660 } else { |
650 return SlowScanJsonString<SeqAsciiString, char>(source_, | 661 return SlowScanJsonString<SeqAsciiString, char>(source_, |
651 beg_pos, | 662 beg_pos, |
652 position_); | 663 position_); |
653 } | 664 } |
654 } while (c0_ != '"'); | 665 } while (c0_ != '"'); |
655 int length = position_ - beg_pos; | 666 int length = position_ - beg_pos; |
656 Handle<String> result; | 667 Handle<String> result; |
657 if (seq_ascii && is_symbol) { | 668 if (seq_ascii && is_symbol) { |
658 result = factory()->LookupAsciiSymbol(seq_source_, | 669 result = factory()->LookupAsciiSymbol(seq_source_, |
659 beg_pos, | 670 beg_pos, |
Michael Starzinger
2012/10/22 16:44:28
Indentation seems off.
Toon Verwaest
2012/10/23 08:05:57
Seems fine here.
On 2012/10/22 16:44:28, Michael
| |
660 length); | 671 length); |
661 } else { | 672 } else { |
662 result = factory()->NewRawAsciiString(length); | 673 result = factory()->NewRawAsciiString(length, tenure_); |
663 char* dest = SeqAsciiString::cast(*result)->GetChars(); | 674 char* dest = SeqAsciiString::cast(*result)->GetChars(); |
664 String::WriteToFlat(*source_, dest, beg_pos, position_); | 675 String::WriteToFlat(*source_, dest, beg_pos, position_); |
665 } | 676 } |
666 ASSERT_EQ('"', c0_); | 677 ASSERT_EQ('"', c0_); |
667 // Advance past the last '"'. | 678 // Advance past the last '"'. |
668 AdvanceSkipWhitespace(); | 679 AdvanceSkipWhitespace(); |
669 return result; | 680 return result; |
670 } | 681 } |
671 | 682 |
672 } } // namespace v8::internal | 683 } } // namespace v8::internal |
673 | 684 |
674 #endif // V8_JSON_PARSER_H_ | 685 #endif // V8_JSON_PARSER_H_ |
OLD | NEW |