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

Side by Side Diff: src/runtime.cc

Issue 6335004: Optimize JSON stringify by allowing QuoteJSONString to prefix with a comma. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 11 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
« src/json.js ('K') | « src/runtime.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 4603 matching lines...) Expand 10 before | Expand all | Expand 10 after
4614 return Heap::AllocateRawTwoByteString(length); 4614 return Heap::AllocateRawTwoByteString(length);
4615 } 4615 }
4616 4616
4617 4617
4618 template <> 4618 template <>
4619 MaybeObject* AllocateRawString<SeqAsciiString>(int length) { 4619 MaybeObject* AllocateRawString<SeqAsciiString>(int length) {
4620 return Heap::AllocateRawAsciiString(length); 4620 return Heap::AllocateRawAsciiString(length);
4621 } 4621 }
4622 4622
4623 4623
4624 template <typename Char, typename StringType> 4624 template <typename Char, typename StringType, bool comma>
4625 static MaybeObject* SlowQuoteJsonString(Vector<const Char> characters) { 4625 static MaybeObject* SlowQuoteJsonString(Vector<const Char> characters) {
Erik Corry 2011/01/14 14:42:57 I think it would be nice to know what the performa
sandholm 2011/01/16 21:08:43 Having this as a normal argument makes the change
4626 int length = characters.length(); 4626 int length = characters.length();
4627 const Char* read_cursor = characters.start(); 4627 const Char* read_cursor = characters.start();
4628 const Char* end = read_cursor + length; 4628 const Char* end = read_cursor + length;
4629 const int kSpaceForQuotes = 2; 4629 const int kSpaceForQuotes = 2 + (comma ? 1 :0);
4630 int quoted_length = kSpaceForQuotes; 4630 int quoted_length = kSpaceForQuotes;
4631 while (read_cursor < end) { 4631 while (read_cursor < end) {
4632 Char c = *(read_cursor++); 4632 Char c = *(read_cursor++);
4633 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) { 4633 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
4634 quoted_length++; 4634 quoted_length++;
4635 } else { 4635 } else {
4636 quoted_length += JsonQuoteLengths[static_cast<unsigned>(c)]; 4636 quoted_length += JsonQuoteLengths[static_cast<unsigned>(c)];
4637 } 4637 }
4638 } 4638 }
4639 MaybeObject* new_alloc = AllocateRawString<StringType>(quoted_length); 4639 MaybeObject* new_alloc = AllocateRawString<StringType>(quoted_length);
4640 Object* new_object; 4640 Object* new_object;
4641 if (!new_alloc->ToObject(&new_object)) { 4641 if (!new_alloc->ToObject(&new_object)) {
4642 return new_alloc; 4642 return new_alloc;
4643 } 4643 }
4644 StringType* new_string = StringType::cast(new_object); 4644 StringType* new_string = StringType::cast(new_object);
4645 4645
4646 Char* write_cursor = reinterpret_cast<Char*>( 4646 Char* write_cursor = reinterpret_cast<Char*>(
4647 new_string->address() + SeqAsciiString::kHeaderSize); 4647 new_string->address() + SeqAsciiString::kHeaderSize);
4648 if (comma) *(write_cursor++) = ',';
4648 *(write_cursor++) = '"'; 4649 *(write_cursor++) = '"';
4649 4650
4650 read_cursor = characters.start(); 4651 read_cursor = characters.start();
4651 while (read_cursor < end) { 4652 while (read_cursor < end) {
4652 Char c = *(read_cursor++); 4653 Char c = *(read_cursor++);
4653 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) { 4654 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
4654 *(write_cursor++) = c; 4655 *(write_cursor++) = c;
4655 } else { 4656 } else {
4656 int len = JsonQuoteLengths[static_cast<unsigned>(c)]; 4657 int len = JsonQuoteLengths[static_cast<unsigned>(c)];
4657 const char* replacement = JsonQuotes + 4658 const char* replacement = JsonQuotes +
4658 static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry; 4659 static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
4659 for (int i = 0; i < len; i++) { 4660 for (int i = 0; i < len; i++) {
4660 *write_cursor++ = *replacement++; 4661 *write_cursor++ = *replacement++;
4661 } 4662 }
4662 } 4663 }
4663 } 4664 }
4664 *(write_cursor++) = '"'; 4665 *(write_cursor++) = '"';
4665 return new_string; 4666 return new_string;
4666 } 4667 }
4667 4668
4668 4669
4669 template <typename Char, typename StringType> 4670 template <typename Char, typename StringType, bool comma>
4670 static MaybeObject* QuoteJsonString(Vector<const Char> characters) { 4671 static MaybeObject* QuoteJsonString(Vector<const Char> characters) {
4671 int length = characters.length(); 4672 int length = characters.length();
4672 Counters::quote_json_char_count.Increment(length); 4673 Counters::quote_json_char_count.Increment(length);
4673 const int kSpaceForQuotes = 2; 4674 const int kSpaceForQuotes = 2 + (comma ? 1 :0);
4674 int worst_case_length = length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; 4675 int worst_case_length = length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes;
4675 if (worst_case_length > kMaxGuaranteedNewSpaceString) { 4676 if (worst_case_length > kMaxGuaranteedNewSpaceString) {
4676 return SlowQuoteJsonString<Char, StringType>(characters); 4677 return SlowQuoteJsonString<Char, StringType, comma>(characters);
4677 } 4678 }
4678 4679
4679 MaybeObject* new_alloc = AllocateRawString<StringType>(worst_case_length); 4680 MaybeObject* new_alloc = AllocateRawString<StringType>(worst_case_length);
4680 Object* new_object; 4681 Object* new_object;
4681 if (!new_alloc->ToObject(&new_object)) { 4682 if (!new_alloc->ToObject(&new_object)) {
4682 return new_alloc; 4683 return new_alloc;
4683 } 4684 }
4684 if (!Heap::new_space()->Contains(new_object)) { 4685 if (!Heap::new_space()->Contains(new_object)) {
4685 // Even if our string is small enough to fit in new space we still have to 4686 // Even if our string is small enough to fit in new space we still have to
4686 // handle it being allocated in old space as may happen in the third 4687 // handle it being allocated in old space as may happen in the third
4687 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in 4688 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in
4688 // CEntryStub::GenerateCore. 4689 // CEntryStub::GenerateCore.
4689 return SlowQuoteJsonString<Char, StringType>(characters); 4690 return SlowQuoteJsonString<Char, StringType, comma>(characters);
4690 } 4691 }
4691 StringType* new_string = StringType::cast(new_object); 4692 StringType* new_string = StringType::cast(new_object);
4692 ASSERT(Heap::new_space()->Contains(new_string)); 4693 ASSERT(Heap::new_space()->Contains(new_string));
4693 4694
4694 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); 4695 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
4695 Char* write_cursor = reinterpret_cast<Char*>( 4696 Char* write_cursor = reinterpret_cast<Char*>(
4696 new_string->address() + SeqAsciiString::kHeaderSize); 4697 new_string->address() + SeqAsciiString::kHeaderSize);
4698 if (comma) *(write_cursor++) = ',';
4697 *(write_cursor++) = '"'; 4699 *(write_cursor++) = '"';
4698 4700
4699 const Char* read_cursor = characters.start(); 4701 const Char* read_cursor = characters.start();
4700 const Char* end = read_cursor + length; 4702 const Char* end = read_cursor + length;
4701 while (read_cursor < end) { 4703 while (read_cursor < end) {
4702 Char c = *(read_cursor++); 4704 Char c = *(read_cursor++);
4703 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) { 4705 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
4704 *(write_cursor++) = c; 4706 *(write_cursor++) = c;
4705 } else { 4707 } else {
4706 int len = JsonQuoteLengths[static_cast<unsigned>(c)]; 4708 int len = JsonQuoteLengths[static_cast<unsigned>(c)];
(...skipping 30 matching lines...) Expand all
4737 if (!str->IsFlat()) { 4739 if (!str->IsFlat()) {
4738 MaybeObject* try_flatten = str->TryFlatten(); 4740 MaybeObject* try_flatten = str->TryFlatten();
4739 Object* flat; 4741 Object* flat;
4740 if (!try_flatten->ToObject(&flat)) { 4742 if (!try_flatten->ToObject(&flat)) {
4741 return try_flatten; 4743 return try_flatten;
4742 } 4744 }
4743 str = String::cast(flat); 4745 str = String::cast(flat);
4744 ASSERT(str->IsFlat()); 4746 ASSERT(str->IsFlat());
4745 } 4747 }
4746 if (str->IsTwoByteRepresentation()) { 4748 if (str->IsTwoByteRepresentation()) {
4747 return QuoteJsonString<uc16, SeqTwoByteString>(str->ToUC16Vector()); 4749 return QuoteJsonString<uc16, SeqTwoByteString, false>(str->ToUC16Vector());
4748 } else { 4750 } else {
4749 return QuoteJsonString<char, SeqAsciiString>(str->ToAsciiVector()); 4751 return QuoteJsonString<char, SeqAsciiString, false>(str->ToAsciiVector());
4750 } 4752 }
4751 } 4753 }
4752 4754
4753 4755
4756 static MaybeObject* Runtime_QuoteJSONStringComma(Arguments args) {
4757 NoHandleAllocation ha;
4758 CONVERT_CHECKED(String, str, args[0]);
4759 if (!str->IsFlat()) {
4760 MaybeObject* try_flatten = str->TryFlatten();
4761 Object* flat;
4762 if (!try_flatten->ToObject(&flat)) {
4763 return try_flatten;
4764 }
4765 str = String::cast(flat);
4766 ASSERT(str->IsFlat());
4767 }
4768 if (str->IsTwoByteRepresentation()) {
4769 return QuoteJsonString<uc16, SeqTwoByteString, true>(str->ToUC16Vector());
4770 } else {
4771 return QuoteJsonString<char, SeqAsciiString, true>(str->ToAsciiVector());
4772 }
4773 }
4774
4754 4775
4755 static MaybeObject* Runtime_StringParseInt(Arguments args) { 4776 static MaybeObject* Runtime_StringParseInt(Arguments args) {
4756 NoHandleAllocation ha; 4777 NoHandleAllocation ha;
4757 4778
4758 CONVERT_CHECKED(String, s, args[0]); 4779 CONVERT_CHECKED(String, s, args[0]);
4759 CONVERT_SMI_CHECKED(radix, args[1]); 4780 CONVERT_SMI_CHECKED(radix, args[1]);
4760 4781
4761 s->TryFlatten(); 4782 s->TryFlatten();
4762 4783
4763 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); 4784 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
(...skipping 6065 matching lines...) Expand 10 before | Expand all | Expand 10 after
10829 } else { 10850 } else {
10830 // Handle last resort GC and make sure to allow future allocations 10851 // Handle last resort GC and make sure to allow future allocations
10831 // to grow the heap without causing GCs (if possible). 10852 // to grow the heap without causing GCs (if possible).
10832 Counters::gc_last_resort_from_js.Increment(); 10853 Counters::gc_last_resort_from_js.Increment();
10833 Heap::CollectAllGarbage(false); 10854 Heap::CollectAllGarbage(false);
10834 } 10855 }
10835 } 10856 }
10836 10857
10837 10858
10838 } } // namespace v8::internal 10859 } } // namespace v8::internal
OLDNEW
« src/json.js ('K') | « src/runtime.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698