[K/N] Do not compile for deprecated targets and legacy MM
^KT-56533 ^KT-58853
This commit is contained in:
committed by
Space Team
parent
d1ce55cbd2
commit
aea8bac7d2
@@ -1,194 +0,0 @@
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class)
|
||||
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.native.runtime.GC
|
||||
import kotlin.native.Platform
|
||||
import kotlin.test.*
|
||||
|
||||
fun test1() {
|
||||
val a = AtomicReference<Any?>(null)
|
||||
val b = AtomicReference<Any?>(null)
|
||||
a.value = b
|
||||
b.value = a
|
||||
}
|
||||
|
||||
class Holder(var other: Any?)
|
||||
|
||||
fun test2() {
|
||||
val array = arrayOf(AtomicReference<Any?>(null), AtomicReference<Any?>(null))
|
||||
val obj1 = Holder(array).freeze()
|
||||
array[0].value = obj1
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
val a1 = FreezableAtomicReference<Any?>(null)
|
||||
val head = Holder(null)
|
||||
var current = head
|
||||
repeat(30) {
|
||||
val next = Holder(null)
|
||||
current.other = next
|
||||
current = next
|
||||
}
|
||||
a1.value = head
|
||||
current.other = a1
|
||||
current.freeze()
|
||||
}
|
||||
|
||||
|
||||
fun makeIt(): Holder {
|
||||
val atomic = AtomicReference<Holder?>(null)
|
||||
val holder = Holder(atomic).freeze()
|
||||
atomic.value = holder
|
||||
return holder
|
||||
}
|
||||
|
||||
|
||||
fun test4() {
|
||||
val holder = makeIt()
|
||||
// To clean rc count coming from rememberNewContainer().
|
||||
kotlin.native.runtime.GC.collect()
|
||||
// Request cyclic collection.
|
||||
kotlin.native.runtime.GC.collectCyclic()
|
||||
// Ensure we processed delayed release.
|
||||
repeat(10) {
|
||||
// Wait a bit and process queue.
|
||||
Worker.current.park(10)
|
||||
Worker.current.processQueue()
|
||||
kotlin.native.runtime.GC.collect()
|
||||
}
|
||||
val value = @Suppress("UNCHECKED_CAST") (holder.other as? AtomicReference<Holder?>?)
|
||||
assertTrue(value != null)
|
||||
assertTrue(value.value == holder)
|
||||
}
|
||||
|
||||
fun createRef(): AtomicReference<Any?> {
|
||||
val atomic1 = AtomicReference<Any?>(null)
|
||||
val atomic2 = AtomicReference<Any?>(null)
|
||||
atomic1.value = atomic2
|
||||
atomic2.value = atomic1
|
||||
return atomic1
|
||||
}
|
||||
|
||||
class Holder2(var value: AtomicReference<Any?>) {
|
||||
fun switch() {
|
||||
value = value.value as AtomicReference<Any?>
|
||||
}
|
||||
}
|
||||
|
||||
fun createHolder2() = Holder2(createRef())
|
||||
|
||||
fun test5() {
|
||||
val holder = createHolder2()
|
||||
kotlin.native.runtime.GC.collect()
|
||||
kotlin.native.runtime.GC.collectCyclic()
|
||||
Worker.current.park(100 * 1000)
|
||||
holder.switch()
|
||||
kotlin.native.runtime.GC.collect()
|
||||
Worker.current.park(100 * 1000)
|
||||
withWorker {
|
||||
executeAfter(0L, {
|
||||
kotlin.native.runtime.GC.collect()
|
||||
}.freeze())
|
||||
}
|
||||
Worker.current.park(1000)
|
||||
assertTrue(holder.value.value != null)
|
||||
}
|
||||
|
||||
fun test6() {
|
||||
val atomic = AtomicReference<Any?>(null)
|
||||
atomic.value = Pair(atomic, Holder(atomic)).freeze()
|
||||
}
|
||||
|
||||
fun createRoot(): AtomicReference<Any?> {
|
||||
val ref1 = AtomicReference<Any?>(null)
|
||||
val ref2 = AtomicReference<Any?>(null)
|
||||
|
||||
ref1.value = Holder(ref2).freeze()
|
||||
ref2.value = Any().freeze()
|
||||
|
||||
return ref1
|
||||
}
|
||||
|
||||
fun test7() {
|
||||
val ref1 = createRoot()
|
||||
kotlin.native.runtime.GC.collect()
|
||||
|
||||
kotlin.native.runtime.GC.collectCyclic()
|
||||
Worker.current.park(500 * 1000L)
|
||||
|
||||
withWorker {
|
||||
executeAfter(0L, {}.freeze())
|
||||
Worker.current.park(500 * 1000L)
|
||||
|
||||
val node = ref1.value as Holder
|
||||
val ref2 = node.other as AtomicReference<Any?>
|
||||
assertTrue(ref2.value != null)
|
||||
}
|
||||
}
|
||||
|
||||
fun array(size: Int) = Array<Any?>(size, { null })
|
||||
|
||||
fun test8() {
|
||||
val ref = AtomicReference<Any?>(null)
|
||||
val obj1 = array(2)
|
||||
val obj2 = array(1)
|
||||
val obj3 = array(2)
|
||||
|
||||
obj1[0] = obj2
|
||||
obj1[1] = obj3
|
||||
|
||||
obj2[0] = obj3
|
||||
|
||||
obj3[0] = obj2
|
||||
obj3[1] = ref
|
||||
|
||||
ref.value = obj1.freeze()
|
||||
}
|
||||
|
||||
fun createNode1(): Holder {
|
||||
val ref = AtomicReference<Any?>(null)
|
||||
val node2 = Holder(ref)
|
||||
val node1 = Holder(node2)
|
||||
ref.value = node1.freeze()
|
||||
|
||||
return node1
|
||||
}
|
||||
|
||||
fun getNode2(): Holder {
|
||||
val node1 = createNode1()
|
||||
GC.collect()
|
||||
|
||||
return node1.other as Holder
|
||||
}
|
||||
|
||||
fun test9() {
|
||||
withWorker {
|
||||
val node2 = getNode2()
|
||||
executeAfter(10 * 1000L, { GC.collectCyclic() }.freeze())
|
||||
|
||||
GC.collect()
|
||||
|
||||
Worker.current.park(50 * 1000L)
|
||||
|
||||
execute(TransferMode.SAFE, {}, {}).result
|
||||
|
||||
val ref = node2.other as AtomicReference<Any?>
|
||||
assertTrue(ref.value != null)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
Platform.isMemoryLeakCheckerActive = true
|
||||
kotlin.native.runtime.GC.cyclicCollectorEnabled = true
|
||||
test1()
|
||||
test2()
|
||||
test3()
|
||||
test4()
|
||||
repeat(10) {
|
||||
test5()
|
||||
}
|
||||
test6()
|
||||
test7()
|
||||
test8()
|
||||
test9()
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.test.*
|
||||
|
||||
@OptIn(kotlin.native.runtime.NativeRuntimeApi::class)
|
||||
fun main() {
|
||||
kotlin.native.runtime.GC.cyclicCollectorEnabled = true
|
||||
|
||||
repeat(10000) {
|
||||
// Create atomic cyclic garbage:
|
||||
val ref = AtomicReference<Any?>(null)
|
||||
ref.value = ref
|
||||
}
|
||||
|
||||
// main thread will then run cycle collector termination, which involves running it and cleaning everything up.
|
||||
// 10000 references should hit [kGcThreshold] then.
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class)
|
||||
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.native.runtime.GC
|
||||
import kotlin.native.Platform
|
||||
import kotlin.test.*
|
||||
|
||||
class Holder(var other: Any?)
|
||||
|
||||
class Holder2(var field1: Any?, var field2: Any?)
|
||||
|
||||
val <T> Array<T>.description: String
|
||||
get() {
|
||||
val result = StringBuilder()
|
||||
result.append('[')
|
||||
for (elem in this) {
|
||||
result.append(elem.toString())
|
||||
result.append(',')
|
||||
}
|
||||
result.append(']')
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
fun assertArrayEquals(
|
||||
expected: Array<Any>,
|
||||
actual: Array<Any>
|
||||
): Unit {
|
||||
val lazyMessage: () -> String? = {
|
||||
"Expected <${expected.description}>, actual <${actual.description}>."
|
||||
}
|
||||
|
||||
asserter.assertTrue(lazyMessage, expected.size == actual.size)
|
||||
for (i in expected.indices) {
|
||||
asserter.assertTrue(lazyMessage, expected[i] == actual[i])
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
fun enableMemoryChecker() {
|
||||
Platform.isMemoryLeakCheckerActive = true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun noCycles() {
|
||||
val atomic1 = AtomicReference<Any?>(null)
|
||||
val atomic2 = AtomicReference<Any?>(null)
|
||||
try {
|
||||
atomic1.value = atomic2
|
||||
val cycles = GC.detectCycles()!!
|
||||
assertEquals(0, cycles.size)
|
||||
assertNull(GC.findCycle(atomic1));
|
||||
assertNull(GC.findCycle(atomic2));
|
||||
} finally {
|
||||
atomic1.value = null
|
||||
atomic2.value = null
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun oneCycle() {
|
||||
val atomic = AtomicReference<Any?>(null)
|
||||
try {
|
||||
atomic.value = atomic
|
||||
val cycles = GC.detectCycles()!!
|
||||
assertEquals(1, cycles.size)
|
||||
assertArrayEquals(arrayOf(atomic, atomic), GC.findCycle(cycles[0])!!)
|
||||
} finally {
|
||||
atomic.value = null
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun oneCycleWithHolder() {
|
||||
val atomic = AtomicReference<Any?>(null)
|
||||
try {
|
||||
atomic.value = Holder(atomic).freeze()
|
||||
val cycles = GC.detectCycles()!!
|
||||
assertEquals(1, cycles.size)
|
||||
assertArrayEquals(arrayOf(atomic, atomic.value!!, atomic), GC.findCycle(cycles[0])!!)
|
||||
assertArrayEquals(arrayOf(atomic.value!!, atomic, atomic.value!!), GC.findCycle(atomic.value!!)!!)
|
||||
} finally {
|
||||
atomic.value = null
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun oneCycleWithArray() {
|
||||
val array = arrayOf(AtomicReference<Any?>(null), AtomicReference<Any?>(null))
|
||||
try {
|
||||
array[0].value = Holder(array).freeze()
|
||||
val cycles = GC.detectCycles()!!
|
||||
assertEquals(1, cycles.size)
|
||||
assertArrayEquals(arrayOf(array[0], array[0].value!!, array, array[0]), GC.findCycle(cycles[0])!!)
|
||||
} finally {
|
||||
array[0].value = null
|
||||
array[1].value = null
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun oneCycleWithLongChain() {
|
||||
val atomic = AtomicReference<Any?>(null)
|
||||
try {
|
||||
val head = Holder(null)
|
||||
var current = head
|
||||
repeat(30) {
|
||||
val next = Holder(null)
|
||||
current.other = next
|
||||
current = next
|
||||
}
|
||||
current.other = atomic
|
||||
atomic.value = head.freeze()
|
||||
val cycles = GC.detectCycles()!!
|
||||
assertEquals(1, cycles.size)
|
||||
val cycle = GC.findCycle(cycles[0])!!
|
||||
assertEquals(33, cycle.size)
|
||||
} finally {
|
||||
atomic.value = null
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun twoCycles() {
|
||||
val atomic1 = AtomicReference<Any?>(null)
|
||||
val atomic2 = AtomicReference<Any?>(null)
|
||||
try {
|
||||
atomic1.value = atomic2
|
||||
atomic2.value = atomic1
|
||||
val cycles = GC.detectCycles()!!
|
||||
assertEquals(2, cycles.size)
|
||||
assertArrayEquals(arrayOf(atomic2, atomic1, atomic2), GC.findCycle(cycles[0])!!)
|
||||
assertArrayEquals(arrayOf(atomic1, atomic2, atomic1), GC.findCycle(cycles[1])!!)
|
||||
} finally {
|
||||
atomic1.value = null
|
||||
atomic2.value = null
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun twoCyclesWithHolder() {
|
||||
val atomic1 = AtomicReference<Any?>(null)
|
||||
val atomic2 = AtomicReference<Any?>(null)
|
||||
try {
|
||||
atomic1.value = atomic2
|
||||
atomic2.value = Holder(atomic1).freeze()
|
||||
val cycles = GC.detectCycles()!!
|
||||
assertEquals(2, cycles.size)
|
||||
assertArrayEquals(arrayOf(atomic2, atomic2.value!!, atomic1, atomic2), GC.findCycle(cycles[0])!!)
|
||||
assertArrayEquals(arrayOf(atomic1, atomic2, atomic2.value!!, atomic1), GC.findCycle(cycles[1])!!)
|
||||
} finally {
|
||||
atomic1.value = null
|
||||
atomic2.value = null
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun threeSeparateCycles() {
|
||||
val atomic1 = AtomicReference<Any?>(null)
|
||||
val atomic2 = AtomicReference<Any?>(null)
|
||||
val atomic3 = AtomicReference<Any?>(null)
|
||||
try {
|
||||
atomic1.value = atomic1
|
||||
atomic2.value = Holder2(atomic1, atomic2).freeze()
|
||||
atomic3.value = Holder2(atomic3, atomic1).freeze()
|
||||
val cycles = GC.detectCycles()!!
|
||||
assertEquals(3, cycles.size)
|
||||
assertArrayEquals(arrayOf(atomic3, atomic3.value!!, atomic3), GC.findCycle(cycles[0])!!)
|
||||
assertArrayEquals(arrayOf(atomic2, atomic2.value!!, atomic2), GC.findCycle(cycles[1])!!)
|
||||
assertArrayEquals(arrayOf(atomic1, atomic1), GC.findCycle(cycles[2])!!)
|
||||
} finally {
|
||||
atomic1.value = null
|
||||
atomic2.value = null
|
||||
atomic3.value = null
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun noCyclesWithFreezableAtomicReference() {
|
||||
val atomic = FreezableAtomicReference<Any?>(null)
|
||||
try {
|
||||
atomic.value = atomic
|
||||
val cycles = GC.detectCycles()!!
|
||||
assertEquals(0, cycles.size)
|
||||
} finally {
|
||||
atomic.value = null
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun oneCycleWithFrozenFreezableAtomicReference() {
|
||||
val atomic = FreezableAtomicReference<Any?>(null)
|
||||
try {
|
||||
atomic.value = atomic
|
||||
atomic.freeze()
|
||||
val cycles = GC.detectCycles()!!
|
||||
assertEquals(1, cycles.size)
|
||||
assertArrayEquals(arrayOf(atomic, atomic), GC.findCycle(cycles[0])!!)
|
||||
} finally {
|
||||
atomic.value = null
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user