From e54b46601037a49ca2adcf15409bacf5b8c13e95 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 8 Nov 2016 11:21:08 +0300 Subject: [PATCH] Make fields representing variables in coroutines non-volatile #KT-14636 Fixed --- .../CoroutineTransformationClassBuilder.kt | 2 +- .../bytecodeListing/coroutineFields.kt | 23 ++++++++++++++++ .../bytecodeListing/coroutineFields.txt | 27 +++++++++++++++++++ .../codegen/AbstractBytecodeListingTest.kt | 4 ++- .../codegen/BytecodeListingTestGenerated.java | 6 +++++ 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeListing/coroutineFields.kt create mode 100644 compiler/testData/codegen/bytecodeListing/coroutineFields.txt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt index 58a7bcb9f39..1c997917d4b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt @@ -281,7 +281,7 @@ class CoroutineTransformerMethodVisitor( val (type, maxIndex) = entry for (index in 0..maxIndex) { classBuilder.newField( - JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_PRIVATE or Opcodes.ACC_VOLATILE, + JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_PRIVATE, type.fieldNameForVar(index), type.descriptor, null, null) } } diff --git a/compiler/testData/codegen/bytecodeListing/coroutineFields.kt b/compiler/testData/codegen/bytecodeListing/coroutineFields.kt new file mode 100644 index 00000000000..d7234d1685d --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/coroutineFields.kt @@ -0,0 +1,23 @@ +class Controller { + suspend fun suspendHere(x: Continuation) { + x.resume("OK") + } +} + +fun builder(coroutine c: Controller.(String, Long) -> Continuation) { + c(Controller(), "", 2L).resume(Unit) +} + +fun box(): String { + var result = "" + + builder { x, y -> + val z = "" + val u = 1L + result = suspendHere() + + result += z + u + } + + return result +} diff --git a/compiler/testData/codegen/bytecodeListing/coroutineFields.txt b/compiler/testData/codegen/bytecodeListing/coroutineFields.txt new file mode 100644 index 00000000000..a51e1efbb2c --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/coroutineFields.txt @@ -0,0 +1,27 @@ +@kotlin.Metadata +public final class Controller { + public method (): void + public final method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): void +} + +@kotlin.Metadata +final class CoroutineFieldsKt$box$1 { + synthetic final field $result: kotlin.jvm.internal.Ref$ObjectRef + private field J$0: long + private field L$0: java.lang.Object + private field L$1: java.lang.Object + private final field p$0: java.lang.String + private final field p$1: long + inner class CoroutineFieldsKt$box$1 + method (p0: kotlin.jvm.internal.Ref$ObjectRef): void + protected final method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): void + public final @org.jetbrains.annotations.NotNull method invoke(@org.jetbrains.annotations.NotNull p0: Controller, @org.jetbrains.annotations.NotNull p1: java.lang.String, p2: long): kotlin.coroutines.Continuation + public synthetic method invoke(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object): java.lang.Object +} + +@kotlin.Metadata +public final class CoroutineFieldsKt { + inner class CoroutineFieldsKt$box$1 + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function3): void +} diff --git a/compiler/tests-common/org/jetbrains/kotlin/codegen/AbstractBytecodeListingTest.kt b/compiler/tests-common/org/jetbrains/kotlin/codegen/AbstractBytecodeListingTest.kt index c8cd43b2a9a..90c8ffa6aed 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/codegen/AbstractBytecodeListingTest.kt +++ b/compiler/tests-common/org/jetbrains/kotlin/codegen/AbstractBytecodeListingTest.kt @@ -140,8 +140,10 @@ abstract class AbstractBytecodeListingTest : CodegenTestCase() { override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? { val type = Type.getType(desc).className - declarationsInsideClass.add(Declaration("field $name: $type")) + val fieldDeclaration = Declaration("field $name: $type") + declarationsInsideClass.add(fieldDeclaration) handleModifiers(access) + if (access and ACC_VOLATILE != 0) addModifier("volatile", fieldDeclaration.annotations) return object : FieldVisitor(ASM5) { override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? { diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 26316bd138b..5ec34ba92cf 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -41,6 +41,12 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { doTest(fileName); } + @TestMetadata("coroutineFields.kt") + public void testCoroutineFields() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/coroutineFields.kt"); + doTest(fileName); + } + @TestMetadata("defaultImpls.kt") public void testDefaultImpls() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/defaultImpls.kt");