test/jdk/jdk/jfr/event/io/TestInstrumentation.java
author goetz
Fri, 20 Jul 2018 09:46:57 +0200
changeset 51214 67736b4846a0
parent 50113 caf115bb98ad
child 52515 746df0ae4fe1
permissions -rw-r--r--
8207830: [aix] disable jfr in build and tests Reviewed-by: kvn, erikj
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     1
/*
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     2
 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     4
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    10
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    15
 * accompanied this code).
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    16
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    20
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    23
 * questions.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    24
 */
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    25
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    26
package jdk.jfr.event.io;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    27
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    28
import java.util.Arrays;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    29
import java.util.Set;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    30
import java.util.HashSet;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    31
import java.io.File;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    32
import java.security.ProtectionDomain;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    33
import java.lang.instrument.ClassFileTransformer;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    34
import java.lang.instrument.Instrumentation;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    35
import java.lang.instrument.IllegalClassFormatException;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    36
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    37
import jdk.internal.org.objectweb.asm.ClassReader;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    38
import jdk.internal.org.objectweb.asm.ClassVisitor;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    39
import jdk.internal.org.objectweb.asm.MethodVisitor;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    40
import jdk.internal.org.objectweb.asm.ClassWriter;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    41
import jdk.internal.org.objectweb.asm.Opcodes;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    42
import jdk.internal.org.objectweb.asm.Type;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    43
import jdk.test.lib.process.OutputAnalyzer;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    44
import jdk.test.lib.process.ProcessTools;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    45
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    46
/*
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    47
 * @test
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    48
 * @summary Test that will instrument the same classes that JFR will also instrument.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    49
 * @key jfr
51214
67736b4846a0 8207830: [aix] disable jfr in build and tests
goetz
parents: 50113
diff changeset
    50
 * @requires vm.hasJFR
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    51
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    52
 * @library /test/lib /test/jdk
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    53
 * @modules java.base/jdk.internal.org.objectweb.asm
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    54
 *          java.instrument
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    55
 *          jdk.jartool/sun.tools.jar
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    56
 *          jdk.jfr
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    57
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    58
 * @run main/othervm jdk.jfr.event.io.TestInstrumentation
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    59
 */
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    60
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    61
// Test that will instrument the same classes that JFR will also instrument.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    62
//
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    63
// The methods that will be instrumented, for example java.io.RandomAccessFile.write,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    64
// will add the following code at the start of the method:
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    65
// InstrumentationCallback.callback("<classname>::<methodname>");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    66
//
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    67
// The class InstrumentationCallback will log all keys added by the callback() function.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    68
//
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    69
// With this instrumentation in place, we will run some existing jfr.io tests
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    70
// to verify that our instrumentation has not broken the JFR instrumentation.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    71
//
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    72
// After the tests have been run, we verify that the callback() function have been
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    73
// called from all instrumented classes and methods. This will verify that JFR has not
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    74
// broken our instrumentation.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    75
//
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    76
// To use instrumentation, the test must be run in a new java process with
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    77
// the -javaagent option.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    78
// We must also create two jars:
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    79
// TestInstrumentation.jar: The javaagent for the instrumentation.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    80
// InstrumentationCallback.jar: This is a separate jar with the instrumentation
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    81
// callback() function. It is in a separate jar because it must be added to
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    82
// the bootclasspath to be called from java.io classes.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    83
//
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    84
// The test contains 3 parts:
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    85
// Setup part that will create jars and launch the new test instance.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    86
// Agent part that contains the instrumentation code.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    87
// The actual test part is in the TestMain class.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    88
//
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    89
public class TestInstrumentation implements ClassFileTransformer {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    90
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    91
    private static Instrumentation instrumentation = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    92
    private static TestInstrumentation testTransformer = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    93
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    94
    // All methods that will be instrumented.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    95
    private static final String[] instrMethodKeys = {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    96
        "java/io/RandomAccessFile::seek::(J)V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    97
        "java/io/RandomAccessFile::read::()I",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    98
        "java/io/RandomAccessFile::read::([B)I",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    99
        "java/io/RandomAccessFile::write::([B)V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   100
        "java/io/RandomAccessFile::write::(I)V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   101
        "java/io/RandomAccessFile::close::()V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   102
        "java/io/FileInputStream::read::([BII)I",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   103
        "java/io/FileInputStream::read::([B)I",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   104
        "java/io/FileInputStream::read::()I",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   105
        "java/io/FileOutputStream::write::(I)V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   106
        "java/io/FileOutputStream::write::([B)V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   107
        "java/io/FileOutputStream::write::([BII)V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   108
        "java/net/SocketInputStream::read::()I",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   109
        "java/net/SocketInputStream::read::([B)I",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   110
        "java/net/SocketInputStream::read::([BII)I",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   111
        "java/net/SocketInputStream::close::()V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   112
        "java/net/SocketOutputStream::write::(I)V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   113
        "java/net/SocketOutputStream::write::([B)V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   114
        "java/net/SocketOutputStream::write::([BII)V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   115
        "java/net/SocketOutputStream::close::()V",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   116
        "java/nio/channels/FileChannel::read::([Ljava/nio/ByteBuffer;)J",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   117
        "java/nio/channels/FileChannel::write::([Ljava/nio/ByteBuffer;)J",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   118
        "java/nio/channels/SocketChannel::open::()Ljava/nio/channels/SocketChannel;",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   119
        "java/nio/channels/SocketChannel::open::(Ljava/net/SocketAddress;)Ljava/nio/channels/SocketChannel;",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   120
        "java/nio/channels/SocketChannel::read::([Ljava/nio/ByteBuffer;)J",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   121
        "java/nio/channels/SocketChannel::write::([Ljava/nio/ByteBuffer;)J",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   122
        "sun/nio/ch/FileChannelImpl::read::(Ljava/nio/ByteBuffer;)I",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   123
        "sun/nio/ch/FileChannelImpl::write::(Ljava/nio/ByteBuffer;)I",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   124
    };
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   125
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   126
    private static String getInstrMethodKey(String className, String methodName, String signature) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   127
        // This key is used to identify a class and method. It is sent to callback(key)
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   128
        return className + "::" + methodName + "::" + signature;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   129
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   130
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   131
    private static String getClassFromMethodKey(String methodKey) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   132
        return methodKey.split("::")[0];
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   133
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   134
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   135
    // Set of all classes targeted for instrumentation.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   136
    private static Set<String> instrClassesTarget = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   137
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   138
    // Set of all classes where instrumentation has been completed.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   139
    private static Set<String> instrClassesDone = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   140
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   141
    static {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   142
        // Split class names from InstrMethodKeys.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   143
        instrClassesTarget = new HashSet<String>();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   144
        instrClassesDone = new HashSet<String>();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   145
        for (String s : instrMethodKeys) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   146
            String className = getClassFromMethodKey(s);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   147
            instrClassesTarget.add(className);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   148
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   149
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   150
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   151
    private static void log(String msg) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   152
        System.out.println("TestTransformation: " + msg);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   153
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   154
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   155
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   156
    ////////////////////////////////////////////////////////////////////
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   157
    // This is the actual test part.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   158
    // A batch of jfr io tests will be run twice with a
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   159
    // retransfromClasses() in between. After each test batch we verify
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   160
    // that all callbacks have been called.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   161
    ////////////////////////////////////////////////////////////////////
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   162
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   163
    public static class TestMain {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   164
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   165
        private enum TransformStatus { Transformed, Retransformed, Removed }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   166
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   167
        public static void main(String[] args) throws Throwable {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   168
            runAllTests(TransformStatus.Transformed);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   169
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   170
            // Retransform all classes and then repeat tests
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   171
            Set<Class<?>> classes = new HashSet<Class<?>>();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   172
            for (String className : instrClassesTarget) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   173
                Class<?> clazz = Class.forName(className.replaceAll("/", "."));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   174
                classes.add(clazz);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   175
                log("Will retransform " + clazz.getName());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   176
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   177
            instrumentation.retransformClasses(classes.toArray(new Class<?>[0]));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   178
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   179
            // Clear all callback keys so we don't read keys from the previous test run.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   180
            InstrumentationCallback.clear();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   181
            runAllTests(TransformStatus.Retransformed);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   182
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   183
            // Remove my test transformer and run tests again. Should not get any callbacks.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   184
            instrumentation.removeTransformer(testTransformer);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   185
            instrumentation.retransformClasses(classes.toArray(new Class<?>[0]));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   186
            InstrumentationCallback.clear();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   187
            runAllTests(TransformStatus.Removed);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   188
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   189
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   190
        // This is not all available jfr io tests, but a reasonable selection.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   191
        public static void runAllTests(TransformStatus status) throws Throwable {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   192
            log("runAllTests, TransformStatus: " + status);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   193
            try {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   194
                String[] noArgs = new String[0];
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   195
                TestRandomAccessFileEvents.main(noArgs);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   196
                TestSocketEvents.main(noArgs);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   197
                TestSocketChannelEvents.main(noArgs);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   198
                TestFileChannelEvents.main(noArgs);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   199
                TestFileStreamEvents.main(noArgs);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   200
                TestDisabledEvents.main(noArgs);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   201
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   202
                // Verify that all expected callbacks have been called.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   203
                Set<String> callbackKeys = InstrumentationCallback.getKeysCopy();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   204
                for (String key : instrMethodKeys) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   205
                    boolean gotCallback = callbackKeys.contains(key);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   206
                    boolean expectsCallback = isClassInstrumented(status, key);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   207
                    String msg = String.format("key:%s, expects:%b", key, expectsCallback);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   208
                    if (gotCallback != expectsCallback) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   209
                        throw new Exception("Wrong callback() for " + msg);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   210
                    } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   211
                        log("Correct callback() for " + msg);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   212
                    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   213
                }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   214
            } catch (Throwable t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   215
                log("Test failed in phase " + status);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   216
                t.printStackTrace();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   217
                throw t;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   218
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   219
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   220
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   221
        private static boolean isClassInstrumented(TransformStatus status, String key) throws Throwable {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   222
            switch (status) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   223
            case Retransformed:
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   224
                return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   225
            case Removed:
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   226
                return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   227
            case Transformed:
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   228
                String className = getClassFromMethodKey(key);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   229
                return instrClassesDone.contains(className);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   230
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   231
            throw new Exception("Test error: Unknown TransformStatus: " + status);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   232
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   233
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   234
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   235
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   236
    ////////////////////////////////////////////////////////////////////
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   237
    // This is the setup part. It will create needed jars and
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   238
    // launch a new java instance that will run the internal class TestMain.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   239
    // This setup step is needed because we must use a javaagent jar to
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   240
    // transform classes.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   241
    ////////////////////////////////////////////////////////////////////
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   242
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   243
    public static void main(String[] args) throws Throwable {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   244
        buildJar("TestInstrumentation", true);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   245
        buildJar("InstrumentationCallback", false);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   246
        launchTest();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   247
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   248
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   249
    private static void buildJar(String jarName, boolean withManifest) throws Throwable {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   250
        final String slash = File.separator;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   251
        final String packageName = "jdk/jfr/event/io".replace("/", slash);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   252
        System.out.println("buildJar packageName: " + packageName);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   253
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   254
        String testClasses = System.getProperty("test.classes", "?");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   255
        String testSrc = System.getProperty("test.src", "?");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   256
        String jarPath = testClasses + slash + jarName + ".jar";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   257
        String manifestPath = testSrc + slash + jarName + ".mf";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   258
        String className = packageName + slash + jarName + ".class";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   259
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   260
        String[] args = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   261
        if (withManifest) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   262
            args = new String[] {"-cfm", jarPath, manifestPath, "-C", testClasses, className};
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   263
        } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   264
            args = new String[] {"-cf", jarPath, "-C", testClasses, className};
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   265
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   266
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   267
        log("Running jar " + Arrays.toString(args));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   268
        sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   269
        if (!jarTool.run(args)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   270
            throw new Exception("jar failed: args=" + Arrays.toString(args));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   271
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   272
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   273
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   274
    // Launch the test instance. Will run the internal class TestMain.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   275
    private static void launchTest() throws Throwable {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   276
        final String slash = File.separator;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   277
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   278
        // Need to add jdk/lib/tools.jar to classpath.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   279
        String classpath =
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   280
            System.getProperty("test.class.path", "") + File.pathSeparator +
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   281
            System.getProperty("test.jdk", ".") + slash + "lib" + slash + "tools.jar";
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   282
        String testClassDir = System.getProperty("test.classes", "") + slash;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   283
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   284
        String[] args = {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   285
            "-Xbootclasspath/a:" + testClassDir + "InstrumentationCallback.jar",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   286
            "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   287
            "-classpath", classpath,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   288
            "-javaagent:" + testClassDir + "TestInstrumentation.jar",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   289
            "jdk.jfr.event.io.TestInstrumentation$TestMain" };
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   290
        OutputAnalyzer output = ProcessTools.executeTestJvm(args);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   291
        output.shouldHaveExitValue(0);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   292
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   293
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   294
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   295
    ////////////////////////////////////////////////////////////////////
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   296
    // This is the java agent part. Used to transform classes.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   297
    //
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   298
    // Each transformed method will add this call:
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   299
    // InstrumentationCallback.callback("<classname>::<methodname>");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   300
    ////////////////////////////////////////////////////////////////////
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   301
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   302
    public static void premain(String args, Instrumentation inst) throws Exception {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   303
        instrumentation = inst;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   304
        testTransformer = new TestInstrumentation();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   305
        inst.addTransformer(testTransformer, true);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   306
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   307
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   308
    public byte[] transform(
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   309
            ClassLoader classLoader, String className, Class<?> classBeingRedefined,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   310
            ProtectionDomain pd, byte[] bytes) throws IllegalClassFormatException {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   311
        // Check if this class should be instrumented.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   312
        if (!instrClassesTarget.contains(className)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   313
            return null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   314
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   315
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   316
        boolean isRedefinition = classBeingRedefined != null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   317
        log("instrument class(" + className + ") " + (isRedefinition ? "redef" : "load"));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   318
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   319
        ClassReader reader = new ClassReader(bytes);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   320
        ClassWriter writer = new ClassWriter(
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   321
                reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   322
        CallbackClassVisitor classVisitor = new CallbackClassVisitor(writer);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   323
        reader.accept(classVisitor, 0);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   324
        instrClassesDone.add(className);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   325
        return writer.toByteArray();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   326
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   327
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   328
    private static class CallbackClassVisitor extends ClassVisitor {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   329
        private String className;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   330
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   331
        public CallbackClassVisitor(ClassVisitor cv) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   332
            super(Opcodes.ASM5, cv);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   333
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   334
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   335
        @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   336
        public void visit(
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   337
                int version, int access, String name, String signature,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   338
                String superName, String[] interfaces) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   339
            cv.visit(version, access, name, signature, superName, interfaces);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   340
            className = name;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   341
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   342
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   343
        @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   344
        public MethodVisitor visitMethod(
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   345
                int access, String methodName, String desc, String signature, String[] exceptions) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   346
            String methodKey = getInstrMethodKey(className, methodName, desc);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   347
            boolean isInstrumentedMethod = Arrays.asList(instrMethodKeys).contains(methodKey);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   348
            MethodVisitor mv = cv.visitMethod(access, methodName, desc, signature, exceptions);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   349
            if (isInstrumentedMethod && mv != null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   350
                mv = new CallbackMethodVisitor(mv, methodKey);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   351
                log("instrumented " + methodKey);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   352
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   353
            return mv;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   354
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   355
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   356
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   357
    public static class CallbackMethodVisitor extends MethodVisitor {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   358
        private String logMessage;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   359
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   360
        public CallbackMethodVisitor(MethodVisitor mv, String logMessage) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   361
            super(Opcodes.ASM5, mv);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   362
            this.logMessage = logMessage;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   363
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   364
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   365
        @Override
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   366
        public void visitCode() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   367
            mv.visitCode();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   368
            String methodDescr = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   369
            String className = InstrumentationCallback.class.getName().replace('.', '/');
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   370
            mv.visitLdcInsn(logMessage);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   371
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, className, "callback", methodDescr);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   372
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   373
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   374
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   375
}