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

Fri, 27 Sep 2019 10:27:29 +0800

author
egahlin
date
Fri, 27 Sep 2019 10:27:29 +0800
changeset 9883
02a4c08a8777
parent 9870
830105382dbd
child 9889
63a1206b8286
permissions
-rw-r--r--

8216064: -XX:StartFlightRecording:settings= doesn't work properly
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 }
apetushkov@9858 451 }
apetushkov@9858 452
apetushkov@9858 453 static const char klass[] = "jdk/jfr/internal/dcmd/DCmdStart";
apetushkov@9858 454 static const char method[] = "execute";
apetushkov@9858 455 static const char signature[] = "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/Long;"
apetushkov@9858 456 "Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/String;"
apetushkov@9858 457 "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/lang/String;";
apetushkov@9858 458
apetushkov@9858 459 JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
apetushkov@9858 460 execute_args.set_receiver(h_dcmd_instance);
apetushkov@9858 461
apetushkov@9858 462 // arguments
apetushkov@9858 463 execute_args.push_jobject(name);
apetushkov@9858 464 execute_args.push_jobject(settings);
apetushkov@9858 465 execute_args.push_jobject(delay);
apetushkov@9858 466 execute_args.push_jobject(duration);
apetushkov@9858 467 execute_args.push_jobject(disk);
apetushkov@9858 468 execute_args.push_jobject(filename);
apetushkov@9858 469 execute_args.push_jobject(maxage);
apetushkov@9858 470 execute_args.push_jobject(maxsize);
apetushkov@9858 471 execute_args.push_jobject(dump_on_exit);
apetushkov@9858 472 execute_args.push_jobject(path_to_gc_roots);
apetushkov@9858 473
apetushkov@9858 474 JfrJavaSupport::call_virtual(&execute_args, THREAD);
apetushkov@9858 475 handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
apetushkov@9858 476 }
apetushkov@9858 477
apetushkov@9858 478 JfrStopFlightRecordingDCmd::JfrStopFlightRecordingDCmd(outputStream* output,
apetushkov@9858 479 bool heap) : DCmdWithParser(output, heap),
apetushkov@9858 480 _name("name", "Recording text,.e.g \\\"My Recording\\\"", "STRING", true, NULL),
apetushkov@9858 481 _filename("filename", "Copy recording data to file, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false, NULL) {
apetushkov@9858 482 _dcmdparser.add_dcmd_option(&_name);
apetushkov@9858 483 _dcmdparser.add_dcmd_option(&_filename);
apetushkov@9858 484 };
apetushkov@9858 485
apetushkov@9858 486 int JfrStopFlightRecordingDCmd::num_arguments() {
apetushkov@9858 487 ResourceMark rm;
apetushkov@9858 488 JfrStopFlightRecordingDCmd* dcmd = new JfrStopFlightRecordingDCmd(NULL, false);
apetushkov@9858 489 if (dcmd != NULL) {
apetushkov@9858 490 DCmdMark mark(dcmd);
apetushkov@9858 491 return dcmd->_dcmdparser.num_arguments();
apetushkov@9858 492 }
apetushkov@9858 493 return 0;
apetushkov@9858 494 }
apetushkov@9858 495
apetushkov@9858 496 void JfrStopFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
apetushkov@9858 497 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 498
apetushkov@9858 499 if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
apetushkov@9858 500 return;
apetushkov@9858 501 }
apetushkov@9858 502
apetushkov@9858 503 ResourceMark rm(THREAD);
apetushkov@9858 504 HandleMark hm(THREAD);
apetushkov@9858 505 JNIHandleBlockManager jni_handle_management(THREAD);
apetushkov@9858 506
apetushkov@9858 507 JavaValue result(T_OBJECT);
apetushkov@9858 508 JfrJavaArguments constructor_args(&result);
apetushkov@9858 509 constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdStop", CHECK);
apetushkov@9858 510 const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
apetushkov@9858 511 Handle h_dcmd_instance(THREAD, dcmd);
apetushkov@9858 512 assert(h_dcmd_instance.not_null(), "invariant");
apetushkov@9858 513
apetushkov@9858 514 jstring name = NULL;
apetushkov@9858 515 if (_name.is_set() && _name.value() != NULL) {
apetushkov@9858 516 name = JfrJavaSupport::new_string(_name.value(), CHECK);
apetushkov@9858 517 }
apetushkov@9858 518
apetushkov@9858 519 jstring filepath = NULL;
apetushkov@9858 520 if (_filename.is_set() && _filename.value() != NULL) {
apetushkov@9858 521 filepath = JfrJavaSupport::new_string(_filename.value(), CHECK);
apetushkov@9858 522 }
apetushkov@9858 523
apetushkov@9858 524 static const char klass[] = "jdk/jfr/internal/dcmd/DCmdStop";
apetushkov@9858 525 static const char method[] = "execute";
apetushkov@9858 526 static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
apetushkov@9858 527
apetushkov@9858 528 JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
apetushkov@9858 529 execute_args.set_receiver(h_dcmd_instance);
apetushkov@9858 530
apetushkov@9858 531 // arguments
apetushkov@9858 532 execute_args.push_jobject(name);
apetushkov@9858 533 execute_args.push_jobject(filepath);
apetushkov@9858 534
apetushkov@9858 535 JfrJavaSupport::call_virtual(&execute_args, THREAD);
apetushkov@9858 536 handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
apetushkov@9858 537 }
apetushkov@9858 538
apetushkov@9858 539 JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* output,
apetushkov@9858 540 bool heap) : DCmdWithParser(output, heap),
apetushkov@9858 541 _repository_path("repositorypath", "Path to repository,.e.g \\\"My Repository\\\"", "STRING", false, NULL),
apetushkov@9858 542 _dump_path("dumppath", "Path to dump,.e.g \\\"My Dump path\\\"", "STRING", false, NULL),
ysuenaga@9870 543 _stack_depth("stackdepth", "Stack Depth", "JULONG", false, "64"),
ysuenaga@9870 544 _global_buffer_count("globalbuffercount", "Number of global buffers,", "JULONG", false, "20"),
ysuenaga@9870 545 _global_buffer_size("globalbuffersize", "Size of a global buffers,", "MEMORY SIZE", false, "512k"),
ysuenaga@9870 546 _thread_buffer_size("thread_buffer_size", "Size of a thread buffer", "MEMORY SIZE", false, "8k"),
ysuenaga@9870 547 _memory_size("memorysize", "Overall memory size, ", "MEMORY SIZE", false, "10m"),
ysuenaga@9870 548 _max_chunk_size("maxchunksize", "Size of an individual disk chunk", "MEMORY SIZE", false, "12m"),
apetushkov@9858 549 _sample_threads("samplethreads", "Activate Thread sampling", "BOOLEAN", false, "true") {
apetushkov@9858 550 _dcmdparser.add_dcmd_option(&_repository_path);
apetushkov@9858 551 _dcmdparser.add_dcmd_option(&_dump_path);
apetushkov@9858 552 _dcmdparser.add_dcmd_option(&_stack_depth);
apetushkov@9858 553 _dcmdparser.add_dcmd_option(&_global_buffer_count);
apetushkov@9858 554 _dcmdparser.add_dcmd_option(&_global_buffer_size);
apetushkov@9858 555 _dcmdparser.add_dcmd_option(&_thread_buffer_size);
apetushkov@9858 556 _dcmdparser.add_dcmd_option(&_memory_size);
apetushkov@9858 557 _dcmdparser.add_dcmd_option(&_max_chunk_size);
apetushkov@9858 558 _dcmdparser.add_dcmd_option(&_sample_threads);
apetushkov@9858 559 };
apetushkov@9858 560
apetushkov@9858 561 int JfrConfigureFlightRecorderDCmd::num_arguments() {
apetushkov@9858 562 ResourceMark rm;
apetushkov@9858 563 JfrConfigureFlightRecorderDCmd* dcmd = new JfrConfigureFlightRecorderDCmd(NULL, false);
apetushkov@9858 564 if (dcmd != NULL) {
apetushkov@9858 565 DCmdMark mark(dcmd);
apetushkov@9858 566 return dcmd->_dcmdparser.num_arguments();
apetushkov@9858 567 }
apetushkov@9858 568 return 0;
apetushkov@9858 569 }
apetushkov@9858 570
apetushkov@9858 571 void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
apetushkov@9858 572 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 573
apetushkov@9858 574 if (invalid_state(output(), THREAD)) {
apetushkov@9858 575 return;
apetushkov@9858 576 }
apetushkov@9858 577
apetushkov@9858 578 ResourceMark rm(THREAD);
apetushkov@9858 579 HandleMark hm(THREAD);
apetushkov@9858 580 JNIHandleBlockManager jni_handle_management(THREAD);
apetushkov@9858 581
apetushkov@9858 582 JavaValue result(T_OBJECT);
apetushkov@9858 583 JfrJavaArguments constructor_args(&result);
apetushkov@9858 584 constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdConfigure", CHECK);
apetushkov@9858 585 const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
apetushkov@9858 586 Handle h_dcmd_instance(THREAD, dcmd);
apetushkov@9858 587 assert(h_dcmd_instance.not_null(), "invariant");
apetushkov@9858 588
apetushkov@9858 589 jstring repository_path = NULL;
apetushkov@9858 590 if (_repository_path.is_set() && _repository_path.value() != NULL) {
apetushkov@9858 591 repository_path = JfrJavaSupport::new_string(_repository_path.value(), CHECK);
apetushkov@9858 592 }
apetushkov@9858 593
apetushkov@9858 594 jstring dump_path = NULL;
apetushkov@9858 595 if (_dump_path.is_set() && _dump_path.value() != NULL) {
apetushkov@9858 596 dump_path = JfrJavaSupport::new_string(_dump_path.value(), CHECK);
apetushkov@9858 597 }
apetushkov@9858 598
apetushkov@9858 599 jobject stack_depth = NULL;
apetushkov@9858 600 if (_stack_depth.is_set()) {
apetushkov@9858 601 stack_depth = JfrJavaSupport::new_java_lang_Integer((jint)_stack_depth.value(), CHECK);
apetushkov@9858 602 }
apetushkov@9858 603
apetushkov@9858 604 jobject global_buffer_count = NULL;
apetushkov@9858 605 if (_global_buffer_count.is_set()) {
apetushkov@9858 606 global_buffer_count = JfrJavaSupport::new_java_lang_Long(_global_buffer_count.value(), CHECK);
apetushkov@9858 607 }
apetushkov@9858 608
apetushkov@9858 609 jobject global_buffer_size = NULL;
apetushkov@9858 610 if (_global_buffer_size.is_set()) {
ysuenaga@9870 611 global_buffer_size = JfrJavaSupport::new_java_lang_Long(_global_buffer_size.value()._size, CHECK);
apetushkov@9858 612 }
apetushkov@9858 613
apetushkov@9858 614 jobject thread_buffer_size = NULL;
apetushkov@9858 615 if (_thread_buffer_size.is_set()) {
ysuenaga@9870 616 thread_buffer_size = JfrJavaSupport::new_java_lang_Long(_thread_buffer_size.value()._size, CHECK);
apetushkov@9858 617 }
apetushkov@9858 618
apetushkov@9858 619 jobject max_chunk_size = NULL;
apetushkov@9858 620 if (_max_chunk_size.is_set()) {
ysuenaga@9870 621 max_chunk_size = JfrJavaSupport::new_java_lang_Long(_max_chunk_size.value()._size, CHECK);
apetushkov@9858 622 }
apetushkov@9858 623
apetushkov@9858 624 jobject memory_size = NULL;
apetushkov@9858 625 if (_memory_size.is_set()) {
ysuenaga@9870 626 memory_size = JfrJavaSupport::new_java_lang_Long(_memory_size.value()._size, CHECK);
apetushkov@9858 627 }
apetushkov@9858 628
apetushkov@9858 629 jobject sample_threads = NULL;
apetushkov@9858 630 if (_sample_threads.is_set()) {
apetushkov@9858 631 sample_threads = JfrJavaSupport::new_java_lang_Boolean(_sample_threads.value(), CHECK);
apetushkov@9858 632 }
apetushkov@9858 633
apetushkov@9858 634 static const char klass[] = "jdk/jfr/internal/dcmd/DCmdConfigure";
apetushkov@9858 635 static const char method[] = "execute";
apetushkov@9858 636 static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;"
apetushkov@9858 637 "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;"
apetushkov@9858 638 "Ljava/lang/Long;Ljava/lang/Boolean;)Ljava/lang/String;";
apetushkov@9858 639
apetushkov@9858 640 JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
apetushkov@9858 641 execute_args.set_receiver(h_dcmd_instance);
apetushkov@9858 642
apetushkov@9858 643 // params
apetushkov@9858 644 execute_args.push_jobject(repository_path);
apetushkov@9858 645 execute_args.push_jobject(dump_path);
apetushkov@9858 646 execute_args.push_jobject(stack_depth);
apetushkov@9858 647 execute_args.push_jobject(global_buffer_count);
apetushkov@9858 648 execute_args.push_jobject(global_buffer_size);
apetushkov@9858 649 execute_args.push_jobject(thread_buffer_size);
apetushkov@9858 650 execute_args.push_jobject(memory_size);
apetushkov@9858 651 execute_args.push_jobject(max_chunk_size);
apetushkov@9858 652 execute_args.push_jobject(sample_threads);
apetushkov@9858 653
apetushkov@9858 654 JfrJavaSupport::call_virtual(&execute_args, THREAD);
apetushkov@9858 655 handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
apetushkov@9858 656 }
apetushkov@9858 657
apetushkov@9858 658 bool register_jfr_dcmds() {
apetushkov@9858 659 uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
apetushkov@9858 660 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrCheckFlightRecordingDCmd>(full_export, true, false));
apetushkov@9858 661 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrDumpFlightRecordingDCmd>(full_export, true, false));
apetushkov@9858 662 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStartFlightRecordingDCmd>(full_export, true, false));
apetushkov@9858 663 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStopFlightRecordingDCmd>(full_export, true, false));
apetushkov@9858 664 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrConfigureFlightRecorderDCmd>(full_export, true, false));
apetushkov@9858 665
apetushkov@9858 666 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrUnlockCommercialFeaturesDCmd>(full_export, true, false));
apetushkov@9858 667 return true;
apetushkov@9858 668 }
apetushkov@9858 669

mercurial