hotspot/src/share/vm/prims/unsafe.cpp
changeset 45055 1c7bbc426b1e
parent 41181 2ce2f1c582ca
child 46458 3c12af929e7d
equal deleted inserted replaced
45054:c09733aaf97f 45055:1c7bbc426b1e
     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)},