src/share/vm/jfr/dcmd/jfrDcmds.cpp

Fri, 17 Jan 2020 17:32:41 +0800

author
egahlin
date
Fri, 17 Jan 2020 17:32:41 +0800
changeset 9889
63a1206b8286
parent 9883
02a4c08a8777
permissions
-rw-r--r--

8209960: -Xlog:jfr* doesn't work with the JFR
Reviewed-by: mgronlun

apetushkov@9858 1 /*
apetushkov@9858 2 * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
apetushkov@9858 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
apetushkov@9858 4 *
apetushkov@9858 5 * This code is free software; you can redistribute it and/or modify it
apetushkov@9858 6 * under the terms of the GNU General Public License version 2 only, as
apetushkov@9858 7 * published by the Free Software Foundation.
apetushkov@9858 8 *
apetushkov@9858 9 * This code is distributed in the hope that it will be useful, but WITHOUT
apetushkov@9858 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
apetushkov@9858 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
apetushkov@9858 12 * version 2 for more details (a copy is included in the LICENSE file that
apetushkov@9858 13 * accompanied this code).
apetushkov@9858 14 *
apetushkov@9858 15 * You should have received a copy of the GNU General Public License version
apetushkov@9858 16 * 2 along with this work; if not, write to the Free Software Foundation,
apetushkov@9858 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
apetushkov@9858 18 *
apetushkov@9858 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
apetushkov@9858 20 * or visit www.oracle.com if you need additional information or have any
apetushkov@9858 21 * questions.
apetushkov@9858 22 *
apetushkov@9858 23 */
apetushkov@9858 24
apetushkov@9858 25 #include "precompiled.hpp"
apetushkov@9858 26 #include "classfile/javaClasses.hpp"
apetushkov@9858 27 #include "classfile/vmSymbols.hpp"
apetushkov@9858 28 #include "jfr/jfr.hpp"
apetushkov@9858 29 #include "jfr/dcmd/jfrDcmds.hpp"
apetushkov@9858 30 #include "jfr/jni/jfrJavaSupport.hpp"
apetushkov@9858 31 #include "jfr/recorder/jfrRecorder.hpp"
apetushkov@9858 32 #include "jfr/recorder/service/jfrOptionSet.hpp"
apetushkov@9858 33 #include "memory/resourceArea.hpp"
apetushkov@9858 34 #include "oops/oop.inline.hpp"
apetushkov@9858 35 #include "oops/symbol.hpp"
apetushkov@9858 36 #include "runtime/handles.inline.hpp"
apetushkov@9858 37 #include "services/diagnosticArgument.hpp"
apetushkov@9858 38 #include "services/diagnosticFramework.hpp"
apetushkov@9858 39 #include "utilities/globalDefinitions.hpp"
apetushkov@9858 40
apetushkov@9858 41 #ifdef _WINDOWS
apetushkov@9858 42 #define JFR_FILENAME_EXAMPLE "C:\\Users\\user\\My Recording.jfr"
apetushkov@9858 43 #endif
apetushkov@9858 44
apetushkov@9858 45 #ifdef __APPLE__
apetushkov@9858 46 #define JFR_FILENAME_EXAMPLE "/Users/user/My Recording.jfr"
apetushkov@9858 47 #endif
apetushkov@9858 48
apetushkov@9858 49 #ifndef JFR_FILENAME_EXAMPLE
apetushkov@9858 50 #define JFR_FILENAME_EXAMPLE "/home/user/My Recording.jfr"
apetushkov@9858 51 #endif
apetushkov@9858 52
apetushkov@9858 53 // JNIHandle management
apetushkov@9858 54
apetushkov@9858 55 // ------------------------------------------------------------------
apetushkov@9858 56 // push_jni_handle_block
apetushkov@9858 57 //
apetushkov@9858 58 // Push on a new block of JNI handles.
apetushkov@9858 59 static void push_jni_handle_block(Thread* const thread) {
apetushkov@9858 60 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(thread));
apetushkov@9858 61
apetushkov@9858 62 // Allocate a new block for JNI handles.
apetushkov@9858 63 // Inlined code from jni_PushLocalFrame()
apetushkov@9858 64 JNIHandleBlock* prev_handles = thread->active_handles();
apetushkov@9858 65 JNIHandleBlock* entry_handles = JNIHandleBlock::allocate_block(thread);
apetushkov@9858 66 assert(entry_handles != NULL && prev_handles != NULL, "should not be NULL");
apetushkov@9858 67 entry_handles->set_pop_frame_link(prev_handles); // make sure prev handles get gc'd.
apetushkov@9858 68 thread->set_active_handles(entry_handles);
apetushkov@9858 69 }
apetushkov@9858 70
apetushkov@9858 71 // ------------------------------------------------------------------
apetushkov@9858 72 // pop_jni_handle_block
apetushkov@9858 73 //
apetushkov@9858 74 // Pop off the current block of JNI handles.
apetushkov@9858 75 static void pop_jni_handle_block(Thread* const thread) {
apetushkov@9858 76 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(thread));
apetushkov@9858 77
apetushkov@9858 78 // Release our JNI handle block
apetushkov@9858 79 JNIHandleBlock* entry_handles = thread->active_handles();
apetushkov@9858 80 JNIHandleBlock* prev_handles = entry_handles->pop_frame_link();
apetushkov@9858 81 // restore
apetushkov@9858 82 thread->set_active_handles(prev_handles);
apetushkov@9858 83 entry_handles->set_pop_frame_link(NULL);
apetushkov@9858 84 JNIHandleBlock::release_block(entry_handles, thread); // may block
apetushkov@9858 85 }
apetushkov@9858 86
apetushkov@9858 87 class JNIHandleBlockManager : public StackObj {
apetushkov@9858 88 private:
apetushkov@9858 89 Thread* const _thread;
apetushkov@9858 90 public:
apetushkov@9858 91 JNIHandleBlockManager(Thread* thread) : _thread(thread) {
apetushkov@9858 92 push_jni_handle_block(_thread);
apetushkov@9858 93 }
apetushkov@9858 94
apetushkov@9858 95 ~JNIHandleBlockManager() {
apetushkov@9858 96 pop_jni_handle_block(_thread);
apetushkov@9858 97 }
apetushkov@9858 98 };
apetushkov@9858 99
apetushkov@9858 100 static bool is_disabled(outputStream* output) {
apetushkov@9858 101 if (Jfr::is_disabled()) {
apetushkov@9858 102 if (output != NULL) {
apetushkov@9858 103 output->print_cr("Flight Recorder is disabled.\n");
apetushkov@9858 104 }
apetushkov@9858 105 return true;
apetushkov@9858 106 }
apetushkov@9858 107 return false;
apetushkov@9858 108 }
apetushkov@9858 109
apetushkov@9858 110 static bool is_recorder_instance_created(outputStream* output) {
apetushkov@9858 111 if (!JfrRecorder::is_created()) {
apetushkov@9858 112 if (output != NULL) {
apetushkov@9858 113 output->print_cr("No available recordings.\n");
apetushkov@9858 114 output->print_cr("Use JFR.start to start a recording.\n");
apetushkov@9858 115 }
apetushkov@9858 116 return false;
apetushkov@9858 117 }
apetushkov@9858 118 return true;
apetushkov@9858 119 }
apetushkov@9858 120
apetushkov@9858 121 static bool invalid_state(outputStream* out, TRAPS) {
apetushkov@9858 122 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 123 return is_disabled(out);
apetushkov@9858 124 }
apetushkov@9858 125
apetushkov@9858 126 static void print_pending_exception(outputStream* output, oop throwable) {
apetushkov@9858 127 assert(throwable != NULL, "invariant");
apetushkov@9858 128
apetushkov@9858 129 oop msg = java_lang_Throwable::message(throwable);
apetushkov@9858 130
apetushkov@9858 131 if (msg != NULL) {
apetushkov@9858 132 char* text = java_lang_String::as_utf8_string(msg);
apetushkov@9858 133 output->print_raw_cr(text);
apetushkov@9858 134 }
apetushkov@9858 135 }
apetushkov@9858 136
apetushkov@9858 137 static void print_message(outputStream* output, const char* message) {
apetushkov@9858 138 if (message != NULL) {
apetushkov@9858 139 output->print_raw(message);
apetushkov@9858 140 }
apetushkov@9858 141 }
apetushkov@9858 142
apetushkov@9858 143 static void handle_dcmd_result(outputStream* output,
apetushkov@9858 144 const oop result,
apetushkov@9858 145 const DCmdSource source,
apetushkov@9858 146 TRAPS) {
apetushkov@9858 147 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 148 assert(output != NULL, "invariant");
apetushkov@9858 149 if (HAS_PENDING_EXCEPTION) {
apetushkov@9858 150 print_pending_exception(output, PENDING_EXCEPTION);
apetushkov@9858 151 // Don't clear excption on startup, JVM should fail initialization.
apetushkov@9858 152 if (DCmd_Source_Internal != source) {
apetushkov@9858 153 CLEAR_PENDING_EXCEPTION;
apetushkov@9858 154 }
apetushkov@9858 155 return;
apetushkov@9858 156 }
apetushkov@9858 157
apetushkov@9858 158 assert(!HAS_PENDING_EXCEPTION, "invariant");
apetushkov@9858 159
apetushkov@9858 160 if (result != NULL) {
apetushkov@9858 161 const char* result_chars = java_lang_String::as_utf8_string(result);
apetushkov@9858 162 print_message(output, result_chars);
apetushkov@9858 163 }
apetushkov@9858 164 }
apetushkov@9858 165
apetushkov@9858 166 static oop construct_dcmd_instance(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 167 assert(args != NULL, "invariant");
apetushkov@9858 168 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 169 assert(args->klass() != NULL, "invariant");
apetushkov@9858 170 args->set_name("<init>", CHECK_NULL);
apetushkov@9858 171 args->set_signature("()V", CHECK_NULL);
apetushkov@9858 172 JfrJavaSupport::new_object(args, CHECK_NULL);
apetushkov@9858 173 return (oop)args->result()->get_jobject();
apetushkov@9858 174 }
apetushkov@9858 175
apetushkov@9858 176 JfrDumpFlightRecordingDCmd::JfrDumpFlightRecordingDCmd(outputStream* output,
apetushkov@9858 177 bool heap) : DCmdWithParser(output, heap),
apetushkov@9858 178 _name("name", "Recording name, e.g. \\\"My Recording\\\"", "STRING", false, NULL),
apetushkov@9858 179 _filename("filename", "Copy recording data to file, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false),
apetushkov@9858 180 _maxage("maxage", "Maximum duration to dump, in (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 60m, or 0 for no limit", "NANOTIME", false, "0"),
apetushkov@9858 181 _maxsize("maxsize", "Maximum amount of bytes to dump, in (M)B or (G)B, e.g. 500M, or 0 for no limit", "MEMORY SIZE", false, "0"),
apetushkov@9858 182 _begin("begin", "Point in time to dump data from, e.g. 09:00, 21:35:00, 2018-06-03T18:12:56.827Z, 2018-06-03T20:13:46.832, -10m, -3h, or -1d", "STRING", false),
apetushkov@9858 183 _end("end", "Point in time to dump data to, e.g. 09:00, 21:35:00, 2018-06-03T18:12:56.827Z, 2018-06-03T20:13:46.832, -10m, -3h, or -1d", "STRING", false),
apetushkov@9858 184 _path_to_gc_roots("path-to-gc-roots", "Collect path to GC roots", "BOOLEAN", false, "false") {
apetushkov@9858 185 _dcmdparser.add_dcmd_option(&_name);
apetushkov@9858 186 _dcmdparser.add_dcmd_option(&_filename);
apetushkov@9858 187 _dcmdparser.add_dcmd_option(&_maxage);
apetushkov@9858 188 _dcmdparser.add_dcmd_option(&_maxsize);
apetushkov@9858 189 _dcmdparser.add_dcmd_option(&_begin);
apetushkov@9858 190 _dcmdparser.add_dcmd_option(&_end);
apetushkov@9858 191 _dcmdparser.add_dcmd_option(&_path_to_gc_roots);
apetushkov@9858 192 };
apetushkov@9858 193
apetushkov@9858 194 int JfrDumpFlightRecordingDCmd::num_arguments() {
apetushkov@9858 195 ResourceMark rm;
apetushkov@9858 196 JfrDumpFlightRecordingDCmd* dcmd = new JfrDumpFlightRecordingDCmd(NULL, false);
apetushkov@9858 197 if (dcmd != NULL) {
apetushkov@9858 198 DCmdMark mark(dcmd);
apetushkov@9858 199 return dcmd->_dcmdparser.num_arguments();
apetushkov@9858 200 }
apetushkov@9858 201 return 0;
apetushkov@9858 202 }
apetushkov@9858 203
apetushkov@9858 204 void JfrDumpFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
apetushkov@9858 205 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 206
apetushkov@9858 207 if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
apetushkov@9858 208 return;
apetushkov@9858 209 }
apetushkov@9858 210
apetushkov@9858 211 ResourceMark rm(THREAD);
apetushkov@9858 212 HandleMark hm(THREAD);
apetushkov@9858 213 JNIHandleBlockManager jni_handle_management(THREAD);
apetushkov@9858 214
apetushkov@9858 215 JavaValue result(T_OBJECT);
apetushkov@9858 216 JfrJavaArguments constructor_args(&result);
apetushkov@9858 217 constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdDump", CHECK);
apetushkov@9858 218 const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
apetushkov@9858 219 Handle h_dcmd_instance(THREAD, dcmd);
apetushkov@9858 220 assert(h_dcmd_instance.not_null(), "invariant");
apetushkov@9858 221
apetushkov@9858 222 jstring name = NULL;
apetushkov@9858 223 if (_name.is_set() && _name.value() != NULL) {
apetushkov@9858 224 name = JfrJavaSupport::new_string(_name.value(), CHECK);
apetushkov@9858 225 }
apetushkov@9858 226
apetushkov@9858 227 jstring filepath = NULL;
apetushkov@9858 228 if (_filename.is_set() && _filename.value() != NULL) {
apetushkov@9858 229 filepath = JfrJavaSupport::new_string(_filename.value(), CHECK);
apetushkov@9858 230 }
apetushkov@9858 231
apetushkov@9858 232 jobject maxage = NULL;
apetushkov@9858 233 if (_maxage.is_set()) {
apetushkov@9858 234 maxage = JfrJavaSupport::new_java_lang_Long(_maxage.value()._nanotime, CHECK);
apetushkov@9858 235 }
apetushkov@9858 236
apetushkov@9858 237 jobject maxsize = NULL;
apetushkov@9858 238 if (_maxsize.is_set()) {
apetushkov@9858 239 maxsize = JfrJavaSupport::new_java_lang_Long(_maxsize.value()._size, CHECK);
apetushkov@9858 240 }
apetushkov@9858 241
apetushkov@9858 242 jstring begin = NULL;
apetushkov@9858 243 if (_begin.is_set() && _begin.value() != NULL) {
apetushkov@9858 244 begin = JfrJavaSupport::new_string(_begin.value(), CHECK);
apetushkov@9858 245 }
apetushkov@9858 246
apetushkov@9858 247 jstring end = NULL;
apetushkov@9858 248 if (_end.is_set() && _end.value() != NULL) {
apetushkov@9858 249 end = JfrJavaSupport::new_string(_end.value(), CHECK);
apetushkov@9858 250 }
apetushkov@9858 251
apetushkov@9858 252 jobject path_to_gc_roots = NULL;
apetushkov@9858 253 if (_path_to_gc_roots.is_set()) {
apetushkov@9858 254 path_to_gc_roots = JfrJavaSupport::new_java_lang_Boolean(_path_to_gc_roots.value(), CHECK);
apetushkov@9858 255 }
apetushkov@9858 256
apetushkov@9858 257 static const char klass[] = "jdk/jfr/internal/dcmd/DCmdDump";
apetushkov@9858 258 static const char method[] = "execute";
apetushkov@9858 259 static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;)Ljava/lang/String;";
apetushkov@9858 260
apetushkov@9858 261 JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
apetushkov@9858 262 execute_args.set_receiver(h_dcmd_instance);
apetushkov@9858 263
apetushkov@9858 264 // arguments
apetushkov@9858 265 execute_args.push_jobject(name);
apetushkov@9858 266 execute_args.push_jobject(filepath);
apetushkov@9858 267 execute_args.push_jobject(maxage);
apetushkov@9858 268 execute_args.push_jobject(maxsize);
apetushkov@9858 269 execute_args.push_jobject(begin);
apetushkov@9858 270 execute_args.push_jobject(end);
apetushkov@9858 271 execute_args.push_jobject(path_to_gc_roots);
apetushkov@9858 272
apetushkov@9858 273 JfrJavaSupport::call_virtual(&execute_args, THREAD);
apetushkov@9858 274 handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
apetushkov@9858 275 }
apetushkov@9858 276
apetushkov@9858 277 JfrCheckFlightRecordingDCmd::JfrCheckFlightRecordingDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
apetushkov@9858 278 _name("name","Recording name, e.g. \\\"My Recording\\\" or omit to see all recordings","STRING",false, NULL),
apetushkov@9858 279 _verbose("verbose","Print event settings for the recording(s)","BOOLEAN",
apetushkov@9858 280 false, "false") {
apetushkov@9858 281 _dcmdparser.add_dcmd_option(&_name);
apetushkov@9858 282 _dcmdparser.add_dcmd_option(&_verbose);
apetushkov@9858 283 };
apetushkov@9858 284
apetushkov@9858 285 int JfrCheckFlightRecordingDCmd::num_arguments() {
apetushkov@9858 286 ResourceMark rm;
apetushkov@9858 287 JfrCheckFlightRecordingDCmd* dcmd = new JfrCheckFlightRecordingDCmd(NULL, false);
apetushkov@9858 288 if (dcmd != NULL) {
apetushkov@9858 289 DCmdMark mark(dcmd);
apetushkov@9858 290 return dcmd->_dcmdparser.num_arguments();
apetushkov@9858 291 }
apetushkov@9858 292 return 0;
apetushkov@9858 293 }
apetushkov@9858 294
apetushkov@9858 295 void JfrCheckFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
apetushkov@9858 296 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 297
apetushkov@9858 298 if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
apetushkov@9858 299 return;
apetushkov@9858 300 }
apetushkov@9858 301
apetushkov@9858 302 ResourceMark rm(THREAD);
apetushkov@9858 303 HandleMark hm(THREAD);
apetushkov@9858 304 JNIHandleBlockManager jni_handle_management(THREAD);
apetushkov@9858 305
apetushkov@9858 306 JavaValue result(T_OBJECT);
apetushkov@9858 307 JfrJavaArguments constructor_args(&result);
apetushkov@9858 308 constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdCheck", CHECK);
apetushkov@9858 309 const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
apetushkov@9858 310 Handle h_dcmd_instance(THREAD, dcmd);
apetushkov@9858 311 assert(h_dcmd_instance.not_null(), "invariant");
apetushkov@9858 312
apetushkov@9858 313 jstring name = NULL;
apetushkov@9858 314 if (_name.is_set() && _name.value() != NULL) {
apetushkov@9858 315 name = JfrJavaSupport::new_string(_name.value(), CHECK);
apetushkov@9858 316 }
apetushkov@9858 317
apetushkov@9858 318 jobject verbose = NULL;
apetushkov@9858 319 if (_verbose.is_set()) {
apetushkov@9858 320 verbose = JfrJavaSupport::new_java_lang_Boolean(_verbose.value(), CHECK);
apetushkov@9858 321 }
apetushkov@9858 322
apetushkov@9858 323 static const char klass[] = "jdk/jfr/internal/dcmd/DCmdCheck";
apetushkov@9858 324 static const char method[] = "execute";
apetushkov@9858 325 static const char signature[] = "(Ljava/lang/String;Ljava/lang/Boolean;)Ljava/lang/String;";
apetushkov@9858 326
apetushkov@9858 327 JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
apetushkov@9858 328 execute_args.set_receiver(h_dcmd_instance);
apetushkov@9858 329
apetushkov@9858 330 // arguments
apetushkov@9858 331 execute_args.push_jobject(name);
apetushkov@9858 332 execute_args.push_jobject(verbose);
apetushkov@9858 333
apetushkov@9858 334 JfrJavaSupport::call_virtual(&execute_args, THREAD);
apetushkov@9858 335 handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
apetushkov@9858 336 }
apetushkov@9858 337
apetushkov@9858 338 JfrStartFlightRecordingDCmd::JfrStartFlightRecordingDCmd(outputStream* output,
apetushkov@9858 339 bool heap) : DCmdWithParser(output, heap),
apetushkov@9858 340 _name("name", "Name that can be used to identify recording, e.g. \\\"My Recording\\\"", "STRING", false, NULL),
apetushkov@9858 341 _settings("settings", "Settings file(s), e.g. profile or default. See JRE_HOME/lib/jfr", "STRING SET", false),
apetushkov@9858 342 _delay("delay", "Delay recording start with (s)econds, (m)inutes), (h)ours), or (d)ays, e.g. 5h.", "NANOTIME", false, "0"),
apetushkov@9858 343 _duration("duration", "Duration of recording in (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 300s.", "NANOTIME", false, "0"),
apetushkov@9858 344 _filename("filename", "Resulting recording filename, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false),
apetushkov@9858 345 _disk("disk", "Recording should be persisted to disk", "BOOLEAN", false),
apetushkov@9858 346 _maxage("maxage", "Maximum time to keep recorded data (on disk) in (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 60m, or 0 for no limit", "NANOTIME", false, "0"),
apetushkov@9858 347 _maxsize("maxsize", "Maximum amount of bytes to keep (on disk) in (k)B, (M)B or (G)B, e.g. 500M, or 0 for no limit", "MEMORY SIZE", false, "0"),
apetushkov@9858 348 _dump_on_exit("dumponexit", "Dump running recording when JVM shuts down", "BOOLEAN", false),
apetushkov@9858 349 _path_to_gc_roots("path-to-gc-roots", "Collect path to GC roots", "BOOLEAN", false, "false") {
apetushkov@9858 350 _dcmdparser.add_dcmd_option(&_name);
apetushkov@9858 351 _dcmdparser.add_dcmd_option(&_settings);
apetushkov@9858 352 _dcmdparser.add_dcmd_option(&_delay);
apetushkov@9858 353 _dcmdparser.add_dcmd_option(&_duration);
apetushkov@9858 354 _dcmdparser.add_dcmd_option(&_disk);
apetushkov@9858 355 _dcmdparser.add_dcmd_option(&_filename);
apetushkov@9858 356 _dcmdparser.add_dcmd_option(&_maxage);
apetushkov@9858 357 _dcmdparser.add_dcmd_option(&_maxsize);
apetushkov@9858 358 _dcmdparser.add_dcmd_option(&_dump_on_exit);
apetushkov@9858 359 _dcmdparser.add_dcmd_option(&_path_to_gc_roots);
apetushkov@9858 360 };
apetushkov@9858 361
apetushkov@9858 362 int JfrStartFlightRecordingDCmd::num_arguments() {
apetushkov@9858 363 ResourceMark rm;
apetushkov@9858 364 JfrStartFlightRecordingDCmd* dcmd = new JfrStartFlightRecordingDCmd(NULL, false);
apetushkov@9858 365 if (dcmd != NULL) {
apetushkov@9858 366 DCmdMark mark(dcmd);
apetushkov@9858 367 return dcmd->_dcmdparser.num_arguments();
apetushkov@9858 368 }
apetushkov@9858 369 return 0;
apetushkov@9858 370 }
apetushkov@9858 371
apetushkov@9858 372 void JfrStartFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
apetushkov@9858 373 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 374
apetushkov@9858 375 if (invalid_state(output(), THREAD)) {
apetushkov@9858 376 return;
apetushkov@9858 377 }
apetushkov@9858 378
apetushkov@9858 379 ResourceMark rm(THREAD);
apetushkov@9858 380 HandleMark hm(THREAD);
apetushkov@9858 381 JNIHandleBlockManager jni_handle_management(THREAD);
apetushkov@9858 382
apetushkov@9858 383 JavaValue result(T_OBJECT);
apetushkov@9858 384 JfrJavaArguments constructor_args(&result);
apetushkov@9858 385 constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdStart", THREAD);
apetushkov@9858 386 const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
apetushkov@9858 387 Handle h_dcmd_instance(THREAD, dcmd);
apetushkov@9858 388 assert(h_dcmd_instance.not_null(), "invariant");
apetushkov@9858 389
apetushkov@9858 390 jstring name = NULL;
apetushkov@9858 391 if (_name.is_set() && _name.value() != NULL) {
apetushkov@9858 392 name = JfrJavaSupport::new_string(_name.value(), CHECK);
apetushkov@9858 393 }
apetushkov@9858 394
apetushkov@9858 395 jstring filename = NULL;
apetushkov@9858 396 if (_filename.is_set() && _filename.value() != NULL) {
apetushkov@9858 397 filename = JfrJavaSupport::new_string(_filename.value(), CHECK);
apetushkov@9858 398 }
apetushkov@9858 399
apetushkov@9858 400 jobject maxage = NULL;
apetushkov@9858 401 if (_maxage.is_set()) {
apetushkov@9858 402 maxage = JfrJavaSupport::new_java_lang_Long(_maxage.value()._nanotime, CHECK);
apetushkov@9858 403 }
apetushkov@9858 404
apetushkov@9858 405 jobject maxsize = NULL;
apetushkov@9858 406 if (_maxsize.is_set()) {
apetushkov@9858 407 maxsize = JfrJavaSupport::new_java_lang_Long(_maxsize.value()._size, CHECK);
apetushkov@9858 408 }
apetushkov@9858 409
apetushkov@9858 410 jobject duration = NULL;
apetushkov@9858 411 if (_duration.is_set()) {
apetushkov@9858 412 duration = JfrJavaSupport::new_java_lang_Long(_duration.value()._nanotime, CHECK);
apetushkov@9858 413 }
apetushkov@9858 414
apetushkov@9858 415 jobject delay = NULL;
apetushkov@9858 416 if (_delay.is_set()) {
apetushkov@9858 417 delay = JfrJavaSupport::new_java_lang_Long(_delay.value()._nanotime, CHECK);
apetushkov@9858 418 }
apetushkov@9858 419
apetushkov@9858 420 jobject disk = NULL;
apetushkov@9858 421 if (_disk.is_set()) {
apetushkov@9858 422 disk = JfrJavaSupport::new_java_lang_Boolean(_disk.value(), CHECK);
apetushkov@9858 423 }
apetushkov@9858 424
apetushkov@9858 425 jobject dump_on_exit = NULL;
apetushkov@9858 426 if (_dump_on_exit.is_set()) {
apetushkov@9858 427 dump_on_exit = JfrJavaSupport::new_java_lang_Boolean(_dump_on_exit.value(), CHECK);
apetushkov@9858 428 }
apetushkov@9858 429
apetushkov@9858 430 jobject path_to_gc_roots = NULL;
apetushkov@9858 431 if (_path_to_gc_roots.is_set()) {
apetushkov@9858 432 path_to_gc_roots = JfrJavaSupport::new_java_lang_Boolean(_path_to_gc_roots.value(), CHECK);
apetushkov@9858 433 }
apetushkov@9858 434
apetushkov@9858 435 jobjectArray settings = NULL;
apetushkov@9858 436 if (_settings.is_set()) {
egahlin@9883 437 int length = _settings.value()->array()->length();
egahlin@9883 438 if (length == 1) {
egahlin@9883 439 const char* c_str = _settings.value()->array()->at(0);
egahlin@9883 440 if (strcmp(c_str, "none") == 0) {
egahlin@9883 441 length = 0;
egahlin@9883 442 }
egahlin@9883 443 }
apetushkov@9858 444 settings = JfrJavaSupport::new_string_array(length, CHECK);
apetushkov@9858 445 assert(settings != NULL, "invariant");
apetushkov@9858 446 for (int i = 0; i < length; ++i) {
apetushkov@9858 447 jobject element = JfrJavaSupport::new_string(_settings.value()->array()->at(i), CHECK);
apetushkov@9858 448 assert(element != NULL, "invariant");
apetushkov@9858 449 JfrJavaSupport::set_array_element(settings, element, i, CHECK);
apetushkov@9858 450 }
egahlin@9889 451 } else {
egahlin@9889 452 settings = JfrJavaSupport::new_string_array(1, CHECK);
egahlin@9889 453 assert(settings != NULL, "invariant");
egahlin@9889 454 jobject element = JfrJavaSupport::new_string("default", CHECK);
egahlin@9889 455 assert(element != NULL, "invariant");
egahlin@9889 456 JfrJavaSupport::set_array_element(settings, element, 0, CHECK);
apetushkov@9858 457 }
apetushkov@9858 458
apetushkov@9858 459 static const char klass[] = "jdk/jfr/internal/dcmd/DCmdStart";
apetushkov@9858 460 static const char method[] = "execute";
apetushkov@9858 461 static const char signature[] = "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/Long;"
apetushkov@9858 462 "Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/String;"
apetushkov@9858 463 "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/lang/String;";
apetushkov@9858 464
apetushkov@9858 465 JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
apetushkov@9858 466 execute_args.set_receiver(h_dcmd_instance);
apetushkov@9858 467
apetushkov@9858 468 // arguments
apetushkov@9858 469 execute_args.push_jobject(name);
apetushkov@9858 470 execute_args.push_jobject(settings);
apetushkov@9858 471 execute_args.push_jobject(delay);
apetushkov@9858 472 execute_args.push_jobject(duration);
apetushkov@9858 473 execute_args.push_jobject(disk);
apetushkov@9858 474 execute_args.push_jobject(filename);
apetushkov@9858 475 execute_args.push_jobject(maxage);
apetushkov@9858 476 execute_args.push_jobject(maxsize);
apetushkov@9858 477 execute_args.push_jobject(dump_on_exit);
apetushkov@9858 478 execute_args.push_jobject(path_to_gc_roots);
apetushkov@9858 479
apetushkov@9858 480 JfrJavaSupport::call_virtual(&execute_args, THREAD);
apetushkov@9858 481 handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
apetushkov@9858 482 }
apetushkov@9858 483
apetushkov@9858 484 JfrStopFlightRecordingDCmd::JfrStopFlightRecordingDCmd(outputStream* output,
apetushkov@9858 485 bool heap) : DCmdWithParser(output, heap),
apetushkov@9858 486 _name("name", "Recording text,.e.g \\\"My Recording\\\"", "STRING", true, NULL),
apetushkov@9858 487 _filename("filename", "Copy recording data to file, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false, NULL) {
apetushkov@9858 488 _dcmdparser.add_dcmd_option(&_name);
apetushkov@9858 489 _dcmdparser.add_dcmd_option(&_filename);
apetushkov@9858 490 };
apetushkov@9858 491
apetushkov@9858 492 int JfrStopFlightRecordingDCmd::num_arguments() {
apetushkov@9858 493 ResourceMark rm;
apetushkov@9858 494 JfrStopFlightRecordingDCmd* dcmd = new JfrStopFlightRecordingDCmd(NULL, false);
apetushkov@9858 495 if (dcmd != NULL) {
apetushkov@9858 496 DCmdMark mark(dcmd);
apetushkov@9858 497 return dcmd->_dcmdparser.num_arguments();
apetushkov@9858 498 }
apetushkov@9858 499 return 0;
apetushkov@9858 500 }
apetushkov@9858 501
apetushkov@9858 502 void JfrStopFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
apetushkov@9858 503 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 504
apetushkov@9858 505 if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
apetushkov@9858 506 return;
apetushkov@9858 507 }
apetushkov@9858 508
apetushkov@9858 509 ResourceMark rm(THREAD);
apetushkov@9858 510 HandleMark hm(THREAD);
apetushkov@9858 511 JNIHandleBlockManager jni_handle_management(THREAD);
apetushkov@9858 512
apetushkov@9858 513 JavaValue result(T_OBJECT);
apetushkov@9858 514 JfrJavaArguments constructor_args(&result);
apetushkov@9858 515 constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdStop", CHECK);
apetushkov@9858 516 const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
apetushkov@9858 517 Handle h_dcmd_instance(THREAD, dcmd);
apetushkov@9858 518 assert(h_dcmd_instance.not_null(), "invariant");
apetushkov@9858 519
apetushkov@9858 520 jstring name = NULL;
apetushkov@9858 521 if (_name.is_set() && _name.value() != NULL) {
apetushkov@9858 522 name = JfrJavaSupport::new_string(_name.value(), CHECK);
apetushkov@9858 523 }
apetushkov@9858 524
apetushkov@9858 525 jstring filepath = NULL;
apetushkov@9858 526 if (_filename.is_set() && _filename.value() != NULL) {
apetushkov@9858 527 filepath = JfrJavaSupport::new_string(_filename.value(), CHECK);
apetushkov@9858 528 }
apetushkov@9858 529
apetushkov@9858 530 static const char klass[] = "jdk/jfr/internal/dcmd/DCmdStop";
apetushkov@9858 531 static const char method[] = "execute";
apetushkov@9858 532 static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
apetushkov@9858 533
apetushkov@9858 534 JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
apetushkov@9858 535 execute_args.set_receiver(h_dcmd_instance);
apetushkov@9858 536
apetushkov@9858 537 // arguments
apetushkov@9858 538 execute_args.push_jobject(name);
apetushkov@9858 539 execute_args.push_jobject(filepath);
apetushkov@9858 540
apetushkov@9858 541 JfrJavaSupport::call_virtual(&execute_args, THREAD);
apetushkov@9858 542 handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
apetushkov@9858 543 }
apetushkov@9858 544
apetushkov@9858 545 JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* output,
apetushkov@9858 546 bool heap) : DCmdWithParser(output, heap),
apetushkov@9858 547 _repository_path("repositorypath", "Path to repository,.e.g \\\"My Repository\\\"", "STRING", false, NULL),
apetushkov@9858 548 _dump_path("dumppath", "Path to dump,.e.g \\\"My Dump path\\\"", "STRING", false, NULL),
ysuenaga@9870 549 _stack_depth("stackdepth", "Stack Depth", "JULONG", false, "64"),
ysuenaga@9870 550 _global_buffer_count("globalbuffercount", "Number of global buffers,", "JULONG", false, "20"),
ysuenaga@9870 551 _global_buffer_size("globalbuffersize", "Size of a global buffers,", "MEMORY SIZE", false, "512k"),
ysuenaga@9870 552 _thread_buffer_size("thread_buffer_size", "Size of a thread buffer", "MEMORY SIZE", false, "8k"),
ysuenaga@9870 553 _memory_size("memorysize", "Overall memory size, ", "MEMORY SIZE", false, "10m"),
ysuenaga@9870 554 _max_chunk_size("maxchunksize", "Size of an individual disk chunk", "MEMORY SIZE", false, "12m"),
apetushkov@9858 555 _sample_threads("samplethreads", "Activate Thread sampling", "BOOLEAN", false, "true") {
apetushkov@9858 556 _dcmdparser.add_dcmd_option(&_repository_path);
apetushkov@9858 557 _dcmdparser.add_dcmd_option(&_dump_path);
apetushkov@9858 558 _dcmdparser.add_dcmd_option(&_stack_depth);
apetushkov@9858 559 _dcmdparser.add_dcmd_option(&_global_buffer_count);
apetushkov@9858 560 _dcmdparser.add_dcmd_option(&_global_buffer_size);
apetushkov@9858 561 _dcmdparser.add_dcmd_option(&_thread_buffer_size);
apetushkov@9858 562 _dcmdparser.add_dcmd_option(&_memory_size);
apetushkov@9858 563 _dcmdparser.add_dcmd_option(&_max_chunk_size);
apetushkov@9858 564 _dcmdparser.add_dcmd_option(&_sample_threads);
apetushkov@9858 565 };
apetushkov@9858 566
apetushkov@9858 567 int JfrConfigureFlightRecorderDCmd::num_arguments() {
apetushkov@9858 568 ResourceMark rm;
apetushkov@9858 569 JfrConfigureFlightRecorderDCmd* dcmd = new JfrConfigureFlightRecorderDCmd(NULL, false);
apetushkov@9858 570 if (dcmd != NULL) {
apetushkov@9858 571 DCmdMark mark(dcmd);
apetushkov@9858 572 return dcmd->_dcmdparser.num_arguments();
apetushkov@9858 573 }
apetushkov@9858 574 return 0;
apetushkov@9858 575 }
apetushkov@9858 576
apetushkov@9858 577 void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
apetushkov@9858 578 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 579
apetushkov@9858 580 if (invalid_state(output(), THREAD)) {
apetushkov@9858 581 return;
apetushkov@9858 582 }
apetushkov@9858 583
apetushkov@9858 584 ResourceMark rm(THREAD);
apetushkov@9858 585 HandleMark hm(THREAD);
apetushkov@9858 586 JNIHandleBlockManager jni_handle_management(THREAD);
apetushkov@9858 587
apetushkov@9858 588 JavaValue result(T_OBJECT);
apetushkov@9858 589 JfrJavaArguments constructor_args(&result);
apetushkov@9858 590 constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdConfigure", CHECK);
apetushkov@9858 591 const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
apetushkov@9858 592 Handle h_dcmd_instance(THREAD, dcmd);
apetushkov@9858 593 assert(h_dcmd_instance.not_null(), "invariant");
apetushkov@9858 594
apetushkov@9858 595 jstring repository_path = NULL;
apetushkov@9858 596 if (_repository_path.is_set() && _repository_path.value() != NULL) {
apetushkov@9858 597 repository_path = JfrJavaSupport::new_string(_repository_path.value(), CHECK);
apetushkov@9858 598 }
apetushkov@9858 599
apetushkov@9858 600 jstring dump_path = NULL;
apetushkov@9858 601 if (_dump_path.is_set() && _dump_path.value() != NULL) {
apetushkov@9858 602 dump_path = JfrJavaSupport::new_string(_dump_path.value(), CHECK);
apetushkov@9858 603 }
apetushkov@9858 604
apetushkov@9858 605 jobject stack_depth = NULL;
apetushkov@9858 606 if (_stack_depth.is_set()) {
apetushkov@9858 607 stack_depth = JfrJavaSupport::new_java_lang_Integer((jint)_stack_depth.value(), CHECK);
apetushkov@9858 608 }
apetushkov@9858 609
apetushkov@9858 610 jobject global_buffer_count = NULL;
apetushkov@9858 611 if (_global_buffer_count.is_set()) {
apetushkov@9858 612 global_buffer_count = JfrJavaSupport::new_java_lang_Long(_global_buffer_count.value(), CHECK);
apetushkov@9858 613 }
apetushkov@9858 614
apetushkov@9858 615 jobject global_buffer_size = NULL;
apetushkov@9858 616 if (_global_buffer_size.is_set()) {
ysuenaga@9870 617 global_buffer_size = JfrJavaSupport::new_java_lang_Long(_global_buffer_size.value()._size, CHECK);
apetushkov@9858 618 }
apetushkov@9858 619
apetushkov@9858 620 jobject thread_buffer_size = NULL;
apetushkov@9858 621 if (_thread_buffer_size.is_set()) {
ysuenaga@9870 622 thread_buffer_size = JfrJavaSupport::new_java_lang_Long(_thread_buffer_size.value()._size, CHECK);
apetushkov@9858 623 }
apetushkov@9858 624
apetushkov@9858 625 jobject max_chunk_size = NULL;
apetushkov@9858 626 if (_max_chunk_size.is_set()) {
ysuenaga@9870 627 max_chunk_size = JfrJavaSupport::new_java_lang_Long(_max_chunk_size.value()._size, CHECK);
apetushkov@9858 628 }
apetushkov@9858 629
apetushkov@9858 630 jobject memory_size = NULL;
apetushkov@9858 631 if (_memory_size.is_set()) {
ysuenaga@9870 632 memory_size = JfrJavaSupport::new_java_lang_Long(_memory_size.value()._size, CHECK);
apetushkov@9858 633 }
apetushkov@9858 634
apetushkov@9858 635 jobject sample_threads = NULL;
apetushkov@9858 636 if (_sample_threads.is_set()) {
apetushkov@9858 637 sample_threads = JfrJavaSupport::new_java_lang_Boolean(_sample_threads.value(), CHECK);
apetushkov@9858 638 }
apetushkov@9858 639
apetushkov@9858 640 static const char klass[] = "jdk/jfr/internal/dcmd/DCmdConfigure";
apetushkov@9858 641 static const char method[] = "execute";
apetushkov@9858 642 static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;"
apetushkov@9858 643 "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;"
apetushkov@9858 644 "Ljava/lang/Long;Ljava/lang/Boolean;)Ljava/lang/String;";
apetushkov@9858 645
apetushkov@9858 646 JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
apetushkov@9858 647 execute_args.set_receiver(h_dcmd_instance);
apetushkov@9858 648
apetushkov@9858 649 // params
apetushkov@9858 650 execute_args.push_jobject(repository_path);
apetushkov@9858 651 execute_args.push_jobject(dump_path);
apetushkov@9858 652 execute_args.push_jobject(stack_depth);
apetushkov@9858 653 execute_args.push_jobject(global_buffer_count);
apetushkov@9858 654 execute_args.push_jobject(global_buffer_size);
apetushkov@9858 655 execute_args.push_jobject(thread_buffer_size);
apetushkov@9858 656 execute_args.push_jobject(memory_size);
apetushkov@9858 657 execute_args.push_jobject(max_chunk_size);
apetushkov@9858 658 execute_args.push_jobject(sample_threads);
apetushkov@9858 659
apetushkov@9858 660 JfrJavaSupport::call_virtual(&execute_args, THREAD);
apetushkov@9858 661 handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
apetushkov@9858 662 }
apetushkov@9858 663
apetushkov@9858 664 bool register_jfr_dcmds() {
apetushkov@9858 665 uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
apetushkov@9858 666 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrCheckFlightRecordingDCmd>(full_export, true, false));
apetushkov@9858 667 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrDumpFlightRecordingDCmd>(full_export, true, false));
apetushkov@9858 668 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStartFlightRecordingDCmd>(full_export, true, false));
apetushkov@9858 669 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStopFlightRecordingDCmd>(full_export, true, false));
apetushkov@9858 670 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrConfigureFlightRecorderDCmd>(full_export, true, false));
apetushkov@9858 671
apetushkov@9858 672 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrUnlockCommercialFeaturesDCmd>(full_export, true, false));
apetushkov@9858 673 return true;
apetushkov@9858 674 }
apetushkov@9858 675

mercurial