25 #ifndef SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDBITS_INLINE_HPP |
25 #ifndef SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDBITS_INLINE_HPP |
26 #define SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDBITS_INLINE_HPP |
26 #define SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDBITS_INLINE_HPP |
27 |
27 |
28 #include "jfr/utilities/jfrTypes.hpp" |
28 #include "jfr/utilities/jfrTypes.hpp" |
29 #include "runtime/atomic.hpp" |
29 #include "runtime/atomic.hpp" |
30 #include "runtime/orderAccess.hpp" |
|
31 #include "utilities/macros.hpp" |
30 #include "utilities/macros.hpp" |
32 |
31 |
33 #ifdef VM_LITTLE_ENDIAN |
32 #ifdef VM_LITTLE_ENDIAN |
34 static const int low_offset = 0; |
33 static const int low_offset = 0; |
35 static const int leakp_offset = low_offset + 1; |
34 static const int leakp_offset = low_offset + 1; |
38 static const int leakp_offset = low_offset - 1; |
37 static const int leakp_offset = low_offset - 1; |
39 #endif |
38 #endif |
40 |
39 |
41 inline void set_bits(jbyte bits, jbyte* const dest) { |
40 inline void set_bits(jbyte bits, jbyte* const dest) { |
42 assert(dest != NULL, "invariant"); |
41 assert(dest != NULL, "invariant"); |
43 const jbyte current = OrderAccess::load_acquire(dest); |
42 if (bits != (*dest & bits)) { |
44 if (bits != (current & bits)) { |
|
45 *dest |= bits; |
43 *dest |= bits; |
46 } |
44 } |
47 } |
45 } |
48 |
46 |
49 inline void set_mask(jbyte mask, jbyte* const dest) { |
47 inline jbyte traceid_and(jbyte current, jbyte bits) { |
50 assert(dest != NULL, "invariant"); |
48 return current & bits; |
51 const jbyte current = OrderAccess::load_acquire(dest); |
|
52 if (mask != (current & mask)) { |
|
53 *dest &= mask; |
|
54 } |
|
55 } |
49 } |
56 |
50 |
57 inline void set_bits_cas(jbyte bits, jbyte* const dest) { |
51 inline jbyte traceid_or(jbyte current, jbyte bits) { |
|
52 return current | bits; |
|
53 } |
|
54 |
|
55 inline jbyte traceid_xor(jbyte current, jbyte bits) { |
|
56 return current ^ bits; |
|
57 } |
|
58 |
|
59 template <jbyte op(jbyte, jbyte)> |
|
60 inline void set_bits_cas_form(jbyte bits, jbyte* const dest) { |
58 assert(dest != NULL, "invariant"); |
61 assert(dest != NULL, "invariant"); |
59 do { |
62 do { |
60 const jbyte current = OrderAccess::load_acquire(dest); |
63 const jbyte current = *dest; |
61 if (bits == (current & bits)) { |
64 const jbyte new_value = op(current, bits); |
62 return; |
|
63 } |
|
64 const jbyte new_value = current | bits; |
|
65 if (Atomic::cmpxchg(new_value, dest, current) == current) { |
65 if (Atomic::cmpxchg(new_value, dest, current) == current) { |
66 return; |
66 return; |
67 } |
67 } |
68 } while (true); |
68 } while (true); |
69 } |
69 } |
70 |
70 |
|
71 inline void set_bits_cas(jbyte bits, jbyte* const dest) { |
|
72 set_bits_cas_form<traceid_or>(bits, dest); |
|
73 } |
|
74 |
71 inline void clear_bits_cas(jbyte bits, jbyte* const dest) { |
75 inline void clear_bits_cas(jbyte bits, jbyte* const dest) { |
72 assert(dest != NULL, "invariant"); |
76 set_bits_cas_form<traceid_xor>(bits, dest); |
73 do { |
77 } |
74 const jbyte current = OrderAccess::load_acquire(dest); |
78 |
75 if (bits != (current & bits)) { |
79 inline void set_mask(jbyte mask, jbyte* const dest) { |
76 return; |
80 set_bits_cas_form<traceid_and>(mask, dest); |
77 } |
|
78 const jbyte new_value = current ^ bits; |
|
79 if (Atomic::cmpxchg(new_value, dest, current) == current) { |
|
80 return; |
|
81 } |
|
82 } while (true); |
|
83 } |
81 } |
84 |
82 |
85 inline void set_traceid_bits(jbyte bits, traceid* dest) { |
83 inline void set_traceid_bits(jbyte bits, traceid* dest) { |
86 set_bits(bits, ((jbyte*)dest) + low_offset); |
84 set_bits(bits, ((jbyte*)dest) + low_offset); |
87 } |
85 } |