Mobile Development 12 min read
How ART Method Inlining Breaks Hot‑Patch Solutions and What Tinker Did to Fix It
The article analyzes Android ART's method‑inlining optimizations, explains how they interfere with popular hot‑patch frameworks like Tinker, and describes the practical workarounds Tinker adopted to maintain patch compatibility while mitigating performance impacts.
WeChat Client Technology Team
WeChat Client Technology Team
Background ART (Android Runtime) replaced Dalvik starting with Android 5.0, pre‑compiling Dex files to native code via dex2oat . Since Android 5.0, ART introduced method‑inlining optimizations that change method layouts and call flows, affecting hot‑patch mechanisms. Different Android versions use different compilers: 4.4 – kQuick (no inlining) 5.x – kQuick, kOptimizing, kPortable (kPortable unused) 6.x – kQuick, kOptimizing (kOptimizing adds new inlining features) 7.0/7.1 – kOptimizing Quick Compiler inlines a method only when the app is not a debug build and the callee meets one of several simple patterns (empty, returns a parameter, returns a constant/null, accesses or sets a non‑static field, etc.) and its bytecode is ≤2 instructions. Optimizing Compiler inlines when the app is not a debug build, the caller and callee are in the same Dex, the bytecode size is within --inline-max-code-units (default 100 for 6.x, 32 for 7.x), the method contains no try blocks or illegal bytecode, and on 7.x it must not invoke interface methods. Inlining can cascade across call chains but is limited by --inline-depth-limit (default 5). Main Hot‑Patch Solutions Hot‑patch frameworks fall into two categories: Native‑based : replace native method descriptors or redirect calls to a common dispatcher. Java‑based : either merge patched classes into a new Dex placed at the front of BaseDexClassLoader 's DexPathList, or inject a guard into each method that decides whether to run patched logic. Images illustrating these approaches are shown below. Impact of Inlining on Tinker Tinker relies on loading patched classes from a new Dex before the original ones. When a method that has been patched is inlined into its caller, the inlined code still points to the old method implementation, so the patch has no effect. Native‑based patches are completely broken by inlining, while Java‑based guard injection remains functional because the guard is copied together with the method. A crash observed during a gray‑release showed a NullPointerException caused by the inlined h.getExternalStorageDirectory method accessing a DexCache entry that belonged to the new Dex but was indexed with an old Dex type ID, leading to out‑of‑bounds or wrong class resolution. Possible Countermeasures One way to prevent inlining is to insert an empty try block at the start of each method, which disables inlining under current ART rules. However, this is brittle because ART’s inlining heuristics evolve. Another approach is to include the entire call chain of patched classes in the patch Dex, but this can dramatically increase patch size and may still fail with future optimizations. Tinker ultimately chose to drop the incremental Dex synthesis for ART and generate a full new Dex. All classes (except the loader) are then loaded from the new Dex, eliminating the inlining problem. To avoid startup ANR after OTA, Tinker checks the system fingerprint and triggers multi‑threaded dex2oat ahead of ApplicationLike initialization. Conclusion ART’s aggressive inlining improves performance but can break hot‑patch strategies that rely on method replacement, because the patched Dex only covers a subset of classes while inlined code still references old indices. Disabling inlining globally harms performance and requires constant maintenance. Tinker’s pragmatic solution—using a full new Dex and pre‑emptive dex2oat —balances compatibility and runtime speed.
Written by
WeChat Client Technology Team
Official account of the WeChat mobile client development team, sharing development experience, cutting‑edge tech, and little‑known stories across Android, iOS, macOS, Windows Phone, and Windows.
0 followers
Reader feedback
How this landed with the community
Rate this article
Was this worth your time?
Discussion
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
