OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |