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

Side by Side Diff: src/json-parser.h

Issue 12440061: Improve SeqString::Truncate for latest allocated strings. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: renamed according to suggestion Created 7 years, 9 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
« no previous file with comments | « no previous file | src/json-stringifier.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 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 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 // Scans the rest of a JSON string starting from position_ and writes 494 // Scans the rest of a JSON string starting from position_ and writes
495 // prefix[start..end] along with the scanned characters into a 495 // prefix[start..end] along with the scanned characters into a
496 // sequential string of type StringType. 496 // sequential string of type StringType.
497 template <bool seq_ascii> 497 template <bool seq_ascii>
498 template <typename StringType, typename SinkChar> 498 template <typename StringType, typename SinkChar>
499 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString( 499 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString(
500 Handle<String> prefix, int start, int end) { 500 Handle<String> prefix, int start, int end) {
501 int count = end - start; 501 int count = end - start;
502 int max_length = count + source_length_ - position_; 502 int max_length = count + source_length_ - position_;
503 int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count)); 503 int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
504 Handle<StringType> seq_str = 504 Handle<StringType> seq_string =
505 NewRawString<StringType>(factory(), length, pretenure_); 505 NewRawString<StringType>(factory(), length, pretenure_);
506 // Copy prefix into seq_str. 506 // Copy prefix into seq_str.
507 SinkChar* dest = seq_str->GetChars(); 507 SinkChar* dest = seq_string->GetChars();
508 String::WriteToFlat(*prefix, dest, start, end); 508 String::WriteToFlat(*prefix, dest, start, end);
509 509
510 while (c0_ != '"') { 510 while (c0_ != '"') {
511 // Check for control character (0x00-0x1f) or unterminated string (<0). 511 // Check for control character (0x00-0x1f) or unterminated string (<0).
512 if (c0_ < 0x20) return Handle<String>::null(); 512 if (c0_ < 0x20) return Handle<String>::null();
513 if (count >= length) { 513 if (count >= length) {
514 // We need to create a longer sequential string for the result. 514 // We need to create a longer sequential string for the result.
515 return SlowScanJsonString<StringType, SinkChar>(seq_str, 0, count); 515 return SlowScanJsonString<StringType, SinkChar>(seq_string, 0, count);
516 } 516 }
517 if (c0_ != '\\') { 517 if (c0_ != '\\') {
518 // If the sink can contain UC16 characters, or source_ contains only 518 // If the sink can contain UC16 characters, or source_ contains only
519 // ASCII characters, there's no need to test whether we can store the 519 // ASCII characters, there's no need to test whether we can store the
520 // character. Otherwise check whether the UC16 source character can fit 520 // character. Otherwise check whether the UC16 source character can fit
521 // in the ASCII sink. 521 // in the ASCII sink.
522 if (sizeof(SinkChar) == kUC16Size || 522 if (sizeof(SinkChar) == kUC16Size ||
523 seq_ascii || 523 seq_ascii ||
524 c0_ <= String::kMaxOneByteCharCode) { 524 c0_ <= String::kMaxOneByteCharCode) {
525 SeqStringSet(seq_str, count++, c0_); 525 SeqStringSet(seq_string, count++, c0_);
526 Advance(); 526 Advance();
527 } else { 527 } else {
528 // StringType is SeqOneByteString and we just read a non-ASCII char. 528 // StringType is SeqOneByteString and we just read a non-ASCII char.
529 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 0, count); 529 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 0, count);
530 } 530 }
531 } else { 531 } else {
532 Advance(); // Advance past the \. 532 Advance(); // Advance past the \.
533 switch (c0_) { 533 switch (c0_) {
534 case '"': 534 case '"':
535 case '\\': 535 case '\\':
536 case '/': 536 case '/':
537 SeqStringSet(seq_str, count++, c0_); 537 SeqStringSet(seq_string, count++, c0_);
538 break; 538 break;
539 case 'b': 539 case 'b':
540 SeqStringSet(seq_str, count++, '\x08'); 540 SeqStringSet(seq_string, count++, '\x08');
541 break; 541 break;
542 case 'f': 542 case 'f':
543 SeqStringSet(seq_str, count++, '\x0c'); 543 SeqStringSet(seq_string, count++, '\x0c');
544 break; 544 break;
545 case 'n': 545 case 'n':
546 SeqStringSet(seq_str, count++, '\x0a'); 546 SeqStringSet(seq_string, count++, '\x0a');
547 break; 547 break;
548 case 'r': 548 case 'r':
549 SeqStringSet(seq_str, count++, '\x0d'); 549 SeqStringSet(seq_string, count++, '\x0d');
550 break; 550 break;
551 case 't': 551 case 't':
552 SeqStringSet(seq_str, count++, '\x09'); 552 SeqStringSet(seq_string, count++, '\x09');
553 break; 553 break;
554 case 'u': { 554 case 'u': {
555 uc32 value = 0; 555 uc32 value = 0;
556 for (int i = 0; i < 4; i++) { 556 for (int i = 0; i < 4; i++) {
557 Advance(); 557 Advance();
558 int digit = HexValue(c0_); 558 int digit = HexValue(c0_);
559 if (digit < 0) { 559 if (digit < 0) {
560 return Handle<String>::null(); 560 return Handle<String>::null();
561 } 561 }
562 value = value * 16 + digit; 562 value = value * 16 + digit;
563 } 563 }
564 if (sizeof(SinkChar) == kUC16Size || 564 if (sizeof(SinkChar) == kUC16Size ||
565 value <= String::kMaxOneByteCharCode) { 565 value <= String::kMaxOneByteCharCode) {
566 SeqStringSet(seq_str, count++, value); 566 SeqStringSet(seq_string, count++, value);
567 break; 567 break;
568 } else { 568 } else {
569 // StringType is SeqOneByteString and we just read a non-ASCII char. 569 // StringType is SeqOneByteString and we just read a non-ASCII char.
570 position_ -= 6; // Rewind position_ to \ in \uxxxx. 570 position_ -= 6; // Rewind position_ to \ in \uxxxx.
571 Advance(); 571 Advance();
572 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 572 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string,
573 0, 573 0,
574 count); 574 count);
575 } 575 }
576 } 576 }
577 default: 577 default:
578 return Handle<String>::null(); 578 return Handle<String>::null();
579 } 579 }
580 Advance(); 580 Advance();
581 } 581 }
582 } 582 }
583 // Shrink seq_string length to count. 583
584 if (isolate()->heap()->InNewSpace(*seq_str)) {
585 isolate()->heap()->new_space()->
586 template ShrinkStringAtAllocationBoundary<StringType>(
587 *seq_str, count);
588 } else {
589 int string_size = StringType::SizeFor(count);
590 int allocated_string_size = StringType::SizeFor(length);
591 int delta = allocated_string_size - string_size;
592 Address start_filler_object = seq_str->address() + string_size;
593 seq_str->set_length(count);
594 isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta);
595 }
596 ASSERT_EQ('"', c0_); 584 ASSERT_EQ('"', c0_);
597 // Advance past the last '"'. 585 // Advance past the last '"'.
598 AdvanceSkipWhitespace(); 586 AdvanceSkipWhitespace();
599 return seq_str; 587
588 // Shrink seq_string length to count and return.
589 return SeqString::Truncate(seq_string, count);
600 } 590 }
601 591
602 592
603 template <bool seq_ascii> 593 template <bool seq_ascii>
604 template <bool is_internalized> 594 template <bool is_internalized>
605 Handle<String> JsonParser<seq_ascii>::ScanJsonString() { 595 Handle<String> JsonParser<seq_ascii>::ScanJsonString() {
606 ASSERT_EQ('"', c0_); 596 ASSERT_EQ('"', c0_);
607 Advance(); 597 Advance();
608 if (c0_ == '"') { 598 if (c0_ == '"') {
609 AdvanceSkipWhitespace(); 599 AdvanceSkipWhitespace();
610 return factory()->empty_string(); 600 return factory()->empty_string();
611 } 601 }
612 602
613 if (seq_ascii && is_internalized) { 603 if (seq_ascii && is_internalized) {
614 // Fast path for existing internalized strings. If the the string being 604 // Fast path for existing internalized strings. If the the string being
615 // parsed is not a known internalized string, contains backslashes or 605 // parsed is not a known internalized string, contains backslashes or
616 // unexpectedly reaches the end of string, return with an empty handle. 606 // unexpectedly reaches the end of string, return with an empty handle.
617 uint32_t running_hash = isolate()->heap()->HashSeed(); 607 uint32_t running_hash = isolate()->heap()->HashSeed();
618 int position = position_; 608 int position = position_;
619 uc32 c0 = c0_; 609 uc32 c0 = c0_;
620 do { 610 do {
621 if (c0 == '\\') { 611 if (c0 == '\\') {
622 c0_ = c0; 612 c0_ = c0;
623 int beg_pos = position_; 613 int beg_pos = position_;
624 position_ = position; 614 position_ = position;
625 return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, 615 return SlowScanJsonString<SeqOneByteString, uint8_t>(source_,
626 beg_pos, 616 beg_pos,
627 position_); 617 position_);
628 } 618 }
629 if (c0 < 0x20) return Handle<String>::null(); 619 if (c0 < 0x20) return Handle<String>::null();
630 if (static_cast<uint32_t>(c0) > 620 if (static_cast<uint32_t>(c0) >
631 unibrow::Utf16::kMaxNonSurrogateCharCode) { 621 unibrow::Utf16::kMaxNonSurrogateCharCode) {
632 running_hash = 622 running_hash =
633 StringHasher::AddCharacterCore(running_hash, 623 StringHasher::AddCharacterCore(running_hash,
634 unibrow::Utf16::LeadSurrogate(c0)); 624 unibrow::Utf16::LeadSurrogate(c0));
635 running_hash = 625 running_hash =
636 StringHasher::AddCharacterCore(running_hash, 626 StringHasher::AddCharacterCore(running_hash,
637 unibrow::Utf16::TrailSurrogate(c0)); 627 unibrow::Utf16::TrailSurrogate(c0));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 } 689 }
700 ASSERT_EQ('"', c0_); 690 ASSERT_EQ('"', c0_);
701 // Advance past the last '"'. 691 // Advance past the last '"'.
702 AdvanceSkipWhitespace(); 692 AdvanceSkipWhitespace();
703 return result; 693 return result;
704 } 694 }
705 695
706 } } // namespace v8::internal 696 } } // namespace v8::internal
707 697
708 #endif // V8_JSON_PARSER_H_ 698 #endif // V8_JSON_PARSER_H_
OLDNEW
« no previous file with comments | « no previous file | src/json-stringifier.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698