changeset 500:ca7d48236048

Merge
author xlu
date Sat, 20 Dec 2008 00:45:18 -0800
parents 8a25d96bcf08 (diff) 7aadaf46ecd7 (current diff)
children 26bc4770e671
files
diffstat 2 files changed, 19 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/os/solaris/vm/os_solaris.cpp	Fri Dec 19 12:15:34 2008 -0800
+++ b/src/os/solaris/vm/os_solaris.cpp	Sat Dec 20 00:45:18 2008 -0800
@@ -1638,16 +1638,24 @@
 // getTimeNanos is guaranteed to not move backward on Solaris
 inline hrtime_t getTimeNanos() {
   if (VM_Version::supports_cx8()) {
-    bool retry = false;
-    hrtime_t newtime = gethrtime();
-    hrtime_t oldmaxtime = max_hrtime;
-    hrtime_t retmaxtime = oldmaxtime;
-    while ((newtime > retmaxtime) && (retry == false || retmaxtime != oldmaxtime)) {
-      oldmaxtime = retmaxtime;
-      retmaxtime = Atomic::cmpxchg(newtime, (volatile jlong *)&max_hrtime, oldmaxtime);
-      retry = true;
-    }
-    return (newtime > retmaxtime) ? newtime : retmaxtime;
+    const hrtime_t now = gethrtime();
+    const hrtime_t prev = max_hrtime;
+    if (now <= prev)  return prev;   // same or retrograde time;
+    const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev);
+    assert(obsv >= prev, "invariant");   // Monotonicity
+    // If the CAS succeeded then we're done and return "now".
+    // If the CAS failed and the observed value "obs" is >= now then
+    // we should return "obs".  If the CAS failed and now > obs > prv then
+    // some other thread raced this thread and installed a new value, in which case
+    // we could either (a) retry the entire operation, (b) retry trying to install now
+    // or (c) just return obs.  We use (c).   No loop is required although in some cases
+    // we might discard a higher "now" value in deference to a slightly lower but freshly
+    // installed obs value.   That's entirely benign -- it admits no new orderings compared
+    // to (a) or (b) -- and greatly reduces coherence traffic.
+    // We might also condition (c) on the magnitude of the delta between obs and now.
+    // Avoiding excessive CAS operations to hot RW locations is critical.
+    // See http://blogs.sun.com/dave/entry/cas_and_cache_trivia_invalidate
+    return (prev == obsv) ? now : obsv ;
   } else {
     return oldgetTimeNanos();
   }
--- a/src/share/vm/runtime/javaCalls.cpp	Fri Dec 19 12:15:34 2008 -0800
+++ b/src/share/vm/runtime/javaCalls.cpp	Sat Dec 20 00:45:18 2008 -0800
@@ -504,7 +504,7 @@
       intptr_t v = _value[p];
       if (v != 0 ) {
         size_t t = (size_t)v;
-        bad = (t < (size_t)os::vm_page_size() ) || !(*(oop*)v)->is_oop_or_null(true);
+        bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true);
         if (CheckJNICalls && bad) {
           ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument");
         }