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 5777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5788 SeqTwoByteString* answer = SeqTwoByteString::cast(object); | 5788 SeqTwoByteString* answer = SeqTwoByteString::cast(object); |
5789 StringBuilderConcatHelper(special, | 5789 StringBuilderConcatHelper(special, |
5790 answer->GetChars(), | 5790 answer->GetChars(), |
5791 fixed_array, | 5791 fixed_array, |
5792 array_length); | 5792 array_length); |
5793 return answer; | 5793 return answer; |
5794 } | 5794 } |
5795 } | 5795 } |
5796 | 5796 |
5797 | 5797 |
5798 template <typename sinkchar> | |
5799 static inline void StringBuilderJoinHelper(String* separator, | |
5800 sinkchar* sink, | |
5801 FixedArray* fixed_array, | |
5802 int array_length) { | |
5803 ASSERT(array_length > 0); | |
5804 String* s = String::cast(fixed_array->get(0)); | |
5805 int position = s->length(); | |
5806 String::WriteToFlat(s, sink, 0, position); | |
5807 | |
5808 int separator_length = separator->length(); | |
5809 | |
5810 for (int i = 1; i < array_length; i++) { | |
5811 String::WriteToFlat(separator, sink + position, 0, separator_length); | |
5812 position += separator_length; | |
5813 | |
5814 String* element = String::cast(fixed_array->get(i)); | |
5815 int element_length = element->length(); | |
5816 String::WriteToFlat(element, sink + position, 0, element_length); | |
5817 position += element_length; | |
5818 } | |
5819 } | |
5820 | |
5821 | |
5822 static MaybeObject* Runtime_StringBuilderJoin(Arguments args) { | |
5823 NoHandleAllocation ha; | |
5824 ASSERT(args.length() == 3); | |
5825 CONVERT_CHECKED(JSArray, array, args[0]); | |
5826 if (!args[1]->IsSmi()) { | |
5827 Top::context()->mark_out_of_memory(); | |
5828 return Failure::OutOfMemoryException(); | |
5829 } | |
5830 int array_length = Smi::cast(args[1])->value(); | |
5831 CONVERT_CHECKED(String, separator, args[2]); | |
5832 | |
5833 if (!array->HasFastElements()) { | |
5834 return Top::Throw(Heap::illegal_argument_symbol()); | |
5835 } | |
5836 FixedArray* fixed_array = FixedArray::cast(array->elements()); | |
5837 if (fixed_array->length() < array_length) { | |
5838 array_length = fixed_array->length(); | |
5839 } | |
5840 | |
5841 if (array_length == 0) { | |
5842 return Heap::empty_string(); | |
5843 } else if (array_length == 1) { | |
5844 Object* first = fixed_array->get(0); | |
5845 if (first->IsString()) return first; | |
5846 } | |
5847 | |
5848 int separator_length = separator->length(); | |
5849 int max_nof_separators = | |
5850 (String::kMaxLength + separator_length - 1) / separator_length; | |
5851 if (max_nof_separators < (array_length - 1)) { | |
5852 Top::context()->mark_out_of_memory(); | |
5853 return Failure::OutOfMemoryException(); | |
5854 } | |
5855 int position = (array_length - 1) * separator_length; | |
5856 bool ascii = separator->HasOnlyAsciiChars(); | |
sandholm
2011/02/14 15:23:04
You will always need a TwoByteString.
If everythin
| |
5857 for (int i = 0; i < array_length; i++) { | |
5858 int increment = 0; | |
5859 String* element = String::cast(fixed_array->get(i)); | |
5860 int element_length = element->length(); | |
5861 increment = element_length; | |
5862 if (ascii && !element->HasOnlyAsciiChars()) { | |
5863 ascii = false; | |
5864 } | |
5865 if (increment > String::kMaxLength - position) { | |
5866 Top::context()->mark_out_of_memory(); | |
5867 return Failure::OutOfMemoryException(); | |
5868 } | |
5869 position += increment; | |
5870 } | |
5871 | |
5872 int length = position; | |
5873 Object* object; | |
5874 | |
5875 if (ascii) { | |
5876 { MaybeObject* maybe_object = Heap::AllocateRawAsciiString(length); | |
5877 if (!maybe_object->ToObject(&object)) return maybe_object; | |
5878 } | |
5879 SeqAsciiString* answer = SeqAsciiString::cast(object); | |
5880 StringBuilderJoinHelper(separator, | |
5881 answer->GetChars(), | |
5882 fixed_array, | |
5883 array_length); | |
5884 return answer; | |
5885 } else { | |
5886 { MaybeObject* maybe_object = Heap::AllocateRawTwoByteString(length); | |
5887 if (!maybe_object->ToObject(&object)) return maybe_object; | |
5888 } | |
5889 SeqTwoByteString* answer = SeqTwoByteString::cast(object); | |
5890 StringBuilderJoinHelper(separator, | |
5891 answer->GetChars(), | |
5892 fixed_array, | |
5893 array_length); | |
5894 return answer; | |
5895 } | |
5896 } | |
5897 | |
5898 | |
5798 static MaybeObject* Runtime_NumberOr(Arguments args) { | 5899 static MaybeObject* Runtime_NumberOr(Arguments args) { |
5799 NoHandleAllocation ha; | 5900 NoHandleAllocation ha; |
5800 ASSERT(args.length() == 2); | 5901 ASSERT(args.length() == 2); |
5801 | 5902 |
5802 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5903 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
5803 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5904 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
5804 return Heap::NumberFromInt32(x | y); | 5905 return Heap::NumberFromInt32(x | y); |
5805 } | 5906 } |
5806 | 5907 |
5807 | 5908 |
(...skipping 5290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11098 } else { | 11199 } else { |
11099 // Handle last resort GC and make sure to allow future allocations | 11200 // Handle last resort GC and make sure to allow future allocations |
11100 // to grow the heap without causing GCs (if possible). | 11201 // to grow the heap without causing GCs (if possible). |
11101 Counters::gc_last_resort_from_js.Increment(); | 11202 Counters::gc_last_resort_from_js.Increment(); |
11102 Heap::CollectAllGarbage(false); | 11203 Heap::CollectAllGarbage(false); |
11103 } | 11204 } |
11104 } | 11205 } |
11105 | 11206 |
11106 | 11207 |
11107 } } // namespace v8::internal | 11208 } } // namespace v8::internal |
OLD | NEW |