From 874b60c53cdee890f05182e3a6fedcd2e4a57267 Mon Sep 17 00:00:00 2001 From: katkerem Date: Fri, 1 Aug 2025 17:39:41 +0100 Subject: [PATCH 1/2] Backport 64ec8b3e5c8a8d44c92591710d73b833f13c1500 --- hotspot/src/share/vm/prims/jvmtiExport.cpp | 18 +++--- .../DynamicCodeGeneratedTest.java | 59 +++++++++++++++++++ .../libDynamicCodeGenerated.cpp | 57 ++++++++++++++++++ 3 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.java create mode 100644 hotspot/test/serviceability/jvmti/DynamicCodeGenerated/libDynamicCodeGenerated.cpp diff --git a/hotspot/src/share/vm/prims/jvmtiExport.cpp b/hotspot/src/share/vm/prims/jvmtiExport.cpp index 3f644102d32..2947c1082d3 100644 --- a/hotspot/src/share/vm/prims/jvmtiExport.cpp +++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp @@ -1890,13 +1890,17 @@ void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* na address code_begin, address code_end) { // register the stub with the current dynamic code event collector - JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current()); - // state can only be NULL if the current thread is exiting which - // should not happen since we're trying to post an event - guarantee(state != NULL, "attempt to register stub via an exiting thread"); - JvmtiDynamicCodeEventCollector* collector = state->get_dynamic_code_event_collector(); - guarantee(collector != NULL, "attempt to register stub without event collector"); - collector->register_stub(name, code_begin, code_end); + // Cannot take safepoint here so do not use state_for to get + // jvmti thread state. + // The collector and/or state might be NULL if JvmtiDynamicCodeEventCollector + // has been initialized while JVMTI_EVENT_DYNAMIC_CODE_GENERATED was disabled. + JvmtiThreadState* state = JavaThread::current()->jvmti_thread_state(); + if (state != NULL) { + JvmtiDynamicCodeEventCollector *collector = state->get_dynamic_code_event_collector(); + if (collector != NULL) { + collector->register_stub(name, code_begin, code_end); + } + } } // Collect all the vm internally allocated objects which are visible to java world diff --git a/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.java b/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.java new file mode 100644 index 00000000000..d20b5b7003d --- /dev/null +++ b/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8212155 + * @summary Test concurrent enabling and posting of DynamicCodeGenerated events. + * @library /test/lib + * @run main/othervm/native -agentlib:DynamicCodeGenerated DynamicCodeGeneratedTest + */ + +public class DynamicCodeGeneratedTest { + static { + System.loadLibrary("DynamicCodeGenerated"); + } + public static native void changeEventNotificationMode(); + + public static void main(String[] args) { + // Try to enable DynamicCodeGenerated event while it is posted + // using JvmtiDynamicCodeEventCollector from VtableStubs::find_stub + Thread t = new Thread(() -> { + changeEventNotificationMode(); + }); + t.setDaemon(true); + t.start(); + + for (int i = 0; i < 2000; i++) { + new Thread(() -> { + String result = "string" + System.currentTimeMillis(); + + // Keep a reference to result + if (result.hashCode() == System.currentTimeMillis()) { + // Shouldn't happen + return; + } + }).start(); + } + } +} diff --git a/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/libDynamicCodeGenerated.cpp b/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/libDynamicCodeGenerated.cpp new file mode 100644 index 00000000000..45c98dcba32 --- /dev/null +++ b/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/libDynamicCodeGenerated.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include + +static jvmtiEnv* jvmti = NULL; + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT +void JNICALL Java_DynamicCodeGeneratedTest_changeEventNotificationMode(JNIEnv* jni, jclass cls) { + while (true) { + jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL); + jvmti->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL); + } +} + +#ifdef __cplusplus +} +#endif + +void JNICALL DynamicCodeGenerated(jvmtiEnv* jvmti, const char* name, const void* address, jint length) { + +} + +jint Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { + vm->GetEnv((void**)&jvmti, JVMTI_VERSION_1_0); + jvmtiEventCallbacks callbacks; + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.DynamicCodeGenerated = DynamicCodeGenerated; + jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); + + return 0; +} From 6dac15dc416f1c2e822692a4cde8deab6645082c Mon Sep 17 00:00:00 2001 From: katkerem Date: Mon, 11 Aug 2025 17:03:24 +0100 Subject: [PATCH 2/2] Fix test for JDK 8 --- ...tedTest.java => DynamicCodeGenerated.java} | 12 +-- .../DynamicCodeGeneratedTest.sh | 82 +++++++++++++++++++ .../libDynamicCodeGenerated.cpp | 2 +- 3 files changed, 85 insertions(+), 11 deletions(-) rename hotspot/test/serviceability/jvmti/DynamicCodeGenerated/{DynamicCodeGeneratedTest.java => DynamicCodeGenerated.java} (84%) create mode 100644 hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.sh diff --git a/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.java b/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGenerated.java similarity index 84% rename from hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.java rename to hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGenerated.java index d20b5b7003d..a5a970ea121 100644 --- a/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.java +++ b/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGenerated.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -21,15 +21,7 @@ * questions. */ -/* - * @test - * @bug 8212155 - * @summary Test concurrent enabling and posting of DynamicCodeGenerated events. - * @library /test/lib - * @run main/othervm/native -agentlib:DynamicCodeGenerated DynamicCodeGeneratedTest - */ - -public class DynamicCodeGeneratedTest { +public class DynamicCodeGenerated { static { System.loadLibrary("DynamicCodeGenerated"); } diff --git a/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.sh b/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.sh new file mode 100644 index 00000000000..4017d3e7044 --- /dev/null +++ b/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/DynamicCodeGeneratedTest.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +# Copyright (c) 2012, 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 +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. + +# @test DynamicCodeGeneratedTest.sh +# @bug 8212155 +# @summary Test concurrent enabling and posting of DynamicCodeGenerated events. +# @run shell DynamicCodeGeneratedTest.sh + +if [ "$TESTSRC" = "" ] +then TESTSRC=. +fi + +if [ "$TESTJAVA" = "" ] +then + PARENT=$(dirname $(which java)) + TESTJAVA=$(dirname $PARENT) + echo "TESTJAVA not set, selecting " $TESTJAVA + echo "If this is incorrect, try setting the variable manually." +fi + +# set platform-dependent variables +OS=$(uname -s) +case "$OS" in + Linux ) + ARCHFLAG= + $TESTJAVA/bin/java -version 2>&1 | grep '64-Bit' > /dev/null + if [ $? -eq '0' ] + then + ARCH="amd64" + else + ARCH="i386" + ARCHFLAG="-m32 -march=i386" + fi + ;; + * ) + echo "Test passed, unrecognized system." + exit 0; + ;; +esac + +echo "OS-ARCH is" linux-$ARCH +$TESTJAVA/jre/bin/java -fullversion 2>&1 + +which gcc >/dev/null 2>&1 +if [ "$?" -ne '0' ] +then + echo "No C compiler found. Test passed." + exit 0 +fi + +JAVA=$TESTJAVA/jre/bin/java +JAVAC=$TESTJAVA/bin/javac +JAVAH=$TESTJAVA/bin/javah + +$JAVAC -d . $TESTSRC/DynamicCodeGenerated.java +$JAVAH -jni -classpath . -d . DynamicCodeGenerated + +gcc --shared $ARCHFLAG -fPIC -O -I$TESTJAVA/include -I$TESTJAVA/include/linux -I. -o libDynamicCodeGenerated.so $TESTSRC/libDynamicCodeGenerated.cpp + +LD_LIBRARY_PATH=. $JAVA -classpath . -agentlib:DynamicCodeGenerated DynamicCodeGenerated + +exit $? diff --git a/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/libDynamicCodeGenerated.cpp b/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/libDynamicCodeGenerated.cpp index 45c98dcba32..7cef753c02c 100644 --- a/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/libDynamicCodeGenerated.cpp +++ b/hotspot/test/serviceability/jvmti/DynamicCodeGenerated/libDynamicCodeGenerated.cpp @@ -31,7 +31,7 @@ extern "C" { #endif JNIEXPORT -void JNICALL Java_DynamicCodeGeneratedTest_changeEventNotificationMode(JNIEnv* jni, jclass cls) { +void JNICALL Java_DynamicCodeGenerated_changeEventNotificationMode(JNIEnv* jni, jclass cls) { while (true) { jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL); jvmti->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL);