summaryrefslogtreecommitdiffstats
path: root/compiler/dex/quick/gen_invoke.cc
diff options
context:
space:
mode:
authorbuzbee <buzbee@google.com>2014-10-03 13:14:17 -0700
committerbuzbee <buzbee@google.com>2014-10-03 13:14:17 -0700
commit7c02e918e752ab36f0b6cab7528f10c0cf55a4ee (patch)
tree704cb9845bbdecc977c8fb31dc0a677450d17303 /compiler/dex/quick/gen_invoke.cc
parentb5325e24ca58299b2b011e57e784b2584f99d687 (diff)
downloadandroid_art-7c02e918e752ab36f0b6cab7528f10c0cf55a4ee.tar.gz
android_art-7c02e918e752ab36f0b6cab7528f10c0cf55a4ee.tar.bz2
android_art-7c02e918e752ab36f0b6cab7528f10c0cf55a4ee.zip
Quick compiler: Fix ambiguous LoadValue()
Internal b/17790197 & hat tip to Stephen Kyle The following custom-edited dex program demonstrated incorrect code generation caused by type confusion. In the example, the constant held in v0 is used in both float and int contexts, and the register class gets confused at the if-eq. .method private static getInt()I .registers 4 const/16 v0, 100 const/4 v1, 1 const/4 v2, 7 :loop if-eq v2, v0, :done add-int v2, v2, v1 goto :loop :done add-float v3, v0, v1 return v2 .end method The bug was introduced in c/96499, "Quick compiler: reference cleanup" That CL created a convenience variant of LoadValue which selected the target register type based on the type of the RegLocation. It should not have done so. The type of a RegLocation is the compiler's best guess of the Dalvik type - and Dalvik allows constants to be used in multiple type contexts. All code generation utilities must specify desired register class based on the capabilities of the instructions to be emitted. In the failing case, OpCmpImmBranch (and GenCompareZeroAndBranch) will be using core registers, so the LoadValue must specify either kCoreReg or kRefReg. The CL deletes the dangerous LoadValue() variant. Change-Id: Ie4ec6e51b19676dbbb9628c72c8b3473a419e7ec
Diffstat (limited to 'compiler/dex/quick/gen_invoke.cc')
-rwxr-xr-xcompiler/dex/quick/gen_invoke.cc2
1 files changed, 1 insertions, 1 deletions
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index c308932bcf..bafb57d60e 100755
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -1643,7 +1643,7 @@ bool Mir2Lir::GenInlinedUnsafePut(CallInfo* info, bool is_long,
FreeTemp(rl_temp_offset);
}
} else {
- rl_value = LoadValue(rl_src_value);
+ rl_value = LoadValue(rl_src_value, LocToRegClass(rl_src_value));
if (rl_value.ref) {
StoreRefIndexed(rl_object.reg, rl_offset.reg, rl_value.reg, 0);
} else {