summaryrefslogtreecommitdiffstats
path: root/compiler/dex
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-04-02 17:09:17 -0700
committerMathieu Chartier <mathieuc@google.com>2014-04-02 17:48:05 -0700
commit7c95cefc168ba81b17a9ed2d987ac5bcf0b05781 (patch)
treef358d12353183bb5800e91f459a158a514039a09 /compiler/dex
parent0807e7bbbafc4b4e8e7fb1d2d54fbcb011c05c82 (diff)
downloadart-7c95cefc168ba81b17a9ed2d987ac5bcf0b05781.zip
art-7c95cefc168ba81b17a9ed2d987ac5bcf0b05781.tar.gz
art-7c95cefc168ba81b17a9ed2d987ac5bcf0b05781.tar.bz2
Use temp register in Unsafe Get/Put intrisics for displaced offset.
Previously, the object register would get clobberd by the adding the offset for wide UnsafeGets and wide UnsafePuts. This resulted in heap corruption in AtomicLongFieldUpdater.compareAndSet and possibly other places. Bug: 13744490 Change-Id: Ic368d930b855c5c57e22060b32b73d0745328ef2
Diffstat (limited to 'compiler/dex')
-rw-r--r--compiler/dex/quick/gen_invoke.cc22
1 files changed, 18 insertions, 4 deletions
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index 0746913..352130d 100644
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -1408,8 +1408,15 @@ bool Mir2Lir::GenInlinedUnsafeGet(CallInfo* info,
RegLocation rl_offset = LoadValue(rl_src_offset, kCoreReg);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (is_long) {
- OpRegReg(kOpAdd, rl_object.reg, rl_offset.reg);
- LoadBaseDispWide(rl_object.reg, 0, rl_result.reg, INVALID_SREG);
+ if (cu_->instruction_set == kX86) {
+ LoadBaseIndexedDisp(rl_object.reg, rl_offset.reg, 1, 0, rl_result.reg.GetLow(),
+ rl_result.reg.GetHigh(), kLong, INVALID_SREG);
+ } else {
+ RegStorage rl_temp_offset = AllocTemp();
+ OpRegRegReg(kOpAdd, rl_temp_offset, rl_object.reg, rl_offset.reg);
+ LoadBaseDispWide(rl_temp_offset, 0, rl_result.reg, INVALID_SREG);
+ FreeTemp(rl_temp_offset.GetReg());
+ }
} else {
LoadBaseIndexed(rl_object.reg, rl_offset.reg, rl_result.reg, 0, kWord);
}
@@ -1449,8 +1456,15 @@ bool Mir2Lir::GenInlinedUnsafePut(CallInfo* info, bool is_long,
RegLocation rl_value;
if (is_long) {
rl_value = LoadValueWide(rl_src_value, kCoreReg);
- OpRegReg(kOpAdd, rl_object.reg, rl_offset.reg);
- StoreBaseDispWide(rl_object.reg, 0, rl_value.reg);
+ if (cu_->instruction_set == kX86) {
+ StoreBaseIndexedDisp(rl_object.reg, rl_offset.reg, 1, 0, rl_value.reg.GetLow(),
+ rl_value.reg.GetHigh(), kLong, INVALID_SREG);
+ } else {
+ RegStorage rl_temp_offset = AllocTemp();
+ OpRegRegReg(kOpAdd, rl_temp_offset, rl_object.reg, rl_offset.reg);
+ StoreBaseDispWide(rl_temp_offset, 0, rl_value.reg);
+ FreeTemp(rl_temp_offset.GetReg());
+ }
} else {
rl_value = LoadValue(rl_src_value, kCoreReg);
StoreBaseIndexed(rl_object.reg, rl_offset.reg, rl_value.reg, 0, kWord);