@Composable fun UserRow() { … } data class UserModel( var name: String, val friends: List<User>, val lastLoggedIn: LocalDateTime ) Compose Compiler Plugin Transformed IR
(%changed and 0b0110 == 0) { %dirty = %dirty or if (%composer.changedInstance(users)) } if (dirty and !%composer.skipping) { … } %composer = %composer.startRestartGroup( <> ) Bit masking
(%changed and 0b0110 == 0) { %dirty = %dirty or if (%composer.changedInstance(users)) } if (dirty and !%composer.skipping) { … } %composer = %composer.startRestartGroup( <> ) enum class StabilityBits(val bits: Int) { UNSTABLE(0b100), STABLE(0b000); fun bitsForSlot(slot: Int): Int }
(%changed and 0b0110 == 0) { %dirty = %dirty or if (%composer.changedInstance(users)) } if (dirty and !%composer.skipping) { … } %composer = %composer.startRestartGroup( <> ) Instance Equality for unstable types
skippableComposables = 0 var restartableComposables = 0 var readonlyComposables = 0 var markedStableClasses = 0 var inferredStableClasses = 0 var inferredUnstableClasses = 0 ... }
: Stability() class Parameter(…) : Stability() class Combined(…) : Stability() class Runtime(…) : Stability() class Unknown(…) : Stability() … } Internal to Compiler
friends: List<String> unstable lastLoggedIn: LocalDateTime } data class UserModel( var name: String, val friends: List<User>, val lastLoggedIn: LocalDateTime )
(%changed and 0b0110 == 0) { %dirty = %dirty or if (%composer.changedInstance(users)) } if (dirty and !%composer.skipping) { … } %composer = %composer.startRestartGroup( <> ) enum class StabilityBits(val bits: Int) { UNSTABLE(0b100), STABLE(0b000); fun bitsForSlot(slot: Int): Int }
%composer.startReplaceGroup() if (%changed) { %dirty = %dirty or if (%composer.changedInstance(…)) } Never calls `$composer.changed( ... )` with its parameters
fun UserRow() { … } data class UserModel( var name: String, val friends: List<User>, val lastLoggedIn: LocalDateTime ) Compose Compiler Plugin Test Snapshot changes
= mutableStateOf(mutableListOf(1)) val derivedState = derivedStateOf(referentialEqualityPolicy()) { state.value } state.value = mutableListOf(1) } State will observe read due to ref check