From 824d8ae55e772c8e7370cadb6737dee4a87a3df8 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Mon, 22 Jul 2019 11:56:31 +0500 Subject: [PATCH] StringBuilder: Use intrinsic if input sequence is a string --- runtime/src/main/cpp/KString.cpp | 13 +++++++------ runtime/src/main/kotlin/kotlin/native/Text.kt | 5 ++++- .../src/main/kotlin/kotlin/text/StringBuilder.kt | 4 ++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/runtime/src/main/cpp/KString.cpp b/runtime/src/main/cpp/KString.cpp index 7df2c535190..924b9ce3c7e 100644 --- a/runtime/src/main/cpp/KString.cpp +++ b/runtime/src/main/cpp/KString.cpp @@ -902,13 +902,14 @@ OBJ_GETTER(Kotlin_String_unsafeStringToUtf8OrThrow, KString thiz, KInt start, KI RETURN_RESULT_OF(unsafeUtf16ToUtf8Impl, thiz, start, size); } -KInt Kotlin_StringBuilder_insertString(KRef builder, KInt position, KString fromString) { +KInt Kotlin_StringBuilder_insertString(KRef builder, KInt distIndex, KString fromString, KInt sourceIndex, KInt count) { auto toArray = builder->array(); - RuntimeAssert(toArray->count_ >= fromString->count_ + position, "must be true"); - memcpy(CharArrayAddressOfElementAt(toArray, position), - CharArrayAddressOfElementAt(fromString, 0), - fromString->count_ * sizeof(KChar)); - return fromString->count_; + RuntimeAssert(sourceIndex >= 0 && sourceIndex + count <= fromString->count_, "must be true"); + RuntimeAssert(distIndex >= 0 && distIndex + count <= toArray->count_, "must be true"); + memcpy(CharArrayAddressOfElementAt(toArray, distIndex), + CharArrayAddressOfElementAt(fromString, sourceIndex), + count * sizeof(KChar)); + return count; } KInt Kotlin_StringBuilder_insertInt(KRef builder, KInt position, KInt value) { diff --git a/runtime/src/main/kotlin/kotlin/native/Text.kt b/runtime/src/main/kotlin/kotlin/native/Text.kt index 37370432a9b..9738b6b759a 100644 --- a/runtime/src/main/kotlin/kotlin/native/Text.kt +++ b/runtime/src/main/kotlin/kotlin/native/Text.kt @@ -112,6 +112,9 @@ internal fun checkBoundsIndexes(startIndex: Int, endIndex: Int, size: Int) { } } +internal fun insertString(array: CharArray, start: Int, value: String): Int = + insertString(array, start, value, 0, value.length) + @SymbolName("Kotlin_ByteArray_unsafeStringFromUtf8") internal external fun ByteArray.unsafeStringFromUtf8(start: Int, size: Int) : String @@ -128,7 +131,7 @@ internal external fun String.unsafeStringToUtf8OrThrow(start: Int, size: Int) : internal external fun unsafeStringFromCharArray(array: CharArray, start: Int, size: Int) : String @SymbolName("Kotlin_StringBuilder_insertString") -internal external fun insertString(array: CharArray, start: Int, value: String): Int +internal external fun insertString(array: CharArray, distIndex: Int, value: String, sourceIndex: Int, count: Int): Int @SymbolName("Kotlin_StringBuilder_insertInt") internal external fun insertInt(array: CharArray, start: Int, value: Int): Int \ No newline at end of file diff --git a/runtime/src/main/kotlin/kotlin/text/StringBuilder.kt b/runtime/src/main/kotlin/kotlin/text/StringBuilder.kt index 941ee6e21b2..4c48f9a80b1 100644 --- a/runtime/src/main/kotlin/kotlin/text/StringBuilder.kt +++ b/runtime/src/main/kotlin/kotlin/text/StringBuilder.kt @@ -227,6 +227,10 @@ actual class StringBuilder private constructor ( val toAppend = csq ?: "null" if (start < 0 || end < start || start > toAppend.length) throw IndexOutOfBoundsException() ensureExtraCapacity(end - start) + (toAppend as? String)?.let { + _length += insertString(array, _length, it, start, end - start) + return this + } var index = start while (index < end) array[_length++] = toAppend[index++]