44 #include "logging/logStream.hpp" |
44 #include "logging/logStream.hpp" |
45 #include "memory/resourceArea.inline.hpp" |
45 #include "memory/resourceArea.inline.hpp" |
46 #include "runtime/handles.inline.hpp" |
46 #include "runtime/handles.inline.hpp" |
47 #include "runtime/globals_extension.hpp" |
47 #include "runtime/globals_extension.hpp" |
48 #include "utilities/growableArray.hpp" |
48 #include "utilities/growableArray.hpp" |
|
49 #ifdef ASSERT |
|
50 #include "prims/jvmtiEnvBase.hpp" |
|
51 #endif |
49 |
52 |
50 bool JfrRecorder::is_disabled() { |
53 bool JfrRecorder::is_disabled() { |
51 // True if -XX:-FlightRecorder has been explicitly set on the |
54 // True if -XX:-FlightRecorder has been explicitly set on the |
52 // command line |
55 // command line |
53 return FLAG_IS_CMDLINE(FlightRecorder) ? !FlightRecorder : false; |
56 return FLAG_IS_CMDLINE(FlightRecorder) ? !FlightRecorder : false; |
55 |
58 |
56 static bool _enabled = false; |
59 static bool _enabled = false; |
57 |
60 |
58 static bool enable() { |
61 static bool enable() { |
59 assert(!_enabled, "invariant"); |
62 assert(!_enabled, "invariant"); |
60 FLAG_SET_MGMT(FlightRecorder, true); |
63 if (!FlightRecorder) { |
|
64 FLAG_SET_MGMT(FlightRecorder, true); |
|
65 } |
61 _enabled = FlightRecorder; |
66 _enabled = FlightRecorder; |
62 assert(_enabled, "invariant"); |
67 assert(_enabled, "invariant"); |
63 return _enabled; |
68 return _enabled; |
64 } |
69 } |
65 |
70 |
66 bool JfrRecorder::is_enabled() { |
71 bool JfrRecorder::is_enabled() { |
67 return _enabled; |
72 return _enabled; |
68 } |
73 } |
69 |
74 |
70 bool JfrRecorder::on_vm_init() { |
75 bool JfrRecorder::on_create_vm_1() { |
71 if (!is_disabled()) { |
76 if (!is_disabled()) { |
72 if (FlightRecorder || StartFlightRecording != NULL) { |
77 if (FlightRecorder || StartFlightRecording != NULL) { |
73 enable(); |
78 enable(); |
74 } |
79 } |
75 } |
80 } |
90 } |
95 } |
91 } |
96 } |
92 |
97 |
93 static void teardown_startup_support() { |
98 static void teardown_startup_support() { |
94 release_recordings(); |
99 release_recordings(); |
95 JfrOptionSet::release_startup_recording_options(); |
100 JfrOptionSet::release_start_flight_recording_options(); |
96 } |
101 } |
97 |
102 |
98 // Parsing options here to detect errors as soon as possible |
103 // Parsing options here to detect errors as soon as possible |
99 static bool parse_recording_options(const char* options, JfrStartFlightRecordingDCmd* dcmd_recording, TRAPS) { |
104 static bool parse_recording_options(const char* options, JfrStartFlightRecordingDCmd* dcmd_recording, TRAPS) { |
100 assert(options != NULL, "invariant"); |
105 assert(options != NULL, "invariant"); |
108 } |
113 } |
109 return true; |
114 return true; |
110 } |
115 } |
111 |
116 |
112 static bool validate_recording_options(TRAPS) { |
117 static bool validate_recording_options(TRAPS) { |
113 const GrowableArray<const char*>* options = JfrOptionSet::startup_recording_options(); |
118 const GrowableArray<const char*>* options = JfrOptionSet::start_flight_recording_options(); |
114 if (options == NULL) { |
119 if (options == NULL) { |
115 return true; |
120 return true; |
116 } |
121 } |
117 const int length = options->length(); |
122 const int length = options->length(); |
118 assert(length >= 1, "invariant"); |
123 assert(length >= 1, "invariant"); |
141 } |
146 } |
142 log_trace(jfr, system)("Finished starting a recording"); |
147 log_trace(jfr, system)("Finished starting a recording"); |
143 return true; |
148 return true; |
144 } |
149 } |
145 |
150 |
146 static bool launch_recordings(TRAPS) { |
151 static bool launch_command_line_recordings(TRAPS) { |
147 bool result = true; |
152 bool result = true; |
148 if (dcmd_recordings_array != NULL) { |
153 if (dcmd_recordings_array != NULL) { |
149 const int length = dcmd_recordings_array->length(); |
154 const int length = dcmd_recordings_array->length(); |
150 assert(length >= 1, "invariant"); |
155 assert(length >= 1, "invariant"); |
151 for (int i = 0; i < length; ++i) { |
156 for (int i = 0; i < length; ++i) { |
166 JfrJavaSupport::is_jdk_jfr_module_available(&stream, THREAD); |
171 JfrJavaSupport::is_jdk_jfr_module_available(&stream, THREAD); |
167 } |
172 } |
168 |
173 |
169 static bool is_cds_dump_requested() { |
174 static bool is_cds_dump_requested() { |
170 // we will not be able to launch recordings if a cds dump is being requested |
175 // we will not be able to launch recordings if a cds dump is being requested |
171 if (Arguments::is_dumping_archive() && (JfrOptionSet::startup_recording_options() != NULL)) { |
176 if (Arguments::is_dumping_archive() && (JfrOptionSet::start_flight_recording_options() != NULL)) { |
172 warning("JFR will be disabled during CDS dumping"); |
177 warning("JFR will be disabled during CDS dumping"); |
173 teardown_startup_support(); |
178 teardown_startup_support(); |
174 return true; |
179 return true; |
175 } |
180 } |
176 return false; |
181 return false; |
177 } |
182 } |
178 |
183 |
179 bool JfrRecorder::on_vm_start() { |
184 bool JfrRecorder::on_create_vm_2() { |
180 if (is_cds_dump_requested()) { |
185 if (is_cds_dump_requested()) { |
181 return true; |
186 return true; |
182 } |
187 } |
183 Thread* const thread = Thread::current(); |
188 Thread* const thread = Thread::current(); |
184 if (!JfrOptionSet::initialize(thread)) { |
189 if (!JfrOptionSet::initialize(thread)) { |
185 return false; |
190 return false; |
186 } |
191 } |
187 if (!register_jfr_dcmds()) { |
192 if (!register_jfr_dcmds()) { |
188 return false; |
193 return false; |
189 } |
194 } |
190 |
|
191 const bool in_graph = JfrJavaSupport::is_jdk_jfr_module_available(); |
195 const bool in_graph = JfrJavaSupport::is_jdk_jfr_module_available(); |
192 |
|
193 if (in_graph) { |
196 if (in_graph) { |
194 if (!validate_recording_options(thread)) { |
197 if (!validate_recording_options(thread)) { |
195 return false; |
198 return false; |
196 } |
199 } |
197 if (!JfrOptionSet::configure(thread)) { |
200 if (!JfrOptionSet::configure(thread)) { |
198 return false; |
201 return false; |
199 } |
202 } |
200 } |
203 } |
201 |
|
202 if (!is_enabled()) { |
204 if (!is_enabled()) { |
203 return true; |
205 return true; |
204 } |
206 } |
205 |
|
206 if (!in_graph) { |
207 if (!in_graph) { |
207 log_jdk_jfr_module_resolution_error(thread); |
208 log_jdk_jfr_module_resolution_error(thread); |
208 return false; |
209 return false; |
209 } |
210 } |
210 |
211 return true; |
211 return launch_recordings(thread); |
212 } |
|
213 |
|
214 bool JfrRecorder::on_create_vm_3() { |
|
215 assert(JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE, "invalid init sequence"); |
|
216 return launch_command_line_recordings(Thread::current()); |
212 } |
217 } |
213 |
218 |
214 static bool _created = false; |
219 static bool _created = false; |
215 |
220 |
216 // |
221 // |
275 } |
280 } |
276 return true; |
281 return true; |
277 } |
282 } |
278 |
283 |
279 // subsystems |
284 // subsystems |
280 static JfrJvmtiAgent* _jvmti_agent = NULL; |
|
281 static JfrPostBox* _post_box = NULL; |
285 static JfrPostBox* _post_box = NULL; |
282 static JfrStorage* _storage = NULL; |
286 static JfrStorage* _storage = NULL; |
283 static JfrCheckpointManager* _checkpoint_manager = NULL; |
287 static JfrCheckpointManager* _checkpoint_manager = NULL; |
284 static JfrRepository* _repository = NULL; |
288 static JfrRepository* _repository = NULL; |
285 static JfrStackTraceRepository* _stack_trace_repository; |
289 static JfrStackTraceRepository* _stack_trace_repository; |