From 99f391e48f79421a4d949152aec6bafe1a7b5b82 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Thu, 3 Apr 2014 12:56:06 +0100 Subject: [PATCH] Fix Unsafe.getLong()/putLong() for x86, add test. Change-Id: Id6841ae50e1047543c04dcdae30254dd6ce82082 --- compiler/dex/quick/gen_invoke.cc | 4 ++-- test/UnsafeTest/UnsafeTest.java | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index 352130d1d..a90ba0400 100644 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -1409,7 +1409,7 @@ bool Mir2Lir::GenInlinedUnsafeGet(CallInfo* info, RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); if (is_long) { if (cu_->instruction_set == kX86) { - LoadBaseIndexedDisp(rl_object.reg, rl_offset.reg, 1, 0, rl_result.reg.GetLow(), + LoadBaseIndexedDisp(rl_object.reg, rl_offset.reg, 0, 0, rl_result.reg.GetLow(), rl_result.reg.GetHigh(), kLong, INVALID_SREG); } else { RegStorage rl_temp_offset = AllocTemp(); @@ -1457,7 +1457,7 @@ bool Mir2Lir::GenInlinedUnsafePut(CallInfo* info, bool is_long, if (is_long) { rl_value = LoadValueWide(rl_src_value, kCoreReg); if (cu_->instruction_set == kX86) { - StoreBaseIndexedDisp(rl_object.reg, rl_offset.reg, 1, 0, rl_value.reg.GetLow(), + StoreBaseIndexedDisp(rl_object.reg, rl_offset.reg, 0, 0, rl_value.reg.GetLow(), rl_value.reg.GetHigh(), kLong, INVALID_SREG); } else { RegStorage rl_temp_offset = AllocTemp(); diff --git a/test/UnsafeTest/UnsafeTest.java b/test/UnsafeTest/UnsafeTest.java index f3d528962..9e2ff876b 100644 --- a/test/UnsafeTest/UnsafeTest.java +++ b/test/UnsafeTest/UnsafeTest.java @@ -29,6 +29,13 @@ public class UnsafeTest { } } + private static void check(long actual, long expected, String msg) { + if (actual != expected) { + System.logE(msg + " : " + actual + " != " + expected); + System.exit(-1); + } + } + private static Unsafe getUnsafe() throws Exception { Class unsafeClass = Class.forName("sun.misc.Unsafe"); Field f = unsafeClass.getDeclaredField("theUnsafe"); @@ -71,6 +78,27 @@ public class UnsafeTest { "Unsafe.arrayIndexScale(long[])"); check(unsafe.arrayIndexScale(Object[].class), vmArrayIndexScale(Object[].class), "Unsafe.arrayIndexScale(Object[])"); + + TestClass t = new TestClass(); + int intValue = 12345678; + Field intField = TestClass.class.getDeclaredField("intVar"); + long intOffset = unsafe.objectFieldOffset(intField); + check(unsafe.getInt(t, intOffset), 0, "Unsafe.getInt(Object, long) - initial"); + unsafe.putInt(t, intOffset, intValue); + check(t.intVar, intValue, "Unsafe.putInt(Object, long, int)"); + check(unsafe.getInt(t, intOffset), intValue, "Unsafe.getInt(Object, long)"); + Field longField = TestClass.class.getDeclaredField("longVar"); + long longOffset = unsafe.objectFieldOffset(longField); + long longValue = 1234567887654321L; + check(unsafe.getLong(t, longOffset), 0, "Unsafe.getLong(Object, long) - initial"); + unsafe.putLong(t, longOffset, longValue); + check(t.longVar, longValue, "Unsafe.putLong(Object, long, long)"); + check(unsafe.getLong(t, longOffset), longValue, "Unsafe.getLong(Object, long)"); + } + + private static class TestClass { + public int intVar = 0; + public long longVar = 0; } private static native int vmArrayBaseOffset(Class clazz); -- 2.11.0