src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdBits.inline.hpp
branchJEP-349-branch
changeset 57870 00860d9caf4d
parent 57360 5d043a159d5c
child 58154 060d9d139109
equal deleted inserted replaced
57862:84ef29ccac56 57870:00860d9caf4d
    30 #include "runtime/orderAccess.hpp"
    30 #include "runtime/orderAccess.hpp"
    31 #include "utilities/macros.hpp"
    31 #include "utilities/macros.hpp"
    32 
    32 
    33 #ifdef VM_LITTLE_ENDIAN
    33 #ifdef VM_LITTLE_ENDIAN
    34 static const int low_offset = 0;
    34 static const int low_offset = 0;
    35 static const int leakp_offset = low_offset + 1;
    35 static const int meta_offset = low_offset + 1;
    36 #else
    36 #else
    37 static const int low_offset = 7;
    37 static const int low_offset = 7;
    38 static const int leakp_offset = low_offset - 1;
    38 static const int meta_offset = low_offset - 1;
    39 #endif
    39 #endif
    40 
    40 
    41 inline void set_bits(jbyte bits, jbyte* const dest) {
    41 inline void set_bits(jbyte bits, jbyte* const dest) {
    42   assert(dest != NULL, "invariant");
    42   assert(dest != NULL, "invariant");
    43   const jbyte current = *dest;
    43   if (bits != (*dest & bits)) {
    44   if (bits != (current & bits)) {
    44     *dest |= bits;
    45     *dest = current | bits;
       
    46 
       
    47     OrderAccess::storestore();
    45     OrderAccess::storestore();
    48   }
    46   }
    49 }
    47 }
    50 
    48 
    51 inline void set_bits_cas(jbyte bits, jbyte* const dest) {
    49 inline jbyte traceid_and(jbyte current, jbyte bits) {
       
    50   return current & bits;
       
    51 }
       
    52 
       
    53 inline jbyte traceid_or(jbyte current, jbyte bits) {
       
    54   return current | bits;
       
    55 }
       
    56 
       
    57 inline jbyte traceid_xor(jbyte current, jbyte bits) {
       
    58   return current ^ bits;
       
    59 }
       
    60 
       
    61 template <jbyte op(jbyte, jbyte)>
       
    62 inline void set_bits_cas_form(jbyte bits, jbyte* const dest) {
    52   assert(dest != NULL, "invariant");
    63   assert(dest != NULL, "invariant");
    53   do {
    64   do {
    54     const jbyte current = OrderAccess::load_acquire(dest);
    65     const jbyte current = *dest;
    55     if (bits == (current & bits)) {
    66     const jbyte new_value = op(current, bits);
    56       return;
       
    57     }
       
    58     const jbyte new_value = current | bits;
       
    59     if (Atomic::cmpxchg(new_value, dest, current) == current) {
    67     if (Atomic::cmpxchg(new_value, dest, current) == current) {
    60       return;
    68       return;
    61     }
    69     }
    62   } while (true);
    70   } while (true);
    63 }
    71 }
    64 
    72 
       
    73 inline void set_bits_cas(jbyte bits, jbyte* const dest) {
       
    74   set_bits_cas_form<traceid_or>(bits, dest);
       
    75 }
       
    76 
    65 inline void clear_bits_cas(jbyte bits, jbyte* const dest) {
    77 inline void clear_bits_cas(jbyte bits, jbyte* const dest) {
    66   assert(dest != NULL, "invariant");
    78   set_bits_cas_form<traceid_xor>(bits, dest);
    67   do {
       
    68     const jbyte current = OrderAccess::load_acquire(dest);
       
    69     if (bits != (current & bits)) {
       
    70       return;
       
    71     }
       
    72     const jbyte new_value = current ^ bits;
       
    73     if (Atomic::cmpxchg(new_value, dest, current) == current) {
       
    74       return;
       
    75     }
       
    76   } while (true);
       
    77 }
    79 }
    78 
    80 
    79 inline void set_mask(jbyte mask, jbyte* const dest) {
    81 inline void set_mask(jbyte mask, jbyte* const dest) {
    80   assert(dest != NULL, "invariant");
    82   set_bits_cas_form<traceid_and>(mask, dest);
    81   const jbyte current = *dest;
       
    82   if (mask != (current & mask)) {
       
    83     *dest = current & mask;
       
    84     OrderAccess::storestore();
       
    85   }
       
    86 }
    83 }
    87 inline void set_mask_cas(jbyte mask, jbyte* const dest) {
    84 
    88   assert(dest != NULL, "invariant");
       
    89   do {
       
    90     const jbyte current = OrderAccess::load_acquire(dest);
       
    91     if (mask == (current & mask)) {
       
    92       return;
       
    93     }
       
    94     const jbyte new_value = current & mask;
       
    95     if (Atomic::cmpxchg(new_value, dest, current) == current) {
       
    96       return;
       
    97     }
       
    98   } while (true);
       
    99 }
       
   100 inline void set_traceid_bits(jbyte bits, traceid* dest) {
    85 inline void set_traceid_bits(jbyte bits, traceid* dest) {
   101   set_bits(bits, ((jbyte*)dest) + low_offset);
    86   set_bits(bits, ((jbyte*)dest) + low_offset);
   102 }
    87 }
   103 
    88 
   104 inline void set_traceid_bits_cas(jbyte bits, traceid* dest) {
    89 inline void set_traceid_bits_cas(jbyte bits, traceid* dest) {
   107 
    92 
   108 inline void set_traceid_mask(jbyte mask, traceid* dest) {
    93 inline void set_traceid_mask(jbyte mask, traceid* dest) {
   109   set_mask(mask, ((jbyte*)dest) + low_offset);
    94   set_mask(mask, ((jbyte*)dest) + low_offset);
   110 }
    95 }
   111 
    96 
   112 inline void set_leakp_traceid_bits(jbyte bits, traceid* dest) {
    97 inline void set_meta_bits(jbyte bits, jbyte* const dest) {
   113   set_bits(bits, ((jbyte*)dest) + leakp_offset);
    98   assert(dest != NULL, "invariant");
       
    99   *dest |= bits;
   114 }
   100 }
   115 
   101 
   116 inline void set_leakp_traceid_bits_cas(jbyte bits, traceid* dest) {
   102 inline void set_traceid_meta_bits(jbyte bits, traceid* dest) {
   117   set_bits_cas(bits, ((jbyte*)dest) + leakp_offset);
   103   set_meta_bits(bits, ((jbyte*)dest) + meta_offset);
   118 }
   104 }
   119 
   105 
   120 inline void set_leakp_traceid_mask(jbyte mask, traceid* dest) {
   106 inline void set_meta_mask(jbyte mask, jbyte* const dest) {
   121   set_mask_cas(mask, ((jbyte*)dest) + leakp_offset);
   107   assert(dest != NULL, "invariant");
       
   108   *dest &= mask;
       
   109 }
       
   110 
       
   111 inline void set_traceid_meta_mask(jbyte mask, traceid* dest) {
       
   112   set_meta_mask(mask, ((jbyte*)dest) + meta_offset);
       
   113 }
       
   114 
       
   115 // only used by a single thread with no visibility requirements
       
   116 inline void clear_meta_bits(jbyte bits, jbyte* const dest) {
       
   117   assert(dest != NULL, "invariant");
       
   118   *dest ^= bits;
   122 }
   119 }
   123 
   120 
   124 #endif // SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDBITS_INLINE_HPP
   121 #endif // SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDBITS_INLINE_HPP