Add tests on variable spilling with debug mode enabled
#KT-48678 Fixed
This commit is contained in:
committed by
Nikita Nazarov
parent
38d97d0621
commit
65bb6abae4
+58
@@ -13227,6 +13227,64 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/debugMode")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class DebugMode {
|
||||
@Test
|
||||
public void testAllFilesPresentInDebugMode() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/debugMode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("backEdge.kt")
|
||||
public void testBackEdge() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/backEdge.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("if.kt")
|
||||
public void testIf() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/if.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullCleanup.kt")
|
||||
public void testNullCleanup() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/nullCleanup.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullNotSpill.kt")
|
||||
public void testNullNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/nullNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoRefs.kt")
|
||||
public void testTwoRefs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/twoRefs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedParamNotSpill.kt")
|
||||
public void testUnusedParamNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/unusedParamNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/when.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -28,6 +28,8 @@ where advanced options include:
|
||||
-Xir-do-not-clear-binding-context
|
||||
When using the IR backend, do not clear BindingContext between psi2ir and lowerings
|
||||
-Xemit-jvm-type-annotations Emit JVM type annotations in bytecode
|
||||
-Xdebug Enable debug mode for compilation.
|
||||
Currently this includes spilling all variables in a suspending context regardless their liveness.
|
||||
-Xjvm-enable-preview Allow using features from Java language that are in preview phase.
|
||||
Works as `--enable-preview` in Java. All class files are marked as preview-generated thus it won't be possible to use them in release environment
|
||||
-Xenhance-type-parameter-types-to-def-not-null
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
spilledVariables += field.name to "${field.get(continuation)}"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test() {
|
||||
for (i in 0..1) {
|
||||
saveSpilledVariables()
|
||||
val a = "a"
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test()
|
||||
}
|
||||
|
||||
val continuationName = "Continuation at BackEdgeKt\$box\$1.invokeSuspend(backEdge.kt:42)"
|
||||
if (spilledVariables != setOf("label" to "1", "I$0" to "0", "L$0" to continuationName, "L$1" to "null")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "I$0" to "0", "L$0" to continuationName, "L$1" to "a")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "1", "I$0" to "1", "L$0" to continuationName, "L$1" to "a")) return "FAIL 3: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "I$0" to "1", "L$0" to continuationName, "L$1" to "a")) return "FAIL 4: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "I$0" to "1", "L$0" to continuationName, "L$1" to "a")) return "FAIL 5: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
val fieldValue = when (val obj = field.get(continuation)) {
|
||||
is Array<*> -> obj.joinToString(prefix = "[", postfix = "]")
|
||||
else -> obj
|
||||
}
|
||||
spilledVariables += field.name to "$fieldValue"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test(check: Boolean) {
|
||||
if (check) {
|
||||
val a = "a1"
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
} else {
|
||||
val a = "a2"
|
||||
val b = "b2"
|
||||
saveSpilledVariables()
|
||||
blackhole(a, b)
|
||||
}
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test(true)
|
||||
}
|
||||
|
||||
var continuationName = "Continuation at IfKt\$box\$1.invokeSuspend(if.kt:51)"
|
||||
if (spilledVariables != setOf("label" to "1", "Z$0" to "true", "L$0" to continuationName, "L$1" to "a1", "L$2" to "null"))
|
||||
return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "Z$0" to "true", "L$0" to continuationName, "L$1" to "a1", "L$2" to "[a1]"))
|
||||
return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "Z$0" to "true", "L$0" to continuationName, "L$1" to "a1", "L$2" to "[a1]"))
|
||||
return "FAIL 3: $spilledVariables"
|
||||
|
||||
builder {
|
||||
test(false)
|
||||
}
|
||||
|
||||
continuationName = "Continuation at IfKt\$box\$2.invokeSuspend(if.kt:65)"
|
||||
if (spilledVariables != setOf("label" to "2", "Z$0" to "false", "L$0" to continuationName, "L$1" to "a2", "L$2" to "b2")) return "FAIL 4: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "Z$0" to "false", "L$0" to continuationName, "L$1" to "a2", "L$2" to "b2")) return "FAIL 5: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "Z$0" to "false", "L$0" to continuationName, "L$1" to "a2", "L$2" to "b2")) return "FAIL 6: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
val fieldValue = when (val obj = field.get(continuation)) {
|
||||
is Array<*> -> obj.joinToString(prefix = "[", postfix = "]")
|
||||
else -> obj
|
||||
}
|
||||
spilledVariables += field.name to "$fieldValue"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test() {
|
||||
var a: String? = "a"
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
a = null
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test()
|
||||
}
|
||||
|
||||
val continuationName = "Continuation at NullCleanupKt\$box\$1.invokeSuspend(nullCleanup.kt:46)"
|
||||
if (spilledVariables != setOf("label" to "1", "L$0" to continuationName, "L$1" to "a")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to continuationName, "L$1" to "[a]")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to continuationName, "L$1" to "[a]")) return "FAIL 3: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
val fieldValue = when (val obj = field.get(continuation)) {
|
||||
is Array<*> -> obj.joinToString(prefix = "[", postfix = "]")
|
||||
else -> obj
|
||||
}
|
||||
spilledVariables += field.name to "$fieldValue"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test() {
|
||||
val a = null
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test()
|
||||
}
|
||||
|
||||
val continuationName = "Continuation at NullNotSpillKt\$box\$1.invokeSuspend(nullNotSpill.kt:44)"
|
||||
if (spilledVariables != setOf("label" to "1", "L$0" to continuationName, "L$1" to "null")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to continuationName, "L$1" to "[null]")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to continuationName, "L$1" to "[null]")) return "FAIL 3: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
val fieldValue = when (val obj = field.get(continuation)) {
|
||||
is Array<*> -> obj.joinToString(prefix = "[", postfix = "]")
|
||||
else -> obj
|
||||
}
|
||||
spilledVariables += field.name to "$fieldValue"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test() {
|
||||
val a = "a"
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test()
|
||||
}
|
||||
|
||||
val continuationName = "Continuation at SimpleKt\$box\$1.invokeSuspend(simple.kt:44)"
|
||||
if (spilledVariables != setOf("label" to "1", "L$0" to continuationName, "L$1" to "a", "L$2" to "null")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to continuationName, "L$1" to "a", "L$2" to "[a]")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to continuationName, "L$1" to "a", "L$2" to "[a]")) return "FAIL 3: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun main() {
|
||||
println(box())
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
val fieldValue = when (val obj = field.get(continuation)) {
|
||||
is Array<*> -> obj.joinToString(prefix = "[", postfix = "]")
|
||||
else -> obj
|
||||
}
|
||||
spilledVariables += field.name to "$fieldValue"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test(a: String, b: String) {
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
saveSpilledVariables()
|
||||
blackhole(b)
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test("a", "b")
|
||||
}
|
||||
|
||||
val continuationName = "Continuation at TwoRefsKt\$box\$1.invokeSuspend(twoRefs.kt:45)"
|
||||
if (spilledVariables != setOf("label" to "1", "L$0" to "a", "L$1" to "b", "L$2" to continuationName, "L$3" to "null")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to "a", "L$1" to "b", "L$2" to continuationName, "L$3" to "[a]")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "L$0" to "a", "L$1" to "b", "L$2" to continuationName, "L$3" to "[b]")) return "FAIL 3: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "L$0" to "a", "L$1" to "b", "L$2" to continuationName, "L$3" to "[b]")) return "FAIL 4: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun main() {
|
||||
println(box())
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
spilledVariables += field.name to "${field.get(continuation)}"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
val test: suspend (Int) -> Unit = { unused ->
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test(1)
|
||||
}
|
||||
|
||||
if (spilledVariables != setOf("label" to "1")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "1")) return "FAIL 2: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
val fieldValue = when (val obj = field.get(continuation)) {
|
||||
is Array<*> -> obj.joinToString(prefix = "[", postfix = "]")
|
||||
else -> obj
|
||||
}
|
||||
spilledVariables += field.name to "$fieldValue"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test(check: Int) {
|
||||
when (check) {
|
||||
0 -> {
|
||||
val a = "a0"
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
}
|
||||
1 -> {
|
||||
val a = "a1"
|
||||
val b = "b1"
|
||||
saveSpilledVariables()
|
||||
blackhole(a, b)
|
||||
}
|
||||
else -> {
|
||||
val a = "a2"
|
||||
val b = "b2"
|
||||
val c = 1
|
||||
saveSpilledVariables()
|
||||
blackhole(a, b, c)
|
||||
}
|
||||
}
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test(0)
|
||||
}
|
||||
|
||||
var continuationName = "Continuation at WhenKt\$box\$1.invokeSuspend(when.kt:61)"
|
||||
if (spilledVariables != setOf("label" to "1", "I$0" to "0", "I$1" to "0", "I$2" to "0", "L$0" to continuationName, "L$1" to "a0", "L$2" to "null"))
|
||||
return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "0", "I$1" to "0", "I$2" to "0", "L$0" to continuationName, "L$1" to "a0", "L$2" to "[a0]"))
|
||||
return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "0", "I$1" to "0", "I$2" to "0", "L$0" to continuationName, "L$1" to "a0", "L$2" to "[a0]"))
|
||||
return "FAIL 3: $spilledVariables"
|
||||
|
||||
builder {
|
||||
test(1)
|
||||
}
|
||||
|
||||
continuationName = "Continuation at WhenKt\$box\$2.invokeSuspend(when.kt:75)"
|
||||
if (spilledVariables != setOf("label" to "2", "I$0" to "1", "I$1" to "1", "I$2" to "0", "L$0" to continuationName, "L$1" to "a1", "L$2" to "b1"))
|
||||
return "FAIL 4: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "1", "I$1" to "1", "I$2" to "0", "L$0" to continuationName, "L$1" to "a1", "L$2" to "b1"))
|
||||
return "FAIL 5: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "1", "I$1" to "1", "I$2" to "0", "L$0" to continuationName, "L$1" to "a1", "L$2" to "b1"))
|
||||
return "FAIL 6: $spilledVariables"
|
||||
|
||||
builder {
|
||||
test(2)
|
||||
}
|
||||
|
||||
continuationName = "Continuation at WhenKt\$box\$3.invokeSuspend(when.kt:89)"
|
||||
if (spilledVariables != setOf("label" to "3", "I$0" to "2", "I$1" to "2", "I$2" to "1", "L$0" to continuationName, "L$1" to "a2", "L$2" to "b2"))
|
||||
return "FAIL 7: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "2", "I$1" to "2", "I$2" to "1", "L$0" to continuationName, "L$1" to "a2", "L$2" to "b2"))
|
||||
return "FAIL 8: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "2", "I$1" to "2", "I$2" to "1", "L$0" to continuationName, "L$1" to "a2", "L$2" to "b2"))
|
||||
return "FAIL 9: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+10
@@ -13107,6 +13107,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/debugMode")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class DebugMode {
|
||||
@Test
|
||||
public void testAllFilesPresentInDebugMode() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/debugMode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+58
@@ -13227,6 +13227,64 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/debugMode")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class DebugMode {
|
||||
@Test
|
||||
public void testAllFilesPresentInDebugMode() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/debugMode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("backEdge.kt")
|
||||
public void testBackEdge() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/backEdge.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("if.kt")
|
||||
public void testIf() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/if.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullCleanup.kt")
|
||||
public void testNullCleanup() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/nullCleanup.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullNotSpill.kt")
|
||||
public void testNullNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/nullNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoRefs.kt")
|
||||
public void testTwoRefs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/twoRefs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedParamNotSpill.kt")
|
||||
public void testUnusedParamNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/unusedParamNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/when.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -77,4 +77,6 @@ object JvmEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
|
||||
description = "Enable serialization of JVM IR",
|
||||
additionalParser = JvmSerializeIrMode.Companion::fromString
|
||||
)
|
||||
|
||||
val ENABLE_DEBUG_MODE by directive("Enable debug mode for compilation")
|
||||
}
|
||||
|
||||
+7
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.USE_JAVAC_BASE
|
||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JDK_KIND
|
||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JVM_TARGET
|
||||
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives.WITH_STDLIB
|
||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.ENABLE_DEBUG_MODE
|
||||
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
|
||||
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirDiagnosticsHandler
|
||||
import org.jetbrains.kotlin.test.model.*
|
||||
@@ -81,6 +82,12 @@ abstract class AbstractJvmBlackBoxCodegenTestBase<R : ResultingArtifact.Frontend
|
||||
configureModernJavaTest(TestJdkKind.FULL_JDK_17, JvmTarget.JVM_17)
|
||||
}
|
||||
|
||||
forTestsMatching("compiler/testData/codegen/box/coroutines/varSpilling/debugMode/*") {
|
||||
defaultDirectives {
|
||||
+ENABLE_DEBUG_MODE
|
||||
}
|
||||
}
|
||||
|
||||
enableMetaInfoHandler()
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirective
|
||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.SERIALIZE_IR
|
||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.STRING_CONCAT
|
||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME
|
||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.ENABLE_DEBUG_MODE
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.DISABLE_CALL_ASSERTIONS
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.DISABLE_PARAM_ASSERTIONS
|
||||
@@ -171,6 +172,7 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
|
||||
register(SERIALIZE_IR, JVMConfigurationKeys.SERIALIZE_IR)
|
||||
register(JDK_RELEASE, JVMConfigurationKeys.JDK_RELEASE)
|
||||
register(USE_TYPE_TABLE, JVMConfigurationKeys.USE_TYPE_TABLE)
|
||||
register(ENABLE_DEBUG_MODE, JVMConfigurationKeys.ENABLE_DEBUG_MODE)
|
||||
}
|
||||
|
||||
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
|
||||
|
||||
+13
@@ -10597,6 +10597,19 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/debugMode")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DebugMode extends AbstractLightAnalysisModeTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDebugMode() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/debugMode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
@@ -9731,6 +9731,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/debugMode")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class DebugMode {
|
||||
@Test
|
||||
public void testAllFilesPresentInDebugMode() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/debugMode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
@@ -9773,6 +9773,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/debugMode")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class DebugMode {
|
||||
@Test
|
||||
public void testAllFilesPresentInDebugMode() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/debugMode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
@@ -8642,6 +8642,19 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/debugMode")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DebugMode extends AbstractIrCodegenBoxWasmTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDebugMode() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/debugMode"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -10703,6 +10703,18 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/debugMode")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@Tag("codegen")
|
||||
@UseExtTestCaseGroupProvider()
|
||||
public class DebugMode {
|
||||
@Test
|
||||
public void testAllFilesPresentInDebugMode() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/debugMode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user