8227605: Kitchensink fails "assert((((klass)->trace_id() & (JfrTraceIdEpoch::leakp_in_use_this_epoch_bit())) != 0)) failed: invariant"
authormgronlun
Wed, 31 Jul 2019 16:09:17 +0200
changeset 57617 5f3b05a36d61
parent 57616 76a82db7181a
child 57618 53154e45385a
8227605: Kitchensink fails "assert((((klass)->trace_id() & (JfrTraceIdEpoch::leakp_in_use_this_epoch_bit())) != 0)) failed: invariant" Reviewed-by: dholmes, dcubed, egahlin
src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdBits.inline.hpp
src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdBits.inline.hpp	Wed Jul 31 09:52:28 2019 +0800
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdBits.inline.hpp	Wed Jul 31 16:09:17 2019 +0200
@@ -27,7 +27,6 @@
 
 #include "jfr/utilities/jfrTypes.hpp"
 #include "runtime/atomic.hpp"
-#include "runtime/orderAccess.hpp"
 #include "utilities/macros.hpp"
 
 #ifdef VM_LITTLE_ENDIAN
@@ -40,46 +39,45 @@
 
 inline void set_bits(jbyte bits, jbyte* const dest) {
   assert(dest != NULL, "invariant");
-  const jbyte current = OrderAccess::load_acquire(dest);
-  if (bits != (current & bits)) {
+  if (bits != (*dest & bits)) {
     *dest |= bits;
   }
 }
 
-inline void set_mask(jbyte mask, jbyte* const dest) {
-  assert(dest != NULL, "invariant");
-  const jbyte current = OrderAccess::load_acquire(dest);
-  if (mask != (current & mask)) {
-    *dest &= mask;
-  }
+inline jbyte traceid_and(jbyte current, jbyte bits) {
+  return current & bits;
+}
+
+inline jbyte traceid_or(jbyte current, jbyte bits) {
+  return current | bits;
 }
 
-inline void set_bits_cas(jbyte bits, jbyte* const dest) {
+inline jbyte traceid_xor(jbyte current, jbyte bits) {
+  return current ^ bits;
+}
+
+template <jbyte op(jbyte, jbyte)>
+inline void set_bits_cas_form(jbyte bits, jbyte* const dest) {
   assert(dest != NULL, "invariant");
   do {
-    const jbyte current = OrderAccess::load_acquire(dest);
-    if (bits == (current & bits)) {
-      return;
-    }
-    const jbyte new_value = current | bits;
+    const jbyte current = *dest;
+    const jbyte new_value = op(current, bits);
     if (Atomic::cmpxchg(new_value, dest, current) == current) {
       return;
     }
   } while (true);
 }
 
+inline void set_bits_cas(jbyte bits, jbyte* const dest) {
+  set_bits_cas_form<traceid_or>(bits, dest);
+}
+
 inline void clear_bits_cas(jbyte bits, jbyte* const dest) {
-  assert(dest != NULL, "invariant");
-  do {
-    const jbyte current = OrderAccess::load_acquire(dest);
-    if (bits != (current & bits)) {
-      return;
-    }
-    const jbyte new_value = current ^ bits;
-    if (Atomic::cmpxchg(new_value, dest, current) == current) {
-      return;
-    }
-  } while (true);
+  set_bits_cas_form<traceid_xor>(bits, dest);
+}
+
+inline void set_mask(jbyte mask, jbyte* const dest) {
+  set_bits_cas_form<traceid_and>(mask, dest);
 }
 
 inline void set_traceid_bits(jbyte bits, traceid* dest) {
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp	Wed Jul 31 09:52:28 2019 +0800
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp	Wed Jul 31 16:09:17 2019 +0200
@@ -108,7 +108,7 @@
 #define SET_USED_THIS_EPOCH(ptr)        (SET_TAG(ptr, IN_USE_THIS_EPOCH_BIT))
 #define SET_USED_PREV_EPOCH(ptr)        (SET_TAG_CAS(ptr, IN_USE_PREV_EPOCH_BIT))
 #define SET_LEAKP_USED_THIS_EPOCH(ptr)  (SET_LEAKP_TAG(ptr, IN_USE_THIS_EPOCH_BIT))
-#define SET_LEAKP_USED_PREV_EPOCH(ptr)  (SET_LEAKP_TAG(ptr, IN_USE_PREV_EPOCH_BIT))
+#define SET_LEAKP_USED_PREV_EPOCH(ptr)  (SET_LEAKP_TAG_CAS(ptr, IN_USE_PREV_EPOCH_BIT))
 #define SET_METHOD_AND_CLASS_USED_THIS_EPOCH(kls) (SET_TAG(kls, METHOD_AND_CLASS_IN_USE_THIS_EPOCH_BITS))
 
 #define USED_THIS_EPOCH(ptr)            (((ptr)->trace_id() & IN_USE_THIS_EPOCH_BIT) != 0)