Problem
Same variable is used in both condition and value of ternary operator before constructor call. This prevents safe inlining because the expression would be evaluated twice.
Affected Files (10 cases)
A-1: RecyclerView.java
File: androidx/recyclerview/widget/RecyclerView.java
public RecyclerView(Context context, AttributeSet attributeSet, int i) {
Context context2 = context; // MOVE: copy context to context2
super(context2, attributeSet, i);
// context2 may be used in subsequent code
}
A-2: DefaultBHttpServerConnection.java
File: cz/msebera/android/httpclient/impl/DefaultBHttpServerConnection.java
public DefaultBHttpServerConnection(..., ContentLengthStrategy contentLengthStrategy, ...) {
ContentLengthStrategy contentLengthStrategy3 = contentLengthStrategy;
super(..., contentLengthStrategy3 == null
? DisallowIdentityContentLengthStrategy.INSTANCE
: contentLengthStrategy3, ...);
// ^^^^^^^^^^^^^^^^^^^^^^^ condition ^^^^^^^^^^^^^^^^^^^^^^^ value
// contentLengthStrategy3 used after super()
this.requestParser = (httpMessageParserFactory2 == null ? ... : httpMessageParserFactory2).create(...);
}
A-3, A-4, A-5: DefaultDrmSessionManager.java (3 cases)
File: com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java
public DefaultDrmSessionManager(UUID uuid, ExoMediaDrm<T> exoMediaDrm,
MediaDrmCallback mediaDrmCallback, HashMap<String, String> map) {
HashMap<String, String> map2 = map;
this(uuid, exoMediaDrm, mediaDrmCallback,
map2 == null ? new HashMap<>() : map2, false, 3);
// ^^^^ condition ^^^^ value
}
A-6: zzbsq.java
File: com/google/android/gms/internal/ads/zzbsq.java
public zzbsq(Context context, Looper looper, ...) {
Context applicationContext = context.getApplicationContext();
super(applicationContext == null ? context : applicationContext, looper, 8, ...);
// ^^^^^^^^^^^^^^^^^^ condition ^^^^^^^^^^^^^^^^^^ value
}
A-7, A-8, A-9, A-10: String.valueOf Pattern (4 cases)
Files: zzga.java, zzwq.java, zzbn.java (2 cases)
zza(String str, Throwable th) {
String strValueOf = String.valueOf(str);
super(strValueOf.length() != 0
? "CodedOutputStream was writing...".concat(strValueOf)
: new String("CodedOutputStream was writing..."), th);
// ^^^^^^^^^ condition (.length()) ^^^^^^^^^ value (.concat())
}
DEX Bytecode Analysis
# Example: getApplicationContext pattern
invoke-virtual {p1}, Landroid/content/Context;->getApplicationContext()Landroid/content/Context;
move-result-object v0 # v0 = result
# v0 used in BOTH condition and value
if-eqz v0, :use_default
move-object v1, v0 # Use v0 as value
goto :continue
:use_default
move-object v1, p1 # Use original context
:continue
invoke-direct {p0, v1, ...}, <init> # super(v1, ...)
Why Inlining Fails
// Original (with temp variable - VALID bytecode, INVALID Java)
Context appContext = context.getApplicationContext();
super(appContext == null ? context : appContext, ...);
// If we inline (INVALID - method called TWICE!)
super(context.getApplicationContext() == null
? context
: context.getApplicationContext(), // ❌ Second call!
...);
Problems with double evaluation:
- Side effects: Method may modify state
- Performance: Expensive operations run twice
- Inconsistency: Results may differ between calls
Theoretical Solution
Implement side-effect analysis to identify pure expressions:
| Expression |
Side-effect |
Safe to Inline |
String.valueOf(str) |
None |
✅ Yes |
map (parameter) |
None |
✅ Yes |
context.getApplicationContext() |
Uncertain |
⚠️ Risky |
contentLengthStrategy (parameter) |
None |
✅ Yes |
Implementation approach:
- Parameter references → Always safe
- Known pure functions (
String.valueOf, Integer.valueOf, etc.) → Safe
- General method calls → Require analysis or whitelist
Status
Partially solvable - Requires side-effect analysis implementation.
Would need to:
- Build a whitelist of known pure methods
- Detect direct parameter references
- Analyze method purity (complex)
Related
Problem
Same variable is used in both condition and value of ternary operator before constructor call. This prevents safe inlining because the expression would be evaluated twice.
Affected Files (10 cases)
A-1: RecyclerView.java
File:
androidx/recyclerview/widget/RecyclerView.javaA-2: DefaultBHttpServerConnection.java
File:
cz/msebera/android/httpclient/impl/DefaultBHttpServerConnection.javaA-3, A-4, A-5: DefaultDrmSessionManager.java (3 cases)
File:
com/google/android/exoplayer2/drm/DefaultDrmSessionManager.javaA-6: zzbsq.java
File:
com/google/android/gms/internal/ads/zzbsq.javaA-7, A-8, A-9, A-10: String.valueOf Pattern (4 cases)
Files:
zzga.java,zzwq.java,zzbn.java(2 cases)DEX Bytecode Analysis
Why Inlining Fails
Problems with double evaluation:
Theoretical Solution
Implement side-effect analysis to identify pure expressions:
String.valueOf(str)map(parameter)context.getApplicationContext()contentLengthStrategy(parameter)Implementation approach:
String.valueOf,Integer.valueOf, etc.) → SafeStatus
Partially solvable - Requires side-effect analysis implementation.
Would need to:
Related