[atomicfu-JVM] Preparation for commonization of JVM and K/N transformers
The following updates in the JVM/IR plugin were made: * Lots of refactoring with preparation for K/N support: commonization of transformations. * Improved error handling (checks for visibility constraints, appending message about usage constraints in case of an error). * Explicit requirements for the visibility of atomic properties: to prevent leaking they should be private/internal or be members of private/internal classes. * Fixed visibility of generated properties: volatile properties are always private and atomic updaters have the same visibility as the original atomic property. * Volatile fields are generated from scratch and original atomic properties are removed. * Delegated properties support is fixed (only declaration in the same scope is allowed). * Non-inline atomic extensions are forbidden. * For top-level atomics: only one wrapper class per file (with corresponding visibility) is generated. * Bug fixes. The corresponding tickets: https://github.com/Kotlin/kotlinx-atomicfu/issues/322 KT-60528 Merge-request: KT-MR-10579 Merged-by: Maria Sokolova <maria.sokolova@jetbrains.com>
This commit is contained in:
Vendored
+79
@@ -0,0 +1,79 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class ArrayInlineExtensionTest {
|
||||
private val intArr = AtomicIntArray(10)
|
||||
private val a = atomic(100)
|
||||
private val longArr = AtomicLongArray(10)
|
||||
private val refArr = atomicArrayOfNulls<Any?>(5)
|
||||
|
||||
class A(val s: String)
|
||||
|
||||
private inline fun casLoop(to: Int): Int {
|
||||
intArr[0].loop { cur ->
|
||||
if (intArr[0].compareAndSet(cur, to)) return intArr[0].value
|
||||
return 777
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun casLoopExpression(to: Long): Long = longArr[3].loop { cur ->
|
||||
if (longArr[3].compareAndSet(cur, to)) return longArr[3].value
|
||||
return 777
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoop(to: Int): Int {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return value
|
||||
return 777
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopExpression(to: Int): Int = loop { cur ->
|
||||
lazySet(cur + 10)
|
||||
return if (compareAndSet(cur, to)) value else incrementAndGet()
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopMixedReceivers(first: Int, second: Int, index: Int): Int {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, first)
|
||||
intArr[index].compareAndSet(first, second)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopRecursive(to: Int): Int {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, to)
|
||||
a.extensionLoop(5)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.foo(to: Int): Int {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return 777
|
||||
else return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.bar(delta: Int): Int {
|
||||
return foo(value + delta)
|
||||
}
|
||||
|
||||
fun testIntExtensionLoops() {
|
||||
assertEquals(5, casLoop(5))
|
||||
assertEquals(6, casLoopExpression(6))
|
||||
assertEquals(66, intArr[1].extensionLoop(66))
|
||||
assertEquals(66, intArr[2].extensionLoop(66))
|
||||
assertEquals(77, intArr[1].extensionLoopExpression(777))
|
||||
assertEquals(99, intArr[1].extensionLoopMixedReceivers(88, 99, 1))
|
||||
assertEquals(100, intArr[1].extensionLoopRecursive(100))
|
||||
assertEquals(777, intArr[1].bar(100))
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testClass = ArrayInlineExtensionTest()
|
||||
testClass.testIntExtensionLoops()
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
@kotlin.Metadata
|
||||
public final class ArrayInlineExtensionTest$A {
|
||||
// source: 'ArrayInlineExtensionTest.kt'
|
||||
private final @org.jetbrains.annotations.NotNull field s: java.lang.String
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
public final @org.jetbrains.annotations.NotNull method getS(): java.lang.String
|
||||
public final inner class ArrayInlineExtensionTest$A
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class ArrayInlineExtensionTest {
|
||||
// source: 'ArrayInlineExtensionTest.kt'
|
||||
private synthetic final static field a$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field a$volatile: int
|
||||
private synthetic final field intArr: java.util.concurrent.atomic.AtomicIntegerArray
|
||||
private synthetic final field longArr: java.util.concurrent.atomic.AtomicLongArray
|
||||
private synthetic final field refArr: java.util.concurrent.atomic.AtomicReferenceArray
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
private synthetic final method bar$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method bar$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private final method casLoop(p0: int): int
|
||||
private final method casLoopExpression(p0: long): long
|
||||
private synthetic final method extensionLoop$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method extensionLoop$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private synthetic final method extensionLoopExpression$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method extensionLoopExpression$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private synthetic final method extensionLoopMixedReceivers$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int, p4: int, p5: int): int
|
||||
private synthetic final method extensionLoopMixedReceivers$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int, p3: int, p4: int): int
|
||||
private synthetic final method extensionLoopRecursive$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method extensionLoopRecursive$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private synthetic final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getA$volatile(): int
|
||||
private synthetic final method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray
|
||||
private synthetic final method getLongArr(): java.util.concurrent.atomic.AtomicLongArray
|
||||
private synthetic final method getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray
|
||||
private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicIntegerArray, p1: int, p2: kotlin.jvm.functions.Function1): void
|
||||
private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicLongArray, p1: int, p2: kotlin.jvm.functions.Function1): void
|
||||
private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void
|
||||
private synthetic final method setA$volatile(p0: int): void
|
||||
public final method testIntExtensionLoops(): void
|
||||
public final inner class ArrayInlineExtensionTest$A
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class ArrayInlineExtensionTestKt {
|
||||
// source: 'ArrayInlineExtensionTest.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class ArrayInlineFunctionTest {
|
||||
private val anyArr = atomicArrayOfNulls<Any?>(5)
|
||||
private val refArr = atomicArrayOfNulls<Box>(5)
|
||||
|
||||
private data class Box(val n: Int)
|
||||
|
||||
fun testSetArrayElementValueInLoop() {
|
||||
anyArr[0].loop { cur ->
|
||||
assertTrue(anyArr[0].compareAndSet(cur, IntArray(5)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private fun action(cur: Box?) = cur?.let { Box(cur.n * 10) }
|
||||
|
||||
fun testArrayElementUpdate() {
|
||||
refArr[0].lazySet(Box(5))
|
||||
refArr[0].update { cur -> cur?.let { Box(cur.n * 10) } }
|
||||
assertEquals(refArr[0].value!!.n, 50)
|
||||
}
|
||||
|
||||
fun testArrayElementGetAndUpdate() {
|
||||
refArr[0].lazySet(Box(5))
|
||||
assertEquals(refArr[0].getAndUpdate { cur -> action(cur) }!!.n, 5)
|
||||
assertEquals(refArr[0].value!!.n, 50)
|
||||
}
|
||||
|
||||
fun testArrayElementUpdateAndGet() {
|
||||
refArr[0].lazySet(Box(5))
|
||||
assertEquals(refArr[0].updateAndGet { cur -> action(cur) }!!.n, 50)
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testClass = ArrayInlineFunctionTest()
|
||||
testClass.testSetArrayElementValueInLoop()
|
||||
testClass.testArrayElementGetAndUpdate()
|
||||
testClass.testArrayElementUpdate()
|
||||
testClass.testArrayElementUpdateAndGet()
|
||||
return "OK"
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
@kotlin.Metadata
|
||||
final class ArrayInlineFunctionTest$Box {
|
||||
// source: 'ArrayLoopTest.kt'
|
||||
private final field n: int
|
||||
public method <init>(p0: int): void
|
||||
public final method component1(): int
|
||||
public synthetic static method copy$default(p0: ArrayInlineFunctionTest$Box, p1: int, p2: int, p3: java.lang.Object): ArrayInlineFunctionTest$Box
|
||||
public final @org.jetbrains.annotations.NotNull method copy(p0: int): ArrayInlineFunctionTest$Box
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public final method getN(): int
|
||||
public method hashCode(): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
private final inner class ArrayInlineFunctionTest$Box
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class ArrayInlineFunctionTest {
|
||||
// source: 'ArrayLoopTest.kt'
|
||||
private synthetic final field anyArr: java.util.concurrent.atomic.AtomicReferenceArray
|
||||
private synthetic final field refArr: java.util.concurrent.atomic.AtomicReferenceArray
|
||||
public method <init>(): void
|
||||
private final method action(p0: ArrayInlineFunctionTest$Box): ArrayInlineFunctionTest$Box
|
||||
private synthetic final method getAndUpdate$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): java.lang.Object
|
||||
private synthetic final method getAnyArr(): java.util.concurrent.atomic.AtomicReferenceArray
|
||||
private synthetic final method getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray
|
||||
private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void
|
||||
public final method testArrayElementGetAndUpdate(): void
|
||||
public final method testArrayElementUpdate(): void
|
||||
public final method testArrayElementUpdateAndGet(): void
|
||||
public final method testSetArrayElementValueInLoop(): void
|
||||
private synthetic final method update$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void
|
||||
private synthetic final method updateAndGet$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): java.lang.Object
|
||||
private final inner class ArrayInlineFunctionTest$Box
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class ArrayLoopTestKt {
|
||||
// source: 'ArrayLoopTest.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class LoopTest {
|
||||
private val a = atomic(10)
|
||||
private val b = atomic(11)
|
||||
private val c = atomic(12)
|
||||
private val r = atomic<String>("aaa")
|
||||
private val intArr = AtomicIntArray(10)
|
||||
|
||||
private inline fun AtomicInt.extensionEmbeddedLoops(to: Int): Int =
|
||||
loop { cur1 ->
|
||||
compareAndSet(cur1, to)
|
||||
loop { cur2 ->
|
||||
return cur2
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun embeddedLoops(to: Int): Int =
|
||||
a.loop { aValue ->
|
||||
b.loop { bValue ->
|
||||
if (b.compareAndSet(bValue, to)) return aValue + bValue
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun embeddedUpdate(to: Int): Int =
|
||||
a.loop { aValue ->
|
||||
a.compareAndSet(aValue, to)
|
||||
return a.updateAndGet { cur -> cur + 100 }
|
||||
}
|
||||
|
||||
private inline fun AtomicRef<String>.extesntionEmbeddedRefUpdate(to: String): String =
|
||||
loop { value ->
|
||||
compareAndSet(value, to)
|
||||
return updateAndGet { cur -> "${cur}AAA" }
|
||||
}
|
||||
|
||||
fun test() {
|
||||
assertEquals(21, embeddedLoops(12))
|
||||
assertEquals(77, c.extensionEmbeddedLoops(77))
|
||||
assertEquals(66, intArr[0].extensionEmbeddedLoops(66))
|
||||
assertEquals(166, embeddedUpdate(66))
|
||||
assertEquals("bbbAAA", r.extesntionEmbeddedRefUpdate("bbb"))
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testClass = LoopTest()
|
||||
testClass.test()
|
||||
return "OK"
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
@kotlin.Metadata
|
||||
public final class ComplexLoopTestKt {
|
||||
// source: 'ComplexLoopTest.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class LoopTest {
|
||||
// source: 'ComplexLoopTest.kt'
|
||||
private synthetic final static field a$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field a$volatile: int
|
||||
private synthetic final static field b$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field b$volatile: int
|
||||
private synthetic final static field c$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field c$volatile: int
|
||||
private synthetic final field intArr: java.util.concurrent.atomic.AtomicIntegerArray
|
||||
private synthetic final static field r$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic volatile field r$volatile: java.lang.Object
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
private final method embeddedLoops(p0: int): int
|
||||
private final method embeddedUpdate(p0: int): int
|
||||
private synthetic final method extensionEmbeddedLoops$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method extensionEmbeddedLoops$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private synthetic final method extesntionEmbeddedRefUpdate$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.String): java.lang.String
|
||||
private synthetic final method extesntionEmbeddedRefUpdate$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.String): java.lang.String
|
||||
private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getA$volatile(): int
|
||||
private synthetic final static method getB$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getB$volatile(): int
|
||||
private synthetic final static method getC$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getC$volatile(): int
|
||||
private synthetic final method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray
|
||||
private synthetic final static method getR$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final method getR$volatile(): java.lang.Object
|
||||
private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicIntegerArray, p1: int, p2: kotlin.jvm.functions.Function1): void
|
||||
private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void
|
||||
private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void
|
||||
private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void
|
||||
private synthetic final method setA$volatile(p0: int): void
|
||||
private synthetic final method setB$volatile(p0: int): void
|
||||
private synthetic final method setC$volatile(p0: int): void
|
||||
private synthetic final method setR$volatile(p0: java.lang.Object): void
|
||||
public final method test(): void
|
||||
private synthetic final method updateAndGet$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): java.lang.Object
|
||||
private synthetic final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): int
|
||||
private synthetic final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): java.lang.Object
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class LoopTest {
|
||||
private val a = atomic(0)
|
||||
private val a1 = atomic(1)
|
||||
private val b = atomic(true)
|
||||
private val l = atomic(5000000000)
|
||||
private val r = atomic<A>(A("aaaa"))
|
||||
private val rs = atomic<String>("bbbb")
|
||||
|
||||
class A(val s: String)
|
||||
|
||||
private inline fun casLoop(to: Int): Int {
|
||||
a.loop { cur ->
|
||||
if (a.compareAndSet(cur, to)) return a.value
|
||||
return 777
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun casLoopExpression(to: Int): Int = a.loop { cur ->
|
||||
if (a.compareAndSet(cur, to)) return a.value
|
||||
return 777
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoop(to: Int): Int {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return value
|
||||
return 777
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopExpression(to: Int): Int = loop { cur ->
|
||||
lazySet(cur + 10)
|
||||
return if (compareAndSet(cur, to)) value else incrementAndGet()
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopMixedReceivers(first: Int, second: Int): Int {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, first)
|
||||
a.compareAndSet(first, second)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopRecursive(to: Int): Int {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, to)
|
||||
a.extensionLoop(5)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.foo(to: Int): Int {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return 777
|
||||
else return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.bar(delta: Int): Int {
|
||||
return foo(value + delta)
|
||||
}
|
||||
|
||||
fun testIntExtensionLoops() {
|
||||
assertEquals(5, casLoop(5))
|
||||
assertEquals(6, casLoopExpression(6))
|
||||
assertEquals(66, a.extensionLoop(66))
|
||||
assertEquals(77, a.extensionLoopExpression(777))
|
||||
assertEquals(99, a.extensionLoopMixedReceivers(88, 99))
|
||||
assertEquals(5, a.extensionLoopRecursive(100))
|
||||
assertEquals(777, a.bar(100))
|
||||
}
|
||||
}
|
||||
|
||||
private val ref = atomic<String>("aaa")
|
||||
|
||||
private inline fun AtomicRef<String>.topLevelExtensionLoop(to: String): String = loop { cur ->
|
||||
lazySet(cur + to)
|
||||
return value
|
||||
}
|
||||
|
||||
fun testTopLevelExtensionLoop() {
|
||||
assertEquals("aaattt", ref.topLevelExtensionLoop("ttt"))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testClass = LoopTest()
|
||||
testClass.testIntExtensionLoops()
|
||||
testTopLevelExtensionLoop()
|
||||
return "OK"
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
@kotlin.Metadata
|
||||
synthetic final class ExtensionLoopTest$VolatileWrapper$atomicfu$private {
|
||||
// source: 'ExtensionLoopTest.kt'
|
||||
private synthetic final static field ref$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic volatile field ref$volatile: java.lang.Object
|
||||
static method <clinit>(): void
|
||||
private method <init>(): void
|
||||
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public synthetic final static method access$getRef$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final static method getRef$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final method getRef$volatile(): java.lang.Object
|
||||
private synthetic final method setRef$volatile(p0: java.lang.Object): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class ExtensionLoopTestKt {
|
||||
// source: 'ExtensionLoopTest.kt'
|
||||
private synthetic final static field extensionLoopTest$VolatileWrapper$atomicfu$private: ExtensionLoopTest$VolatileWrapper$atomicfu$private
|
||||
static method <clinit>(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
private synthetic final static method getExtensionLoopTest$VolatileWrapper$atomicfu$private(): ExtensionLoopTest$VolatileWrapper$atomicfu$private
|
||||
private synthetic final static method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void
|
||||
private synthetic final static method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void
|
||||
public final static method testTopLevelExtensionLoop(): void
|
||||
private synthetic final static method topLevelExtensionLoop$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.String): java.lang.String
|
||||
private synthetic final static method topLevelExtensionLoop$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.String): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class LoopTest$A {
|
||||
// source: 'ExtensionLoopTest.kt'
|
||||
private final @org.jetbrains.annotations.NotNull field s: java.lang.String
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
public final @org.jetbrains.annotations.NotNull method getS(): java.lang.String
|
||||
public final inner class LoopTest$A
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class LoopTest {
|
||||
// source: 'ExtensionLoopTest.kt'
|
||||
private synthetic final static field a$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field a$volatile: int
|
||||
private synthetic final static field a1$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field a1$volatile: int
|
||||
private synthetic final static field b$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field b$volatile: int
|
||||
private synthetic final static field l$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater
|
||||
private synthetic volatile field l$volatile: long
|
||||
private synthetic final static field r$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic volatile field r$volatile: java.lang.Object
|
||||
private synthetic final static field rs$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic volatile field rs$volatile: java.lang.Object
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
private synthetic final method bar$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method bar$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private final method casLoop(p0: int): int
|
||||
private final method casLoopExpression(p0: int): int
|
||||
private synthetic final method extensionLoop$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method extensionLoop$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private synthetic final method extensionLoopExpression$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method extensionLoopExpression$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private synthetic final method extensionLoopMixedReceivers$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int, p4: int): int
|
||||
private synthetic final method extensionLoopMixedReceivers$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int, p3: int): int
|
||||
private synthetic final method extensionLoopRecursive$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method extensionLoopRecursive$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private synthetic final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int
|
||||
private synthetic final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int
|
||||
private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getA$volatile(): int
|
||||
private synthetic final static method getA1$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getA1$volatile(): int
|
||||
private synthetic final static method getB$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getB$volatile(): int
|
||||
private synthetic final static method getL$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater
|
||||
private synthetic final method getL$volatile(): long
|
||||
private synthetic final static method getR$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final method getR$volatile(): java.lang.Object
|
||||
private synthetic final static method getRs$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final method getRs$volatile(): java.lang.Object
|
||||
private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicIntegerArray, p1: int, p2: kotlin.jvm.functions.Function1): void
|
||||
private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void
|
||||
private synthetic final method setA$volatile(p0: int): void
|
||||
private synthetic final method setA1$volatile(p0: int): void
|
||||
private synthetic final method setB$volatile(p0: int): void
|
||||
private synthetic final method setL$volatile(p0: long): void
|
||||
private synthetic final method setR$volatile(p0: java.lang.Object): void
|
||||
private synthetic final method setRs$volatile(p0: java.lang.Object): void
|
||||
public final method testIntExtensionLoops(): void
|
||||
public final inner class LoopTest$A
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class ExtensionsTest {
|
||||
private val a = atomic(0)
|
||||
private val l = atomic(0L)
|
||||
private val s = atomic<String?>(null)
|
||||
private val b = atomic(true)
|
||||
|
||||
fun testScopedFieldGetters() {
|
||||
check(a.value == 0)
|
||||
val update = 3
|
||||
a.lazySet(update)
|
||||
check(a.compareAndSet(update, 8))
|
||||
a.lazySet(1)
|
||||
check(a.value == 1)
|
||||
check(a.getAndSet(2) == 1)
|
||||
check(a.value == 2)
|
||||
check(a.getAndIncrement() == 2)
|
||||
check(a.value == 3)
|
||||
check(a.getAndDecrement() == 3)
|
||||
check(a.value == 2)
|
||||
check(a.getAndAdd(2) == 2)
|
||||
check(a.value == 4)
|
||||
check(a.addAndGet(3) == 7)
|
||||
check(a.value == 7)
|
||||
check(a.incrementAndGet() == 8)
|
||||
check(a.value == 8)
|
||||
check(a.decrementAndGet() == 7)
|
||||
check(a.value == 7)
|
||||
check(a.compareAndSet(7, 10))
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.intExtensionArithmetic() {
|
||||
value = 0
|
||||
check(value == 0)
|
||||
val update = 3
|
||||
lazySet(update)
|
||||
check(compareAndSet(update, 8))
|
||||
lazySet(1)
|
||||
check(value == 1)
|
||||
check(getAndSet(2) == 1)
|
||||
check(value == 2)
|
||||
check(getAndIncrement() == 2)
|
||||
check(value == 3)
|
||||
check(getAndDecrement() == 3)
|
||||
check(value == 2)
|
||||
check(getAndAdd(2) == 2)
|
||||
check(value == 4)
|
||||
check(addAndGet(3) == 7)
|
||||
check(value == 7)
|
||||
check(incrementAndGet() == 8)
|
||||
check(value == 8)
|
||||
check(decrementAndGet() == 7)
|
||||
check(value == 7)
|
||||
check(compareAndSet(7, 10))
|
||||
check(compareAndSet(value, 55))
|
||||
check(value == 55)
|
||||
}
|
||||
|
||||
private inline fun AtomicLong.longExtensionArithmetic() {
|
||||
value = 2424920024888888848
|
||||
check(value == 2424920024888888848)
|
||||
lazySet(8424920024888888848)
|
||||
check(value == 8424920024888888848)
|
||||
check(getAndSet(8924920024888888848) == 8424920024888888848)
|
||||
check(value == 8924920024888888848)
|
||||
check(incrementAndGet() == 8924920024888888849) // fails
|
||||
check(value == 8924920024888888849)
|
||||
check(getAndDecrement() == 8924920024888888849)
|
||||
check(value == 8924920024888888848)
|
||||
check(getAndAdd(100000000000000000) == 8924920024888888848)
|
||||
check(value == 9024920024888888848)
|
||||
check(addAndGet(-9223372036854775807) == -198452011965886959)
|
||||
check(value == -198452011965886959)
|
||||
check(incrementAndGet() == -198452011965886958)
|
||||
check(value == -198452011965886958)
|
||||
check(decrementAndGet() == -198452011965886959)
|
||||
check(value == -198452011965886959)
|
||||
}
|
||||
|
||||
private inline fun AtomicRef<String?>.refExtension() {
|
||||
value = "aaa"
|
||||
check(value == "aaa")
|
||||
lazySet("bb")
|
||||
check(value == "bb")
|
||||
check(getAndSet("ccc") == "bb")
|
||||
check(value == "ccc")
|
||||
}
|
||||
|
||||
private inline fun AtomicBoolean.booleanExtensionArithmetic() {
|
||||
value = false
|
||||
check(!value)
|
||||
lazySet(true)
|
||||
check(value)
|
||||
check(getAndSet(true))
|
||||
check(compareAndSet(value, false))
|
||||
check(!value)
|
||||
}
|
||||
|
||||
fun testExtension() {
|
||||
a.intExtensionArithmetic()
|
||||
l.longExtensionArithmetic()
|
||||
s.refExtension()
|
||||
b.booleanExtensionArithmetic()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val testClass = ExtensionsTest()
|
||||
testClass.testScopedFieldGetters()
|
||||
testClass.testExtension()
|
||||
return "OK"
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
@kotlin.Metadata
|
||||
public final class ExtensionsTest {
|
||||
// source: 'ExtensionsTest.kt'
|
||||
private synthetic final static field a$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field a$volatile: int
|
||||
private synthetic final static field b$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field b$volatile: int
|
||||
private synthetic final static field l$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater
|
||||
private synthetic volatile field l$volatile: long
|
||||
private synthetic final static field s$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic volatile field s$volatile: java.lang.Object
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
private synthetic final method booleanExtensionArithmetic$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int): void
|
||||
private synthetic final method booleanExtensionArithmetic$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater): void
|
||||
private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getA$volatile(): int
|
||||
private synthetic final static method getB$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getB$volatile(): int
|
||||
private synthetic final static method getL$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater
|
||||
private synthetic final method getL$volatile(): long
|
||||
private synthetic final static method getS$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final method getS$volatile(): java.lang.Object
|
||||
private synthetic final method intExtensionArithmetic$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int): void
|
||||
private synthetic final method intExtensionArithmetic$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater): void
|
||||
private synthetic final method longExtensionArithmetic$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicLongArray, p2: int): void
|
||||
private synthetic final method longExtensionArithmetic$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicLongFieldUpdater): void
|
||||
private synthetic final method refExtension$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int): void
|
||||
private synthetic final method refExtension$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater): void
|
||||
private synthetic final method setA$volatile(p0: int): void
|
||||
private synthetic final method setB$volatile(p0: int): void
|
||||
private synthetic final method setL$volatile(p0: long): void
|
||||
private synthetic final method setS$volatile(p0: java.lang.Object): void
|
||||
public final method testExtension(): void
|
||||
public final method testScopedFieldGetters(): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class ExtensionsTestKt {
|
||||
// source: 'ExtensionsTest.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class InlineExtensionWithTypeParameterTest {
|
||||
abstract class Segment<S : Segment<S>>(val id: Int)
|
||||
class SemaphoreSegment(id: Int) : Segment<SemaphoreSegment>(id)
|
||||
|
||||
private inline fun <S : Segment<S>> AtomicRef<S>.foo(
|
||||
id: Int,
|
||||
startFrom: S
|
||||
): Int {
|
||||
lazySet(startFrom)
|
||||
return value.getSegmentId()
|
||||
}
|
||||
|
||||
private inline fun <S : Segment<S>> S.getSegmentId(): Int {
|
||||
var cur: S = this
|
||||
return cur.id
|
||||
}
|
||||
|
||||
private val sref = atomic(SemaphoreSegment(0))
|
||||
|
||||
fun testInlineExtensionWithTypeParameter() {
|
||||
val s = SemaphoreSegment(77)
|
||||
assertEquals(77, sref.foo(0, s))
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testClass = InlineExtensionWithTypeParameterTest()
|
||||
testClass.testInlineExtensionWithTypeParameter()
|
||||
return "OK"
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
@kotlin.Metadata
|
||||
public abstract class InlineExtensionWithTypeParameterTest$Segment {
|
||||
// source: 'InlineExtensionWithTypeParameterTest.kt'
|
||||
private final field id: int
|
||||
public method <init>(p0: int): void
|
||||
public final method getId(): int
|
||||
public abstract inner class InlineExtensionWithTypeParameterTest$Segment
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class InlineExtensionWithTypeParameterTest$SemaphoreSegment {
|
||||
// source: 'InlineExtensionWithTypeParameterTest.kt'
|
||||
public method <init>(p0: int): void
|
||||
public abstract inner class InlineExtensionWithTypeParameterTest$Segment
|
||||
public final inner class InlineExtensionWithTypeParameterTest$SemaphoreSegment
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class InlineExtensionWithTypeParameterTest {
|
||||
// source: 'InlineExtensionWithTypeParameterTest.kt'
|
||||
private synthetic final static field sref$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic volatile field sref$volatile: java.lang.Object
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
private synthetic final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: int, p4: InlineExtensionWithTypeParameterTest$Segment): int
|
||||
private synthetic final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: int, p3: InlineExtensionWithTypeParameterTest$Segment): int
|
||||
private final method getSegmentId(p0: InlineExtensionWithTypeParameterTest$Segment): int
|
||||
private synthetic final static method getSref$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final method getSref$volatile(): java.lang.Object
|
||||
private synthetic final method setSref$volatile(p0: java.lang.Object): void
|
||||
public final method testInlineExtensionWithTypeParameter(): void
|
||||
public abstract inner class InlineExtensionWithTypeParameterTest$Segment
|
||||
public final inner class InlineExtensionWithTypeParameterTest$SemaphoreSegment
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class InlineExtensionWithTypeParameterTestKt {
|
||||
// source: 'InlineExtensionWithTypeParameterTest.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class LambdaTest {
|
||||
private val a = atomic(0)
|
||||
private val rs = atomic<String>("bbbb")
|
||||
|
||||
private inline fun <T> inlineLambda(
|
||||
arg: T,
|
||||
crossinline block: (T) -> Unit
|
||||
) = block(arg)
|
||||
|
||||
fun loopInLambda1(to: Int) = inlineLambda(to) sc@ { arg ->
|
||||
a.loop { value ->
|
||||
a.compareAndSet(value, arg)
|
||||
return@sc
|
||||
}
|
||||
}
|
||||
|
||||
fun loopInLambda2(to: Int) = inlineLambda(to) { arg1 ->
|
||||
inlineLambda(arg1) sc@ { arg2 ->
|
||||
a.loop { value ->
|
||||
a.compareAndSet(value, arg2)
|
||||
return@sc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loopInLambda2Ref(to: String) = inlineLambda(to) { arg1 ->
|
||||
inlineLambda(arg1) sc@ { arg2 ->
|
||||
rs.loop { value ->
|
||||
rs.compareAndSet(value, arg2)
|
||||
return@sc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
loopInLambda1(34)
|
||||
assertEquals(34, a.value)
|
||||
loopInLambda1(77)
|
||||
assertEquals(77, a.value)
|
||||
loopInLambda2Ref("bbb")
|
||||
assertEquals("bbb", rs.value)
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testClass = LambdaTest()
|
||||
testClass.test()
|
||||
return "OK"
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
@kotlin.Metadata
|
||||
public final class LambdaTest {
|
||||
// source: 'LambdaTest.kt'
|
||||
private synthetic final static field a$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field a$volatile: int
|
||||
private synthetic final static field rs$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic volatile field rs$volatile: java.lang.Object
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
public synthetic final static method access$getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
public synthetic final static method access$getRs$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getA$volatile(): int
|
||||
private synthetic final static method getRs$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final method getRs$volatile(): java.lang.Object
|
||||
private final method inlineLambda(p0: java.lang.Object, p1: kotlin.jvm.functions.Function1): void
|
||||
private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void
|
||||
private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void
|
||||
public final method loopInLambda1(p0: int): void
|
||||
public final method loopInLambda2(p0: int): void
|
||||
public final method loopInLambda2Ref(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
private synthetic final method setA$volatile(p0: int): void
|
||||
private synthetic final method setRs$volatile(p0: java.lang.Object): void
|
||||
public final method test(): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class LambdaTestKt {
|
||||
// source: 'LambdaTest.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class LockFreeIntBitsTest {
|
||||
fun testBasic() {
|
||||
val bs = LockFreeIntBits()
|
||||
assertTrue(!bs[0])
|
||||
assertTrue(bs.bitSet(0))
|
||||
assertTrue(bs[0])
|
||||
assertTrue(!bs.bitSet(0))
|
||||
|
||||
assertTrue(!bs[1])
|
||||
assertTrue(bs.bitSet(1))
|
||||
assertTrue(bs[1])
|
||||
assertTrue(!bs.bitSet(1))
|
||||
assertTrue(!bs.bitSet(0))
|
||||
|
||||
assertTrue(bs[0])
|
||||
assertTrue(bs.bitClear(0))
|
||||
assertTrue(!bs.bitClear(0))
|
||||
|
||||
assertTrue(bs[1])
|
||||
}
|
||||
}
|
||||
|
||||
class LockFreeIntBits {
|
||||
private val bits = atomic(0)
|
||||
|
||||
private fun Int.mask() = 1 shl this
|
||||
|
||||
operator fun get(index: Int): Boolean = bits.value and index.mask() != 0
|
||||
|
||||
// User-defined private inline function
|
||||
private inline fun bitUpdate(check: (Int) -> Boolean, upd: (Int) -> Int): Boolean {
|
||||
bits.update {
|
||||
if (check(it)) return false
|
||||
upd(it)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun bitSet(index: Int): Boolean {
|
||||
val mask = index.mask()
|
||||
return bitUpdate({ it and mask != 0 }, { it or mask })
|
||||
}
|
||||
|
||||
fun bitClear(index: Int): Boolean {
|
||||
val mask = index.mask()
|
||||
return bitUpdate({ it and mask == 0 }, { it and mask.inv() })
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testClass = LockFreeIntBitsTest()
|
||||
testClass.testBasic()
|
||||
return "OK"
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
@kotlin.Metadata
|
||||
public final class LockFreeIntBits {
|
||||
// source: 'LockFreeIntBitsTest.kt'
|
||||
private synthetic final static field bits$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field bits$volatile: int
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
public final method bitClear(p0: int): boolean
|
||||
public final method bitSet(p0: int): boolean
|
||||
private final method bitUpdate(p0: kotlin.jvm.functions.Function1, p1: kotlin.jvm.functions.Function1): boolean
|
||||
public final method get(p0: int): boolean
|
||||
private synthetic final static method getBits$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getBits$volatile(): int
|
||||
private final method mask(p0: int): int
|
||||
private synthetic final method setBits$volatile(p0: int): void
|
||||
private synthetic final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class LockFreeIntBitsTest {
|
||||
// source: 'LockFreeIntBitsTest.kt'
|
||||
public method <init>(): void
|
||||
public final method testBasic(): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class LockFreeIntBitsTestKt {
|
||||
// source: 'LockFreeIntBitsTest.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class LockTest {
|
||||
private val inProgressLock = atomic(false)
|
||||
|
||||
fun testLock() {
|
||||
var result = ""
|
||||
if (inProgressLock.tryAcquire()) {
|
||||
result = "OK"
|
||||
}
|
||||
assertEquals("OK", result)
|
||||
}
|
||||
}
|
||||
|
||||
// This function will be removed by transformer
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
private inline fun AtomicBoolean.tryAcquire(): Boolean = compareAndSet(false, true)
|
||||
|
||||
// This function is here to test if the Kotlin metadata still consistent after transform
|
||||
// It is used in ReflectionTest, DO NOT REMOVE
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun <AA, BB : Number> String.reflectionTest(mapParam: Map<in AA, BB>): List<BB> = error("no impl")
|
||||
|
||||
fun box(): String {
|
||||
val testClass = LockTest()
|
||||
testClass.testLock()
|
||||
return "OK"
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
@kotlin.Metadata
|
||||
public final class LockTest {
|
||||
// source: 'LockTest.kt'
|
||||
private synthetic final static field inProgressLock$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field inProgressLock$volatile: int
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
private synthetic final static method getInProgressLock$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method getInProgressLock$volatile(): int
|
||||
private synthetic final method setInProgressLock$volatile(p0: int): void
|
||||
public final method testLock(): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class LockTestKt {
|
||||
// source: 'LockTest.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static @org.jetbrains.annotations.NotNull method reflectionTest(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: java.util.Map): java.util.List
|
||||
private synthetic final static method tryAcquire$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int): boolean
|
||||
private synthetic final static method tryAcquire$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater): boolean
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class ParameterizedInlineFunExtensionTest {
|
||||
|
||||
private inline fun <S> AtomicRef<S>.foo(res1: S, res2: S, foo: (S) -> S): S {
|
||||
val res = bar(res1, res2)
|
||||
return res
|
||||
}
|
||||
|
||||
private inline fun <S> AtomicRef<S>.bar(res1: S, res2: S): S {
|
||||
return res2
|
||||
}
|
||||
|
||||
private val tail = atomic("aaa")
|
||||
|
||||
fun testClose() {
|
||||
val res = tail.foo("bbb", "ccc") { s -> s }
|
||||
assertEquals("ccc", res)
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testClass = ParameterizedInlineFunExtensionTest()
|
||||
testClass.testClose()
|
||||
return "OK"
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
@kotlin.Metadata
|
||||
public final class ParameterizedInlineFunExtensionTest {
|
||||
// source: 'ParameterizedInlineFunExtensionTest.kt'
|
||||
private synthetic final static field tail$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic volatile field tail$volatile: java.lang.Object
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
private synthetic final method bar$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.Object, p4: java.lang.Object): java.lang.Object
|
||||
private synthetic final method bar$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.Object, p3: java.lang.Object): java.lang.Object
|
||||
private synthetic final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.Object, p4: java.lang.Object, p5: kotlin.jvm.functions.Function1): java.lang.Object
|
||||
private synthetic final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.Object, p3: java.lang.Object, p4: kotlin.jvm.functions.Function1): java.lang.Object
|
||||
private synthetic final static method getTail$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final method getTail$volatile(): java.lang.Object
|
||||
private synthetic final method setTail$volatile(p0: java.lang.Object): void
|
||||
public final method testClose(): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class ParameterizedInlineFunExtensionTestKt {
|
||||
// source: 'ParameterizedInlineFunExtensionTest.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
Reference in New Issue
Block a user