| OLD | NEW |
| 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 5705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5716 if (index < 0) return; | 5716 if (index < 0) return; |
| 5717 indices->Add(index); | 5717 indices->Add(index); |
| 5718 index += pattern_length; | 5718 index += pattern_length; |
| 5719 limit--; | 5719 limit--; |
| 5720 } | 5720 } |
| 5721 } | 5721 } |
| 5722 | 5722 |
| 5723 | 5723 |
| 5724 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) { | 5724 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) { |
| 5725 ASSERT(args.length() == 3); | 5725 ASSERT(args.length() == 3); |
| 5726 HandleScope handle_scope(isolate); | 5726 CONVERT_CHECKED(String, subject, args[0]); |
| 5727 CONVERT_ARG_CHECKED(String, subject, 0); | 5727 CONVERT_CHECKED(String, pattern, args[1]); |
| 5728 CONVERT_ARG_CHECKED(String, pattern, 1); | |
| 5729 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); | 5728 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); |
| 5730 | 5729 |
| 5731 int subject_length = subject->length(); | 5730 int subject_length = subject->length(); |
| 5732 int pattern_length = pattern->length(); | 5731 int pattern_length = pattern->length(); |
| 5733 RUNTIME_ASSERT(pattern_length > 0); | 5732 RUNTIME_ASSERT(pattern_length > 0); |
| 5734 | 5733 |
| 5735 // The limit can be very large (0xffffffffu), but since the pattern | 5734 // The limit can be very large (0xffffffffu), but since the pattern |
| 5736 // isn't empty, we can never create more parts than ~half the length | 5735 // isn't empty, we can never create more parts than ~half the length |
| 5737 // of the subject. | 5736 // of the subject. |
| 5738 | 5737 |
| 5739 if (!subject->IsFlat()) FlattenString(subject); | 5738 if (!subject->IsFlat()) { |
| 5740 | 5739 Object* flat; |
| 5740 { MaybeObject* maybe_flat = subject->TryFlatten(); |
| 5741 if (!maybe_flat->ToObject(&flat)) return maybe_flat; |
| 5742 } |
| 5743 subject = String::cast(flat); |
| 5744 } |
| 5741 static const int kMaxInitialListCapacity = 16; | 5745 static const int kMaxInitialListCapacity = 16; |
| 5742 | 5746 |
| 5743 ZoneScope scope(isolate, DELETE_ON_EXIT); | 5747 ZoneScope scope(isolate, DELETE_ON_EXIT); |
| 5744 | 5748 |
| 5745 // Find (up to limit) indices of separator and end-of-string in subject | 5749 // Find (up to limit) indices of separator and end-of-string in subject |
| 5746 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); | 5750 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); |
| 5747 ZoneList<int> indices(initial_capacity); | 5751 ZoneList<int> indices(initial_capacity); |
| 5748 if (!pattern->IsFlat()) FlattenString(pattern); | 5752 if (!pattern->IsFlat()) { |
| 5753 Object* flat; |
| 5754 { MaybeObject* maybe_flat = pattern->TryFlatten(); |
| 5755 if (!maybe_flat->ToObject(&flat)) return maybe_flat; |
| 5756 } |
| 5757 pattern = String::cast(flat); |
| 5758 } |
| 5749 | 5759 |
| 5750 // No allocation block. | 5760 // No allocation block. |
| 5751 { | 5761 { |
| 5752 AssertNoAllocation nogc; | 5762 AssertNoAllocation nogc; |
| 5753 if (subject->IsAsciiRepresentation()) { | 5763 if (subject->IsAsciiRepresentation()) { |
| 5754 Vector<const char> subject_vector = subject->ToAsciiVector(); | 5764 Vector<const char> subject_vector = subject->ToAsciiVector(); |
| 5755 if (pattern->IsAsciiRepresentation()) { | 5765 if (pattern->IsAsciiRepresentation()) { |
| 5756 FindStringIndices(isolate, | 5766 FindStringIndices(isolate, |
| 5757 subject_vector, | 5767 subject_vector, |
| 5758 pattern->ToAsciiVector(), | 5768 pattern->ToAsciiVector(), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 5784 } | 5794 } |
| 5785 | 5795 |
| 5786 if (static_cast<uint32_t>(indices.length()) < limit) { | 5796 if (static_cast<uint32_t>(indices.length()) < limit) { |
| 5787 indices.Add(subject_length); | 5797 indices.Add(subject_length); |
| 5788 } | 5798 } |
| 5789 | 5799 |
| 5790 // The list indices now contains the end of each part to create. | 5800 // The list indices now contains the end of each part to create. |
| 5791 | 5801 |
| 5792 // Create JSArray of substrings separated by separator. | 5802 // Create JSArray of substrings separated by separator. |
| 5793 int part_count = indices.length(); | 5803 int part_count = indices.length(); |
| 5794 | 5804 Object* result; |
| 5795 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); | 5805 { MaybeObject* maybe_result = |
| 5796 result->set_length(Smi::FromInt(part_count)); | 5806 isolate->heap()->AllocateFixedArray(part_count); |
| 5797 | 5807 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 5798 ASSERT(result->HasFastElements()); | 5808 } |
| 5809 FixedArray* elements = FixedArray::cast(result); |
| 5799 | 5810 |
| 5800 if (part_count == 1 && indices.at(0) == subject_length) { | 5811 if (part_count == 1 && indices.at(0) == subject_length) { |
| 5801 FixedArray::cast(result->elements())->set(0, *subject); | 5812 elements->set(0, subject); |
| 5802 return *result; | 5813 } else { |
| 5814 int part_start = 0; |
| 5815 for (int i = 0; i < part_count; i++) { |
| 5816 int part_end = indices.at(i); |
| 5817 Object* result; |
| 5818 { MaybeObject* maybe_result = |
| 5819 isolate->heap()->AllocateSubString(subject, part_start, part_end); |
| 5820 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 5821 } |
| 5822 elements->set(i, result); |
| 5823 part_start = part_end + pattern_length; |
| 5824 } |
| 5803 } | 5825 } |
| 5804 | 5826 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
| 5805 Handle<FixedArray> elements(FixedArray::cast(result->elements())); | 5827 isolate->context()->global_context()->array_function()); |
| 5806 int part_start = 0; | 5828 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 5807 for (int i = 0; i < part_count; i++) { | |
| 5808 HandleScope local_loop_handle; | |
| 5809 int part_end = indices.at(i); | |
| 5810 Handle<String> substring = | |
| 5811 isolate->factory()->NewSubString(subject, part_start, part_end); | |
| 5812 elements->set(i, *substring); | |
| 5813 part_start = part_end + pattern_length; | |
| 5814 } | 5829 } |
| 5815 | 5830 JSArray* array = JSArray::cast(result); |
| 5816 return *result; | 5831 array->SetContent(elements); |
| 5832 ASSERT(array->HasFastElements()); |
| 5833 return array; |
| 5817 } | 5834 } |
| 5818 | 5835 |
| 5819 | 5836 |
| 5820 // Copies ascii characters to the given fixed array looking up | 5837 // Copies ascii characters to the given fixed array looking up |
| 5821 // one-char strings in the cache. Gives up on the first char that is | 5838 // one-char strings in the cache. Gives up on the first char that is |
| 5822 // not in the cache and fills the remainder with smi zeros. Returns | 5839 // not in the cache and fills the remainder with smi zeros. Returns |
| 5823 // the length of the successfully copied prefix. | 5840 // the length of the successfully copied prefix. |
| 5824 static int CopyCachedAsciiCharsToArray(Heap* heap, | 5841 static int CopyCachedAsciiCharsToArray(Heap* heap, |
| 5825 const char* chars, | 5842 const char* chars, |
| 5826 FixedArray* elements, | 5843 FixedArray* elements, |
| (...skipping 6537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12364 } else { | 12381 } else { |
| 12365 // Handle last resort GC and make sure to allow future allocations | 12382 // Handle last resort GC and make sure to allow future allocations |
| 12366 // to grow the heap without causing GCs (if possible). | 12383 // to grow the heap without causing GCs (if possible). |
| 12367 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12384 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 12368 isolate->heap()->CollectAllGarbage(false); | 12385 isolate->heap()->CollectAllGarbage(false); |
| 12369 } | 12386 } |
| 12370 } | 12387 } |
| 12371 | 12388 |
| 12372 | 12389 |
| 12373 } } // namespace v8::internal | 12390 } } // namespace v8::internal |
| OLD | NEW |