From c8ed56b24a781f8a4dc32564a0ab98317b36fc3b Mon Sep 17 00:00:00 2001 From: Vasily Levchenko Date: Fri, 10 Feb 2017 16:02:51 +0300 Subject: [PATCH] STDLIB: support for vararg of primitive types - *Array.copyRangeTo for Byte,Short,Char,Long,Float,Double - bunch of *ArrayOf(vararg elements:*) = elements and inlined - small inhancement in c++ part of Kotlin_*Array_copyImpl(...) refactored --- runtime/src/main/cpp/Arrays.cpp | 56 ++++++++++--- runtime/src/main/kotlin/kotlin/Arrays.kt | 81 ++----------------- .../kotlin/kotlin/collections/ArrayUtil.kt | 47 +++++++++++ 3 files changed, 102 insertions(+), 82 deletions(-) diff --git a/runtime/src/main/cpp/Arrays.cpp b/runtime/src/main/cpp/Arrays.cpp index 93ed72e297f..647acd41f98 100644 --- a/runtime/src/main/cpp/Arrays.cpp +++ b/runtime/src/main/cpp/Arrays.cpp @@ -7,6 +7,21 @@ #include "Natives.h" #include "Types.h" +template +static inline void copyImpl(KConstRef thiz, KInt fromIndex, + KRef destination, KInt toIndex, KInt count) { + const ArrayHeader* array = thiz->array(); + ArrayHeader* destinationArray = destination->array(); + if (fromIndex < 0 || fromIndex + count > array->count_ || + toIndex < 0 || toIndex + count > destinationArray->count_) { + ThrowArrayIndexOutOfBoundsException(); + } + + memmove(PrimitiveArrayAddressOfElementAt(destinationArray, toIndex), + PrimitiveArrayAddressOfElementAt(array, fromIndex), + count * sizeof(T)); +} + extern "C" { // TODO: those must be compiler intrinsics afterwards. @@ -226,19 +241,42 @@ void Kotlin_IntArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KInt valu } } +void Kotlin_ByteArray_copyImpl(KConstRef thiz, KInt fromIndex, + KRef destination, KInt toIndex, KInt count) { + copyImpl(thiz, fromIndex, destination, toIndex, count); +} + +void Kotlin_ShortArray_copyImpl(KConstRef thiz, KInt fromIndex, + KRef destination, KInt toIndex, KInt count) { + copyImpl(thiz, fromIndex, destination, toIndex, count); +} + +void Kotlin_CharArray_copyImpl(KConstRef thiz, KInt fromIndex, + KRef destination, KInt toIndex, KInt count) { + copyImpl(thiz, fromIndex, destination, toIndex, count); +} + void Kotlin_IntArray_copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { - const ArrayHeader* array = thiz->array(); - ArrayHeader* destinationArray = destination->array(); - if (fromIndex < 0 || fromIndex + count > array->count_ || - toIndex < 0 || toIndex + count > destinationArray->count_) { - ThrowArrayIndexOutOfBoundsException(); - } - memmove(PrimitiveArrayAddressOfElementAt(destinationArray, toIndex), - PrimitiveArrayAddressOfElementAt(array, fromIndex), - count * sizeof(KInt)); + copyImpl(thiz, fromIndex, destination, toIndex, count); } +void Kotlin_LongArray_copyImpl(KConstRef thiz, KInt fromIndex, + KRef destination, KInt toIndex, KInt count) { + copyImpl(thiz, fromIndex, destination, toIndex, count); +} + +void Kotlin_FloatArray_copyImpl(KConstRef thiz, KInt fromIndex, + KRef destination, KInt toIndex, KInt count) { + copyImpl(thiz, fromIndex, destination, toIndex, count); +} + +void Kotlin_DoubleArray_copyImpl(KConstRef thiz, KInt fromIndex, + KRef destination, KInt toIndex, KInt count) { + copyImpl(thiz, fromIndex, destination, toIndex, count); +} + + KLong Kotlin_LongArray_get(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); if (static_cast(index) >= array->count_) { diff --git a/runtime/src/main/kotlin/kotlin/Arrays.kt b/runtime/src/main/kotlin/kotlin/Arrays.kt index d9902de728f..0d27b546a89 100644 --- a/runtime/src/main/kotlin/kotlin/Arrays.kt +++ b/runtime/src/main/kotlin/kotlin/Arrays.kt @@ -898,108 +898,43 @@ public inline fun arrayOfNulls(size: Int): Array */ public inline fun arrayOf(vararg elements: T): Array = elements as Array -// TODO: optimize those operations. /** * Returns an array containing the specified [Double] numbers. */ -public fun doubleArrayOf(vararg elements: Double): DoubleArray { - val result = DoubleArray(elements.size) - var index = 0 - while (index < elements.size) { - result[index] = elements[index] - index++ - } - return result -} +public inline fun doubleArrayOf(vararg elements: Double) = elements /** * Returns an array containing the specified [Float] numbers. */ -public fun floatArrayOf(vararg elements: Float): FloatArray { - val result = FloatArray(elements.size) - var index = 0 - while (index < elements.size) { - result[index] = elements[index] - index++ - } - return result -} +public inline fun floatArrayOf(vararg elements: Float) = elements /** * Returns an array containing the specified [Long] numbers. */ -public fun longArrayOf(vararg elements: Long): LongArray { - val result = LongArray(elements.size) - var index = 0 - while (index < elements.size) { - result[index] = elements[index] - index++ - } - return result -} +public inline fun longArrayOf(vararg elements: Long) = elements /** * Returns an array containing the specified [Int] numbers. */ -public fun intArrayOf(vararg elements: Int): IntArray { - val result = IntArray(elements.size) - var index = 0 - while (index < elements.size) { - result[index] = elements[index] - index++ - } - return result -} +public inline fun intArrayOf(vararg elements: Int) = elements /** * Returns an array containing the specified characters. */ -public fun charArrayOf(vararg elements: Char): CharArray { - val result = CharArray(elements.size) - var index = 0 - while (index < elements.size) { - result[index] = elements[index] - index++ - } - return result -} +public inline fun charArrayOf(vararg elements: Char) = elements /** * Returns an array containing the specified [Short] numbers. */ -public fun shortArrayOf(vararg elements: Short): ShortArray { - val result = ShortArray(elements.size) - var index = 0 - while (index < elements.size) { - result[index] = elements[index] - index++ - } - return result -} +public inline fun shortArrayOf(vararg elements: Short) = elements /** * Returns an array containing the specified [Byte] numbers. */ -public fun byteArrayOf(vararg elements: Byte): ByteArray { - val result = ByteArray(elements.size) - var index = 0 - while (index < elements.size) { - result[index] = elements[index] - index++ - } - return result -} +public inline fun byteArrayOf(vararg elements: Byte) = elements /** * Returns an array containing the specified boolean values. */ -public fun booleanArrayOf(vararg elements: Boolean): BooleanArray { - val result = BooleanArray(elements.size) - var index = 0 - while (index < elements.size) { - result[index] = elements[index] - index++ - } - return result -} \ No newline at end of file +public inline fun booleanArrayOf(vararg elements: Boolean) = elements \ No newline at end of file diff --git a/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt b/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt index b2faaa21d2c..16b58e9944b 100644 --- a/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt +++ b/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt @@ -62,9 +62,33 @@ internal fun IntArray.fill(fromIndex: Int, toIndex: Int, value: Int) { external private fun copyImpl(array: Array, fromIndex: Int, destination: Array, toIndex: Int, count: Int) +@SymbolName("Kotlin_ByteArray_copyImpl") +external private fun copyImpl(array: ByteArray, fromIndex: Int, + destination: ByteArray, toIndex: Int, count: Int) + +@SymbolName("Kotlin_ShortArray_copyImpl") +external private fun copyImpl(array: ShortArray, fromIndex: Int, + destination: ShortArray, toIndex: Int, count: Int) + +@SymbolName("Kotlin_CharArray_copyImpl") +external private fun copyImpl(array: CharArray, fromIndex: Int, + destination: CharArray, toIndex: Int, count: Int) + @SymbolName("Kotlin_IntArray_copyImpl") external private fun copyImpl(array: IntArray, fromIndex: Int, destination: IntArray, toIndex: Int, count: Int) +@SymbolName("Kotlin_LongArray_copyImpl") +external private fun copyImpl(array: LongArray, fromIndex: Int, + destination: LongArray, toIndex: Int, count: Int) + +@SymbolName("Kotlin_FloatArray_copyImpl") +external private fun copyImpl(array: FloatArray, fromIndex: Int, + destination: FloatArray, toIndex: Int, count: Int) + +@SymbolName("Kotlin_DoubleArray_copyImpl") +external private fun copyImpl(array: DoubleArray, fromIndex: Int, + destination: DoubleArray, toIndex: Int, count: Int) + /** * Copies a range of array elements at a specified [fromIndex] (inclusive) to [toIndex] (exclusive) range of indices @@ -76,10 +100,33 @@ fun Array.copyRangeTo(destination: Array, fromIndex: Int, toIndex: Int destinationIndex, toIndex - fromIndex) } +fun ByteArray.copyRangeTo(destination: ByteArray, fromIndex: Int, toIndex: Int, destinationIndex: Int = 0) { + copyImpl(this, fromIndex, destination, destinationIndex, toIndex - fromIndex) +} + +fun ShortArray.copyRangeTo(destination: ShortArray, fromIndex: Int, toIndex: Int, destinationIndex: Int = 0) { + copyImpl(this, fromIndex, destination, destinationIndex, toIndex - fromIndex) +} + +fun CharArray.copyRangeTo(destination: CharArray, fromIndex: Int, toIndex: Int, destinationIndex: Int = 0) { + copyImpl(this, fromIndex, destination, destinationIndex, toIndex - fromIndex) +} + fun IntArray.copyRangeTo(destination: IntArray, fromIndex: Int, toIndex: Int, destinationIndex: Int = 0) { copyImpl(this, fromIndex, destination, destinationIndex, toIndex - fromIndex) } +fun LongArray.copyRangeTo(destination: LongArray, fromIndex: Int, toIndex: Int, destinationIndex: Int = 0) { + copyImpl(this, fromIndex, destination, destinationIndex, toIndex - fromIndex) +} + +fun FloatArray.copyRangeTo(destination: FloatArray, fromIndex: Int, toIndex: Int, destinationIndex: Int = 0) { + copyImpl(this, fromIndex, destination, destinationIndex, toIndex - fromIndex) +} + +fun DoubleArray.copyRangeTo(destination: DoubleArray, fromIndex: Int, toIndex: Int, destinationIndex: Int = 0) { + copyImpl(this, fromIndex, destination, destinationIndex, toIndex - fromIndex) +} /** * Copies a range of array elements at a specified [fromIndex] (inclusive) to [toIndex] (exclusive) range of indices * to another part of this array starting at [destinationIndex].