src/hotspot/share/jfr/recorder/jfrRecorder.cpp
changeset 50873 ce53844224b6
parent 50851 b1b5306fadea
child 53303 65a1d49d1718
--- a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp	Thu Jun 28 11:32:32 2018 +0200
+++ b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp	Thu Jun 28 11:37:02 2018 +0200
@@ -46,6 +46,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/flags/jvmFlag.hpp"
 #include "runtime/globals.hpp"
+#include "utilities/growableArray.hpp"
 
 static bool is_disabled_on_command_line() {
   static const size_t length = strlen("FlightRecorder");
@@ -85,31 +86,30 @@
   return JfrTime::initialize();
 }
 
-static JfrStartFlightRecordingDCmd* _startup_recording = NULL;
+static GrowableArray<JfrStartFlightRecordingDCmd*>* dcmd_recordings_array = NULL;
 
-static void release_startup_recording() {
-  if (_startup_recording != NULL) {
-    delete _startup_recording;
-    _startup_recording = NULL;
+static void release_recordings() {
+  if (dcmd_recordings_array != NULL) {
+    const int length = dcmd_recordings_array->length();
+    for (int i = 0; i < length; ++i) {
+      delete dcmd_recordings_array->at(i);
+    }
+    delete dcmd_recordings_array;
+    dcmd_recordings_array = NULL;
   }
 }
 
 static void teardown_startup_support() {
-  release_startup_recording();
-  JfrOptionSet::release_startup_recordings();
+  release_recordings();
+  JfrOptionSet::release_startup_recording_options();
 }
 
-
 // Parsing options here to detect errors as soon as possible
-static bool parse_recording_options(const char* options, TRAPS) {
+static bool parse_recording_options(const char* options, JfrStartFlightRecordingDCmd* dcmd_recording, TRAPS) {
   assert(options != NULL, "invariant");
-  if (_startup_recording != NULL) {
-    delete _startup_recording;
-  }
+  assert(dcmd_recording != NULL, "invariant");
   CmdLine cmdline(options, strlen(options), true);
-  _startup_recording = new (ResourceObj::C_HEAP, mtTracing) JfrStartFlightRecordingDCmd(tty, true);
-  assert(_startup_recording != NULL, "invariant");
-  _startup_recording->parse(&cmdline, ',', THREAD);
+  dcmd_recording->parse(&cmdline, ',', THREAD);
   if (HAS_PENDING_EXCEPTION) {
     java_lang_Throwable::print(PENDING_EXCEPTION, tty);
     CLEAR_PENDING_EXCEPTION;
@@ -119,24 +119,30 @@
 }
 
 static bool validate_recording_options(TRAPS) {
-  const GrowableArray<const char*>* startup_options = JfrOptionSet::startup_recordings();
-  if (startup_options == NULL) {
+  const GrowableArray<const char*>* options = JfrOptionSet::startup_recording_options();
+  if (options == NULL) {
     return true;
   }
-  const int length = startup_options->length();
+  const int length = options->length();
   assert(length >= 1, "invariant");
+  assert(dcmd_recordings_array == NULL, "invariant");
+  dcmd_recordings_array = new (ResourceObj::C_HEAP, mtTracing)GrowableArray<JfrStartFlightRecordingDCmd*>(length, true, mtTracing);
+  assert(dcmd_recordings_array != NULL, "invariant");
   for (int i = 0; i < length; ++i) {
-    if (!parse_recording_options(startup_options->at(i), THREAD)) {
+    JfrStartFlightRecordingDCmd* const dcmd_recording = new(ResourceObj::C_HEAP, mtTracing) JfrStartFlightRecordingDCmd(tty, true);
+    assert(dcmd_recording != NULL, "invariant");
+    dcmd_recordings_array->append(dcmd_recording);
+    if (!parse_recording_options(options->at(i), dcmd_recording, THREAD)) {
       return false;
     }
   }
   return true;
 }
 
-static bool launch_recording(TRAPS) {
-  assert(_startup_recording != NULL, "invariant");
+static bool launch_recording(JfrStartFlightRecordingDCmd* dcmd_recording, TRAPS) {
+  assert(dcmd_recording != NULL, "invariant");
   log_trace(jfr, system)("Starting a recording");
-  _startup_recording->execute(DCmd_Source_Internal, Thread::current());
+  dcmd_recording->execute(DCmd_Source_Internal, THREAD);
   if (HAS_PENDING_EXCEPTION) {
     log_debug(jfr, system)("Exception while starting a recording");
     CLEAR_PENDING_EXCEPTION;
@@ -146,31 +152,20 @@
   return true;
 }
 
-static bool launch_recordings(const GrowableArray<const char*>* startup_options, TRAPS) {
-  assert(startup_options != NULL, "invariant");
-  const int length = startup_options->length();
-  assert(length >= 1, "invariant");
-  if (length == 1) {
-    // already parsed and ready, launch it
-    return launch_recording(THREAD);
-  }
-  for (int i = 0; i < length; ++i) {
-    parse_recording_options(startup_options->at(i), THREAD);
-    if (!launch_recording(THREAD)) {
-      return false;
+static bool launch_recordings(TRAPS) {
+  bool result = true;
+  if (dcmd_recordings_array != NULL) {
+    const int length = dcmd_recordings_array->length();
+    assert(length >= 1, "invariant");
+    for (int i = 0; i < length; ++i) {
+      if (!launch_recording(dcmd_recordings_array->at(i), THREAD)) {
+        result = false;
+        break;
+      }
     }
   }
-  return true;
-}
-
-static bool startup_recordings(TRAPS) {
-  const GrowableArray<const char*>* startup_options = JfrOptionSet::startup_recordings();
-  if (startup_options == NULL) {
-    return true;
-  }
-  const bool ret = launch_recordings(startup_options, THREAD);
   teardown_startup_support();
-  return ret;
+  return result;
 }
 
 static void log_jdk_jfr_module_resolution_error(TRAPS) {
@@ -180,13 +175,20 @@
   JfrJavaSupport::is_jdk_jfr_module_available(&stream, THREAD);
 }
 
-bool JfrRecorder::on_vm_start() {
-  if (DumpSharedSpaces && (JfrOptionSet::startup_recordings() != NULL)) {
+static bool is_cds_dump_requested() {
+  // we will not be able to launch recordings if a cds dump is being requested
+  if (DumpSharedSpaces && (JfrOptionSet::startup_recording_options() != NULL)) {
     warning("JFR will be disabled during CDS dumping");
     teardown_startup_support();
     return true;
   }
-  const bool in_graph = JfrJavaSupport::is_jdk_jfr_module_available();
+  return false;
+}
+
+bool JfrRecorder::on_vm_start() {
+  if (is_cds_dump_requested()) {
+    return true;
+  }
   Thread* const thread = Thread::current();
   if (!JfrOptionSet::initialize(thread)) {
     return false;
@@ -194,10 +196,13 @@
   if (!register_jfr_dcmds()) {
     return false;
   }
-  if (!validate_recording_options(thread)) {
-    return false;
-  }
+
+  const bool in_graph = JfrJavaSupport::is_jdk_jfr_module_available();
+
   if (in_graph) {
+    if (!validate_recording_options(thread)) {
+      return false;
+    }
     if (!JfrJavaEventWriter::initialize()) {
       return false;
     }
@@ -205,14 +210,17 @@
       return false;
     }
   }
+
   if (!is_enabled()) {
     return true;
   }
+
   if (!in_graph) {
     log_jdk_jfr_module_resolution_error(thread);
     return false;
   }
-  return startup_recordings(thread);
+
+  return launch_recordings(thread);
 }
 
 static bool _created = false;