Native implementations of Array.fill

KT-32359
This commit is contained in:
Ilya Gorbunov
2019-07-25 01:28:05 +03:00
committed by ilya-g
parent 3f39b75a89
commit 226fd310bf
4 changed files with 215 additions and 20 deletions
+2 -2
View File
@@ -20,8 +20,8 @@ buildKotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds
remoteRoot=konan_tests
kotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.60-dev-346,branch:default:any,pinned:true/artifacts/content/maven
kotlinVersion=1.3.60-dev-346
kotlinStdlibRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.60-dev-346,branch:default:any,pinned:true/artifacts/content/maven
kotlinStdlibVersion=1.3.60-dev-346
kotlinStdlibRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.60-dev-570,branch:default:any,pinned:true/artifacts/content/maven
kotlinStdlibVersion=1.3.60-dev-570
testKotlinCompilerVersion=1.3.60-dev-346
konanVersion=1.3.60
org.gradle.jvmargs='-Dfile.encoding=UTF-8'
+43 -11
View File
@@ -23,6 +23,8 @@
#include "Natives.h"
#include "Types.h"
extern "C" void checkRangeIndexes(KInt from, KInt to, KInt size);
namespace {
ALWAYS_INLINE inline void mutabilityCheck(KConstRef thiz) {
@@ -32,6 +34,17 @@ ALWAYS_INLINE inline void mutabilityCheck(KConstRef thiz) {
}
}
template<typename T>
inline void fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, T value) {
ArrayHeader* array = thiz->array();
checkRangeIndexes(fromIndex, toIndex, array->count_);
mutabilityCheck(thiz);
T* address = PrimitiveArrayAddressOfElementAt<T>(array, fromIndex);
for (KInt index = fromIndex; index < toIndex; ++index) {
*address++ = value;
}
}
template<typename T>
inline void copyImpl(KConstRef thiz, KInt fromIndex,
KRef destination, KInt toIndex, KInt count) {
@@ -102,9 +115,7 @@ KInt Kotlin_Array_getArrayLength(KConstRef thiz) {
void Kotlin_Array_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KRef value) {
ArrayHeader* array = thiz->array();
if (fromIndex < 0 || toIndex < fromIndex || toIndex > array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
checkRangeIndexes(fromIndex, toIndex, array->count_);
mutabilityCheck(thiz);
for (KInt index = fromIndex; index < toIndex; ++index) {
UpdateHeapRef(ArrayAddressOfElementAt(array, index), value);
@@ -483,15 +494,36 @@ KInt Kotlin_IntArray_getArrayLength(KConstRef thiz) {
return array->count_;
}
void Kotlin_ByteArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KByte value) {
fillImpl<KByte>(thiz, fromIndex, toIndex, value);
}
void Kotlin_ShortArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KShort value) {
fillImpl<KShort>(thiz, fromIndex, toIndex, value);
}
void Kotlin_CharArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KChar value) {
fillImpl<KChar>(thiz, fromIndex, toIndex, value);
}
void Kotlin_IntArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KInt value) {
ArrayHeader* array = thiz->array();
if (fromIndex < 0 || toIndex < fromIndex || toIndex >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
mutabilityCheck(thiz);
for (KInt index = fromIndex; index < toIndex; ++index) {
*PrimitiveArrayAddressOfElementAt<KInt>(array, index) = value;
}
fillImpl<KInt>(thiz, fromIndex, toIndex, value);
}
void Kotlin_LongArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KLong value) {
fillImpl<KLong>(thiz, fromIndex, toIndex, value);
}
void Kotlin_FloatArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KFloat value) {
fillImpl<KFloat>(thiz, fromIndex, toIndex, value);
}
void Kotlin_DoubleArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KDouble value) {
fillImpl<KDouble>(thiz, fromIndex, toIndex, value);
}
void Kotlin_BooleanArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KBoolean value) {
fillImpl<KBoolean>(thiz, fromIndex, toIndex, value);
}
void Kotlin_ByteArray_copyImpl(KConstRef thiz, KInt fromIndex,
@@ -1341,6 +1341,141 @@ internal fun CharArray.copyOfUninitializedElements(newSize: Int): CharArray {
return copyOfUninitializedElements(0, newSize)
}
/**
* Fills this array or its subrange with the specified [element] value.
*
* @param fromIndex the start of the range (inclusive), 0 by default.
* @param toIndex the end of the range (exclusive), size of this array by default.
*
* @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array.
* @throws IllegalArgumentException if [fromIndex] is greater than [toIndex].
*/
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun <T> Array<T>.fill(element: T, fromIndex: Int = 0, toIndex: Int = size): Unit {
arrayFill(this, fromIndex, toIndex, element)
}
/**
* Fills this array or its subrange with the specified [element] value.
*
* @param fromIndex the start of the range (inclusive), 0 by default.
* @param toIndex the end of the range (exclusive), size of this array by default.
*
* @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array.
* @throws IllegalArgumentException if [fromIndex] is greater than [toIndex].
*/
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun ByteArray.fill(element: Byte, fromIndex: Int = 0, toIndex: Int = size): Unit {
arrayFill(this, fromIndex, toIndex, element)
}
/**
* Fills this array or its subrange with the specified [element] value.
*
* @param fromIndex the start of the range (inclusive), 0 by default.
* @param toIndex the end of the range (exclusive), size of this array by default.
*
* @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array.
* @throws IllegalArgumentException if [fromIndex] is greater than [toIndex].
*/
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun ShortArray.fill(element: Short, fromIndex: Int = 0, toIndex: Int = size): Unit {
arrayFill(this, fromIndex, toIndex, element)
}
/**
* Fills this array or its subrange with the specified [element] value.
*
* @param fromIndex the start of the range (inclusive), 0 by default.
* @param toIndex the end of the range (exclusive), size of this array by default.
*
* @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array.
* @throws IllegalArgumentException if [fromIndex] is greater than [toIndex].
*/
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun IntArray.fill(element: Int, fromIndex: Int = 0, toIndex: Int = size): Unit {
arrayFill(this, fromIndex, toIndex, element)
}
/**
* Fills this array or its subrange with the specified [element] value.
*
* @param fromIndex the start of the range (inclusive), 0 by default.
* @param toIndex the end of the range (exclusive), size of this array by default.
*
* @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array.
* @throws IllegalArgumentException if [fromIndex] is greater than [toIndex].
*/
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun LongArray.fill(element: Long, fromIndex: Int = 0, toIndex: Int = size): Unit {
arrayFill(this, fromIndex, toIndex, element)
}
/**
* Fills this array or its subrange with the specified [element] value.
*
* @param fromIndex the start of the range (inclusive), 0 by default.
* @param toIndex the end of the range (exclusive), size of this array by default.
*
* @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array.
* @throws IllegalArgumentException if [fromIndex] is greater than [toIndex].
*/
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun FloatArray.fill(element: Float, fromIndex: Int = 0, toIndex: Int = size): Unit {
arrayFill(this, fromIndex, toIndex, element)
}
/**
* Fills this array or its subrange with the specified [element] value.
*
* @param fromIndex the start of the range (inclusive), 0 by default.
* @param toIndex the end of the range (exclusive), size of this array by default.
*
* @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array.
* @throws IllegalArgumentException if [fromIndex] is greater than [toIndex].
*/
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun DoubleArray.fill(element: Double, fromIndex: Int = 0, toIndex: Int = size): Unit {
arrayFill(this, fromIndex, toIndex, element)
}
/**
* Fills this array or its subrange with the specified [element] value.
*
* @param fromIndex the start of the range (inclusive), 0 by default.
* @param toIndex the end of the range (exclusive), size of this array by default.
*
* @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array.
* @throws IllegalArgumentException if [fromIndex] is greater than [toIndex].
*/
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun BooleanArray.fill(element: Boolean, fromIndex: Int = 0, toIndex: Int = size): Unit {
arrayFill(this, fromIndex, toIndex, element)
}
/**
* Fills this array or its subrange with the specified [element] value.
*
* @param fromIndex the start of the range (inclusive), 0 by default.
* @param toIndex the end of the range (exclusive), size of this array by default.
*
* @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array.
* @throws IllegalArgumentException if [fromIndex] is greater than [toIndex].
*/
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun CharArray.fill(element: Char, fromIndex: Int = 0, toIndex: Int = size): Unit {
arrayFill(this, fromIndex, toIndex, element)
}
/**
* Returns an array containing all elements of the original array and then the given [element].
*/
@@ -6,6 +6,7 @@
package kotlin.collections
import kotlin.native.internal.PointsTo
import kotlin.native.internal.ExportForCppRuntime
/**
* Returns an array of objects of the given type with the given [size], initialized with _uninitialized_ values.
@@ -75,10 +76,41 @@ internal fun <E> Array<E>.resetAt(index: Int) {
@SymbolName("Kotlin_Array_fillImpl")
@PointsTo(0b01000, 0, 0, 0b00001) // <array> points to <value>, <value> points to <array>.
external private fun fillImpl(array: Array<Any?>, fromIndex: Int, toIndex: Int, value: Any?)
internal external fun <T> arrayFill(array: Array<T>, fromIndex: Int, toIndex: Int, value: T)
@SymbolName("Kotlin_ByteArray_fillImpl")
internal external fun arrayFill(array: ByteArray, fromIndex: Int, toIndex: Int, value: Byte)
@SymbolName("Kotlin_ShortArray_fillImpl")
internal external fun arrayFill(array: ShortArray, fromIndex: Int, toIndex: Int, value: Short)
@SymbolName("Kotlin_CharArray_fillImpl")
internal external fun arrayFill(array: CharArray, fromIndex: Int, toIndex: Int, value: Char)
@SymbolName("Kotlin_IntArray_fillImpl")
external private fun fillImpl(array: IntArray, fromIndex: Int, toIndex: Int, value: Int)
internal external fun arrayFill(array: IntArray, fromIndex: Int, toIndex: Int, value: Int)
@SymbolName("Kotlin_LongArray_fillImpl")
internal external fun arrayFill(array: LongArray, fromIndex: Int, toIndex: Int, value: Long)
@SymbolName("Kotlin_DoubleArray_fillImpl")
internal external fun arrayFill(array: DoubleArray, fromIndex: Int, toIndex: Int, value: Double)
@SymbolName("Kotlin_FloatArray_fillImpl")
internal external fun arrayFill(array: FloatArray, fromIndex: Int, toIndex: Int, value: Float)
@SymbolName("Kotlin_BooleanArray_fillImpl")
internal external fun arrayFill(array: BooleanArray, fromIndex: Int, toIndex: Int, value: Boolean)
@ExportForCppRuntime
internal fun checkRangeIndexes(fromIndex: Int, toIndex: Int, size: Int) {
if (fromIndex < 0 || toIndex > size) {
throw IndexOutOfBoundsException("fromIndex: $fromIndex, toIndex: $toIndex, size: $size")
}
if (fromIndex > toIndex) {
throw IllegalArgumentException("fromIndex: $fromIndex > toIndex: $toIndex")
}
}
/**
* Resets a range of array elements at a specified [fromIndex] (inclusive) to [toIndex] (exclusive) range of indices
@@ -88,11 +120,7 @@ external private fun fillImpl(array: IntArray, fromIndex: Int, toIndex: Int, val
* either throwing exception or returning some kind of implementation-specific default value.
*/
internal fun <E> Array<E>.resetRange(fromIndex: Int, toIndex: Int) {
fillImpl(@Suppress("UNCHECKED_CAST") (this as Array<Any?>), fromIndex, toIndex, null)
}
internal fun IntArray.fill(fromIndex: Int, toIndex: Int, value: Int) {
fillImpl(this, fromIndex, toIndex, value)
arrayFill(@Suppress("UNCHECKED_CAST") (this as Array<Any?>), fromIndex, toIndex, null)
}
@SymbolName("Kotlin_Array_copyImpl")