1 /* |
1 /* |
2 * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
376 // VM_Version::supports_cx8() is a surrogate for 'supports atomic long memory ops'. |
376 // VM_Version::supports_cx8() is a surrogate for 'supports atomic long memory ops'. |
377 // |
377 // |
378 // On platforms which do not support atomic compare-and-swap of jlong (8 byte) |
378 // On platforms which do not support atomic compare-and-swap of jlong (8 byte) |
379 // values we have to use a lock-based scheme to enforce atomicity. This has to be |
379 // values we have to use a lock-based scheme to enforce atomicity. This has to be |
380 // applied to all Unsafe operations that set the value of a jlong field. Even so |
380 // applied to all Unsafe operations that set the value of a jlong field. Even so |
381 // the compareAndSwapLong operation will not be atomic with respect to direct stores |
381 // the compareAndSetLong operation will not be atomic with respect to direct stores |
382 // to the field from Java code. It is important therefore that any Java code that |
382 // to the field from Java code. It is important therefore that any Java code that |
383 // utilizes these Unsafe jlong operations does not perform direct stores. To permit |
383 // utilizes these Unsafe jlong operations does not perform direct stores. To permit |
384 // direct loads of the field from Java code we must also use Atomic::store within the |
384 // direct loads of the field from Java code we must also use Atomic::store within the |
385 // locked regions. And for good measure, in case there are direct stores, we also |
385 // locked regions. And for good measure, in case there are direct stores, we also |
386 // employ Atomic::load within those regions. Note that the field in question must be |
386 // employ Atomic::load within those regions. Note that the field in question must be |
1011 return val; |
1011 return val; |
1012 } |
1012 } |
1013 #endif |
1013 #endif |
1014 } UNSAFE_END |
1014 } UNSAFE_END |
1015 |
1015 |
1016 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) { |
1016 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) { |
1017 oop x = JNIHandles::resolve(x_h); |
1017 oop x = JNIHandles::resolve(x_h); |
1018 oop e = JNIHandles::resolve(e_h); |
1018 oop e = JNIHandles::resolve(e_h); |
1019 oop p = JNIHandles::resolve(obj); |
1019 oop p = JNIHandles::resolve(obj); |
1020 HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset); |
1020 HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset); |
1021 oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e, true); |
1021 oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e, true); |
1026 update_barrier_set((void*)addr, x); |
1026 update_barrier_set((void*)addr, x); |
1027 |
1027 |
1028 return true; |
1028 return true; |
1029 } UNSAFE_END |
1029 } UNSAFE_END |
1030 |
1030 |
1031 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) { |
1031 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) { |
1032 oop p = JNIHandles::resolve(obj); |
1032 oop p = JNIHandles::resolve(obj); |
1033 jint* addr = (jint *)index_oop_from_field_offset_long(p, offset); |
1033 jint* addr = (jint *)index_oop_from_field_offset_long(p, offset); |
1034 |
1034 |
1035 return (jint)(Atomic::cmpxchg(x, addr, e)) == e; |
1035 return (jint)(Atomic::cmpxchg(x, addr, e)) == e; |
1036 } UNSAFE_END |
1036 } UNSAFE_END |
1037 |
1037 |
1038 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) { |
1038 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) { |
1039 Handle p(THREAD, JNIHandles::resolve(obj)); |
1039 Handle p(THREAD, JNIHandles::resolve(obj)); |
1040 jlong* addr = (jlong*)index_oop_from_field_offset_long(p(), offset); |
1040 jlong* addr = (jlong*)index_oop_from_field_offset_long(p(), offset); |
1041 |
1041 |
1042 #ifdef SUPPORTS_NATIVE_CX8 |
1042 #ifdef SUPPORTS_NATIVE_CX8 |
1043 return (jlong)(Atomic::cmpxchg(x, addr, e)) == e; |
1043 return (jlong)(Atomic::cmpxchg(x, addr, e)) == e; |
1192 {CC "pageSize", CC "()I", FN_PTR(Unsafe_PageSize)}, |
1192 {CC "pageSize", CC "()I", FN_PTR(Unsafe_PageSize)}, |
1193 |
1193 |
1194 {CC "defineClass0", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass0)}, |
1194 {CC "defineClass0", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass0)}, |
1195 {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)}, |
1195 {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)}, |
1196 {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)}, |
1196 {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)}, |
1197 {CC "compareAndSwapObject", CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSwapObject)}, |
1197 {CC "compareAndSetObject",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetObject)}, |
1198 {CC "compareAndSwapInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)}, |
1198 {CC "compareAndSetInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSetInt)}, |
1199 {CC "compareAndSwapLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)}, |
1199 {CC "compareAndSetLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSetLong)}, |
1200 {CC "compareAndExchangeObjectVolatile", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeObject)}, |
1200 {CC "compareAndExchangeObject", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeObject)}, |
1201 {CC "compareAndExchangeIntVolatile", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)}, |
1201 {CC "compareAndExchangeInt", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)}, |
1202 {CC "compareAndExchangeLongVolatile", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)}, |
1202 {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)}, |
1203 |
1203 |
1204 {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)}, |
1204 {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)}, |
1205 {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)}, |
1205 {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)}, |
1206 |
1206 |
1207 {CC "getLoadAverage0", CC "([DI)I", FN_PTR(Unsafe_GetLoadAverage0)}, |
1207 {CC "getLoadAverage0", CC "([DI)I", FN_PTR(Unsafe_GetLoadAverage0)}, |