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

Side by Side Diff: src/runtime/runtime-strings.cc

Issue 1806443002: Speed up repeating the separator between elements in sparse array .join (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Don't index into buffer unless we're going to write Created 4 years, 9 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
« 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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/runtime/runtime-utils.h" 5 #include "src/runtime/runtime-utils.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/conversions-inl.h" 8 #include "src/conversions-inl.h"
9 #include "src/isolate-inl.h" 9 #include "src/isolate-inl.h"
10 #include "src/regexp/jsregexp-inl.h" 10 #include "src/regexp/jsregexp-inl.h"
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 DisallowHeapAllocation no_gc; 550 DisallowHeapAllocation no_gc;
551 551
552 uc16* sink = answer->GetChars(); 552 uc16* sink = answer->GetChars();
553 #ifdef DEBUG 553 #ifdef DEBUG
554 uc16* end = sink + length; 554 uc16* end = sink + length;
555 #endif 555 #endif
556 556
557 RUNTIME_ASSERT(fixed_array->get(0)->IsString()); 557 RUNTIME_ASSERT(fixed_array->get(0)->IsString());
558 String* first = String::cast(fixed_array->get(0)); 558 String* first = String::cast(fixed_array->get(0));
559 String* separator_raw = *separator; 559 String* separator_raw = *separator;
560
560 int first_length = first->length(); 561 int first_length = first->length();
561 String::WriteToFlat(first, sink, 0, first_length); 562 String::WriteToFlat(first, sink, 0, first_length);
562 sink += first_length; 563 sink += first_length;
563 564
564 for (int i = 1; i < array_length; i++) { 565 for (int i = 1; i < array_length; i++) {
565 DCHECK(sink + separator_length <= end); 566 DCHECK(sink + separator_length <= end);
566 String::WriteToFlat(separator_raw, sink, 0, separator_length); 567 String::WriteToFlat(separator_raw, sink, 0, separator_length);
567 sink += separator_length; 568 sink += separator_length;
568 569
569 RUNTIME_ASSERT(fixed_array->get(i)->IsString()); 570 RUNTIME_ASSERT(fixed_array->get(i)->IsString());
570 String* element = String::cast(fixed_array->get(i)); 571 String* element = String::cast(fixed_array->get(i));
571 int element_length = element->length(); 572 int element_length = element->length();
572 DCHECK(sink + element_length <= end); 573 DCHECK(sink + element_length <= end);
573 String::WriteToFlat(element, sink, 0, element_length); 574 String::WriteToFlat(element, sink, 0, element_length);
574 sink += element_length; 575 sink += element_length;
575 } 576 }
576 DCHECK(sink == end); 577 DCHECK(sink == end);
577 578
578 // Use %_FastOneByteArrayJoin instead. 579 // Use %_FastOneByteArrayJoin instead.
579 DCHECK(!answer->IsOneByteRepresentation()); 580 DCHECK(!answer->IsOneByteRepresentation());
580 return *answer; 581 return *answer;
581 } 582 }
582 583
584 template <typename sinkchar>
585 static void WriteRepeatToFlat(String* src, Vector<sinkchar> buffer, int cursor,
586 int repeat, int length) {
587 if (repeat == 0) return;
588
589 sinkchar* start = &buffer[cursor];
590 String::WriteToFlat<sinkchar>(src, start, 0, length);
591
592 int done = 1;
593 sinkchar* next = start + length;
594
595 while (done < repeat) {
596 int block = Min(done, repeat - done);
597 int block_chars = block * length;
598 CopyChars(next, start, block_chars);
599 next += block_chars;
600 done += block;
601 }
602 }
603
583 template <typename Char> 604 template <typename Char>
584 static void JoinSparseArrayWithSeparator(FixedArray* elements, 605 static void JoinSparseArrayWithSeparator(FixedArray* elements,
585 int elements_length, 606 int elements_length,
586 uint32_t array_length, 607 uint32_t array_length,
587 String* separator, 608 String* separator,
588 Vector<Char> buffer) { 609 Vector<Char> buffer) {
589 DisallowHeapAllocation no_gc; 610 DisallowHeapAllocation no_gc;
590 int previous_separator_position = 0; 611 int previous_separator_position = 0;
591 int separator_length = separator->length(); 612 int separator_length = separator->length();
613 DCHECK_LT(0, separator_length);
592 int cursor = 0; 614 int cursor = 0;
593 for (int i = 0; i < elements_length; i += 2) { 615 for (int i = 0; i < elements_length; i += 2) {
594 int position = NumberToInt32(elements->get(i)); 616 int position = NumberToInt32(elements->get(i));
595 String* string = String::cast(elements->get(i + 1)); 617 String* string = String::cast(elements->get(i + 1));
596 int string_length = string->length(); 618 int string_length = string->length();
597 if (string->length() > 0) { 619 if (string->length() > 0) {
598 while (previous_separator_position < position) { 620 int repeat = position - previous_separator_position;
599 String::WriteToFlat<Char>(separator, &buffer[cursor], 0, 621 WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat,
600 separator_length); 622 separator_length);
601 cursor += separator_length; 623 cursor += repeat * separator_length;
602 previous_separator_position++; 624 previous_separator_position = position;
603 }
604 String::WriteToFlat<Char>(string, &buffer[cursor], 0, string_length); 625 String::WriteToFlat<Char>(string, &buffer[cursor], 0, string_length);
605 cursor += string->length(); 626 cursor += string->length();
606 } 627 }
607 } 628 }
608 if (separator_length > 0) { 629
609 // Array length must be representable as a signed 32-bit number, 630 int last_array_index = static_cast<int>(array_length - 1);
610 // otherwise the total string length would have been too large. 631 // Array length must be representable as a signed 32-bit number,
611 DCHECK(array_length <= 0x7fffffff); // Is int32_t. 632 // otherwise the total string length would have been too large.
612 int last_array_index = static_cast<int>(array_length - 1); 633 DCHECK(array_length <= 0x7fffffff); // Is int32_t.
613 while (previous_separator_position < last_array_index) { 634 int repeat = last_array_index - previous_separator_position;
614 String::WriteToFlat<Char>(separator, &buffer[cursor], 0, 635 WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat, separator_length);
615 separator_length); 636 cursor += repeat * separator_length;
616 cursor += separator_length;
617 previous_separator_position++;
618 }
619 }
620 DCHECK(cursor <= buffer.length()); 637 DCHECK(cursor <= buffer.length());
621 } 638 }
622 639
623 640
624 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { 641 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
625 HandleScope scope(isolate); 642 HandleScope scope(isolate);
626 DCHECK(args.length() == 3); 643 DCHECK(args.length() == 3);
627 CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0); 644 CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
628 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); 645 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
629 CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); 646 CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 SealHandleScope shs(isolate); 1319 SealHandleScope shs(isolate);
1303 DCHECK(args.length() == 2); 1320 DCHECK(args.length() == 2);
1304 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); 1321 if (!args[0]->IsString()) return isolate->heap()->undefined_value();
1305 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); 1322 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value();
1306 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); 1323 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value();
1307 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); 1324 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
1308 } 1325 }
1309 1326
1310 } // namespace internal 1327 } // namespace internal
1311 } // namespace v8 1328 } // namespace v8
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