8249158: THREAD_START and THREAD_END event posted in primordial phase

Fri, 17 Jul 2020 11:54:17 +0200

author
jbachorik
date
Fri, 17 Jul 2020 11:54:17 +0200
changeset 9986
85e682d8ab91
parent 9985
8712be1ae49a
child 9987
a025f6d9e6e8

8249158: THREAD_START and THREAD_END event posted in primordial phase
Reviewed-by: adinn

src/share/vm/jfr/instrumentation/jfrJvmtiAgent.cpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/jfr.cpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/jfr.hpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/jni/jfrJavaSupport.cpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/jni/jfrJavaSupport.hpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/jni/jfrJniMethod.cpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/recorder/jfrRecorder.cpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/recorder/jfrRecorder.hpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/recorder/service/jfrOptionSet.cpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/recorder/service/jfrOptionSet.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/thread.cpp file | annotate | diff | comparison | revisions
test/runtime/8233197/T.java file | annotate | diff | comparison | revisions
test/runtime/8233197/Test8233197.sh file | annotate | diff | comparison | revisions
test/runtime/8233197/libJvmtiAgent.c file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/jfr/instrumentation/jfrJvmtiAgent.cpp	Tue Jun 30 18:05:34 2020 +0200
     1.2 +++ b/src/share/vm/jfr/instrumentation/jfrJvmtiAgent.cpp	Fri Jul 17 11:54:17 2020 +0200
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -31,9 +31,7 @@
    1.11  #include "jfr/recorder/service/jfrOptionSet.hpp"
    1.12  #include "jfr/support/jfrEventClass.hpp"
    1.13  #include "memory/resourceArea.hpp"
    1.14 -#include "prims/jvmtiEnvBase.hpp"
    1.15  #include "prims/jvmtiExport.hpp"
    1.16 -#include "prims/jvmtiUtil.hpp"
    1.17  #include "runtime/interfaceSupport.hpp"
    1.18  #include "runtime/thread.inline.hpp"
    1.19  #include "utilities/exceptions.hpp"
    1.20 @@ -53,17 +51,19 @@
    1.21    }
    1.22  }
    1.23  
    1.24 -static bool set_event_notification_mode(jvmtiEventMode mode,
    1.25 -                                        jvmtiEvent event,
    1.26 -                                        jthread event_thread,
    1.27 -                                        ...) {
    1.28 -  assert(jfr_jvmti_env != NULL, "invariant");
    1.29 +static jvmtiError set_event_notification_mode(jvmtiEventMode mode,
    1.30 +                                              jvmtiEvent event,
    1.31 +                                              jthread event_thread,
    1.32 +                                              ...) {
    1.33 +  if (jfr_jvmti_env == NULL) {
    1.34 +    return JVMTI_ERROR_NONE;
    1.35 +  }
    1.36    const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventNotificationMode(mode, event, event_thread);
    1.37    check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventNotificationMode");
    1.38 -  return jvmti_ret_code == JVMTI_ERROR_NONE;
    1.39 +  return jvmti_ret_code;
    1.40  }
    1.41  
    1.42 -static bool update_class_file_load_hook_event(jvmtiEventMode mode) {
    1.43 +static jvmtiError update_class_file_load_hook_event(jvmtiEventMode mode) {
    1.44    return set_event_notification_mode(mode, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
    1.45  }
    1.46  
    1.47 @@ -116,23 +116,12 @@
    1.48    return classes;
    1.49  }
    1.50  
    1.51 -// caller needs ResourceMark
    1.52 -static void log_and_throw(jvmtiError error, TRAPS) {
    1.53 +static void log_and_throw(TRAPS) {
    1.54    if (!HAS_PENDING_EXCEPTION) {
    1.55      DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
    1.56      ThreadInVMfromNative tvmfn((JavaThread*)THREAD);
    1.57 -    const char base_error_msg[] = "JfrJvmtiAgent::retransformClasses failed: ";
    1.58 -    size_t length = sizeof base_error_msg; // includes terminating null
    1.59 -    const char* const jvmti_error_name = JvmtiUtil::error_name(error);
    1.60 -    assert(jvmti_error_name != NULL, "invariant");
    1.61 -    length += strlen(jvmti_error_name);
    1.62 -    char* error_msg = NEW_RESOURCE_ARRAY(char, length);
    1.63 -    jio_snprintf(error_msg, length, "%s%s", base_error_msg, jvmti_error_name);
    1.64 -    if (JVMTI_ERROR_INVALID_CLASS_FORMAT == error) {
    1.65 -      JfrJavaSupport::throw_class_format_error(error_msg, THREAD);
    1.66 -    } else {
    1.67 -      JfrJavaSupport::throw_runtime_exception(error_msg, THREAD);
    1.68 -    }
    1.69 +    if (true) tty->print_cr("JfrJvmtiAgent::retransformClasses failed");
    1.70 +    JfrJavaSupport::throw_class_format_error("JfrJvmtiAgent::retransformClasses failed", THREAD);
    1.71    }
    1.72  }
    1.73  
    1.74 @@ -147,15 +136,12 @@
    1.75    }
    1.76  }
    1.77  
    1.78 -static bool is_valid_jvmti_phase() {
    1.79 -  return JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE;
    1.80 -}
    1.81 -
    1.82  void JfrJvmtiAgent::retransform_classes(JNIEnv* env, jobjectArray classes_array, TRAPS) {
    1.83    assert(env != NULL, "invariant");
    1.84 -  assert(classes_array != NULL, "invariant");
    1.85 -  assert(is_valid_jvmti_phase(), "invariant");
    1.86    DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
    1.87 +  if (classes_array == NULL) {
    1.88 +    return;
    1.89 +  }
    1.90    const jint classes_count = env->GetArrayLength(classes_array);
    1.91    if (classes_count <= 0) {
    1.92      return;
    1.93 @@ -166,27 +152,27 @@
    1.94    for (jint i = 0; i < classes_count; i++) {
    1.95      jclass clz = (jclass)env->GetObjectArrayElement(classes_array, i);
    1.96      check_exception_and_log(env, THREAD);
    1.97 -    classes[i] = clz;
    1.98 -  }
    1.99 -  {
   1.100 +
   1.101      // inspecting the oop/klass requires a thread transition
   1.102 -    ThreadInVMfromNative transition((JavaThread*)THREAD);
   1.103 -    for (jint i = 0; i < classes_count; ++i) {
   1.104 -      jclass clz = classes[i];
   1.105 -      if (!JdkJfrEvent::is_a(clz)) {
   1.106 +    {
   1.107 +      ThreadInVMfromNative transition((JavaThread*)THREAD);
   1.108 +      if (JdkJfrEvent::is_a(clz)) {
   1.109 +        // should have been tagged already
   1.110 +        assert(JdkJfrEvent::is_subklass(clz), "invariant");
   1.111 +      } else {
   1.112          // outside the event hierarchy
   1.113          JdkJfrEvent::tag_as_host(clz);
   1.114        }
   1.115      }
   1.116 +
   1.117 +    classes[i] = clz;
   1.118    }
   1.119 -  DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
   1.120 -  const jvmtiError result = jfr_jvmti_env->RetransformClasses(classes_count, classes);
   1.121 -  if (result != JVMTI_ERROR_NONE) {
   1.122 -    log_and_throw(result, THREAD);
   1.123 +  if (jfr_jvmti_env->RetransformClasses(classes_count, classes) != JVMTI_ERROR_NONE) {
   1.124 +    log_and_throw(THREAD);
   1.125    }
   1.126  }
   1.127  
   1.128 -static bool register_callbacks(JavaThread* jt) {
   1.129 +static jvmtiError register_callbacks(JavaThread* jt) {
   1.130    assert(jfr_jvmti_env != NULL, "invariant");
   1.131    DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(jt));
   1.132    jvmtiEventCallbacks callbacks;
   1.133 @@ -195,10 +181,10 @@
   1.134    callbacks.ClassFileLoadHook = jfr_on_class_file_load_hook;
   1.135    const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
   1.136    check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventCallbacks");
   1.137 -  return jvmti_ret_code == JVMTI_ERROR_NONE;
   1.138 +  return jvmti_ret_code;
   1.139  }
   1.140  
   1.141 -static bool register_capabilities(JavaThread* jt) {
   1.142 +static jvmtiError register_capabilities(JavaThread* jt) {
   1.143    assert(jfr_jvmti_env != NULL, "invariant");
   1.144    DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(jt));
   1.145    jvmtiCapabilities capabilities;
   1.146 @@ -208,7 +194,7 @@
   1.147    capabilities.can_retransform_any_class = 1;
   1.148    const jvmtiError jvmti_ret_code = jfr_jvmti_env->AddCapabilities(&capabilities);
   1.149    check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "Add Capabilities");
   1.150 -  return jvmti_ret_code == JVMTI_ERROR_NONE;
   1.151 +  return jvmti_ret_code;
   1.152  }
   1.153  
   1.154  static jint create_jvmti_env(JavaThread* jt) {
   1.155 @@ -219,14 +205,16 @@
   1.156    return vm->GetEnv((void **)&jfr_jvmti_env, JVMTI_VERSION);
   1.157  }
   1.158  
   1.159 -static bool unregister_callbacks(JavaThread* jt) {
   1.160 -  assert(jfr_jvmti_env != NULL, "invariant");
   1.161 +static jvmtiError unregister_callbacks(JavaThread* jt) {
   1.162 +  if (jfr_jvmti_env == NULL) {
   1.163 +    return JVMTI_ERROR_NONE;
   1.164 +  }
   1.165    jvmtiEventCallbacks callbacks;
   1.166    /* Set empty callbacks */
   1.167    memset(&callbacks, 0, sizeof(callbacks));
   1.168    const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
   1.169    check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventCallbacks");
   1.170 -  return jvmti_ret_code == JVMTI_ERROR_NONE;
   1.171 +  return jvmti_ret_code;
   1.172  }
   1.173  
   1.174  JfrJvmtiAgent::JfrJvmtiAgent() {}
   1.175 @@ -234,17 +222,20 @@
   1.176  JfrJvmtiAgent::~JfrJvmtiAgent() {
   1.177    JavaThread* jt = current_java_thread();
   1.178    DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(jt));
   1.179 +  ThreadToNativeFromVM transition(jt);
   1.180 +  update_class_file_load_hook_event(JVMTI_DISABLE);
   1.181 +  unregister_callbacks(jt);
   1.182    if (jfr_jvmti_env != NULL) {
   1.183 -    ThreadToNativeFromVM transition(jt);
   1.184 -    update_class_file_load_hook_event(JVMTI_DISABLE);
   1.185 -    unregister_callbacks(jt);
   1.186      jfr_jvmti_env->DisposeEnvironment();
   1.187      jfr_jvmti_env = NULL;
   1.188    }
   1.189 +  agent = NULL;
   1.190  }
   1.191  
   1.192 -static bool initialize(JavaThread* jt) {
   1.193 +static bool initialize() {
   1.194 +  JavaThread* const jt = current_java_thread();
   1.195    assert(jt != NULL, "invariant");
   1.196 +  assert(jt->thread_state() == _thread_in_vm, "invariant");
   1.197    DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(jt));
   1.198    ThreadToNativeFromVM transition(jt);
   1.199    if (create_jvmti_env(jt) != JNI_OK) {
   1.200 @@ -252,38 +243,25 @@
   1.201      return false;
   1.202    }
   1.203    assert(jfr_jvmti_env != NULL, "invariant");
   1.204 -  if (!register_capabilities(jt)) {
   1.205 +  if (register_capabilities(jt) != JVMTI_ERROR_NONE) {
   1.206      return false;
   1.207    }
   1.208 -  if (!register_callbacks(jt)) {
   1.209 +  if (register_callbacks(jt) != JVMTI_ERROR_NONE) {
   1.210      return false;
   1.211    }
   1.212 -  return update_class_file_load_hook_event(JVMTI_ENABLE);
   1.213 -}
   1.214 -
   1.215 -static void log_and_throw_illegal_state_exception(TRAPS) {
   1.216 -  DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   1.217 -  const char* const illegal_state_msg = "An attempt was made to start JFR too early in the VM initialization sequence.";
   1.218 -  if (true) {
   1.219 -    tty->print_cr("%s\n", illegal_state_msg);
   1.220 -    tty->print_cr("JFR uses JVMTI RetransformClasses and requires the JVMTI state to have entered JVMTI_PHASE_LIVE.\n");
   1.221 -    tty->print_cr("Please initialize JFR in response to event JVMTI_EVENT_VM_INIT instead of JVMTI_EVENT_VM_START.\n");
   1.222 +  if (update_class_file_load_hook_event(JVMTI_ENABLE) != JVMTI_ERROR_NONE) {
   1.223 +    return false;
   1.224    }
   1.225 -  JfrJavaSupport::throw_illegal_state_exception(illegal_state_msg, THREAD);
   1.226 +  return true;
   1.227  }
   1.228  
   1.229  bool JfrJvmtiAgent::create() {
   1.230 -  assert(agent == NULL, "invariant");
   1.231 -  JavaThread* const jt = current_java_thread();
   1.232 -  if (!is_valid_jvmti_phase()) {
   1.233 -    log_and_throw_illegal_state_exception(jt);
   1.234 -    return false;
   1.235 -  }
   1.236 +  assert(jfr_jvmti_env == NULL, "invariant");
   1.237    agent = new JfrJvmtiAgent();
   1.238    if (agent == NULL) {
   1.239      return false;
   1.240    }
   1.241 -  if (!initialize(jt)) {
   1.242 +  if (!initialize()) {
   1.243      delete agent;
   1.244      agent = NULL;
   1.245      return false;
   1.246 @@ -297,3 +275,4 @@
   1.247      agent = NULL;
   1.248    }
   1.249  }
   1.250 +
     2.1 --- a/src/share/vm/jfr/jfr.cpp	Tue Jun 30 18:05:34 2020 +0200
     2.2 +++ b/src/share/vm/jfr/jfr.cpp	Fri Jul 17 11:54:17 2020 +0200
     2.3 @@ -32,7 +32,6 @@
     2.4  #include "jfr/recorder/service/jfrOptionSet.hpp"
     2.5  #include "jfr/support/jfrThreadLocal.hpp"
     2.6  #include "runtime/java.hpp"
     2.7 -#include "utilities/defaultStream.hpp"
     2.8  
     2.9  bool Jfr::is_enabled() {
    2.10    return JfrRecorder::is_enabled();
    2.11 @@ -46,21 +45,15 @@
    2.12    return JfrRecorder::is_recording();
    2.13  }
    2.14  
    2.15 -void Jfr::on_create_vm_1() {
    2.16 -  if (!JfrRecorder::on_create_vm_1()) {
    2.17 -    vm_exit_during_initialization("Failure when starting JFR on_create_vm_1");
    2.18 +void Jfr::on_vm_init() {
    2.19 +  if (!JfrRecorder::on_vm_init()) {
    2.20 +    vm_exit_during_initialization("Failure when starting JFR on_vm_init");
    2.21    }
    2.22  }
    2.23  
    2.24 -void Jfr::on_create_vm_2() {
    2.25 -  if (!JfrRecorder::on_create_vm_2()) {
    2.26 -    vm_exit_during_initialization("Failure when starting JFR on_create_vm_2");
    2.27 -  }
    2.28 -}
    2.29 -
    2.30 -void Jfr::on_create_vm_3() {
    2.31 -  if (!JfrRecorder::on_create_vm_3()) {
    2.32 -    vm_exit_during_initialization("Failure when starting JFR on_create_vm_3");
    2.33 +void Jfr::on_vm_start() {
    2.34 +  if (!JfrRecorder::on_vm_start()) {
    2.35 +    vm_exit_during_initialization("Failure when starting JFR on_vm_start");
    2.36    }
    2.37  }
    2.38  
     3.1 --- a/src/share/vm/jfr/jfr.hpp	Tue Jun 30 18:05:34 2020 +0200
     3.2 +++ b/src/share/vm/jfr/jfr.hpp	Fri Jul 17 11:54:17 2020 +0200
     3.3 @@ -43,9 +43,8 @@
     3.4    static bool is_enabled();
     3.5    static bool is_disabled();
     3.6    static bool is_recording();
     3.7 -  static void on_create_vm_1();
     3.8 -  static void on_create_vm_2();
     3.9 -  static void on_create_vm_3();
    3.10 +  static void on_vm_init();
    3.11 +  static void on_vm_start();
    3.12    static void on_unloading_classes();
    3.13    static void on_thread_start(Thread* thread);
    3.14    static void on_thread_exit(Thread* thread);
     4.1 --- a/src/share/vm/jfr/jni/jfrJavaSupport.cpp	Tue Jun 30 18:05:34 2020 +0200
     4.2 +++ b/src/share/vm/jfr/jni/jfrJavaSupport.cpp	Fri Jul 17 11:54:17 2020 +0200
     4.3 @@ -515,10 +515,6 @@
     4.4    create_and_throw(vmSymbols::java_lang_ClassFormatError(), message, THREAD);
     4.5  }
     4.6  
     4.7 -void JfrJavaSupport::throw_runtime_exception(const char* message, TRAPS) {
     4.8 -  create_and_throw(vmSymbols::java_lang_RuntimeException(), message, THREAD);
     4.9 -}
    4.10 -
    4.11  void JfrJavaSupport::abort(jstring errorMsg, Thread* t) {
    4.12    DEBUG_ONLY(check_java_thread_in_vm(t));
    4.13  
     5.1 --- a/src/share/vm/jfr/jni/jfrJavaSupport.hpp	Tue Jun 30 18:05:34 2020 +0200
     5.2 +++ b/src/share/vm/jfr/jni/jfrJavaSupport.hpp	Fri Jul 17 11:54:17 2020 +0200
     5.3 @@ -81,7 +81,6 @@
     5.4    static void throw_internal_error(const char* message, TRAPS);
     5.5    static void throw_out_of_memory_error(const char* message, TRAPS);
     5.6    static void throw_class_format_error(const char* message, TRAPS);
     5.7 -  static void throw_runtime_exception(const char* message, TRAPS);
     5.8  
     5.9    static jlong jfr_thread_id(jobject target_thread);
    5.10  
     6.1 --- a/src/share/vm/jfr/jni/jfrJniMethod.cpp	Tue Jun 30 18:05:34 2020 +0200
     6.2 +++ b/src/share/vm/jfr/jni/jfrJniMethod.cpp	Fri Jul 17 11:54:17 2020 +0200
     6.3 @@ -191,9 +191,7 @@
     6.4      return JNI_TRUE;
     6.5    }
     6.6    if (!JfrRecorder::create(simulate_failure == JNI_TRUE)) {
     6.7 -    if (!thread->has_pending_exception()) {
     6.8 -      JfrJavaSupport::throw_illegal_state_exception("Unable to start Jfr", thread);
     6.9 -    }
    6.10 +    JfrJavaSupport::throw_illegal_state_exception("Unable to start Jfr", thread);
    6.11      return JNI_FALSE;
    6.12    }
    6.13    return JNI_TRUE;
     7.1 --- a/src/share/vm/jfr/recorder/jfrRecorder.cpp	Tue Jun 30 18:05:34 2020 +0200
     7.2 +++ b/src/share/vm/jfr/recorder/jfrRecorder.cpp	Fri Jul 17 11:54:17 2020 +0200
     7.3 @@ -44,9 +44,6 @@
     7.4  #include "runtime/handles.inline.hpp"
     7.5  #include "runtime/globals_extension.hpp"
     7.6  #include "utilities/growableArray.hpp"
     7.7 -#ifdef ASSERT
     7.8 -#include "prims/jvmtiEnvBase.hpp"
     7.9 -#endif
    7.10  
    7.11  bool JfrRecorder::_shutting_down = false;
    7.12  
    7.13 @@ -60,9 +57,7 @@
    7.14  
    7.15  static bool enable() {
    7.16    assert(!_enabled, "invariant");
    7.17 -  if (!FlightRecorder) {
    7.18 -    FLAG_SET_MGMT(bool, FlightRecorder, true);
    7.19 -  }
    7.20 +  FLAG_SET_MGMT(bool, FlightRecorder, true);
    7.21    _enabled = FlightRecorder;
    7.22    assert(_enabled, "invariant");
    7.23    return _enabled;
    7.24 @@ -72,7 +67,7 @@
    7.25    return _enabled;
    7.26  }
    7.27  
    7.28 -bool JfrRecorder::on_create_vm_1() {
    7.29 +bool JfrRecorder::on_vm_init() {
    7.30    if (!is_disabled()) {
    7.31      if (FlightRecorder || StartFlightRecording != NULL) {
    7.32        enable();
    7.33 @@ -97,7 +92,7 @@
    7.34  
    7.35  static void teardown_startup_support() {
    7.36    release_recordings();
    7.37 -  JfrOptionSet::release_start_flight_recording_options();
    7.38 +  JfrOptionSet::release_startup_recording_options();
    7.39  }
    7.40  
    7.41  // Parsing options here to detect errors as soon as possible
    7.42 @@ -115,7 +110,7 @@
    7.43  }
    7.44  
    7.45  static bool validate_recording_options(TRAPS) {
    7.46 -  const GrowableArray<const char*>* options = JfrOptionSet::start_flight_recording_options();
    7.47 +  const GrowableArray<const char*>* options = JfrOptionSet::startup_recording_options();
    7.48    if (options == NULL) {
    7.49      return true;
    7.50    }
    7.51 @@ -148,7 +143,7 @@
    7.52    return true;
    7.53  }
    7.54  
    7.55 -static bool launch_command_line_recordings(TRAPS) {
    7.56 +static bool launch_recordings(TRAPS) {
    7.57    bool result = true;
    7.58    if (dcmd_recordings_array != NULL) {
    7.59      const int length = dcmd_recordings_array->length();
    7.60 @@ -166,7 +161,7 @@
    7.61  
    7.62  static bool is_cds_dump_requested() {
    7.63    // we will not be able to launch recordings if a cds dump is being requested
    7.64 -  if (DumpSharedSpaces && (JfrOptionSet::start_flight_recording_options() != NULL)) {
    7.65 +  if (DumpSharedSpaces && (JfrOptionSet::startup_recording_options() != NULL)) {
    7.66      warning("JFR will be disabled during CDS dumping");
    7.67      teardown_startup_support();
    7.68      return true;
    7.69 @@ -174,7 +169,7 @@
    7.70    return false;
    7.71  }
    7.72  
    7.73 -bool JfrRecorder::on_create_vm_2() {
    7.74 +bool JfrRecorder::on_vm_start() {
    7.75    if (is_cds_dump_requested()) {
    7.76      return true;
    7.77    }
    7.78 @@ -201,14 +196,10 @@
    7.79    if (!is_enabled()) {
    7.80      return true;
    7.81    }
    7.82 -  return true;
    7.83 +
    7.84 +  return launch_recordings(thread);
    7.85  }
    7.86  
    7.87 -bool JfrRecorder::on_create_vm_3() {
    7.88 -  assert(JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE, "invalid init sequence");
    7.89 -  return launch_command_line_recordings(Thread::current());
    7.90 - }
    7.91 -
    7.92  static bool _created = false;
    7.93  
    7.94  //
    7.95 @@ -275,6 +266,7 @@
    7.96  }
    7.97  
    7.98  // subsystems
    7.99 +static JfrJvmtiAgent* _jvmti_agent = NULL;
   7.100  static JfrPostBox* _post_box = NULL;
   7.101  static JfrStorage* _storage = NULL;
   7.102  static JfrCheckpointManager* _checkpoint_manager = NULL;
     8.1 --- a/src/share/vm/jfr/recorder/jfrRecorder.hpp	Tue Jun 30 18:05:34 2020 +0200
     8.2 +++ b/src/share/vm/jfr/recorder/jfrRecorder.hpp	Fri Jul 17 11:54:17 2020 +0200
     8.3 @@ -40,9 +40,6 @@
     8.4   private:
     8.5    static bool _shutting_down;
     8.6  
     8.7 -  static bool on_create_vm_1();
     8.8 -  static bool on_create_vm_2();
     8.9 -  static bool on_create_vm_3();
    8.10    static bool create_checkpoint_manager();
    8.11    static bool create_chunk_repository();
    8.12    static bool create_java_event_writer();
    8.13 @@ -57,6 +54,8 @@
    8.14    static bool create_components();
    8.15    static void destroy_components();
    8.16    static void on_recorder_thread_exit();
    8.17 +  static bool on_vm_start();
    8.18 +  static bool on_vm_init();
    8.19  
    8.20   public:
    8.21    static bool is_enabled();
     9.1 --- a/src/share/vm/jfr/recorder/service/jfrOptionSet.cpp	Tue Jun 30 18:05:34 2020 +0200
     9.2 +++ b/src/share/vm/jfr/recorder/service/jfrOptionSet.cpp	Fri Jul 17 11:54:17 2020 +0200
     9.3 @@ -676,7 +676,7 @@
     9.4    return false;
     9.5  }
     9.6  
     9.7 -static GrowableArray<const char*>* start_flight_recording_options_array = NULL;
     9.8 +static GrowableArray<const char*>* startup_recording_options_array = NULL;
     9.9  
    9.10  bool JfrOptionSet::parse_start_flight_recording_option(const JavaVMOption** option, char* delimiter) {
    9.11    assert(option != NULL, "invariant");
    9.12 @@ -699,28 +699,28 @@
    9.13    assert(value != NULL, "invariant");
    9.14    const size_t value_length = strlen(value);
    9.15  
    9.16 -  if (start_flight_recording_options_array == NULL) {
    9.17 -    start_flight_recording_options_array = new (ResourceObj::C_HEAP, mtTracing) GrowableArray<const char*>(8, true, mtTracing);
    9.18 +  if (startup_recording_options_array == NULL) {
    9.19 +    startup_recording_options_array = new (ResourceObj::C_HEAP, mtTracing) GrowableArray<const char*>(8, true, mtTracing);
    9.20    }
    9.21 -  assert(start_flight_recording_options_array != NULL, "invariant");
    9.22 +  assert(startup_recording_options_array != NULL, "invariant");
    9.23    char* const startup_value = NEW_C_HEAP_ARRAY(char, value_length + 1, mtTracing);
    9.24    strncpy(startup_value, value, value_length + 1);
    9.25    assert(strncmp(startup_value, value, value_length) == 0, "invariant");
    9.26 -  start_flight_recording_options_array->append(startup_value);
    9.27 +  startup_recording_options_array->append(startup_value);
    9.28    return false;
    9.29  }
    9.30  
    9.31 -const GrowableArray<const char*>* JfrOptionSet::start_flight_recording_options() {
    9.32 -  return start_flight_recording_options_array;
    9.33 +const GrowableArray<const char*>* JfrOptionSet::startup_recording_options() {
    9.34 +  return startup_recording_options_array;
    9.35  }
    9.36  
    9.37 -void JfrOptionSet::release_start_flight_recording_options() {
    9.38 -  if (start_flight_recording_options_array != NULL) {
    9.39 -    const int length = start_flight_recording_options_array->length();
    9.40 +void JfrOptionSet::release_startup_recording_options() {
    9.41 +  if (startup_recording_options_array != NULL) {
    9.42 +    const int length = startup_recording_options_array->length();
    9.43      for (int i = 0; i < length; ++i) {
    9.44 -      FREE_C_HEAP_ARRAY(char, start_flight_recording_options_array->at(i), mtTracing);
    9.45 +      FREE_C_HEAP_ARRAY(char, startup_recording_options_array->at(i), mtTracing);
    9.46      }
    9.47 -    delete start_flight_recording_options_array;
    9.48 -    start_flight_recording_options_array = NULL;
    9.49 +    delete startup_recording_options_array;
    9.50 +    startup_recording_options_array = NULL;
    9.51    }
    9.52  }
    10.1 --- a/src/share/vm/jfr/recorder/service/jfrOptionSet.hpp	Tue Jun 30 18:05:34 2020 +0200
    10.2 +++ b/src/share/vm/jfr/recorder/service/jfrOptionSet.hpp	Fri Jul 17 11:54:17 2020 +0200
    10.3 @@ -80,8 +80,8 @@
    10.4  
    10.5    static bool parse_flight_recorder_option(const JavaVMOption** option, char* delimiter);
    10.6    static bool parse_start_flight_recording_option(const JavaVMOption** option, char* delimiter);
    10.7 -  static const GrowableArray<const char*>* start_flight_recording_options();
    10.8 -  static void release_start_flight_recording_options();
    10.9 +  static const GrowableArray<const char*>* startup_recording_options();
   10.10 +  static void release_startup_recording_options();
   10.11  };
   10.12  
   10.13  #endif // SHARE_VM_JFR_RECORDER_SERVICE_JFROPTIONSET_HPP
    11.1 --- a/src/share/vm/runtime/thread.cpp	Tue Jun 30 18:05:34 2020 +0200
    11.2 +++ b/src/share/vm/runtime/thread.cpp	Fri Jul 17 11:54:17 2020 +0200
    11.3 @@ -3440,7 +3440,7 @@
    11.4      return status;
    11.5    }
    11.6  
    11.7 -  JFR_ONLY(Jfr::on_create_vm_1();)
    11.8 +  JFR_ONLY(Jfr::on_vm_init();)
    11.9  
   11.10    // Should be done after the heap is fully created
   11.11    main_thread->cache_global_variables();
   11.12 @@ -3491,16 +3491,11 @@
   11.13      ShouldNotReachHere();
   11.14    }
   11.15  
   11.16 -#if !INCLUDE_JFR
   11.17 -  // if JFR is not enabled at the build time keep the original JvmtiExport location
   11.18 -
   11.19    // Always call even when there are not JVMTI environments yet, since environments
   11.20    // may be attached late and JVMTI must track phases of VM execution
   11.21    JvmtiExport::enter_start_phase();
   11.22  
   11.23    // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents.
   11.24 -  JvmtiExport::post_vm_start();
   11.25 -#endif
   11.26  
   11.27    {
   11.28      TraceTime timer("Initialize java.lang classes", TraceStartupTime);
   11.29 @@ -3547,19 +3542,6 @@
   11.30      initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0);
   11.31    }
   11.32  
   11.33 -  JFR_ONLY(
   11.34 -    Jfr::on_create_vm_2();
   11.35 -
   11.36 -    // if JFR is enabled at build time the JVMTI needs to be handled only after on_create_vm_2() call
   11.37 -
   11.38 -    // Always call even when there are not JVMTI environments yet, since environments
   11.39 -    // may be attached late and JVMTI must track phases of VM execution
   11.40 -    JvmtiExport::enter_start_phase();
   11.41 -
   11.42 -    // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents.
   11.43 -    JvmtiExport::post_vm_start();
   11.44 -  )
   11.45 -
   11.46    // See        : bugid 4211085.
   11.47    // Background : the static initializer of java.lang.Compiler tries to read
   11.48    //              property"java.compiler" and read & write property "java.vm.info".
   11.49 @@ -3654,7 +3636,7 @@
   11.50    // Notify JVMTI agents that VM initialization is complete - nop if no agents.
   11.51    JvmtiExport::post_vm_initialized();
   11.52  
   11.53 -  JFR_ONLY(Jfr::on_create_vm_3();)
   11.54 +  JFR_ONLY(Jfr::on_vm_start();)
   11.55  
   11.56    if (CleanChunkPoolAsync) {
   11.57      Chunk::start_chunk_pool_cleaner_task();
    12.1 --- a/test/runtime/8233197/T.java	Tue Jun 30 18:05:34 2020 +0200
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,11 +0,0 @@
    12.4 -public class T
    12.5 -{
    12.6 -  public static void main(String[] args) throws Exception
    12.7 -  {
    12.8 -    for (int i = 0; i < 50; i++) {
    12.9 -      System.out.print("+");
   12.10 -      Thread.sleep(1);
   12.11 -    }
   12.12 -    System.out.println();
   12.13 -  }
   12.14 -}
    13.1 --- a/test/runtime/8233197/Test8233197.sh	Tue Jun 30 18:05:34 2020 +0200
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,153 +0,0 @@
    13.4 -#!/bin/sh
    13.5 -
    13.6 -# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    13.7 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.8 -#
    13.9 -# This code is free software; you can redistribute it and/or modify it
   13.10 -# under the terms of the GNU General Public License version 2 only, as
   13.11 -# published by the Free Software Foundation.
   13.12 -#
   13.13 -# This code is distributed in the hope that it will be useful, but WITHOUT
   13.14 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.15 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.16 -# version 2 for more details (a copy is included in the LICENSE file that
   13.17 -# accompanied this code).
   13.18 -#
   13.19 -# You should have received a copy of the GNU General Public License version
   13.20 -# 2 along with this work; if not, write to the Free Software Foundation,
   13.21 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.22 -#
   13.23 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.24 -# or visit www.oracle.com if you need additional information or have any
   13.25 -# questions.
   13.26 -
   13.27 -##
   13.28 -## @test Test8233197.sh
   13.29 -## @bug 8233197
   13.30 -## @summary Check that JFR subsystem can be initialized from VMStart JVMTI event
   13.31 -## @compile T.java
   13.32 -## @run shell Test8233197.sh
   13.33 -##
   13.34 -
   13.35 -set -x
   13.36 -if [ "${TESTSRC}" = "" ]
   13.37 -then
   13.38 -  TESTSRC=${PWD}
   13.39 -  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
   13.40 -fi
   13.41 -echo "TESTSRC=${TESTSRC}"
   13.42 -## Adding common setup Variables for running shell tests.
   13.43 -. ${TESTSRC}/../../test_env.sh
   13.44 -
   13.45 -# set platform-dependent variables
   13.46 -OS=`uname -s`
   13.47 -case "$OS" in
   13.48 -  Linux)
   13.49 -    gcc_cmd=`which gcc`
   13.50 -    if [ "x$gcc_cmd" == "x" ]; then
   13.51 -        echo "WARNING: gcc not found. Cannot execute test." 2>&1
   13.52 -        exit 0;
   13.53 -    fi
   13.54 -    NULL=/dev/null
   13.55 -    PS=":"
   13.56 -    FS="/"
   13.57 -    ;;
   13.58 -  * )
   13.59 -    echo "Test passed; only valid for Linux"
   13.60 -    exit 0;
   13.61 -    ;;
   13.62 -esac
   13.63 -
   13.64 -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion > vm_version.out 2>&1
   13.65 -
   13.66 -# Bitness:
   13.67 -# Cannot simply look at TESTVMOPTS as -d64 is not
   13.68 -# passed if there is only a 64-bit JVM available.
   13.69 -
   13.70 -grep "64-Bit" vm_version.out > ${NULL}
   13.71 -if [ "$?" = "0" ]
   13.72 -then
   13.73 -  COMP_FLAG="-m64"
   13.74 -else
   13.75 -  COMP_FLAG="-m32"
   13.76 -fi
   13.77 -
   13.78 -
   13.79 -# Architecture:
   13.80 -# Translate uname output to JVM directory name, but permit testing
   13.81 -# 32-bit x86 on an x64 platform.
   13.82 -ARCH=`uname -m`
   13.83 -case "$ARCH" in
   13.84 -  x86_64)
   13.85 -    if [ "$COMP_FLAG" = "-m32" ]; then
   13.86 -      ARCH=i386
   13.87 -    else
   13.88 -      ARCH=amd64
   13.89 -    fi
   13.90 -    ;;
   13.91 -  ppc64)
   13.92 -    if [ "$COMP_FLAG" = "-m32" ]; then
   13.93 -      ARCH=ppc
   13.94 -    else
   13.95 -      ARCH=ppc64
   13.96 -    fi
   13.97 -    ;;
   13.98 -  sparc64)
   13.99 -    if [ "$COMP_FLAG" = "-m32" ]; then
  13.100 -      ARCH=sparc
  13.101 -    else
  13.102 -      ARCH=sparc64
  13.103 -    fi
  13.104 -    ;;
  13.105 -  arm*)
  13.106 -    # 32-bit ARM machine: compiler may not recognise -m32
  13.107 -    COMP_FLAG=""
  13.108 -    ARCH=arm
  13.109 -    ;;
  13.110 -  aarch64)
  13.111 -    # 64-bit arm machine, could be testing 32 or 64-bit:
  13.112 -    if [ "$COMP_FLAG" = "-m32" ]; then
  13.113 -      ARCH=arm
  13.114 -    else
  13.115 -      ARCH=aarch64
  13.116 -    fi
  13.117 -    ;;
  13.118 -  i586)
  13.119 -    ARCH=i386
  13.120 -    ;;
  13.121 -  i686)
  13.122 -    ARCH=i386
  13.123 -    ;;
  13.124 -  # Assuming other ARCH values need no translation
  13.125 -esac
  13.126 -
  13.127 -
  13.128 -# VM type: need to know server or client
  13.129 -VMTYPE=client
  13.130 -grep Server vm_version.out > ${NULL}
  13.131 -if [ "$?" = "0" ]
  13.132 -then
  13.133 -  VMTYPE=server
  13.134 -fi
  13.135 -
  13.136 -
  13.137 -LD_LIBRARY_PATH=.:${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE}:/usr/lib:$LD_LIBRARY_PATH
  13.138 -export LD_LIBRARY_PATH
  13.139 -
  13.140 -cp ${TESTSRC}${FS}libJvmtiAgent.c .
  13.141 -
  13.142 -# Copy the result of our @compile action:
  13.143 -cp ${TESTCLASSES}${FS}T.class .
  13.144 -
  13.145 -echo "Architecture: ${ARCH}"
  13.146 -echo "Compilation flag: ${COMP_FLAG}"
  13.147 -echo "VM type: ${VMTYPE}"
  13.148 -
  13.149 -$gcc_cmd -DLINUX ${COMP_FLAG} -Wl, -g -fno-strict-aliasing -fPIC -fno-omit-frame-pointer -W -Wall  -Wno-unused -Wno-parentheses -c -o libJvmtiAgent.o \
  13.150 -    -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
  13.151 -    -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
  13.152 -    libJvmtiAgent.c
  13.153 -$gcc_cmd -shared -o libJvmtiAgent.so libJvmtiAgent.o
  13.154 -
  13.155 -"$TESTJAVA/bin/java" $TESTVMOPTS -agentlib:JvmtiAgent -cp $(pwd) T > T.out
  13.156 -exit $?
  13.157 \ No newline at end of file
    14.1 --- a/test/runtime/8233197/libJvmtiAgent.c	Tue Jun 30 18:05:34 2020 +0200
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,124 +0,0 @@
    14.4 -/*
    14.5 - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
    14.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 - *
    14.8 - * This code is free software; you can redistribute it and/or modify it
    14.9 - * under the terms of the GNU General Public License version 2 only, as
   14.10 - * published by the Free Software Foundation.
   14.11 - *
   14.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   14.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.15 - * version 2 for more details (a copy is included in the LICENSE file that
   14.16 - * accompanied this code).
   14.17 - *
   14.18 - * You should have received a copy of the GNU General Public License version
   14.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   14.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.21 - *
   14.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   14.23 - * or visit www.oracle.com if you need additional information or have any
   14.24 - * questions.
   14.25 - */
   14.26 -
   14.27 -#include <stdio.h>
   14.28 -#include <stdlib.h>
   14.29 -#include <string.h>
   14.30 -#include "jvmti.h"
   14.31 -
   14.32 -#ifdef __cplusplus
   14.33 -extern "C" {
   14.34 -#endif
   14.35 -
   14.36 -#ifndef JNI_ENV_ARG
   14.37 -
   14.38 -#ifdef __cplusplus
   14.39 -#define JNI_ENV_ARG(x, y) y
   14.40 -#define JNI_ENV_PTR(x) x
   14.41 -#else
   14.42 -#define JNI_ENV_ARG(x,y) x, y
   14.43 -#define JNI_ENV_PTR(x) (*x)
   14.44 -#endif
   14.45 -
   14.46 -#endif
   14.47 -
   14.48 -#define TranslateError(err) "JVMTI error"
   14.49 -
   14.50 -static jvmtiEnv *jvmti = NULL;
   14.51 -
   14.52 -static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved);
   14.53 -
   14.54 -JNIEXPORT
   14.55 -jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
   14.56 -    return Agent_Initialize(jvm, options, reserved);
   14.57 -}
   14.58 -
   14.59 -JNIEXPORT
   14.60 -jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
   14.61 -    return Agent_Initialize(jvm, options, reserved);
   14.62 -}
   14.63 -
   14.64 -JNIEXPORT
   14.65 -jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
   14.66 -    return JNI_VERSION_1_8;
   14.67 -}
   14.68 -
   14.69 -static void JNICALL
   14.70 -Callback_VMStart(jvmtiEnv *jvmti_env, JNIEnv *env) {
   14.71 -    printf("Localizing jdk.jfr.FlightRecorder\n");
   14.72 -    // without fix for 8233197 the process will crash at the following line
   14.73 -    jclass cls = (*env)->FindClass(env, "jdk/jfr/FlightRecorder");
   14.74 -    jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getFlightRecorder", "()Ljdk/jfr/FlightRecorder;");
   14.75 -    if (mid == 0) {
   14.76 -        printf("Unable to localize jdk.jfr.FlightRecorder#getFlightRecorder() method\n");
   14.77 -        // crash the tested JVM to make the test fail
   14.78 -        exit(-1);
   14.79 -    }
   14.80 -    printf("Going to initialize JFR subsystem ...\n");
   14.81 -    jobject jfr = (*env)->CallStaticObjectMethod(env, cls, mid);
   14.82 -
   14.83 -    if (!(*env)->ExceptionCheck(env)) {
   14.84 -        // crash the tested JVM to make the test fail
   14.85 -        printf("JFR subsystem is wrongly initialized too early\n");
   14.86 -        exit(-2);
   14.87 -    }
   14.88 -    // exit VM
   14.89 -    exit(0);
   14.90 -}
   14.91 -
   14.92 -static
   14.93 -jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
   14.94 -    jint res, size;
   14.95 -    jvmtiCapabilities caps;
   14.96 -    jvmtiEventCallbacks callbacks;
   14.97 -    jvmtiError err;
   14.98 -
   14.99 -    res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),
  14.100 -        JVMTI_VERSION_1_2);
  14.101 -    if (res != JNI_OK || jvmti == NULL) {
  14.102 -        printf("    Error: wrong result of a valid call to GetEnv!\n");
  14.103 -        return JNI_ERR;
  14.104 -    }
  14.105 -
  14.106 -    size = (jint)sizeof(callbacks);
  14.107 -
  14.108 -    memset(&callbacks, 0, sizeof(callbacks));
  14.109 -    callbacks.VMStart = Callback_VMStart;
  14.110 -
  14.111 -    err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size);
  14.112 -    if (err != JVMTI_ERROR_NONE) {
  14.113 -        printf("    Error in SetEventCallbacks: %s (%d)\n", TranslateError(err), err);
  14.114 -        return JNI_ERR;
  14.115 -    }
  14.116 -
  14.117 -    err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, (jthread)NULL);
  14.118 -    if (err != JVMTI_ERROR_NONE) {
  14.119 -        printf("    Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err);
  14.120 -        return JNI_ERR;
  14.121 -    }
  14.122 -    return JNI_OK;
  14.123 -}
  14.124 -
  14.125 -#ifdef __cplusplus
  14.126 -}
  14.127 -#endif

mercurial