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

Side by Side Diff: src/runtime.cc

Issue 7003083: Don't allocate handles for substrings when filling up the split result array. Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 6 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
« no previous file with comments | « no previous file | 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 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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698