Status Update
Comments
au...@google.com <au...@google.com> #2
Note that baseline.prof
is the same, but baseline.profm
is different. Attaching what I got locally from two runs.
fl...@obfusk.net <fl...@obfusk.net> #4
This seems to be an ordering issue that should be easy to fix:
$ cmp 1.profm 2.profm
1.profm 2.profm differ: byte 24, line 1
$ diff -Naur <( repro-apk dump-baseline 1.profm ) <( repro-apk dump-baseline 2.profm )
profm version=002
num_dex_files=2
profile_idx=0
- profile_key='classes2.dex'
- num_type_ids=2418
- num_class_ids=0
-profile_idx=1
profile_key='classes.dex'
num_type_ids=8122
num_class_ids=738
+profile_idx=1
+ profile_key='classes2.dex'
+ num_type_ids=2418
+ num_class_ids=0
$ repro-apk sort-baseline 1.profm 1s.profm
$ cmp 1s.profm 2.profm && echo OK
OK
fl...@obfusk.net <fl...@obfusk.net> #5
This seems trivial to fix when generating the file.
As a workaround, adding build.gradle
makes it stable:
import com.android.tools.profgen.ArtProfileKt
import com.android.tools.profgen.ArtProfileSerializer
import com.android.tools.profgen.DexFile
project.afterEvaluate {
tasks.compileReleaseArtProfile.doLast {
outputs.files.each { file ->
if (file.toString().endsWith(".profm")) {
println("Sorting ${file} ...")
def version = ArtProfileSerializer.valueOf("METADATA_0_0_2")
def profile = ArtProfileKt.ArtProfile(file)
def keys = new ArrayList(profile.profileData.keySet())
def sortedData = new LinkedHashMap()
Collections.sort keys, new DexFile.Companion()
keys.each { key -> sortedData[key] = profile.profileData[key] }
new FileOutputStream(file).with {
write(version.magicBytes$profgen)
write(version.versionBytes$profgen)
version.write$profgen(it, sortedData, "")
}
}
}
}
}
ra...@google.com <ra...@google.com>
sp...@google.com <sp...@google.com> #6
This might have been fixed with
fl...@obfusk.net <fl...@obfusk.net> #7
Unfortunately, I've confirmed the issue with com.android.tools.build:gradle:7.4.0
(and 7.3.0
).
fl...@obfusk.net <fl...@obfusk.net> #8
The problem is that in ArtProfile.kt
:
val profileData = HashMap<DexFile, DexFileData>()
Which means the order of iterating over profileData
is non-deterministic.
In ArtProfileSerializer.kt
, METADATA_FOR_N
, V0_1_0_P
, and V0_0_9_OMR1
sort before iterating:
profileData.entries.sortedBy { it.key.name }
And V0_0_5_O
and V0_0_1_N
sort as well:
for ((dex, data) in profileData.toSortedMap(DexFile)) {
But METADATA_0_0_2
doesn't sort:
profileData.onEachIndexed { index, entry ->
And neither does V0_1_5_S
:
profileData.forEach { entry ->
profileData.onEachIndexed { index, entry ->
profileData.onEachIndexed { index, entry ->
Which is why their output is non-deterministic.
fl...@obfusk.net <fl...@obfusk.net> #10
Thanks! I was hoping to see the fix, but that URL seems to be only accessible to Google employees.
fl...@obfusk.net <fl...@obfusk.net> #13
What AGP version can we expect the fix to be in?
sp...@google.com <sp...@google.com> #14
AGP 8.1.0-alpha03
Description
Repro steps
glance:glance-wear-tiles:integration-tests:demos:assembleRelease --rerun-task
../../out/androidx/glance/glance-wear-tiles/integration-tests/demos/build/outputs/apk/release/glance-wear-tiles-demos-testapp-release.apk 1.apk
glance:glance-wear-tiles:integration-tests:demos:assembleRelease --rerun-task
again../../out/androidx/glance/glance-wear-tiles/integration-tests/demos/build/outputs/apk/release/glance-wear-tiles-demos-testapp-release.apk 2.apk
Expected
APKs are identical
Actual
APKs are different due to change in
assets/dexopt/baseline.profm
I assume this is AGP bug, but I wanted to run by androidx team first.