diff --git a/src/hotspot/share/prims/jvmtiExport.cpp b/src/hotspot/share/prims/jvmtiExport.cpp index 10614f445d3d8..cdd32f13646c1 100644 --- a/src/hotspot/share/prims/jvmtiExport.cpp +++ b/src/hotspot/share/prims/jvmtiExport.cpp @@ -675,6 +675,13 @@ void JvmtiExport::post_early_vm_start() { void JvmtiExport::post_vm_start() { EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("Trg VM start event triggered" )); + // The JvmtiThreadState is incomplete if initialized in post_early_vm_start + // before classes are initialized. It should be updated now. + JavaThread *thread = JavaThread::current(); + if (thread->jvmti_thread_state() != nullptr) { + thread->jvmti_thread_state()->update_thread_oop_during_vm_start(); + } + // can now enable some events JvmtiEventController::vm_start(); @@ -684,7 +691,6 @@ void JvmtiExport::post_vm_start() { if (!env->early_vmstart_env() && env->is_enabled(JVMTI_EVENT_VM_START)) { EVT_TRACE(JVMTI_EVENT_VM_START, ("Evt VM start event sent" )); - JavaThread *thread = JavaThread::current(); JvmtiThreadEventMark jem(thread); JvmtiJavaThreadEventTransition jet(thread); jvmtiEventVMStart callback = env->callbacks()->VMStart; diff --git a/src/hotspot/share/prims/jvmtiThreadState.cpp b/src/hotspot/share/prims/jvmtiThreadState.cpp index 01600b26c28c5..e76782e3d3385 100644 --- a/src/hotspot/share/prims/jvmtiThreadState.cpp +++ b/src/hotspot/share/prims/jvmtiThreadState.cpp @@ -1041,6 +1041,13 @@ oop JvmtiThreadState::get_thread_oop() { return _thread_oop_h.resolve(); } +void JvmtiThreadState::update_thread_oop_during_vm_start() { + assert(_thread->threadObj() != nullptr, "santity check"); + if (get_thread_oop() == nullptr) { + _thread_oop_h.replace(_thread->threadObj()); + } +} + void JvmtiThreadState::set_thread(JavaThread* thread) { _thread_saved = nullptr; // Common case. if (!_is_virtual && thread == nullptr) { diff --git a/src/hotspot/share/prims/jvmtiThreadState.hpp b/src/hotspot/share/prims/jvmtiThreadState.hpp index 62d0c45e33728..cec251613f36d 100644 --- a/src/hotspot/share/prims/jvmtiThreadState.hpp +++ b/src/hotspot/share/prims/jvmtiThreadState.hpp @@ -312,6 +312,8 @@ class JvmtiThreadState : public CHeapObj { void set_thread(JavaThread* thread); oop get_thread_oop(); + void update_thread_oop_during_vm_start(); + inline bool is_virtual() { return _is_virtual; } // the _thread is virtual inline bool is_exception_detected() { return _exception_state == ES_DETECTED; } diff --git a/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions/AllowedFunctions.java b/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions/AllowedFunctions.java index b4465d8fa56ec..35d3d56441558 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions/AllowedFunctions.java +++ b/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions/AllowedFunctions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,13 @@ /** * @test - * @bug 8172970 + * @bug 8172970 8362203 * @summary Verify the functions that are allowed to operate in the start phase * with and without can_generate_early_vmstart capability. * @requires vm.jvmti * @run main/othervm/native -agentlib:AllowedFunctions AllowedFunctions * @run main/othervm/native -agentlib:AllowedFunctions=with_early_vmstart AllowedFunctions + * @run main/othervm/native -agentlib:AllowedFunctions=with_early_vmstart -Xrunjdwp:transport=dt_socket,address=0,server=y,suspend=n AllowedFunctions */ public class AllowedFunctions {