1 /*
2  * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #ifndef SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDEPOCH_HPP
26 #define SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDEPOCH_HPP
27 
28 #include "jfr/utilities/jfrSignal.hpp"
29 #include "jfr/utilities/jfrTypes.hpp"
30 #include "memory/allocation.hpp"
31 #include "runtime/atomic.hpp"
32 
33 #define BIT                                  1
34 #define METHOD_BIT                           (BIT << 2)
35 #define EPOCH_0_SHIFT                        0
36 #define EPOCH_1_SHIFT                        1
37 #define EPOCH_0_BIT                          (BIT << EPOCH_0_SHIFT)
38 #define EPOCH_1_BIT                          (BIT << EPOCH_1_SHIFT)
39 #define EPOCH_0_METHOD_BIT                   (METHOD_BIT << EPOCH_0_SHIFT)
40 #define EPOCH_1_METHOD_BIT                   (METHOD_BIT << EPOCH_1_SHIFT)
41 #define METHOD_AND_CLASS_BITS                (METHOD_BIT | BIT)
42 #define EPOCH_0_METHOD_AND_CLASS_BITS        (METHOD_AND_CLASS_BITS << EPOCH_0_SHIFT)
43 #define EPOCH_1_METHOD_AND_CLASS_BITS        (METHOD_AND_CLASS_BITS << EPOCH_1_SHIFT)
44 
45  // Epoch alternation on each rotation allow for concurrent tagging.
46  // The epoch shift happens only during a safepoint.
47  //
48  // _synchronizing is a transition state, the purpose of which is to
49  // have JavaThreads that run _thread_in_native (i.e. Compiler threads)
50  // respect the current epoch shift in-progress during the safepoint.
51  //
52  // _changed_tag_state == true signals an incremental modification to artifact tagging
53  // (klasses, methods, CLDs, etc), purpose of which is to trigger collection of artifacts.
54  //
55 class JfrTraceIdEpoch : AllStatic {
56   friend class JfrCheckpointManager;
57  private:
58   static JfrSignal _tag_state;
59   static bool _epoch_state;
60   static bool _synchronizing;
61 
62   static void begin_epoch_shift();
63   static void end_epoch_shift();
64 
65  public:
epoch()66   static bool epoch() {
67     return _epoch_state;
68   }
69 
epoch_address()70   static address epoch_address() {
71     return (address)&_epoch_state;
72   }
73 
current()74   static u1 current() {
75     return _epoch_state ? (u1)1 : (u1)0;
76   }
77 
previous()78   static u1 previous() {
79     return _epoch_state ? (u1)0 : (u1)1;
80   }
81 
is_synchronizing()82   static bool is_synchronizing() {
83     return Atomic::load_acquire(&_synchronizing);
84   }
85 
this_epoch_bit()86   static traceid this_epoch_bit() {
87     return _epoch_state ? EPOCH_1_BIT : EPOCH_0_BIT;
88   }
89 
previous_epoch_bit()90   static traceid previous_epoch_bit() {
91     return _epoch_state ? EPOCH_0_BIT : EPOCH_1_BIT;
92   }
93 
this_epoch_method_bit()94   static traceid this_epoch_method_bit() {
95     return _epoch_state ? EPOCH_1_METHOD_BIT : EPOCH_0_METHOD_BIT;
96   }
97 
previous_epoch_method_bit()98   static traceid previous_epoch_method_bit() {
99     return _epoch_state ? EPOCH_0_METHOD_BIT : EPOCH_1_METHOD_BIT;
100   }
101 
this_epoch_method_and_class_bits()102   static traceid this_epoch_method_and_class_bits() {
103     return _epoch_state ? EPOCH_1_METHOD_AND_CLASS_BITS : EPOCH_0_METHOD_AND_CLASS_BITS;
104   }
105 
previous_epoch_method_and_class_bits()106   static traceid previous_epoch_method_and_class_bits() {
107     return _epoch_state ? EPOCH_0_METHOD_AND_CLASS_BITS : EPOCH_1_METHOD_AND_CLASS_BITS;
108   }
109 
has_changed_tag_state()110   static bool has_changed_tag_state() {
111     return _tag_state.is_signaled_with_reset();
112   }
113 
has_changed_tag_state_no_reset()114   static bool has_changed_tag_state_no_reset() {
115     return _tag_state.is_signaled();
116   }
117 
set_changed_tag_state()118   static void set_changed_tag_state() {
119     _tag_state.signal();
120   }
121 
signal_address()122   static address signal_address() {
123     return _tag_state.signaled_address();
124   }
125 };
126 
127 #endif // SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDEPOCH_HPP
128