Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the way the Compose interop works to avoid Android 12 bug #1370

Merged
merged 2 commits into from
Jan 25, 2024

Conversation

rossbacher
Copy link
Collaborator

The way the composeEpoxyModel function was written it would create a function that looked like this (in decompiled dex bytecode (for readability compiled to Java))

public static final ComposeEpoxyModel composeEpoxyModel(String id, Object[] keys, Function2<? super Composer, ? super Integer, Unit> composeFunction) {
    ...
    ComposeEpoxyModel $this$composeEpoxyModel_u24lambda_u240 = new ComposeEpoxyModel(Arrays.copyOf(keys, keys.length), composeFunction);
    $this$composeEpoxyModel_u24lambda_u240.id(id);
    return $this$composeEpoxyModel_u24lambda_u240;
}

this would trigger a ART bug in the (non mainline patched version of Android 12) to optimize the this line away

$this$composeEpoxyModel_u24lambda_u240.id(id);

and lead to crashes on Android 12.

More background at:
#1199 and
https://issuetracker.google.com/issues/197818595

This works around this issue by making sure that the creation, setting the id and adding to the controller of a ComposeEpoxyModel is happening in the same location in compiled bytecode.

Note: If you run R8 with optimization enabled, the method outlining optimization might still outline some of that inlined code again and thus still cause this problem but that is a different issue that can be dealt with by disabling outlining or all optimization.

Andreas Rossbacher added 2 commits January 22, 2024 13:01
…unction that looked like this (in decompiled dex bytecode)

```
public static final ComposeEpoxyModel composeEpoxyModel(String id, Object[] keys, Function2<? super Composer, ? super Integer, Unit> composeFunction) {
    ...
    ComposeEpoxyModel $this$composeEpoxyModel_u24lambda_u240 = new ComposeEpoxyModel(Arrays.copyOf(keys, keys.length), composeFunction);
    $this$composeEpoxyModel_u24lambda_u240.id(id);
    return $this$composeEpoxyModel_u24lambda_u240;
}
```

this would trigger a ART bug in the (non mainline patched version of Android 12) to optimize the this line

```
$this$composeEpoxyModel_u24lambda_u240.id(id);
```

and lead to crashes on Android 12.

More background at:
#1199 and
https://issuetracker.google.com/issues/197818595

This works around this issue by making sure that the creation, setting the id and adding to the controller of a ComposeEpoxyModelis happening in the same location in compiled bytecode.

Note: If you run R8 with optimization enabled, outlining might still outline some of that inlined code again and thus still cause this probblem but that is a different issue that can be dealed with by disabling outlining or all optimization.
Copy link
Contributor

@elihart elihart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@rossbacher rossbacher merged commit a3400cc into master Jan 25, 2024
1 check passed
@rossbacher rossbacher mentioned this pull request Jan 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants