[K/N] Intrinsics for atomic get/set of volatile properties.
These intrinsics are equivalent to KMutableProperty0.get/set invocation and used internally to optimize allocation of a property reference. Merge-request: KT-MR-11233 Merged-by: Maria Sokolova <maria.sokolova@jetbrains.com>
This commit is contained in:
+4
@@ -94,6 +94,8 @@ internal enum class IntrinsicType {
|
||||
// Worker
|
||||
WORKER_EXECUTE,
|
||||
// Atomics
|
||||
ATOMIC_GET_FIELD,
|
||||
ATOMIC_SET_FIELD,
|
||||
COMPARE_AND_SET_FIELD,
|
||||
COMPARE_AND_EXCHANGE_FIELD,
|
||||
GET_AND_SET_FIELD,
|
||||
@@ -263,6 +265,8 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
||||
IntrinsicType.INTEROP_MEMORY_COPY -> emitMemoryCopy(callSite, args)
|
||||
IntrinsicType.IS_EXPERIMENTAL_MM -> emitIsExperimentalMM()
|
||||
IntrinsicType.THE_UNIT_INSTANCE -> theUnitInstanceRef.llvm
|
||||
IntrinsicType.ATOMIC_GET_FIELD -> reportNonLoweredIntrinsic(intrinsicType)
|
||||
IntrinsicType.ATOMIC_SET_FIELD -> reportNonLoweredIntrinsic(intrinsicType)
|
||||
IntrinsicType.COMPARE_AND_SET -> emitCompareAndSet(callSite, args)
|
||||
IntrinsicType.COMPARE_AND_EXCHANGE -> emitCompareAndSwap(callSite, args, resultSlot)
|
||||
IntrinsicType.GET_AND_SET -> emitGetAndSet(callSite, args, resultSlot)
|
||||
|
||||
+12
-5
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
@@ -28,6 +29,7 @@ import org.jetbrains.kotlin.ir.util.irCall
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
|
||||
object IR_DECLARATION_ORIGIN_VOLATILE : IrDeclarationOriginImpl("VOLATILE")
|
||||
|
||||
@@ -219,7 +221,9 @@ internal class VolatileFieldsLowering(val context: Context) : FileLoweringPass {
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
val intrinsicType = tryGetIntrinsicType(expression).takeIf { it in intrinsicMap } ?: return expression
|
||||
val intrinsicType = tryGetIntrinsicType(expression).takeIf {
|
||||
it in intrinsicMap || it == IntrinsicType.ATOMIC_GET_FIELD || it == IntrinsicType.ATOMIC_SET_FIELD
|
||||
} ?: return expression
|
||||
builder.at(expression)
|
||||
val reference = getConstPropertyReference(expression.extensionReceiver, null)
|
||||
?: return unsupported("Only compile-time known IrProperties supported for $intrinsicType")
|
||||
@@ -231,12 +235,15 @@ internal class VolatileFieldsLowering(val context: Context) : FileLoweringPass {
|
||||
if (backingField?.hasAnnotation(KonanFqNames.volatile) != true) {
|
||||
return unsupported("Only volatile properties are supported for $intrinsicType")
|
||||
}
|
||||
val function = intrinsicMap[intrinsicType]!!(backingField)
|
||||
val function = when(intrinsicType) {
|
||||
IntrinsicType.ATOMIC_GET_FIELD -> property.getter ?: error("Getter is not defined for the property: ${property.render()}")
|
||||
IntrinsicType.ATOMIC_SET_FIELD -> property.setter ?: error("Setter is not defined for the property: ${property.render()}")
|
||||
else -> intrinsicMap[intrinsicType]!!(backingField)
|
||||
}
|
||||
return builder.irCall(function).apply {
|
||||
dispatchReceiver = reference.dispatchReceiver
|
||||
putValueArgument(0, expression.getValueArgument(0))
|
||||
if (intrinsicType == IntrinsicType.COMPARE_AND_SET_FIELD || intrinsicType == IntrinsicType.COMPARE_AND_EXCHANGE_FIELD) {
|
||||
putValueArgument(1, expression.getValueArgument(1))
|
||||
for (index in 0 until expression.valueArgumentsCount) {
|
||||
putValueArgument(index, expression.getValueArgument(index))
|
||||
}
|
||||
}.let {
|
||||
if (backingField.requiresBooleanConversion()) {
|
||||
|
||||
Reference in New Issue
Block a user