From 1d9bdf8382e75135216b7cd6f4ea7fc61eb93f3d Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 7 Apr 2014 14:41:42 -0600 Subject: [PATCH] fix some Unsafe bugs * Unsafe.arrayIndexScale was always returning the native word size, due to a thinko on my part * Unsafe.getLongVolatile and putLongVolatile did not work for array elements on 32-bit systems --- src/builtin.cpp | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index e70a5189ae..aa6bc88992 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -699,17 +699,17 @@ Avian_sun_misc_Unsafe_arrayIndexScale { object c = jclassVmClass(t, reinterpret_cast(arguments[1])); - if (c == type(t, Machine::JbooleanType) - || c == type(t, Machine::JbyteType)) + if (c == type(t, Machine::BooleanArrayType) + || c == type(t, Machine::ByteArrayType)) return 1; - else if (c == type(t, Machine::JshortType) - || c == type(t, Machine::JcharType)) + else if (c == type(t, Machine::ShortArrayType) + || c == type(t, Machine::CharArrayType)) return 2; - else if (c == type(t, Machine::JintType) - || c == type(t, Machine::JfloatType)) + else if (c == type(t, Machine::IntArrayType) + || c == type(t, Machine::FloatArrayType)) return 4; - else if (c == type(t, Machine::JlongType) - || c == type(t, Machine::JdoubleType)) + else if (c == type(t, Machine::LongArrayType) + || c == type(t, Machine::DoubleArrayType)) return 8; else return BytesPerWord; @@ -832,6 +832,7 @@ Avian_sun_misc_Unsafe_compareAndSwapLong return atomicCompareAndSwap64 (&fieldAtOffset(target, offset), expect, update); #else + PROTECT(t, target); ACQUIRE_FIELD_FOR_WRITE(t, fieldForOffset(t, target, offset)); if (fieldAtOffset(target, offset) == expect) { fieldAtOffset(target, offset) = update; @@ -849,18 +850,23 @@ Avian_sun_misc_Unsafe_getLongVolatile object o = reinterpret_cast(arguments[1]); int64_t offset; memcpy(&offset, arguments + 2, 8); - object field; + object lock; if (BytesPerWord < 8) { - field = fieldForOffset(t, o, offset); + if (classArrayDimensions(t, objectClass(t, o))) { + lock = objectClass(t, o); + } else { + lock = fieldForOffset(t, o, offset); + } - PROTECT(t, field); - acquire(t, field); + PROTECT(t, o); + PROTECT(t, lock); + acquire(t, lock); } int64_t result = fieldAtOffset(o, offset); if (BytesPerWord < 8) { - release(t, field); + release(t, lock); } else { loadMemoryBarrier(); } @@ -876,12 +882,17 @@ Avian_sun_misc_Unsafe_putLongVolatile int64_t offset; memcpy(&offset, arguments + 2, 8); int64_t value; memcpy(&value, arguments + 4, 8); - object field; + object lock; if (BytesPerWord < 8) { - field = fieldForOffset(t, o, offset); + if (classArrayDimensions(t, objectClass(t, o))) { + lock = objectClass(t, o); + } else { + lock = fieldForOffset(t, o, offset); + } - PROTECT(t, field); - acquire(t, field); + PROTECT(t, o); + PROTECT(t, lock); + acquire(t, lock); } else { storeStoreMemoryBarrier(); } @@ -889,7 +900,7 @@ Avian_sun_misc_Unsafe_putLongVolatile fieldAtOffset(o, offset) = value; if (BytesPerWord < 8) { - release(t, field); + release(t, lock); } else { storeLoadMemoryBarrier(); }