Move everything under kotlin-native folder
I was forced to manually do update the following files, because otherwise they would be ignored according .gitignore settings. Probably they should be deleted from repo. Interop/.idea/compiler.xml Interop/.idea/gradle.xml Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_3.xml Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_3.xml Interop/.idea/modules.xml Interop/.idea/modules/Indexer/Indexer.iml Interop/.idea/modules/Runtime/Runtime.iml Interop/.idea/modules/StubGenerator/StubGenerator.iml backend.native/backend.native.iml backend.native/bc.frontend/bc.frontend.iml backend.native/cli.bc/cli.bc.iml backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt backend.native/tests/link/lib/foo.kt backend.native/tests/link/lib/foo2.kt backend.native/tests/teamcity-test.property
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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 runtime.memory.basic0
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class A {
|
||||
var field: B? = null
|
||||
}
|
||||
|
||||
class B(var field: Int)
|
||||
|
||||
@Test fun runTest() {
|
||||
val a = A()
|
||||
a.field = B(2)
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.native.internal.GC
|
||||
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.internal.GC.collect()
|
||||
// Request cyclic collection.
|
||||
kotlin.native.internal.GC.collectCyclic()
|
||||
// Ensure we processed delayed release.
|
||||
repeat(10) {
|
||||
// Wait a bit and process queue.
|
||||
Worker.current.park(10)
|
||||
Worker.current.processQueue()
|
||||
kotlin.native.internal.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.internal.GC.collect()
|
||||
kotlin.native.internal.GC.collectCyclic()
|
||||
Worker.current.park(100 * 1000)
|
||||
holder.switch()
|
||||
kotlin.native.internal.GC.collect()
|
||||
Worker.current.park(100 * 1000)
|
||||
withWorker {
|
||||
executeAfter(0L, {
|
||||
kotlin.native.internal.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.internal.GC.collect()
|
||||
|
||||
kotlin.native.internal.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() {
|
||||
kotlin.native.internal.GC.cyclicCollectorEnabled = true
|
||||
test1()
|
||||
test2()
|
||||
test3()
|
||||
test4()
|
||||
repeat(10) {
|
||||
test5()
|
||||
}
|
||||
test6()
|
||||
test7()
|
||||
test8()
|
||||
test9()
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.native.internal.GC
|
||||
import kotlin.test.*
|
||||
|
||||
fun main() {
|
||||
kotlin.native.internal.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.
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.native.internal.GC
|
||||
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])
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 runtime.memory.cycles0
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
data class Node(val data: Int, var next: Node?, var prev: Node?, val outer: Node?)
|
||||
|
||||
fun makeCycle(len: Int, outer: Node?): Node {
|
||||
val start = Node(0, null, null, outer)
|
||||
var prev = start
|
||||
for (i in 1 .. len - 1) {
|
||||
prev = Node(i, prev, null, outer)
|
||||
}
|
||||
start.next = prev
|
||||
return start
|
||||
}
|
||||
|
||||
fun makeDoubleCycle(len: Int): Node {
|
||||
val start = makeCycle(len, null)
|
||||
var prev = start
|
||||
var cur = prev.next
|
||||
while (cur != start) {
|
||||
cur!!.prev = prev
|
||||
prev = cur
|
||||
cur = cur.next
|
||||
}
|
||||
start.prev = prev
|
||||
return start
|
||||
}
|
||||
|
||||
fun createCycles(junk: Node) {
|
||||
val cycle1 = makeCycle(1, junk)
|
||||
val cycle2 = makeCycle(2, junk)
|
||||
val cycle10 = makeCycle(10, junk)
|
||||
val cycle100 = makeCycle(100, junk)
|
||||
val dcycle1 = makeDoubleCycle(1)
|
||||
val dcycle2 = makeDoubleCycle(2)
|
||||
val dcycle10 = makeDoubleCycle(10)
|
||||
val dcycle100 = makeDoubleCycle(100)
|
||||
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
// Create outer link from cyclic garbage.
|
||||
val outer = Node(42, null, null, null)
|
||||
createCycles(outer)
|
||||
kotlin.native.internal.GC.collect()
|
||||
// Ensure outer is not collected.
|
||||
println(outer.data)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 runtime.memory.cycles1
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.native.ref.*
|
||||
|
||||
@Test fun runTest() {
|
||||
// TODO: make it work in relaxed model as well.
|
||||
if (Platform.memoryModel == MemoryModel.RELAXED) return
|
||||
val weakRefToTrashCycle = createLoop()
|
||||
kotlin.native.internal.GC.collect()
|
||||
assertNull(weakRefToTrashCycle.get())
|
||||
}
|
||||
|
||||
private fun createLoop(): WeakReference<Any> {
|
||||
val loop = Array<Any?>(1, { null })
|
||||
loop[0] = loop
|
||||
|
||||
return WeakReference(loop)
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 runtime.memory.escape0
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
//fun foo1(arg: String) : String = foo0(arg)
|
||||
fun foo1(arg: Any) : Any = foo0(arg)
|
||||
|
||||
fun foo0(arg: Any) : Any = Any()
|
||||
|
||||
var global : Any = Any()
|
||||
|
||||
fun foo0_escape(arg: Any) : Any{
|
||||
global = arg
|
||||
return Any()
|
||||
}
|
||||
|
||||
class Node(var previous: Node?)
|
||||
|
||||
fun zoo3() : Node {
|
||||
var current = Node(null)
|
||||
for (i in 1 .. 5) {
|
||||
current = Node(current)
|
||||
}
|
||||
return current
|
||||
}
|
||||
|
||||
fun zoo4(arg: Int) : Any {
|
||||
var a = Any()
|
||||
var b = Any()
|
||||
var c = Any()
|
||||
a = b
|
||||
val x = 3
|
||||
a = when {
|
||||
x < arg -> b
|
||||
else -> c
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
fun zoo5(arg: Any) : Any{
|
||||
foo1(arg)
|
||||
return arg
|
||||
}
|
||||
|
||||
fun zoo6(arg: Any) : Any {
|
||||
return zoo7(arg, "foo", 11)
|
||||
}
|
||||
|
||||
fun zoo7(arg1: Any, arg2: Any, selector: Int) : Any {
|
||||
return if (selector < 2) arg1 else arg2;
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
//val z = zoo7(Any(), Any(), 1)
|
||||
val x = zoo5(Any())
|
||||
//println(bar(foo1(foo2("")), foo2(foo1(""))))
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 runtime.memory.escape1
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class B(val s: String)
|
||||
|
||||
class A {
|
||||
val b = B("zzz")
|
||||
}
|
||||
|
||||
fun foo(): B {
|
||||
val a = A()
|
||||
return a.b
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
println(foo().s)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 runtime.memory.escape2
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class A(val s: String)
|
||||
|
||||
class B {
|
||||
var a: A? = null
|
||||
}
|
||||
|
||||
class C(val b: B)
|
||||
|
||||
fun foo(c: C) {
|
||||
c.b.a = A("zzz")
|
||||
}
|
||||
|
||||
fun bar(b: B) {
|
||||
val c = C(b)
|
||||
foo(c)
|
||||
}
|
||||
|
||||
@ThreadLocal
|
||||
val global = B()
|
||||
|
||||
@Test fun runTest() {
|
||||
bar(global)
|
||||
println(global.a!!.s)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun main() {
|
||||
StableRef.create(Any())
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
kotlin.native.internal.GC.collect()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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 runtime.memory.stable_ref_cross_thread_check
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
@Test
|
||||
fun runTest1() {
|
||||
val worker = Worker.start()
|
||||
|
||||
val future = worker.execute(TransferMode.SAFE, { }) {
|
||||
StableRef.create(Any())
|
||||
}
|
||||
val ref = future.result
|
||||
assertFailsWith<IncorrectDereferenceException> {
|
||||
val value = ref.get()
|
||||
println(value.toString())
|
||||
}
|
||||
|
||||
worker.requestTermination().result
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runTest2() {
|
||||
val worker = Worker.start()
|
||||
|
||||
val mainThreadRef = StableRef.create(Any())
|
||||
// Simulate this going through interop as raw C pointer.
|
||||
val pointerValue: Long = mainThreadRef.asCPointer().toLong()
|
||||
val future = worker.execute(TransferMode.SAFE, { pointerValue }) {
|
||||
val pointer: COpaquePointer = it.toCPointer()!!
|
||||
assertFailsWith<IncorrectDereferenceException> {
|
||||
// Even attempting to convert a pointer to StableRef should fail.
|
||||
val otherThreadRef: StableRef<Any> = pointer.asStableRef()
|
||||
println(otherThreadRef.toString())
|
||||
}
|
||||
Unit
|
||||
}
|
||||
future.result
|
||||
|
||||
worker.requestTermination().result
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 runtime.memory.throw_cleanup
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test fun runTest() {
|
||||
foo(false)
|
||||
try {
|
||||
foo(true)
|
||||
} catch (e: Error) {
|
||||
println("Ok")
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(b: Boolean): Any {
|
||||
var result = Any()
|
||||
if (b) {
|
||||
throw Error()
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 runtime.memory.var1
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class Integer(val value: Int) {
|
||||
operator fun inc() = Integer(value + 1)
|
||||
}
|
||||
|
||||
fun foo(x: Any, y: Any) {
|
||||
x.use()
|
||||
y.use()
|
||||
}
|
||||
|
||||
@Test fun runTest1() {
|
||||
var x = Integer(0)
|
||||
|
||||
for (i in 0..1) {
|
||||
val c = Integer(0)
|
||||
if (i == 0) x = c
|
||||
}
|
||||
|
||||
// x refcount is 1.
|
||||
|
||||
foo(x, ++x)
|
||||
}
|
||||
|
||||
fun Any?.use() {
|
||||
var x = this
|
||||
}
|
||||
|
||||
@kotlin.native.internal.CanBePrecreated
|
||||
object CompileTime {
|
||||
|
||||
const val int = Int.MIN_VALUE
|
||||
const val byte = Byte.MIN_VALUE
|
||||
const val short = Short.MIN_VALUE
|
||||
const val long = Long.MIN_VALUE
|
||||
const val boolean = true
|
||||
const val float = 1.0f
|
||||
const val double = 1.0
|
||||
const val char = Char.MIN_VALUE
|
||||
}
|
||||
|
||||
class AClass {
|
||||
companion object {}
|
||||
}
|
||||
|
||||
@Test fun runTest2() {
|
||||
assertEquals(Int.MIN_VALUE, CompileTime.int)
|
||||
assertEquals(Byte.MIN_VALUE, CompileTime.byte)
|
||||
assertEquals(Short.MIN_VALUE, CompileTime.short)
|
||||
assertEquals(Long.MIN_VALUE, CompileTime.long)
|
||||
assertEquals(true, CompileTime.boolean)
|
||||
assertEquals(1.0f, CompileTime.float)
|
||||
assertEquals(1.0, CompileTime.double)
|
||||
assertEquals(Char.MIN_VALUE, CompileTime.char)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 runtime.memory.var2
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test fun runTest() {
|
||||
var x = Any()
|
||||
|
||||
for (i in 0..1) {
|
||||
val c = Any()
|
||||
if (i == 0) x = c
|
||||
}
|
||||
|
||||
// x refcount is 1.
|
||||
|
||||
val y = try {
|
||||
x
|
||||
} finally {
|
||||
x = Any()
|
||||
}
|
||||
|
||||
y.use()
|
||||
}
|
||||
|
||||
fun Any?.use() {
|
||||
var x = this
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 runtime.memory.var3
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test fun runTest() {
|
||||
foo().use()
|
||||
}
|
||||
|
||||
fun foo(): Any {
|
||||
var x = Any()
|
||||
|
||||
for (i in 0..1) {
|
||||
val c = Any()
|
||||
if (i == 0) x = c
|
||||
}
|
||||
|
||||
// x refcount is 1.
|
||||
|
||||
try {
|
||||
return x
|
||||
} finally {
|
||||
x = Any()
|
||||
}
|
||||
}
|
||||
|
||||
fun Any?.use() {
|
||||
var x = this
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 runtime.memory.var4
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test fun runTest() {
|
||||
var x = Error()
|
||||
|
||||
for (i in 0..1) {
|
||||
val c = Error()
|
||||
if (i == 0) x = c
|
||||
}
|
||||
|
||||
// x refcount is 1.
|
||||
|
||||
try {
|
||||
try {
|
||||
throw x
|
||||
} finally {
|
||||
x = Error()
|
||||
}
|
||||
} catch (e: Error) {
|
||||
e.use()
|
||||
}
|
||||
}
|
||||
|
||||
fun Any?.use() {
|
||||
var x = this
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 runtime.memory.weak0
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.native.ref.*
|
||||
|
||||
data class Data(val s: String)
|
||||
|
||||
fun localWeak(): WeakReference<Data> {
|
||||
val x = Data("Hello")
|
||||
val weak = WeakReference(x)
|
||||
println(weak.get())
|
||||
return weak
|
||||
}
|
||||
|
||||
fun multiWeak(): Array<WeakReference<Data>> {
|
||||
val x = Data("Hello")
|
||||
val weaks = Array(100, { WeakReference(x) } )
|
||||
weaks.forEach {
|
||||
it -> if (it.get()?.s != "Hello") throw Error("bad reference")
|
||||
}
|
||||
return weaks
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
val weak = localWeak()
|
||||
kotlin.native.internal.GC.collect()
|
||||
val value = weak.get()
|
||||
println(value?.toString())
|
||||
|
||||
val weaks = multiWeak()
|
||||
|
||||
kotlin.native.internal.GC.collect()
|
||||
|
||||
weaks.forEach {
|
||||
it -> if (it.get()?.s != null) throw Error("not null")
|
||||
}
|
||||
println("OK")
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 runtime.memory.weak1
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.native.ref.*
|
||||
|
||||
class Node(var next: Node?)
|
||||
|
||||
@Test fun runTest1() {
|
||||
val node1 = Node(null)
|
||||
val node2 = Node(node1)
|
||||
node1.next = node2
|
||||
|
||||
kotlin.native.ref.WeakReference(node1)
|
||||
println("OK")
|
||||
}
|
||||
|
||||
@Test fun runTest2() {
|
||||
val string = "Hello"
|
||||
val refString = WeakReference(string)
|
||||
assertEquals(string, refString.value)
|
||||
val zero = 0
|
||||
val refZero = WeakReference(zero)
|
||||
assertEquals(0, refZero.value)
|
||||
val long = Long.MAX_VALUE
|
||||
val refLong = WeakReference(long)
|
||||
assertEquals(Long.MAX_VALUE, refLong.value)
|
||||
}
|
||||
Reference in New Issue
Block a user