--- /dev/null 2018-06-17 23:18:20.806999507 +0800 +++ new/src/share/classes/jdk/jfr/internal/JVM.java 2019-01-29 10:59:30.777816285 +0800 @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2017, 2019, 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.io.IOException; +import java.util.List; + +import jdk.jfr.Event; + +/** + * Interface against the JVM. + * + */ +public final class JVM { + private static final JVM jvm = new JVM(); + + // JVM signals file changes by doing Object#notifu on this object + static final Object FILE_DELTA_CHANGE = new Object(); + + static final long RESERVED_CLASS_ID_LIMIT = 400; + + private volatile boolean recording; + 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. + * + * @return the JVM + */ + public static JVM getJVM() { + return jvm; + } + + private JVM() { + } + + /** + * Begin recording events + * + * Requires that JFR has been started with {@link #createNativeJFR()} + */ + public native void beginRecording(); + + /** + * Return ticks + * + * @return the time, in ticks + * + */ + public static native long counterTime(); + + + /** + * 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); + + /** + * End recording events, which includes flushing data in thread buffers + * + * Requires that JFR has been started with {@link #createNativeJFR()} + * + */ + public native void endRecording(); + + /** + * Return a list of all classes deriving from {@link Event} + * + * @return list of event classes. + */ + public native List> getAllEventClasses(); + + /** + * 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. + * + * @param clazz clazz + * + * @return a unique class identifier + */ + 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. + * + * @return process identifier + */ + public native String getPid(); + + /** + * 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 + * + * @param t thread + * @return a unique thread identifier + */ + public native long getThreadId(Thread t); + + /** + * 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 + * + * @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 + * + * @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 + * + * @param classes + */ + public native synchronized void retransformClasses(Class[] classes); + + /** + * 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 {@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 + * + * @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 + * + * @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 + * + * @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. + * + * @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 {@link #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 {@link #beginRecording()}
+     *    false     *        file     Ignore, but start recording to disk with {@link #beginRecording()}
+     *
+     * 
+ * + * 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). + * + * @throws IOException + */ + public native void setOutput(String file); + + /** + * 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. + * + * @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. + * + * @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. + * + * @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 + * + * @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. + * + * @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 + * + * @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 {@link #createNativeJFR()} + * + * @param bytes binary representation of metadata descriptor + * + * @param binary representation of descriptor + */ + public native void storeMetadataDescriptor(byte[] bytes); + + public void endRecording_() { + endRecording(); + recording = false; + } + + public void beginRecording_() { + beginRecording(); + recording = true; + } + + public boolean isRecording() { + return recording; + } + + /** + * 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 + * + * @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, + * for instance if commercial features are not enabled. + * + */ + 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 {@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. + * + * @return + */ + public native boolean isAvailable(); + + /** + * To convert ticks to wall clock time. + */ + public native double getTimeConversionFactor(); + + /** + * Return a unique identifier for a class. Compared to {@link #getClassId()} + * , 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 + * + * @return thread local EventWriter + */ + public static native Object getEventWriter(); + + /** + * Create a new EventWriter + * + * @return thread local EventWriter + */ + public static native EventWriter newEventWriter(); + + /** + * Flushes the EventWriter for this thread. + */ + public static native boolean flush(EventWriter writer, int uncommittedSize, int requestedSize); + + /** + * 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. + * + *@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. + * + * @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. + * + * @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 + * + * @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. + * + * @param cutoff the cutoff in ticks + * @param emitAll emit all samples in old object queue + */ + public native void emitOldObjectSamples(long cutoff, boolean emitAll); +}