Chromium Code Reviews| 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 |