/*
 * Copyright (c) 2017, 2020, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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.
 */

package jdk.jfr.internal;

import java.util.List;

import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.jfr.Event;
import jdk.jfr.internal.handlers.EventHandler;

Interface against the JVM.
/** * Interface against the JVM. * */
public final class JVM { private static final JVM jvm = new JVM(); // JVM signals file changes by doing Object#notify on this object static final Object FILE_DELTA_CHANGE = new Object(); static final long RESERVED_CLASS_ID_LIMIT = 500; private volatile boolean nativeOK; private static native void registerNatives(); static { registerNatives(); for (LogTag tag : LogTag.values()) { subscribeLogLevel(tag, tag.id); } Options.ensureInitialized(); }
Get the one and only JVM.
Returns:the JVM
/** * Get the one and only JVM. * * @return the JVM */
public static JVM getJVM() { return jvm; } private JVM() { }
Marks current chunk as final

This allows streaming clients to read the chunk header and close the stream when no more data will be written into the current repository.

/** * Marks current chunk as final * <p> * This allows streaming clients to read the chunk header and * close the stream when no more data will be written into * the current repository. */
public native void markChunkFinal();
Begin recording events Requires that JFR has been started with createNativeJFR()
/** * Begin recording events * * Requires that JFR has been started with {@link #createNativeJFR()} */
public native void beginRecording();
Return true if the JVM is recording
/** * Return true if the JVM is recording */
public native boolean isRecording();
End recording events, which includes flushing data in thread buffers Requires that JFR has been started with createNativeJFR()
/** * End recording events, which includes flushing data in thread buffers * * Requires that JFR has been started with {@link #createNativeJFR()} * */
public native void endRecording();
Return ticks
Returns:the time, in ticks
/** * Return ticks * * @return the time, in ticks * */
@HotSpotIntrinsicCandidate public static native long counterTime();
Emits native periodic event.
Params:
  • eventTypeId – type id
  • timestamp – commit time for event
  • when – when it is being done When
Returns:true if the event was committed
/** * Emits native periodic event. * * @param eventTypeId type id * * @param timestamp commit time for event * @param when when it is being done {@link Periodic.When} * * @return true if the event was committed */
public native boolean emitEvent(long eventTypeId, long timestamp, long when);
Return a list of all classes deriving from Event
Returns:list of event classes.
/** * Return a list of all classes deriving from {@link jdk.internal.event.Event} * * @return list of event classes. */
public native List<Class<? extends jdk.internal.event.Event>> getAllEventClasses();
Return a count of the number of unloaded classes deriving from Event
Returns:number of unloaded event classes.
/** * Return a count of the number of unloaded classes deriving from {@link Event} * * @return number of unloaded event classes. */
public native long getUnloadedEventClassCount();
Return a unique identifier for a class. The class is marked as being "in use" in JFR.
Params:
  • clazz – clazz
Returns:a unique class identifier
/** * Return a unique identifier for a class. The class is marked as being * "in use" in JFR. * * @param clazz clazz * * @return a unique class identifier */
@HotSpotIntrinsicCandidate public static native long getClassId(Class<?> clazz); // temporary workaround until we solve intrinsics supporting epoch shift tagging public static native long getClassIdNonIntrinsic(Class<?> clazz);
Return process identifier.
Returns:process identifier
/** * Return process identifier. * * @return process identifier */
public native String getPid();
Return unique identifier for stack trace. Requires that JFR has been started with createNativeJFR()
Params:
  • skipCount – number of frames to skip
Returns:a unique stack trace identifier
/** * Return unique identifier for stack trace. * * Requires that JFR has been started with {@link #createNativeJFR()} * * @param skipCount number of frames to skip * @return a unique stack trace identifier */
public native long getStackTraceId(int skipCount);
Return identifier for thread
Params:
  • t – thread
Returns:a unique thread identifier
/** * Return identifier for thread * * @param t thread * @return a unique thread identifier */
public native long getThreadId(Thread t);
Frequency, ticks per second
Returns:frequency
/** * Frequency, ticks per second * * @return frequency */
public native long getTicksFrequency();
Write message to log. Should swallow null or empty message, and be able to handle any Java character and not crash with very large message
Params:
  • tagSetId – the tagset id
  • level – on level
  • message – log message
/** * Write message to log. Should swallow null or empty message, and be able * to handle any Java character and not crash with very large message * * @param tagSetId the tagset id * @param level on level * @param message log message * */
public static native void log(int tagSetId, int level, String message);
Subscribe to LogLevel updates for LogTag
Params:
  • lt – the log tag to subscribe
  • tagSetId – the tagset id
/** * Subscribe to LogLevel updates for LogTag * * @param lt the log tag to subscribe * @param tagSetId the tagset id */
public static native void subscribeLogLevel(LogTag lt, int tagSetId);
Call to invoke event tagging and retransformation of the passed classes
Params:
  • classes –
Throws:
/** * Call to invoke event tagging and retransformation of the passed classes * * @param classes * * @throws IllegalStateException if wrong JVMTI phase. */
public native synchronized void retransformClasses(Class<?>[] classes);
Enable event
Params:
  • eventTypeId – event type id
  • enabled – enable event
/** * Enable event * * @param eventTypeId event type id * * @param enabled enable event */
public native void setEnabled(long eventTypeId, boolean enabled);
Interval at which the JVM should notify on FILE_DELTA_CHANGE
Params:
  • delta – number of bytes, reset after file rotation
/** * Interval at which the JVM should notify on {@link #FILE_DELTA_CHANGE} * * @param delta number of bytes, reset after file rotation */
public native void setFileNotification(long delta);
Set the number of global buffers to use
Params:
  • count –
Throws:
/** * Set the number of global buffers to use * * @param count * * @throws IllegalArgumentException if count is not within a valid range * @throws IllegalStateException if value can't be changed */
public native void setGlobalBufferCount(long count) throws IllegalArgumentException, IllegalStateException;
Set size of a global buffer
Params:
  • size –
Throws:
/** * Set size of a global buffer * * @param size * * @throws IllegalArgumentException if buffer size is not within a valid * range */
public native void setGlobalBufferSize(long size) throws IllegalArgumentException;
Set overall memory size
Params:
  • size –
Throws:
/** * Set overall memory size * * @param size * * @throws IllegalArgumentException if memory size is not within a valid * range */
public native void setMemorySize(long size) throws IllegalArgumentException;
Set interval for method samples, in milliseconds. Setting interval to 0 turns off the method sampler.
Params:
  • intervalMillis – the sampling interval
/** * Set interval for method samples, in milliseconds. * * Setting interval to 0 turns off the method sampler. * * @param intervalMillis the sampling interval */
public native void setMethodSamplingInterval(long type, long intervalMillis);
Sets the file where data should be written. Requires that JFR has been started with createNativeJFR()
Recording Previous Current Action ============================================== true null null Ignore, keep recording in-memory true null file1 Start disk recording true file null Copy out metadata to disk and continue in-memory recording true file1 file2 Copy out metadata and start with new File (file2) false * null Ignore, but start recording to memory with beginRecording() false * file Ignore, but start recording to disk with beginRecording() 
recording can be set to true/false with beginRecording() endRecording()
Params:
  • file – the file where data should be written, or null if it should not be copied out (in memory).
/** * Sets the file where data should be written. * * Requires that JFR has been started with {@link #createNativeJFR()} * * <pre> * Recording Previous Current Action * ============================================== * true null null Ignore, keep recording in-memory * true null file1 Start disk recording * true file null Copy out metadata to disk and continue in-memory recording * true file1 file2 Copy out metadata and start with new File (file2) * false * null Ignore, but start recording to memory with {@link #beginRecording()} * false * file Ignore, but start recording to disk with {@link #beginRecording()} * * </pre> * * recording can be set to true/false with {@link #beginRecording()} * {@link #endRecording()} * * @param file the file where data should be written, or null if it should * not be copied out (in memory). */
public native void setOutput(String file);
Controls if a class deriving from jdk.jfr.Event should always be instrumented on class load.
@paramforce, true to force initialization, false otherwise
/** * Controls if a class deriving from jdk.jfr.Event should * always be instrumented on class load. * * @param force, true to force initialization, false otherwise */
public native void setForceInstrumentation(boolean force);
Turn on/off thread sampling.
Params:
  • sampleThreads – true if threads should be sampled, false otherwise.
Throws:
/** * Turn on/off thread sampling. * * @param sampleThreads true if threads should be sampled, false otherwise. * * @throws IllegalStateException if state can't be changed. */
public native void setSampleThreads(boolean sampleThreads) throws IllegalStateException;
Turn on/off compressed integers.
Params:
  • compressed – true if compressed integers should be used, false otherwise.
Throws:
/** * Turn on/off compressed integers. * * @param compressed true if compressed integers should be used, false * otherwise. * * @throws IllegalStateException if state can't be changed. */
public native void setCompressedIntegers(boolean compressed) throws IllegalStateException;
Set stack depth.
Params:
  • depth –
Throws:
/** * Set stack depth. * * @param depth * * @throws IllegalArgumentException if not within a valid range * @throws IllegalStateException if depth can't be changed */
public native void setStackDepth(int depth) throws IllegalArgumentException, IllegalStateException;
Turn on stack trace for an event
Params:
  • eventTypeId – the event id
  • enabled – if stack traces should be enabled
/** * Turn on stack trace for an event * * @param eventTypeId the event id * * @param enabled if stack traces should be enabled */
public native void setStackTraceEnabled(long eventTypeId, boolean enabled);
Set thread buffer size.
Params:
  • size –
Throws:
/** * Set thread buffer size. * * @param size * * @throws IllegalArgumentException if size is not within a valid range * @throws IllegalStateException if size can't be changed */
public native void setThreadBufferSize(long size) throws IllegalArgumentException, IllegalStateException;
Set threshold for event, Long.MAXIMUM_VALUE = no limit
Params:
  • eventTypeId – the id of the event type
  • ticks – threshold in ticks,
Returns:true, if it could be set
/** * Set threshold for event, * * Long.MAXIMUM_VALUE = no limit * * @param eventTypeId the id of the event type * @param ticks threshold in ticks, * @return true, if it could be set */
public native boolean setThreshold(long eventTypeId, long ticks);
Store the metadata descriptor that is to be written at the end of a chunk, data should be written after GMT offset and size of metadata event should be adjusted Requires that JFR has been started with createNativeJFR()
Params:
  • bytes – binary representation of metadata descriptor
/** * Store the metadata descriptor that is to be written at the end of a * chunk, data should be written after GMT offset and size of metadata event * should be adjusted * * Requires that JFR has been started with {@link #createNativeJFR()} * * @param bytes binary representation of metadata descriptor */
public native void storeMetadataDescriptor(byte[] bytes);
If the JVM supports JVM TI and retransformation has not been disabled this method will return true. This flag can not change during the lifetime of the JVM.
Returns:if transform is allowed
/** * If the JVM supports JVM TI and retransformation has not been disabled this * method will return true. This flag can not change during the lifetime of * the JVM. * * @return if transform is allowed */
public native boolean getAllowedToDoEventRetransforms();
Set up native resources, data structures, threads etc. for JFR
Params:
  • simulateFailure – simulate a initialization failure and rollback in native, used for testing purposes
Throws:
/** * Set up native resources, data structures, threads etc. for JFR * * @param simulateFailure simulate a initialization failure and rollback in * native, used for testing purposes * * @throws IllegalStateException if native part of JFR could not be created. * */
private native boolean createJFR(boolean simulateFailure) throws IllegalStateException;
Destroys native part of JFR. If already destroy, call is ignored. Requires that JFR has been started with createNativeJFR()
Returns:if an instance was actually destroyed.
/** * Destroys native part of JFR. If already destroy, call is ignored. * * Requires that JFR has been started with {@link #createNativeJFR()} * * @return if an instance was actually destroyed. * */
private native boolean destroyJFR(); public boolean createFailedNativeJFR() throws IllegalStateException { return createJFR(true); } public void createNativeJFR() { nativeOK = createJFR(false); } public boolean destroyNativeJFR() { boolean result = destroyJFR(); nativeOK = !result; return result; } public boolean hasNativeJFR() { return nativeOK; }
Cheap test to check if JFR functionality is available.
Returns:
/** * Cheap test to check if JFR functionality is available. * * @return */
public native boolean isAvailable();
To convert ticks to wall clock time.
/** * To convert ticks to wall clock time. */
public native double getTimeConversionFactor();
Return a unique identifier for a class. Compared to getClassId(Class<?>), this method does not tag the class as being "in-use".
Params:
  • clazz – class
Returns:a unique class identifier
/** * Return a unique identifier for a class. Compared to {@link #getClassId(Class)}, * this method does not tag the class as being "in-use". * * @param clazz class * * @return a unique class identifier */
public native long getTypeId(Class<?> clazz);
Fast path fetching the EventWriter using VM intrinsics
Returns:thread local EventWriter
/** * Fast path fetching the EventWriter using VM intrinsics * * @return thread local EventWriter */
@HotSpotIntrinsicCandidate public static native Object getEventWriter();
Create a new EventWriter
Returns:thread local EventWriter
/** * Create a new EventWriter * * @return thread local EventWriter */
public static native EventWriter newEventWriter();
Flushes the EventWriter for this thread.
/** * Flushes the EventWriter for this thread. */
public static native boolean flush(EventWriter writer, int uncommittedSize, int requestedSize);
Flushes all thread buffers to disk and the constant pool data needed to read them.

When the method returns, the chunk header should be updated with valid pointers to the metadata event, last check point event, correct file size and the generation id.

/** * Flushes all thread buffers to disk and the constant pool data needed to read * them. * <p> * When the method returns, the chunk header should be updated with valid * pointers to the metadata event, last check point event, correct file size and * the generation id. * */
public native void flush();
Sets the location of the disk repository, to be used at an emergency dump.
Params:
  • dirText –
/** * Sets the location of the disk repository, to be used at an emergency * dump. * * @param dirText */
public native void setRepositoryLocation(String dirText);
Access to VM termination support.
Params:
  • errorMsg – descriptive message to be include in VM termination sequence
/** * Access to VM termination support. * * @param errorMsg descriptive message to be include in VM termination sequence */
public native void abort(String errorMsg);
Adds a string to the string constant pool. If the same string is added twice, two entries will be created.
Params:
  • id – identifier associated with the string, not negative
  • s – string constant to be added, not null
Returns:the current epoch of this insertion attempt
/** * Adds a string to the string constant pool. * * If the same string is added twice, two entries will be created. * * @param id identifier associated with the string, not negative * * @param s string constant to be added, not null * * @return the current epoch of this insertion attempt */
public static native boolean addStringConstant(boolean epoch, long id, String s);
Gets the address of the jboolean epoch. The epoch alternates every checkpoint.
Returns:The address of the jboolean.
/** * Gets the address of the jboolean epoch. * * The epoch alternates every checkpoint. * * @return The address of the jboolean. */
public native long getEpochAddress(); public native void uncaughtException(Thread thread, Throwable t);
Sets cutoff for event. Determines how long the event should be allowed to run. Long.MAXIMUM_VALUE = no limit
Params:
  • eventTypeId – the id of the event type
  • cutoffTicks – cutoff in ticks,
Returns:true, if it could be set
/** * Sets cutoff for event. * * Determines how long the event should be allowed to run. * * Long.MAXIMUM_VALUE = no limit * * @param eventTypeId the id of the event type * @param cutoffTicks cutoff in ticks, * @return true, if it could be set */
public native boolean setCutoff(long eventTypeId, long cutoffTicks);
Emit old object sample events.
Params:
  • cutoff – the cutoff in ticks
  • emitAll – emit all samples in old object queue
  • skipBFS – don't use BFS when searching for path to GC root
/** * Emit old object sample events. * * @param cutoff the cutoff in ticks * @param emitAll emit all samples in old object queue * @param skipBFS don't use BFS when searching for path to GC root */
public native void emitOldObjectSamples(long cutoff, boolean emitAll, boolean skipBFS);
Test if a chunk rotation is warranted.
Returns:if it is time to perform a chunk rotation
/** * Test if a chunk rotation is warranted. * * @return if it is time to perform a chunk rotation */
public native boolean shouldRotateDisk();
Exclude a thread from the jfr system
/** * Exclude a thread from the jfr system * */
public native void exclude(Thread thread);
Include a thread back into the jfr system
/** * Include a thread back into the jfr system * */
public native void include(Thread thread);
Test if a thread ius currently excluded from the jfr system.
Returns:is thread currently excluded
/** * Test if a thread ius currently excluded from the jfr system. * * @return is thread currently excluded */
public native boolean isExcluded(Thread thread);
Get the start time in nanos from the header of the current chunk
Returns:start time of the recording in nanos, -1 in case of in-memory
/** * Get the start time in nanos from the header of the current chunk * * @return start time of the recording in nanos, -1 in case of in-memory */
public native long getChunkStartNanos();
Stores an EventHandler to the eventHandler field of an event class.
Params:
  • eventClass – the class, not null
  • handler – the handler, may be null
Returns:if the field could be set
/** * Stores an EventHandler to the eventHandler field of an event class. * * @param eventClass the class, not {@code null} * * @param handler the handler, may be {@code null} * * @return if the field could be set */
public native boolean setHandler(Class<? extends jdk.internal.event.Event> eventClass, EventHandler handler);
Retrieves the EventHandler for an event class.
Params:
  • eventClass – the class, not null
Returns:the handler, may be null
/** * Retrieves the EventHandler for an event class. * * @param eventClass the class, not {@code null} * * @return the handler, may be {@code null} */
public native Object getHandler(Class<? extends jdk.internal.event.Event> eventClass);
Returns the id for the Java types defined in metadata.xml.
Params:
  • name – the name of the type
Returns:the id, or a negative value if it does not exists.
/** * Returns the id for the Java types defined in metadata.xml. * * @param name the name of the type * * @return the id, or a negative value if it does not exists. */
public native long getTypeId(String name); }