Repository navigation
Speed up -AAA on large snapshots without changing its results - #26
Merged
Merged
Conversation
On a 37,863-function Dart 3.13 iOS app `r2flutter -AAA` took 19 minutes (1,136s). Three costs grew with snapshot size: - read_mem cached a single 1 MB window. modern_load_rodata_strings alternates between a cluster alloc stream and the RO data image megabytes away, so each string refilled the window twice (a 1 MB read plus the 0xff fill r_io_bank_read_at does first). Keep four windows with LRU eviction. Move the cache behind a pointer so DartCtx copies (flutter_model_load, dart_recovery_model_load) share buffers together with their addresses instead of leaving the original with stale ones, and drop a window whose refill failed since the failed read already overwrote it. `-f` 12.4s -> 0.5s; -c/-i/-T/-S ~6s -> <0.25s. - afs stores prototypes through r_anal_save_parsed_type, which calls r_anal_remove_parsed_type for each declared type. For an existing name that sorts and scans the whole type database although r_type_del has already removed every key of a function type. Names repeat often: anonymous closures, and names the C parser cuts at ':' (dyn:call is stored as `call`). Parse the prototype with r_anal_cparse and r_type_del those names first so afs takes its early return. The signature pass went from 1,127s to 27s. - With anal.trycatch (the radare2 6.2.2 default) every af walks all flags twice for try.<addr>.catch|filter. After -AAA creates its flags that is O(flags) per function. Disable it around r2flutter's af loops when no try.* flag exists, which cannot change the result. -AAA now takes 36s on that app (35s -> 6s on a smaller 3.13 build). A dump of afl, afs @@f, f, CC and ax after -AAA is byte-identical to the previous build on both apps (796,194 and 138,032 lines), and so is stderr. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmxPHTVwSkr2HTHJHQsord
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On a 37,863-function Dart 3.13 iOS app
r2flutter -AAAtook 19 minutes (1,136s).Three costs grew with snapshot size:
read_mem cached a single 1 MB window. modern_load_rodata_strings alternates between a cluster alloc stream and the RO data image megabytes away, so each string refilled the window twice (a 1 MB read plus the 0xff fill r_io_bank_read_at does first). Keep four windows with LRU eviction. Move the cache behind a pointer so DartCtx copies (flutter_model_load, dart_recovery_model_load) share buffers together with their addresses instead of leaving the original with stale ones, and drop a window whose refill failed since the failed read already overwrote it.
-f12.4s -> 0.5s; -c/-i/-T/-S ~6s -> <0.25s.afs stores prototypes through r_anal_save_parsed_type, which calls r_anal_remove_parsed_type for each declared type. For an existing name that sorts and scans the whole type database although r_type_del has already removed every key of a function type. Names repeat often: anonymous closures, and names the C parser cuts at ':' (dyn:call is stored as
call). Parse the prototype with r_anal_cparse and r_type_del those names first so afs takes its early return. The signature pass went from 1,127s to 27s.With anal.trycatch (the radare2 6.2.2 default) every af walks all flags twice for try..catch|filter. After -AAA creates its flags that is O(flags) per function. Disable it around r2flutter's af loops when no try.* flag exists, which cannot change the result.
-AAA now takes 36s on that app (35s -> 6s on a smaller 3.13 build).