Merge

Fri, 19 Dec 2014 01:29:51 +0000

author
dholmes
date
Fri, 19 Dec 2014 01:29:51 +0000
changeset 7549
190b6bbfec69
parent 7546
4181e5e64dd0
parent 7548
c1c044c745b2
child 7550
aca52dbbc08f

Merge

     1.1 --- a/src/share/vm/prims/unsafe.cpp	Tue Nov 25 15:59:42 2014 +0100
     1.2 +++ b/src/share/vm/prims/unsafe.cpp	Fri Dec 19 01:29:51 2014 +0000
     1.3 @@ -322,10 +322,33 @@
     1.4  UNSAFE_END
     1.5  
     1.6  #ifndef SUPPORTS_NATIVE_CX8
     1.7 -// Keep old code for platforms which may not have atomic jlong (8 bytes) instructions
     1.8  
     1.9 -// Volatile long versions must use locks if !VM_Version::supports_cx8().
    1.10 -// support_cx8 is a surrogate for 'supports atomic long memory ops'.
    1.11 +// VM_Version::supports_cx8() is a surrogate for 'supports atomic long memory ops'.
    1.12 +//
    1.13 +// On platforms which do not support atomic compare-and-swap of jlong (8 byte)
    1.14 +// values we have to use a lock-based scheme to enforce atomicity. This has to be
    1.15 +// applied to all Unsafe operations that set the value of a jlong field. Even so
    1.16 +// the compareAndSwapLong operation will not be atomic with respect to direct stores
    1.17 +// to the field from Java code. It is important therefore that any Java code that
    1.18 +// utilizes these Unsafe jlong operations does not perform direct stores. To permit
    1.19 +// direct loads of the field from Java code we must also use Atomic::store within the
    1.20 +// locked regions. And for good measure, in case there are direct stores, we also
    1.21 +// employ Atomic::load within those regions. Note that the field in question must be
    1.22 +// volatile and so must have atomic load/store accesses applied at the Java level.
    1.23 +//
    1.24 +// The locking scheme could utilize a range of strategies for controlling the locking
    1.25 +// granularity: from a lock per-field through to a single global lock. The latter is
    1.26 +// the simplest and is used for the current implementation. Note that the Java object
    1.27 +// that contains the field, can not, in general, be used for locking. To do so can lead
    1.28 +// to deadlocks as we may introduce locking into what appears to the Java code to be a
    1.29 +// lock-free path.
    1.30 +//
    1.31 +// As all the locked-regions are very short and themselves non-blocking we can treat
    1.32 +// them as leaf routines and elide safepoint checks (ie we don't perform any thread
    1.33 +// state transitions even when blocking for the lock). Note that if we do choose to
    1.34 +// add safepoint checks and thread state transitions, we must ensure that we calculate
    1.35 +// the address of the field _after_ we have acquired the lock, else the object may have
    1.36 +// been moved by the GC
    1.37  
    1.38  UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
    1.39    UnsafeWrapper("Unsafe_GetLongVolatile");
    1.40 @@ -337,8 +360,8 @@
    1.41      else {
    1.42        Handle p (THREAD, JNIHandles::resolve(obj));
    1.43        jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
    1.44 -      ObjectLocker ol(p, THREAD);
    1.45 -      jlong value = *addr;
    1.46 +      MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
    1.47 +      jlong value = Atomic::load(addr);
    1.48        return value;
    1.49      }
    1.50    }
    1.51 @@ -353,8 +376,8 @@
    1.52      else {
    1.53        Handle p (THREAD, JNIHandles::resolve(obj));
    1.54        jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
    1.55 -      ObjectLocker ol(p, THREAD);
    1.56 -      *addr = x;
    1.57 +      MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
    1.58 +      Atomic::store(x, addr);
    1.59      }
    1.60    }
    1.61  UNSAFE_END
    1.62 @@ -463,8 +486,8 @@
    1.63      else {
    1.64        Handle p (THREAD, JNIHandles::resolve(obj));
    1.65        jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
    1.66 -      ObjectLocker ol(p, THREAD);
    1.67 -      *addr = x;
    1.68 +      MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
    1.69 +      Atomic::store(x, addr);
    1.70      }
    1.71    }
    1.72  #endif
    1.73 @@ -1213,14 +1236,19 @@
    1.74    UnsafeWrapper("Unsafe_CompareAndSwapLong");
    1.75    Handle p (THREAD, JNIHandles::resolve(obj));
    1.76    jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
    1.77 +#ifdef SUPPORTS_NATIVE_CX8
    1.78 +  return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
    1.79 +#else
    1.80    if (VM_Version::supports_cx8())
    1.81      return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
    1.82    else {
    1.83      jboolean success = false;
    1.84 -    ObjectLocker ol(p, THREAD);
    1.85 -    if (*addr == e) { *addr = x; success = true; }
    1.86 +    MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
    1.87 +    jlong val = Atomic::load(addr);
    1.88 +    if (val == e) { Atomic::store(x, addr); success = true; }
    1.89      return success;
    1.90    }
    1.91 +#endif
    1.92  UNSAFE_END
    1.93  
    1.94  UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
     2.1 --- a/src/share/vm/runtime/mutexLocker.cpp	Tue Nov 25 15:59:42 2014 +0100
     2.2 +++ b/src/share/vm/runtime/mutexLocker.cpp	Fri Dec 19 01:29:51 2014 +0000
     2.3 @@ -135,6 +135,10 @@
     2.4  Mutex*   JfrThreadGroups_lock         = NULL;
     2.5  #endif
     2.6  
     2.7 +#ifndef SUPPORTS_NATIVE_CX8
     2.8 +Mutex*   UnsafeJlong_lock             = NULL;
     2.9 +#endif
    2.10 +
    2.11  #define MAX_NUM_MUTEX 128
    2.12  static Monitor * _mutex_array[MAX_NUM_MUTEX];
    2.13  static int _num_mutex;
    2.14 @@ -286,6 +290,9 @@
    2.15    def(JfrStacktrace_lock           , Mutex,   special,     true );
    2.16  #endif
    2.17  
    2.18 +#ifndef SUPPORTS_NATIVE_CX8
    2.19 +  def(UnsafeJlong_lock             , Mutex,   special,     false);
    2.20 +#endif
    2.21  }
    2.22  
    2.23  GCMutexLocker::GCMutexLocker(Monitor * mutex) {
     3.1 --- a/src/share/vm/runtime/mutexLocker.hpp	Tue Nov 25 15:59:42 2014 +0100
     3.2 +++ b/src/share/vm/runtime/mutexLocker.hpp	Fri Dec 19 01:29:51 2014 +0000
     3.3 @@ -151,6 +151,10 @@
     3.4  extern Mutex*   JfrThreadGroups_lock;            // protects JFR access to Thread Groups
     3.5  #endif
     3.6  
     3.7 +#ifndef SUPPORTS_NATIVE_CX8
     3.8 +extern Mutex*   UnsafeJlong_lock;                // provides Unsafe atomic updates to jlongs on platforms that don't support cx8
     3.9 +#endif
    3.10 +
    3.11  // A MutexLocker provides mutual exclusion with respect to a given mutex
    3.12  // for the scope which contains the locker.  The lock is an OS lock, not
    3.13  // an object lock, and the two do not interoperate.  Do not use Mutex-based

mercurial