| Index: src/runtime/runtime-strings.cc
|
| diff --git a/src/runtime/runtime-strings.cc b/src/runtime/runtime-strings.cc
|
| index 3654968a3b199c765bc6dfd52ac5664aa55e85ee..e3b589643b474ce291a0d668f669316d8e40f2cb 100644
|
| --- a/src/runtime/runtime-strings.cc
|
| +++ b/src/runtime/runtime-strings.cc
|
| @@ -557,6 +557,7 @@ RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
|
| RUNTIME_ASSERT(fixed_array->get(0)->IsString());
|
| String* first = String::cast(fixed_array->get(0));
|
| String* separator_raw = *separator;
|
| +
|
| int first_length = first->length();
|
| String::WriteToFlat(first, sink, 0, first_length);
|
| sink += first_length;
|
| @@ -580,6 +581,26 @@ RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
|
| return *answer;
|
| }
|
|
|
| +template <typename sinkchar>
|
| +static void WriteRepeatToFlat(String* src, Vector<sinkchar> buffer, int cursor,
|
| + int repeat, int length) {
|
| + if (repeat == 0) return;
|
| +
|
| + sinkchar* start = &buffer[cursor];
|
| + String::WriteToFlat<sinkchar>(src, start, 0, length);
|
| +
|
| + int done = 1;
|
| + sinkchar* next = start + length;
|
| +
|
| + while (done < repeat) {
|
| + int block = Min(done, repeat - done);
|
| + int block_chars = block * length;
|
| + CopyChars(next, start, block_chars);
|
| + next += block_chars;
|
| + done += block;
|
| + }
|
| +}
|
| +
|
| template <typename Char>
|
| static void JoinSparseArrayWithSeparator(FixedArray* elements,
|
| int elements_length,
|
| @@ -589,34 +610,30 @@ static void JoinSparseArrayWithSeparator(FixedArray* elements,
|
| DisallowHeapAllocation no_gc;
|
| int previous_separator_position = 0;
|
| int separator_length = separator->length();
|
| + DCHECK_LT(0, separator_length);
|
| int cursor = 0;
|
| for (int i = 0; i < elements_length; i += 2) {
|
| int position = NumberToInt32(elements->get(i));
|
| String* string = String::cast(elements->get(i + 1));
|
| int string_length = string->length();
|
| if (string->length() > 0) {
|
| - while (previous_separator_position < position) {
|
| - String::WriteToFlat<Char>(separator, &buffer[cursor], 0,
|
| - separator_length);
|
| - cursor += separator_length;
|
| - previous_separator_position++;
|
| - }
|
| + int repeat = position - previous_separator_position;
|
| + WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat,
|
| + separator_length);
|
| + cursor += repeat * separator_length;
|
| + previous_separator_position = position;
|
| String::WriteToFlat<Char>(string, &buffer[cursor], 0, string_length);
|
| cursor += string->length();
|
| }
|
| }
|
| - if (separator_length > 0) {
|
| - // Array length must be representable as a signed 32-bit number,
|
| - // otherwise the total string length would have been too large.
|
| - DCHECK(array_length <= 0x7fffffff); // Is int32_t.
|
| - int last_array_index = static_cast<int>(array_length - 1);
|
| - while (previous_separator_position < last_array_index) {
|
| - String::WriteToFlat<Char>(separator, &buffer[cursor], 0,
|
| - separator_length);
|
| - cursor += separator_length;
|
| - previous_separator_position++;
|
| - }
|
| - }
|
| +
|
| + int last_array_index = static_cast<int>(array_length - 1);
|
| + // Array length must be representable as a signed 32-bit number,
|
| + // otherwise the total string length would have been too large.
|
| + DCHECK(array_length <= 0x7fffffff); // Is int32_t.
|
| + int repeat = last_array_index - previous_separator_position;
|
| + WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat, separator_length);
|
| + cursor += repeat * separator_length;
|
| DCHECK(cursor <= buffer.length());
|
| }
|
|
|
|
|