Allow sharing top level vals with types marked as frozen. (#2086)
This commit is contained in:
+6
-2
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
|
|||||||
import org.jetbrains.kotlin.backend.konan.optimizations.*
|
import org.jetbrains.kotlin.backend.konan.optimizations.*
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
|
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
|
||||||
@@ -39,10 +38,11 @@ import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.resolve.hasBackingField
|
||||||
|
|
||||||
private val threadLocalAnnotationFqName = FqName("kotlin.native.ThreadLocal")
|
private val threadLocalAnnotationFqName = FqName("kotlin.native.ThreadLocal")
|
||||||
private val sharedAnnotationFqName = FqName("kotlin.native.SharedImmutable")
|
private val sharedAnnotationFqName = FqName("kotlin.native.SharedImmutable")
|
||||||
|
private val frozenAnnotationFqName = FqName("kotlin.native.internal.Frozen")
|
||||||
|
|
||||||
val IrField.propertyDescriptor: PropertyDescriptor
|
val IrField.propertyDescriptor: PropertyDescriptor
|
||||||
get() {
|
get() {
|
||||||
@@ -67,7 +67,11 @@ internal val IrField.storageClass: FieldStorage get() {
|
|||||||
val descriptor = propertyDescriptor
|
val descriptor = propertyDescriptor
|
||||||
return when {
|
return when {
|
||||||
descriptor.annotations.hasAnnotation(threadLocalAnnotationFqName) -> FieldStorage.THREAD_LOCAL
|
descriptor.annotations.hasAnnotation(threadLocalAnnotationFqName) -> FieldStorage.THREAD_LOCAL
|
||||||
|
!isFinal -> FieldStorage.MAIN_THREAD
|
||||||
descriptor.annotations.hasAnnotation(sharedAnnotationFqName) -> FieldStorage.SHARED
|
descriptor.annotations.hasAnnotation(sharedAnnotationFqName) -> FieldStorage.SHARED
|
||||||
|
// TODO: simplify, once IR types are fully there.
|
||||||
|
type is IrSimpleType && (type as IrSimpleType).
|
||||||
|
classifier.descriptor.annotations.hasAnnotation(frozenAnnotationFqName) -> FieldStorage.SHARED
|
||||||
else -> FieldStorage.MAIN_THREAD
|
else -> FieldStorage.MAIN_THREAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -659,6 +659,12 @@ task worker9(type: RunKonanTest) {
|
|||||||
source = "runtime/workers/worker9.kt"
|
source = "runtime/workers/worker9.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task worker10(type: RunKonanTest) {
|
||||||
|
disabled = (project.testTarget == 'wasm32') // Workers need pthreads.
|
||||||
|
goldValue = "OK\n"
|
||||||
|
source = "runtime/workers/worker10.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task freeze0(type: RunKonanTest) {
|
task freeze0(type: RunKonanTest) {
|
||||||
disabled = (project.testTarget == 'wasm32') // No workers on WASM.
|
disabled = (project.testTarget == 'wasm32') // No workers on WASM.
|
||||||
goldValue = "frozen bit is true\n" +
|
goldValue = "frozen bit is true\n" +
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package runtime.workers.worker10
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
import kotlin.native.concurrent.*
|
||||||
|
|
||||||
|
class Data(val x: Int)
|
||||||
|
|
||||||
|
val topInt = 1
|
||||||
|
val topString = "string"
|
||||||
|
var topStringVar = "string"
|
||||||
|
val topSharedStringWithGetter: String
|
||||||
|
get() = "top"
|
||||||
|
val topData = Data(42)
|
||||||
|
@SharedImmutable
|
||||||
|
val topSharedData = Data(43)
|
||||||
|
|
||||||
|
@Test fun runTest() {
|
||||||
|
val worker = Worker.start()
|
||||||
|
|
||||||
|
assertEquals(1, topInt)
|
||||||
|
assertEquals("string", topString)
|
||||||
|
assertEquals(42, topData.x)
|
||||||
|
assertEquals(43, topSharedData.x)
|
||||||
|
assertEquals("top", topSharedStringWithGetter)
|
||||||
|
|
||||||
|
worker.execute(TransferMode.SAFE, { -> }, {
|
||||||
|
it -> topInt == 1
|
||||||
|
}).consume {
|
||||||
|
result -> assertEquals(true, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.execute(TransferMode.SAFE, { -> }, {
|
||||||
|
it -> topString == "string"
|
||||||
|
}).consume {
|
||||||
|
result -> assertEquals(true, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.execute(TransferMode.SAFE, { -> }, {
|
||||||
|
it -> try {
|
||||||
|
topStringVar == "string"
|
||||||
|
} catch (e: IncorrectDereferenceException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}).consume {
|
||||||
|
result -> assertEquals(false, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.execute(TransferMode.SAFE, { -> }, {
|
||||||
|
it -> try {
|
||||||
|
topSharedStringWithGetter == "top"
|
||||||
|
} catch (e: IncorrectDereferenceException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}).consume {
|
||||||
|
result -> assertEquals(true, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.execute(TransferMode.SAFE, { -> }, {
|
||||||
|
it -> try {
|
||||||
|
topData.x == 42
|
||||||
|
} catch (e: IncorrectDereferenceException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}).consume {
|
||||||
|
result -> assertEquals(false, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.execute(TransferMode.SAFE, { -> }, {
|
||||||
|
it -> try {
|
||||||
|
topSharedData.x == 43
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}).consume {
|
||||||
|
result -> assertEquals(true, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.requestTermination().result
|
||||||
|
println("OK")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user