diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt index 510050dffb2..6d601960428 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt @@ -330,8 +330,6 @@ internal class KonanSymbols(context: Context, private val symbolTable: SymbolTab override val returnIfSuspended = internalFunction("returnIfSuspended") - - val coroutineLaunchpad = internalFunction("coroutineLaunchpad") val konanSuspendCoroutineUninterceptedOrReturn = internalFunction("suspendCoroutineUninterceptedOrReturn") diff --git a/gradle.properties b/gradle.properties index e5d0b84ca74..baa661d31e8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,11 +18,11 @@ buildKotlinVersion=1.3.50-dev-787 buildKotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.50-dev-787,branch:default:any,pinned:true/artifacts/content/maven remoteRoot=konan_tests -kotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.50-dev-1913,branch:default:any,pinned:true/artifacts/content/maven -kotlinVersion=1.3.50-dev-1913 -kotlinStdlibRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.50-dev-1913,branch:default:any,pinned:true/artifacts/content/maven -kotlinStdlibVersion=1.3.50-dev-1913 -testKotlinCompilerVersion=1.3.50-dev-1913 +kotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.50-dev-2110,branch:default:any,pinned:true/artifacts/content/maven +kotlinVersion=1.3.50-dev-2110 +kotlinStdlibRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.50-dev-2110,branch:default:any,pinned:true/artifacts/content/maven +kotlinStdlibVersion=1.3.50-dev-2110 +testKotlinCompilerVersion=1.3.50-dev-2110 konanVersion=1.3.50 org.gradle.jvmargs='-Dfile.encoding=UTF-8' org.gradle.workers.max=4 diff --git a/runtime/src/main/cpp/Operator.cpp b/runtime/src/main/cpp/Operator.cpp index 5bfb2e5c0c9..1fc2673fabf 100644 --- a/runtime/src/main/cpp/Operator.cpp +++ b/runtime/src/main/cpp/Operator.cpp @@ -67,4 +67,15 @@ ALWAYS_INLINE KBoolean Kotlin_Double_isNaN(KDouble a) { return isnan(a) ALWAYS_INLINE KBoolean Kotlin_Double_isInfinite(KDouble a) { return isinf(a); } ALWAYS_INLINE KBoolean Kotlin_Double_isFinite(KDouble a) { return isfinite(a); } +//--- Bit operations ---------------------------------------------------------// + +ALWAYS_INLINE KInt Kotlin_Int_countOneBits(KInt value) { return __builtin_popcount(value); } +ALWAYS_INLINE KInt Kotlin_Long_countOneBits(KLong value) { return __builtin_popcountll(value); } + +ALWAYS_INLINE KInt Kotlin_Int_countTrailingZeroBits(KInt value) { return __builtin_ctz(value); } +ALWAYS_INLINE KInt Kotlin_Long_countTrailingZeroBits(KLong value) { return __builtin_ctzll(value); } + +ALWAYS_INLINE KInt Kotlin_Int_countLeadingZeroBits(KInt value) { return __builtin_clz(value); } +ALWAYS_INLINE KInt Kotlin_Long_countLeadingZeroBits(KLong value) { return __builtin_clzll(value); } + } // extern "C" diff --git a/runtime/src/main/kotlin/kotlin/Numbers.kt b/runtime/src/main/kotlin/kotlin/Numbers.kt index 579f716d845..8b6874d18d9 100644 --- a/runtime/src/main/kotlin/kotlin/Numbers.kt +++ b/runtime/src/main/kotlin/kotlin/Numbers.kt @@ -13,38 +13,38 @@ import kotlin.native.internal.IntrinsicType * Not-a-Number (NaN) value, `false` otherwise. */ @SymbolName("Kotlin_Double_isNaN") -external public actual fun Double.isNaN(): Boolean +public actual external fun Double.isNaN(): Boolean /** * Returns `true` if the specified number is a * Not-a-Number (NaN) value, `false` otherwise. */ @SymbolName("Kotlin_Float_isNaN") -external public actual fun Float.isNaN(): Boolean +public actual external fun Float.isNaN(): Boolean /** * Returns `true` if this value is infinitely large in magnitude. */ @SymbolName("Kotlin_Double_isInfinite") -external public actual fun Double.isInfinite(): Boolean +public actual external fun Double.isInfinite(): Boolean /** * Returns `true` if this value is infinitely large in magnitude. */ @SymbolName("Kotlin_Float_isInfinite") -external public actual fun Float.isInfinite(): Boolean +public actual external fun Float.isInfinite(): Boolean /** * Returns `true` if the argument is a finite floating-point value; returns `false` otherwise (for `NaN` and infinity arguments). */ @SymbolName("Kotlin_Double_isFinite") -external public actual fun Double.isFinite(): Boolean +public actual external fun Double.isFinite(): Boolean /** * Returns `true` if the argument is a finite floating-point value; returns `false` otherwise (for `NaN` and infinity arguments). */ @SymbolName("Kotlin_Float_isFinite") -external public actual fun Float.isFinite(): Boolean +public actual external fun Float.isFinite(): Boolean /** * Returns a bit representation of the specified floating-point value as [Long] @@ -72,7 +72,7 @@ public actual inline fun Double.Companion.fromBits(bits: Long): Double = kotlin. @PublishedApi @TypedIntrinsic(IntrinsicType.REINTERPRET) -external internal fun fromBits(bits: Long): Double +internal external fun fromBits(bits: Long): Double /** * Returns a bit representation of the specified floating-point value as [Int] @@ -100,4 +100,181 @@ public actual inline fun Float.Companion.fromBits(bits: Int): Float = kotlin.fro @PublishedApi @TypedIntrinsic(IntrinsicType.REINTERPRET) -external internal fun fromBits(bits: Int): Float +internal external fun fromBits(bits: Int): Float + +// TODO: Replace 32 and 64 literals with Int/Long.SIZE_BITS constants when constant propagation is working + +/** + * Counts the number of set bits in the binary representation of this [Int] number. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@SymbolName("Kotlin_Int_countOneBits") +public actual external fun Int.countOneBits(): Int + +/** + * Counts the number of consecutive most significant bits that are zero in the binary representation of [Int] [value]. + * Returns undefined result for zero [value]. + */ +@SymbolName("Kotlin_Int_countLeadingZeroBits") +private external fun countLeadingZeroBits(value: Int): Int + +/** + * Counts the number of consecutive most significant bits that are zero in the binary representation of this [Int] number. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Int.countLeadingZeroBits(): Int = + if (this == 0) 32 else countLeadingZeroBits(this) + +/** + * Counts the number of consecutive least significant bits that are zero in the binary representation of [Int] [value]. + * Returns undefined result for zero [value]. + */ +@SymbolName("Kotlin_Int_countTrailingZeroBits") +private external fun countTrailingZeroBits(value: Int): Int + +/** + * Counts the number of consecutive least significant bits that are zero in the binary representation of this [Int] number. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Int.countTrailingZeroBits(): Int = + if (this == 0) 32 else countTrailingZeroBits(this) + +/** + * Returns a number having a single bit set in the position of the most significant set bit of this [Int] number, + * or zero, if this number is zero. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Int.takeHighestOneBit(): Int = + if (this == 0) 0 else 1.shl(32 - 1 - countLeadingZeroBits(this)) + +/** + * Returns a number having a single bit set in the position of the least significant set bit of this [Int] number, + * or zero, if this number is zero. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Int.takeLowestOneBit(): Int = + this and -this + +/** + * Rotates the binary representation of this [Int] number left by the specified [bitCount] number of bits. + * The most significant bits pushed out from the left side reenter the number as the least significant bits on the right side. + * + * Rotating the number left by a negative bit count is the same as rotating it right by the negated bit count: + * `number.rotateLeft(-n) == number.rotateRight(n)` + * + * Rotating by a multiple of [Int.SIZE_BITS] (32) returns the same number, or more generally + * `number.rotateLeft(n) == number.rotateLeft(n % 32)` + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Int.rotateLeft(bitCount: Int): Int = + shl(bitCount) or ushr(32 - bitCount) + + +/** + * Rotates the binary representation of this [Int] number right by the specified [bitCount] number of bits. + * The least significant bits pushed out from the right side reenter the number as the most significant bits on the left side. + * + * Rotating the number right by a negative bit count is the same as rotating it left by the negated bit count: + * `number.rotateRight(-n) == number.rotateLeft(n)` + * + * Rotating by a multiple of [Int.SIZE_BITS] (32) returns the same number, or more generally + * `number.rotateRight(n) == number.rotateRight(n % 32)` + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Int.rotateRight(bitCount: Int): Int = + shl(32 - bitCount) or ushr(bitCount) + + +/** + * Counts the number of set bits in the binary representation of this [Long] number. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@SymbolName("Kotlin_Long_countOneBits") +public actual external fun Long.countOneBits(): Int + +/** + * Counts the number of consecutive most significant bits that are zero in the binary representation of [Long] [value]. + * Returns undefined result for zero [value]. + */ +@SymbolName("Kotlin_Long_countLeadingZeroBits") +private external fun countLeadingZeroBits(value: Long): Int + +/** + * Counts the number of consecutive most significant bits that are zero in the binary representation of this [Long] number. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Long.countLeadingZeroBits(): Int = + if (this == 0L) 64 else countLeadingZeroBits(this) + +/** + * Counts the number of consecutive least significant bits that are zero in the binary representation of [Long] [value]. + * Returns undefined result for zero [value]. + */ +@SymbolName("Kotlin_Long_countTrailingZeroBits") +private external fun countTrailingZeroBits(value: Long): Int + +/** + * Counts the number of consecutive least significant bits that are zero in the binary representation of this [Long] number. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Long.countTrailingZeroBits(): Int = + if (this == 0L) 64 else countTrailingZeroBits(this) + +/** + * Returns a number having a single bit set in the position of the most significant set bit of this [Long] number, + * or zero, if this number is zero. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Long.takeHighestOneBit(): Long = + if (this == 0L) 0L else 1L.shl(64 - 1 - countLeadingZeroBits(this)) + +/** + * Returns a number having a single bit set in the position of the least significant set bit of this [Long] number, + * or zero, if this number is zero. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Long.takeLowestOneBit(): Long = + this and -this + +/** + * Rotates the binary representation of this [Long] number left by the specified [bitCount] number of bits. + * The most significant bits pushed out from the left side reenter the number as the least significant bits on the right side. + * + * Rotating the number left by a negative bit count is the same as rotating it right by the negated bit count: + * `number.rotateLeft(-n) == number.rotateRight(n)` + * + * Rotating by a multiple of [Long.SIZE_BITS] (64) returns the same number, or more generally + * `number.rotateLeft(n) == number.rotateLeft(n % 64)` + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public actual fun Long.rotateLeft(bitCount: Int): Long = + shl(bitCount) or ushr(64 - bitCount) + +/** + * Rotates the binary representation of this [Long] number right by the specified [bitCount] number of bits. + * The least significant bits pushed out from the right side reenter the number as the most significant bits on the left side. + * + * Rotating the number right by a negative bit count is the same as rotating it left by the negated bit count: + * `number.rotateRight(-n) == number.rotateLeft(n)` + * + * Rotating by a multiple of [Long.SIZE_BITS] (64) returns the same number, or more generally + * `number.rotateRight(n) == number.rotateRight(n % 64)` + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public actual inline fun Long.rotateRight(bitCount: Int): Long = + shl(64 - bitCount) or ushr(bitCount) diff --git a/runtime/src/main/kotlin/kotlin/collections/HashMap.kt b/runtime/src/main/kotlin/kotlin/collections/HashMap.kt index 63893db0d85..4757343ccd1 100644 --- a/runtime/src/main/kotlin/kotlin/collections/HashMap.kt +++ b/runtime/src/main/kotlin/kotlin/collections/HashMap.kt @@ -511,9 +511,11 @@ actual class HashMap private constructor( const val INITIAL_MAX_PROBE_DISTANCE = 2 const val TOMBSTONE = -1 - fun computeHashSize(capacity: Int): Int = (capacity.coerceAtLeast(1) * 3).highestOneBit() + @UseExperimental(ExperimentalStdlibApi::class) + fun computeHashSize(capacity: Int): Int = (capacity.coerceAtLeast(1) * 3).takeHighestOneBit() - fun computeShift(hashSize: Int): Int = hashSize.numberOfLeadingZeros() + 1 + @UseExperimental(ExperimentalStdlibApi::class) + fun computeShift(hashSize: Int): Int = hashSize.countLeadingZeroBits() + 1 } internal open class Itr( diff --git a/runtime/src/main/kotlin/kotlin/collections/IntUtil.kt b/runtime/src/main/kotlin/kotlin/collections/IntUtil.kt deleted file mode 100644 index d2d901fa059..00000000000 --- a/runtime/src/main/kotlin/kotlin/collections/IntUtil.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the LICENSE file. - */ - -package kotlin.collections - -internal fun Int.highestOneBit() : Int { - var index = 31 - - while (index >= 0) { - var mask = (1 shl index) - if ((mask and this) != 0) { - return mask - } - index-- - } - return 0 -} - -internal fun Int.numberOfLeadingZeros() : Int { - var index = 31 - - while (index >= 0) { - var mask = (1 shl index) - if ((mask and this) != 0) { - return 31 - index - } - index-- - } - return 0 -} \ No newline at end of file diff --git a/runtime/src/main/kotlin/kotlin/random/Random.kt b/runtime/src/main/kotlin/kotlin/random/Random.kt index ee2b4e56cb5..9d1942152f1 100644 --- a/runtime/src/main/kotlin/kotlin/random/Random.kt +++ b/runtime/src/main/kotlin/kotlin/random/Random.kt @@ -36,8 +36,5 @@ internal object NativeRandom : Random() { internal actual fun defaultPlatformRandom(): Random = NativeRandom -internal actual fun fastLog2(value: Int): Int = - 31 - value.numberOfLeadingZeros() - internal actual fun doubleFromParts(hi26: Int, low27: Int): Double = (hi26.toLong().shl(27) + low27) / (1L shl 53).toDouble()