Skip to content

Commit

Permalink
Merge pull request #20854 from tajila/jfr2
Browse files Browse the repository at this point in the history
Add check for JFR enablement
  • Loading branch information
babsingh authored Dec 18, 2024
2 parents 92742f1 + 85626b6 commit f82a1e0
Show file tree
Hide file tree
Showing 16 changed files with 151 additions and 21 deletions.
3 changes: 3 additions & 0 deletions jcl/src/java.base/share/classes/com/ibm/oti/vm/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,9 @@ public static Properties internalGetProperties() {
}

/*[IF JFR_SUPPORT]*/

public static native boolean isJFREnabled();

/**
* Check if a JFR recording has been started.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -700,14 +700,17 @@ private static DiagnosticProperties doCheckpointJVM(String diagnosticCommand) {
/*[ENDIF] CRAC_SUPPORT */

/*[IF JFR_SUPPORT]*/
commandTable.put(DIAGNOSTICS_JFR_START, DiagnosticUtils::doJFR);
helpTable.put(DIAGNOSTICS_JFR_START, DIAGNOSTICS_JFR_START_HELP);
if (VM.isJFREnabled()) {
commandTable.put(DIAGNOSTICS_JFR_START, DiagnosticUtils::doJFR);
helpTable.put(DIAGNOSTICS_JFR_START, DIAGNOSTICS_JFR_START_HELP);

commandTable.put(DIAGNOSTICS_JFR_DUMP, DiagnosticUtils::doJFR);
helpTable.put(DIAGNOSTICS_JFR_DUMP, DIAGNOSTICS_JFR_DUMP_HELP);
commandTable.put(DIAGNOSTICS_JFR_DUMP, DiagnosticUtils::doJFR);
helpTable.put(DIAGNOSTICS_JFR_DUMP, DIAGNOSTICS_JFR_DUMP_HELP);

commandTable.put(DIAGNOSTICS_JFR_STOP, DiagnosticUtils::doJFR);
helpTable.put(DIAGNOSTICS_JFR_STOP, DIAGNOSTICS_JFR_STOP_HELP);
}

commandTable.put(DIAGNOSTICS_JFR_STOP, DiagnosticUtils::doJFR);
helpTable.put(DIAGNOSTICS_JFR_STOP, DIAGNOSTICS_JFR_STOP_HELP);
/*[ENDIF] JFR_SUPPORT */
}
}
8 changes: 8 additions & 0 deletions runtime/jcl/common/com_ibm_oti_vm_VM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ Java_com_ibm_oti_vm_VM_isJVMInSingleThreadedMode(JNIEnv *env, jclass unused)
}

#if defined(J9VM_OPT_JFR)
jboolean JNICALL
Java_com_ibm_oti_vm_VM_isJFREnabled(JNIEnv *env, jclass unused)
{
J9JavaVM *vm = ((J9VMThread *)env)->javaVM;

return vm->internalVMFunctions->isJFREnabled(vm) ? JNI_TRUE : JNI_FALSE;
}

