Fri, 17 Jul 2020 11:54:17 +0200
8249158: THREAD_START and THREAD_END event posted in primordial phase
Reviewed-by: adinn
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