diff --git a/classpath/sun/misc/Unsafe.java b/classpath/sun/misc/Unsafe.java index e5fd094c45..5cb571ee9c 100644 --- a/classpath/sun/misc/Unsafe.java +++ b/classpath/sun/misc/Unsafe.java @@ -48,6 +48,8 @@ public final class Unsafe { public native void putIntVolatile(Object o, long offset, int x); + public native long getLongVolatile(Object o, long offset); + public native void putOrderedInt(Object o, long offset, int x); public native Object getObject(Object o, long offset); diff --git a/src/builtin.cpp b/src/builtin.cpp index ff29d6e3ce..1a7d283231 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -48,6 +48,60 @@ resolveSystemClassThrow(Thread* t, object loader, object spec) (t, loader, spec, true, Machine::ClassNotFoundExceptionType); } +object +fieldForOffsetInClass(Thread* t, object c, unsigned offset) +{ + object super = classSuper(t, c); + if (super) { + object field = fieldForOffsetInClass(t, super, offset); + if (field) { + return field; + } + } + + object table = classFieldTable(t, c); + if (table) { + for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { + object field = objectArrayBody(t, table, i); + if ((fieldFlags(t, field) & ACC_STATIC) == 0 + and fieldOffset(t, field) == offset) + { + return field; + } + } + } + + return 0; +} + +object +fieldForOffset(Thread* t, object o, unsigned offset) +{ + object c = objectClass(t, o); + if (classVmFlags(t, c) & SingletonFlag) { + c = singletonObject(t, o, 0); + object table = classFieldTable(t, c); + if (table) { + for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { + object field = objectArrayBody(t, table, i); + if ((fieldFlags(t, field) & ACC_STATIC) + and fieldOffset(t, field) == offset) + { + return field; + } + } + } + abort(t); + } else { + object field = fieldForOffsetInClass(t, c, offset); + if (field) { + return field; + } else { + abort(t); + } + } +} + } // namespace extern "C" AVIAN_EXPORT void JNICALL @@ -694,7 +748,7 @@ Avian_sun_misc_Unsafe_compareAndSwapLong return atomicCompareAndSwap64 (&fieldAtOffset(target, offset), expect, update); #else - ACQUIRE_FIELD_FOR_WRITE(t, local::fieldForOffset(t, target, offset)); + ACQUIRE_FIELD_FOR_WRITE(t, fieldForOffset(t, target, offset)); if (fieldAtOffset(target, offset) == expect) { fieldAtOffset(target, offset) = update; return true; @@ -704,6 +758,36 @@ Avian_sun_misc_Unsafe_compareAndSwapLong #endif } +extern "C" AVIAN_EXPORT int64_t JNICALL +Avian_sun_misc_Unsafe_getLongVolatile +(Thread* t, object, uintptr_t* arguments) +{ + object o = reinterpret_cast(arguments[1]); + int64_t offset; memcpy(&offset, arguments + 2, 8); + + // avoid blocking the VM if this is being called in a busy loop + PROTECT(t, o); + { ENTER(t, Thread::IdleState); } + + object field; + if (BytesPerWord < 8) { + field = fieldForOffset(t, o, offset); + + PROTECT(t, field); + acquire(t, field); + } + + int64_t result = fieldAtOffset(o, offset); + + if (BytesPerWord < 8) { + release(t, field); + } else { + loadMemoryBarrier(); + } + + return result; +} + extern "C" AVIAN_EXPORT void JNICALL Avian_sun_misc_Unsafe_unpark (Thread* t, object, uintptr_t* arguments) diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index a49bd43db2..ac406b3adb 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -2460,60 +2460,6 @@ pipeAvailable(int fd, int* available) #endif } -object -fieldForOffsetInClass(Thread* t, object c, unsigned offset) -{ - object super = classSuper(t, c); - if (super) { - object field = fieldForOffsetInClass(t, super, offset); - if (field) { - return field; - } - } - - object table = classFieldTable(t, c); - if (table) { - for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { - object field = objectArrayBody(t, table, i); - if ((fieldFlags(t, field) & ACC_STATIC) == 0 - and fieldOffset(t, field) == offset) - { - return field; - } - } - } - - return 0; -} - -object -fieldForOffset(Thread* t, object o, unsigned offset) -{ - object c = objectClass(t, o); - if (classVmFlags(t, c) & SingletonFlag) { - c = singletonObject(t, o, 0); - object table = classFieldTable(t, c); - if (table) { - for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { - object field = objectArrayBody(t, table, i); - if ((fieldFlags(t, field) & ACC_STATIC) - and fieldOffset(t, field) == offset) - { - return field; - } - } - } - abort(t); - } else { - object field = fieldForOffsetInClass(t, c, offset); - if (field) { - return field; - } else { - abort(t); - } - } -} - } // namespace local } // namespace @@ -2737,36 +2683,6 @@ Avian_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J (t, method, arguments); } -extern "C" AVIAN_EXPORT int64_t JNICALL -Avian_sun_misc_Unsafe_getLongVolatile -(Thread* t, object, uintptr_t* arguments) -{ - object o = reinterpret_cast(arguments[1]); - int64_t offset; memcpy(&offset, arguments + 2, 8); - - // avoid blocking the VM if this is being called in a busy loop - PROTECT(t, o); - { ENTER(t, Thread::IdleState); } - - object field; - if (BytesPerWord < 8) { - field = local::fieldForOffset(t, o, offset); - - PROTECT(t, field); - acquire(t, field); - } - - int64_t result = fieldAtOffset(o, offset); - - if (BytesPerWord < 8) { - release(t, field); - } else { - loadMemoryBarrier(); - } - - return result; -} - extern "C" AVIAN_EXPORT void JNICALL Avian_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB (Thread*, object, uintptr_t* arguments)