jboolean JNICALL
Java_com_ibm_oti_vm_VM_isJFRRecordingStarted(JNIEnv *env, jclass unused)
{
Expand Down
1 change: 1 addition & 0 deletions runtime/jcl/exports.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ endif()

if(J9VM_OPT_JFR)
omr_add_exports(jclse
Java_com_ibm_oti_vm_VM_isJFREnabled
Java_com_ibm_oti_vm_VM_isJFRRecordingStarted
Java_com_ibm_oti_vm_VM_jfrDump
Java_com_ibm_oti_vm_VM_setJFRRecordingFileName
Expand Down
6 changes: 6 additions & 0 deletions runtime/jcl/uma/jfr_jdk11_exports.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ OpenJDK Assembly Exception [2].
SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
-->
<exports group="jfr_jdk11">
<export name="Java_com_ibm_oti_vm_VM_isJFRRecordingStarted" />
<export name="Java_com_ibm_oti_vm_VM_jfrDump" />
<export name="Java_com_ibm_oti_vm_VM_setJFRRecordingFileName" />
<export name="Java_com_ibm_oti_vm_VM_startJFR" />
<export name="Java_com_ibm_oti_vm_VM_stopJFR" />
<export name="Java_com_ibm_oti_vm_VM_triggerExecutionSample" />
<export name="Java_jdk_jfr_internal_JVM_abort" />
<export name="Java_jdk_jfr_internal_JVM_addStringConstant" />
<export name="Java_jdk_jfr_internal_JVM_beginRecording" />
Expand Down
6 changes: 0 additions & 6 deletions runtime/jcl/uma/jfr_jdk21_exports.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ OpenJDK Assembly Exception [2].
SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
-->
<exports group="jfr_jdk21">
<export name="Java_com_ibm_oti_vm_VM_isJFRRecordingStarted" />
<export name="Java_com_ibm_oti_vm_VM_jfrDump" />
<export name="Java_com_ibm_oti_vm_VM_setJFRRecordingFileName" />
<export name="Java_com_ibm_oti_vm_VM_startJFR" />
<export name="Java_com_ibm_oti_vm_VM_stopJFR" />
<export name="Java_com_ibm_oti_vm_VM_triggerExecutionSample" />
<export name="Java_jdk_jfr_internal_JVM_abort" />
<export name="Java_jdk_jfr_internal_JVM_addStringConstant" />
<export name="Java_jdk_jfr_internal_JVM_beginRecording" />
Expand Down
3 changes: 3 additions & 0 deletions runtime/oti/j9consts.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,9 @@ extern "C" {
#define J9_EXTENDED_RUNTIME2_RAMSTATE_SNAPSHOT_RUN 0x40000000
#define J9_EXTENDED_RUNTIME2_RAMSTATE_RESTORE_RUN 0x80000000

/* constants for J9JavaVM.extendedRuntimeFlags3 */
#define J9_EXTENDED_RUNTIME3_START_FLIGHT_RECORDING 0x1

#define J9_OBJECT_HEADER_AGE_DEFAULT 0xA /* OBJECT_HEADER_AGE_DEFAULT */
#define J9_OBJECT_HEADER_SHAPE_MASK 0xE /* OBJECT_HEADER_SHAPE_MASK */
#define J9_OBJECT_HEADER_REMEMBERED_BITS_TO_SET 0x10 /* OBJECT_HEADER_LOWEST_REMEMBERED */
Expand Down
2 changes: 2 additions & 0 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -5265,6 +5265,7 @@ typedef struct J9InternalVMFunctions {
#endif /* defined(J9VM_ZOS_3164_INTEROPERABILITY) && (JAVA_SPEC_VERSION >= 17) */
#if defined(J9VM_OPT_JFR)
jint (*initializeJFR)(struct J9JavaVM *vm, BOOLEAN lateInit);
jboolean (*isJFREnabled)(struct J9JavaVM *vm);
jboolean (*isJFRRecordingStarted)(struct J9JavaVM *vm);
void (*jfrDump)(struct J9VMThread *currentThread, BOOLEAN finalWrite);
void (*jfrExecutionSample)(struct J9VMThread *currentThread, struct J9VMThread *sampleThread);
Expand Down Expand Up @@ -5798,6 +5799,7 @@ typedef struct J9JavaVM {
U_32 runtimeFlags;
U_32 extendedRuntimeFlags;
U_32 extendedRuntimeFlags2;
U_32 extendedRuntimeFlags3;
UDATA zeroOptions;
struct J9Pool* hotFieldClassInfoPool;
omrthread_monitor_t hotFieldClassInfoPoolMutex;
Expand Down
2 changes: 2 additions & 0 deletions runtime/oti/jclprots.h
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,8 @@ Java_com_ibm_oti_vm_VM_isJVMInSingleThreadedMode(JNIEnv *env, jclass unused);

#if defined(J9VM_OPT_JFR)
jboolean JNICALL
Java_com_ibm_oti_vm_VM_isJFREnabled(JNIEnv *env, jclass unused);
jboolean JNICALL
Java_com_ibm_oti_vm_VM_isJFRRecordingStarted(JNIEnv *env, jclass unused);
void JNICALL
Java_com_ibm_oti_vm_VM_jfrDump(JNIEnv *env, jclass unused);
Expand Down
2 changes: 2 additions & 0 deletions runtime/oti/jvminit.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,8 @@ enum INIT_STAGE {
#define VMOPT_XXFLIGHTRECORDER "-XX:+FlightRecorder"
#define VMOPT_XXNOFLIGHTRECORDER "-XX:-FlightRecorder"

#define VMOPT_XXSTARTFLIGHTRECORDING "-XX:StartFlightRecording"

#define VMOPT_XXCONTINUATIONCACHE "-XX:ContinuationCache:"

#if JAVA_SPEC_VERSION >= 22
Expand Down
10 changes: 10 additions & 0 deletions runtime/oti/vm_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -5458,6 +5458,16 @@ hasMemoryScope(J9VMThread *walkThread, j9object_t scope);
jint
initializeJFR(J9JavaVM *vm, BOOLEAN lateInit);

/**
* Check if a JFR is enabled on the JVM.
*
* @param vm[in] the J9JavaVM
*
* @returns JNI_TRUE if a JFR enabled, JNI_FALSE otherwise
*/
jboolean
isJFREnabled(J9JavaVM *vm);

/**
* Check if a JFR recording has been started.
*
Expand Down
1 change: 1 addition & 0 deletions runtime/vm/intfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ J9InternalVMFunctions J9InternalFunctions = {
#endif /* defined(J9VM_ZOS_3164_INTEROPERABILITY) && (JAVA_SPEC_VERSION >= 17) */
#if defined(J9VM_OPT_JFR)
initializeJFR,
isJFREnabled,
isJFRRecordingStarted,
jfrDump,
jfrExecutionSample,
Expand Down
6 changes: 6 additions & 0 deletions runtime/vm/jfr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,12 @@ initializeEventFields(J9VMThread *currentThread, J9JFREvent *event, UDATA eventT
event->vmThread = currentThread;
}

jboolean
isJFREnabled(J9JavaVM *vm)
{
return J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_JFR_ENABLED) ? JNI_TRUE : JNI_FALSE;
}

jboolean
isJFRRecordingStarted(J9JavaVM *vm)
{
Expand Down
19 changes: 14 additions & 5 deletions runtime/vm/jvminit.c
Original file line number Diff line number Diff line change
Expand Up @@ -4340,12 +4340,19 @@ processVMArgsFromFirstToLast(J9JavaVM * vm)
{
IDATA flightRecorder = FIND_AND_CONSUME_VMARG(EXACT_MATCH, VMOPT_XXFLIGHTRECORDER, NULL);
IDATA noFlightRecorder = FIND_AND_CONSUME_VMARG(EXACT_MATCH, VMOPT_XXNOFLIGHTRECORDER, NULL);
if (flightRecorder > noFlightRecorder) {
vm->extendedRuntimeFlags2 |= J9_EXTENDED_RUNTIME2_JFR_ENABLED;
} else if (flightRecorder < noFlightRecorder) {

vm->extendedRuntimeFlags2 |= J9_EXTENDED_RUNTIME2_JFR_ENABLED;

if (flightRecorder < noFlightRecorder) {
vm->extendedRuntimeFlags2 &= ~(UDATA)J9_EXTENDED_RUNTIME2_JFR_ENABLED;
}
}
{
if (0 <= FIND_AND_CONSUME_VMARG(EXACT_MATCH, VMOPT_XXSTARTFLIGHTRECORDING, NULL)) {
vm->extendedRuntimeFlags3 |= J9_EXTENDED_RUNTIME3_START_FLIGHT_RECORDING;
}
}

#endif /* defined(J9VM_OPT_JFR) */

if (FIND_AND_CONSUME_VMARG(EXACT_MATCH, VMOPT_XXKEEPJNIIDS, NULL) != -1) {
Expand Down Expand Up @@ -7604,8 +7611,10 @@ protectedInitializeJavaVM(J9PortLibrary* portLibrary, void * userData)

#if defined(J9VM_OPT_JFR)
if (J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_JFR_ENABLED)) {
if (JNI_OK != initializeJFR(vm, FALSE)) {
goto error;
if (J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_START_FLIGHT_RECORDING)) {
if (JNI_OK != initializeJFR(vm, FALSE)) {
goto error;
}
}
}
#endif /* defined(J9VM_OPT_JFR) */
Expand Down
42 changes: 38 additions & 4 deletions test/functional/cmdLineTests/jfr/jfr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,56 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
<suite id="JFR Tests" timeout="300">
<envvar name="OPENJ9_METADATA_BLOB_FILE_PATH" value="$METADATA_BLOB_PATH$" />
<test id="triggerExecutionSample">
<command>$EXE$ -XX:+FlightRecorder --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.TriggerExecutionSample</command>
<command>$EXE$ -XX:StartFlightRecording --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.TriggerExecutionSample</command>
<return type="success" value="0" />
</test>
<test id="runWorkload - approx 30seconds">
<command>$EXE$ -XX:+FlightRecorder --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.WorkLoad</command>
<command>$EXE$ -XX:StartFlightRecording --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.WorkLoad</command>
<output type="success" caseSensitive="yes" regex="no">All runs complete.</output>
<output type="failure" caseSensitive="yes" regex="no">Exception</output>
</test>
<test id="runWorkload 2 - approx 2mins">
<command>$EXE$ -XX:+FlightRecorder --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.WorkLoad 200 20000 200</command>
<command>$EXE$ -XX:StartFlightRecording --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.WorkLoad 200 20000 200</command>
<output type="success" caseSensitive="yes" regex="no">All runs complete.</output>
<output type="failure" caseSensitive="yes" regex="no">Exception</output>
</test>
<test id="runWorkload 2 - approx 2mins">
<test id="VM API Test - approx 2mins">
<command>$EXE$ --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.VMAPITest</command>
<output type="success" caseSensitive="yes" regex="no">All runs complete.</output>
<output type="failure" caseSensitive="yes" regex="no">Failed</output>
</test>
<test id="Test JFR enablement 1">
<command>$EXE$ --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.JFRCMDLineTest</command>
<output type="required" caseSensitive="yes" regex="no">All runs complete</output>
<output type="failure" caseSensitive="yes" regex="no">JFR recording has started</output>
<output type="success" caseSensitive="yes" regex="no">JFR is enabled</output>
</test>
<test id="Test JFR enablement 2">
<command>$EXE$ -XX:+FlightRecorder --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.JFRCMDLineTest</command>
<output type="required" caseSensitive="yes" regex="no">All runs complete</output>
<output type="failure" caseSensitive="yes" regex="no">JFR recording has started</output>
<output type="success" caseSensitive="yes" regex="no">JFR is enabled</output>
</test>
<test id="Test JFR enablement 3">
<command>$EXE$ -XX:-FlightRecorder --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.JFRCMDLineTest</command>
<output type="required" caseSensitive="yes" regex="no">All runs complete</output>
<output type="failure" caseSensitive="yes" regex="no">JFR recording has started</output>
<output type="failure" caseSensitive="yes" regex="no">JFR is enabled</output>
<output type="success" caseSensitive="yes" regex="no">JFR is not enabled</output>
</test>
<test id="Test Start flight recording 1">
<command>$EXE$ -XX:-FlightRecorder -XX:StartFlightRecording --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.JFRCMDLineTest</command>
<output type="required" caseSensitive="yes" regex="no">All runs complete</output>
<output type="failure" caseSensitive="yes" regex="no">JFR recording has started</output>
<output type="failure" caseSensitive="yes" regex="no">JFR is enabled</output>
<output type="success" caseSensitive="yes" regex="no">JFR is not enabled</output>
</test>
<test id="Test Start flight recording 2">
<command>$EXE$ -XX:StartFlightRecording --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.JFRCMDLineTest</command>
<output type="required" caseSensitive="yes" regex="no">All runs complete</output>
<output type="success" caseSensitive="yes" regex="no">JFR recording has started</output>
<output type="success" caseSensitive="yes" regex="no">JFR is enabled</output>
<output type="failure" caseSensitive="yes" regex="no">JFR is not enabled</output>
</test>

</suite>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright IBM Corp. and others 2024
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
* or the Apache License, Version 2.0 which accompanies this distribution and
* is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following
* Secondary Licenses when the conditions for such availability set
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
* General Public License, version 2 with the GNU Classpath
* Exception [1] and GNU General Public License, version 2 with the
* OpenJDK Assembly Exception [2].
*
* [1] https://www.gnu.org/software/classpath/license.html
* [2] https://openjdk.org/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
*/
package org.openj9.test;

import com.ibm.oti.vm.VM;

public class JFRCMDLineTest {

public static void main(String[] args) throws Throwable {

final WorkLoad workLoad = new WorkLoad(200, 20000, 200);

if (VM.isJFRRecordingStarted()) {
System.out.println("JFR recording has started");
} else {
System.out.println("JFR recording has not started");
}

if (VM.isJFREnabled()) {
System.out.println("JFR is enabled");
} else {
System.out.println("JFR is not enabled");
}

System.out.println("All runs complete");
}
}

0 comments on commit f82a1e0

Please sign in to comment.