feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2012, 2018, 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.instrument;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
final class ConstructorTracerWriter extends ClassVisitor {
private ConstructorWriter useInputParameter, noUseInputParameter;
static byte[] generateBytes(Class<?> clz, byte[] oldBytes) throws IOException {
InputStream in = new ByteArrayInputStream(oldBytes);
ClassReader cr = new ClassReader(in);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ConstructorTracerWriter ctw = new ConstructorTracerWriter(cw, clz);
cr.accept(ctw, 0);
return cw.toByteArray();
}
private ConstructorTracerWriter(ClassVisitor cv, Class<?> classToChange) {
super(Opcodes.ASM5, cv);
useInputParameter = new ConstructorWriter(classToChange, true);
noUseInputParameter = new ConstructorWriter(classToChange, false);
}
private boolean isConstructor(String name) {
return name.equals("<init>");
}
private boolean takesStringParameter(String desc) {
Type[] types = Type.getArgumentTypes(desc);
if (types.length > 0 && types[0].getClassName().equals(String.class.getName())) {
return true;
}
return false;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
// Get a hold of the constructors that takes a String as a parameter
if (isConstructor(name)) {
if (takesStringParameter(desc)) {
useInputParameter.setMethodVisitor(mv);
return useInputParameter;
}
noUseInputParameter.setMethodVisitor(mv);
return noUseInputParameter;
}
return mv;
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) 2012, 2018, 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.instrument;
import static jdk.internal.org.objectweb.asm.Opcodes.ACONST_NULL;
import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
final class ConstructorWriter extends MethodVisitor {
private boolean useInputParameter;
private String shortClassName;
private String fullClassName;
ConstructorWriter(Class<?> classToChange, boolean useInputParameter) {
super(Opcodes.ASM5);
this.useInputParameter = useInputParameter;
shortClassName = classToChange.getSimpleName();
fullClassName = classToChange.getName().replace('.', '/');
}
@Override
public void visitInsn(int opcode)
{
if (opcode == RETURN) {
if (useInputParameter) {
useInput();
} else {
noInput();
}
}
mv.visitInsn(opcode);
}
@SuppressWarnings("deprecation")
private void useInput()
{
//Load 'this' from local variable 0
//Load first input parameter
//Invoke ThrowableTracer.traceCLASS(this, parameter) for current class
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESTATIC, "jdk/jfr/internal/instrument/ThrowableTracer",
"trace" + shortClassName, "(L" + fullClassName +
";Ljava/lang/String;)V");
}
@SuppressWarnings("deprecation")
private void noInput()
{
//Load 'this' from local variable 0
//Load ""
//Invoke ThrowableTracer.traceCLASS(this, "") for current class
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(ACONST_NULL);
mv.visitMethodInsn(INVOKESTATIC, "jdk/jfr/internal/instrument/ThrowableTracer",
"trace" + shortClassName, "(L" + fullClassName +
";Ljava/lang/String;)V");
}
public void setMethodVisitor(MethodVisitor mv) {
this.mv = mv;
}
}

View File

@@ -0,0 +1,197 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.io.IOException;
import java.nio.ByteBuffer;
import jdk.jfr.events.FileForceEvent;
import jdk.jfr.events.FileReadEvent;
import jdk.jfr.events.FileWriteEvent;
/**
* See {@link JITracer} for an explanation of this code.
*/
@JIInstrumentationTarget("sun.nio.ch.FileChannelImpl")
final class FileChannelImplInstrumentor {
private FileChannelImplInstrumentor() {
}
private String path;
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public void force(boolean metaData) throws IOException {
FileForceEvent event = FileForceEvent.EVENT.get();
if (!event.isEnabled()) {
force(metaData);
return;
}
try {
event.begin();
force(metaData);
} finally {
event.path = path;
event.metaData = metaData;
event.commit();
event.reset();
}
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int read(ByteBuffer dst) throws IOException {
FileReadEvent event = FileReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read(dst);
}
int bytesRead = 0;
try {
event.begin();
bytesRead = read(dst);
} finally {
if (bytesRead < 0) {
event.endOfFile = true;
} else {
event.bytesRead = bytesRead;
}
event.path = path;
event.commit();
event.reset();
}
return bytesRead;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int read(ByteBuffer dst, long position) throws IOException {
FileReadEvent event = FileReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read(dst, position);
}
int bytesRead = 0;
try {
event.begin();
bytesRead = read(dst, position);
} finally {
if (bytesRead < 0) {
event.endOfFile = true;
} else {
event.bytesRead = bytesRead;
}
event.path = path;
event.commit();
event.reset();
}
return bytesRead;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
FileReadEvent event = FileReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read(dsts, offset, length);
}
long bytesRead = 0;
try {
event.begin();
bytesRead = read(dsts, offset, length);
} finally {
if (bytesRead < 0) {
event.endOfFile = true;
} else {
event.bytesRead = bytesRead;
}
event.path = path;
event.commit();
event.reset();
}
return bytesRead;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int write(ByteBuffer src) throws IOException {
FileWriteEvent event = FileWriteEvent.EVENT.get();
if (!event.isEnabled()) {
return write(src);
}
int bytesWritten = 0;
try {
event.begin();
bytesWritten = write(src);
} finally {
event.bytesWritten = bytesWritten > 0 ? bytesWritten : 0;
event.path = path;
event.commit();
event.reset();
}
return bytesWritten;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int write(ByteBuffer src, long position) throws IOException {
FileWriteEvent event = FileWriteEvent.EVENT.get();
if (!event.isEnabled()) {
return write(src, position);
}
int bytesWritten = 0;
try {
event.begin();
bytesWritten = write(src, position);
} finally {
event.bytesWritten = bytesWritten > 0 ? bytesWritten : 0;
event.path = path;
event.commit();
event.reset();
}
return bytesWritten;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
FileWriteEvent event = FileWriteEvent.EVENT.get();
if (!event.isEnabled()) {
return write(srcs, offset, length);
}
long bytesWritten = 0;
try {
event.begin();
bytesWritten = write(srcs, offset, length);
} finally {
event.bytesWritten = bytesWritten > 0 ? bytesWritten : 0;
event.path = path;
event.commit();
event.reset();
}
return bytesWritten;
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.io.IOException;
import jdk.jfr.events.FileReadEvent;
/**
* See {@link JITracer} for an explanation of this code.
*/
@JIInstrumentationTarget("java.io.FileInputStream")
final class FileInputStreamInstrumentor {
private FileInputStreamInstrumentor() {
}
private String path;
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int read() throws IOException {
FileReadEvent event = FileReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read();
}
int result = 0;
try {
event.begin();
result = read();
if (result < 0) {
event.endOfFile = true;
} else {
event.bytesRead = 1;
}
} finally {
event.path = path;
event.commit();
event.reset();
}
return result;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int read(byte b[]) throws IOException {
FileReadEvent event = FileReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read(b);
}
int bytesRead = 0;
try {
event.begin();
bytesRead = read(b);
} finally {
if (bytesRead < 0) {
event.endOfFile = true;
} else {
event.bytesRead = bytesRead;
}
event.path = path;
event.commit();
event.reset();
}
return bytesRead;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int read(byte b[], int off, int len) throws IOException {
FileReadEvent event = FileReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read(b, off, len);
}
int bytesRead = 0;
try {
event.begin();
bytesRead = read(b, off, len);
} finally {
if (bytesRead < 0) {
event.endOfFile = true;
} else {
event.bytesRead = bytesRead;
}
event.path = path;
event.commit();
event.reset();
}
return bytesRead;
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.io.IOException;
import jdk.jfr.events.FileWriteEvent;
/**
* See {@link JITracer} for an explanation of this code.
*/
@JIInstrumentationTarget("java.io.FileOutputStream")
final class FileOutputStreamInstrumentor {
private FileOutputStreamInstrumentor() {
}
private String path;
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public void write(int b) throws IOException {
FileWriteEvent event = FileWriteEvent.EVENT.get();
if (!event.isEnabled()) {
write(b);
return;
}
try {
event.begin();
write(b);
event.bytesWritten = 1;
} finally {
event.path = path;
event.commit();
event.reset();
}
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public void write(byte b[]) throws IOException {
FileWriteEvent event = FileWriteEvent.EVENT.get();
if (!event.isEnabled()) {
write(b);
return;
}
try {
event.begin();
write(b);
event.bytesWritten = b.length;
} finally {
event.path = path;
event.commit();
event.reset();
}
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public void write(byte b[], int off, int len) throws IOException {
FileWriteEvent event = FileWriteEvent.EVENT.get();
if (!event.isEnabled()) {
write(b, off, len);
return;
}
try {
event.begin();
write(b, off, len);
event.bytesWritten = len;
} finally {
event.path = path;
event.commit();
event.reset();
}
}
}

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) 2016, 2018, 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.instrument;
import java.util.ArrayList;
import java.util.List;
import jdk.jfr.Event;
import jdk.jfr.events.ActiveRecordingEvent;
import jdk.jfr.events.ActiveSettingEvent;
import jdk.jfr.events.ErrorThrownEvent;
import jdk.jfr.events.ExceptionStatisticsEvent;
import jdk.jfr.events.ExceptionThrownEvent;
import jdk.jfr.events.FileForceEvent;
import jdk.jfr.events.FileReadEvent;
import jdk.jfr.events.FileWriteEvent;
import jdk.jfr.events.SocketReadEvent;
import jdk.jfr.events.SocketWriteEvent;
import jdk.jfr.internal.JVM;
import jdk.jfr.internal.LogLevel;
import jdk.jfr.internal.LogTag;
import jdk.jfr.internal.Logger;
import jdk.jfr.internal.RequestEngine;
import jdk.jfr.internal.SecuritySupport;
public final class JDKEvents {
private static final Class<?>[] eventClasses = {
FileForceEvent.class,
FileReadEvent.class,
FileWriteEvent.class,
SocketReadEvent.class,
SocketWriteEvent.class,
ExceptionThrownEvent.class,
ExceptionStatisticsEvent.class,
ErrorThrownEvent.class,
ActiveSettingEvent.class,
ActiveRecordingEvent.class
};
// This is a list of the classes with instrumentation code that should be applied.
private static final Class<?>[] instrumentationClasses = new Class<?>[] {
FileInputStreamInstrumentor.class,
FileOutputStreamInstrumentor.class,
RandomAccessFileInstrumentor.class,
FileChannelImplInstrumentor.class,
SocketInputStreamInstrumentor.class,
SocketOutputStreamInstrumentor.class,
SocketChannelImplInstrumentor.class
};
private static final Class<?>[] targetClasses = new Class<?>[instrumentationClasses.length];
private static final JVM jvm = JVM.getJVM();
private static final Runnable emitExceptionStatistics = JDKEvents::emitExceptionStatistics;
private static boolean initializationTriggered;
@SuppressWarnings("unchecked")
public synchronized static void initialize() {
try {
if (initializationTriggered == false) {
for (Class<?> eventClass : eventClasses) {
SecuritySupport.registerEvent((Class<? extends Event>) eventClass);
}
initializationTriggered = true;
RequestEngine.addTrustedJDKHook(ExceptionStatisticsEvent.class, emitExceptionStatistics);
}
} catch (Exception e) {
Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Could not initialize JDK events. " + e.getMessage());
}
}
public static void addInstrumentation() {
try {
List<Class<?>> list = new ArrayList<>();
for (int i = 0; i < instrumentationClasses.length; i++) {
JIInstrumentationTarget tgt = instrumentationClasses[i].getAnnotation(JIInstrumentationTarget.class);
Class<?> clazz = Class.forName(tgt.value());
targetClasses[i] = clazz;
list.add(clazz);
}
list.add(java.lang.Throwable.class);
list.add(java.lang.Error.class);
Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Retransformed JDK classes");
jvm.retransformClasses(list.toArray(new Class<?>[list.size()]));
} catch (Exception e) {
Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Could not add instrumentation for JDK events. " + e.getMessage());
}
}
private static void emitExceptionStatistics() {
ExceptionStatisticsEvent t = new ExceptionStatisticsEvent();
t.throwables = ThrowableTracer.numThrowables();
t.commit();
}
@SuppressWarnings("deprecation")
public static byte[] retransformCallback(Class<?> klass, byte[] oldBytes) throws Throwable {
if (java.lang.Throwable.class == klass) {
Logger.log(LogTag.JFR_SYSTEM, LogLevel.TRACE, "Instrumenting java.lang.Throwable");
return ConstructorTracerWriter.generateBytes(java.lang.Throwable.class, oldBytes);
}
if (java.lang.Error.class == klass) {
Logger.log(LogTag.JFR_SYSTEM, LogLevel.TRACE, "Instrumenting java.lang.Error");
return ConstructorTracerWriter.generateBytes(java.lang.Error.class, oldBytes);
}
for (int i = 0; i < targetClasses.length; i++) {
if (targetClasses[i].equals(klass)) {
Class<?> c = instrumentationClasses[i];
Logger.log(LogTag.JFR_SYSTEM, LogLevel.TRACE, () -> "Processing instrumentation class: " + c);
return new JIClassInstrumentation(instrumentationClasses[i], klass, oldBytes).getNewBytes();
}
}
return oldBytes;
}
public static void remove() {
RequestEngine.removeHook(JDKEvents::emitExceptionStatistics);
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.tree.ClassNode;
import jdk.jfr.internal.SecuritySupport;
import jdk.jfr.internal.Utils;
/**
* This class will perform byte code instrumentation given an "instrumentor" class.
*
* @see JITracer
*
* @author Staffan Larsen
*/
@Deprecated
final class JIClassInstrumentation {
private final Class<?> instrumentor;
private final String targetName;
private final String instrumentorName;
private final byte[] newBytes;
private final ClassReader targetClassReader;
private final ClassReader instrClassReader;
/**
* Creates an instance and performs the instrumentation.
*
* @param instrumentor instrumentor class
* @param target target class
* @param old_target_bytes bytes in target
*
* @throws ClassNotFoundException
* @throws IOException
*/
JIClassInstrumentation(Class<?> instrumentor, Class<?> target, byte[] old_target_bytes) throws ClassNotFoundException, IOException {
instrumentorName = instrumentor.getName();
this.targetName = target.getName();
this.instrumentor = instrumentor;
this.targetClassReader = new ClassReader(old_target_bytes);
this.instrClassReader = new ClassReader(getOriginalClassBytes(instrumentor));
this.newBytes = makeBytecode();
Utils.writeGeneratedASM(target.getName(), newBytes);
}
private static byte[] getOriginalClassBytes(Class<?> clazz) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String name = "/" + clazz.getName().replace(".", "/") + ".class";
InputStream is = SecuritySupport.getResourceAsStream(name);
int bytesRead;
byte[] buffer = new byte[16384];
while ((bytesRead = is.read(buffer, 0, buffer.length)) != -1) {
baos.write(buffer, 0, bytesRead);
}
baos.flush();
is.close();
return baos.toByteArray();
}
private byte[] makeBytecode() throws IOException, ClassNotFoundException {
// Find the methods to instrument and inline
final List<Method> instrumentationMethods = new ArrayList<>();
for (final Method m : instrumentor.getDeclaredMethods()) {
JIInstrumentationMethod im = m.getAnnotation(JIInstrumentationMethod.class);
if (im != null) {
instrumentationMethods.add(m);
}
}
// We begin by inlining the target's methods into the instrumentor
ClassNode temporary = new ClassNode();
ClassVisitor inliner = new JIInliner(
Opcodes.ASM5,
temporary,
targetName,
instrumentorName,
targetClassReader,
instrumentationMethods);
instrClassReader.accept(inliner, ClassReader.EXPAND_FRAMES);
// Now we have the target's methods inlined into the instrumentation code (in 'temporary').
// We now need to replace the target's method with the code in the
// instrumentation method.
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
JIMethodMergeAdapter ma = new JIMethodMergeAdapter(
cw,
temporary,
instrumentationMethods,
instrumentor.getAnnotationsByType(JITypeMapping.class));
targetClassReader.accept(ma, ClassReader.EXPAND_FRAMES);
return cw.toByteArray();
}
/**
* Get the instrumented byte codes that can be used to retransform the class.
*
* @return bytes
*/
public byte[] getNewBytes() {
return newBytes.clone();
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.tree.ClassNode;
import jdk.internal.org.objectweb.asm.tree.MethodNode;
import jdk.jfr.internal.LogLevel;
import jdk.jfr.internal.LogTag;
import jdk.jfr.internal.Logger;
@Deprecated
final class JIInliner extends ClassVisitor {
private final String targetClassName;
private final String instrumentationClassName;
private final ClassNode targetClassNode;
private final List<Method> instrumentationMethods;
/**
* A ClassVisitor which will check all methods of the class it visits against the instrumentationMethods
* list. If a method is on that list, the method will be further processed for inlining into that
* method.
*/
JIInliner(int api, ClassVisitor cv, String targetClassName, String instrumentationClassName,
ClassReader targetClassReader,
List<Method> instrumentationMethods) {
super(api, cv);
this.targetClassName = targetClassName;
this.instrumentationClassName = instrumentationClassName;
this.instrumentationMethods = instrumentationMethods;
ClassNode cn = new ClassNode(Opcodes.ASM5);
targetClassReader.accept(cn, ClassReader.EXPAND_FRAMES);
this.targetClassNode = cn;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
if (isInstrumentationMethod(name, desc)) {
MethodNode methodToInline = findTargetMethodNode(name, desc);
if (methodToInline == null) {
throw new IllegalArgumentException("Could not find the method to instrument in the target class");
}
if (Modifier.isNative(methodToInline.access)) {
throw new IllegalArgumentException("Cannot instrument native methods: " + targetClassNode.name + "." + methodToInline.name + methodToInline.desc);
}
Logger.log(LogTag.JFR_SYSTEM_BYTECODE, LogLevel.DEBUG, "Inliner processing method " + name + desc);
JIMethodCallInliner mci = new JIMethodCallInliner(access,
desc,
mv,
methodToInline,
targetClassName,
instrumentationClassName);
return mci;
}
return mv;
}
private boolean isInstrumentationMethod(String name, String desc) {
for(Method m : instrumentationMethods) {
if (m.getName().equals(name) && Type.getMethodDescriptor(m).equals(desc)) {
return true;
}
}
return false;
}
private MethodNode findTargetMethodNode(String name, String desc) {
for (MethodNode mn : targetClassNode.methods) {
if (mn.desc.equals(desc) && mn.name.equals(name)) {
return mn;
}
}
throw new IllegalArgumentException("could not find MethodNode for "
+ name + desc);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface JIInstrumentationMethod {
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface JIInstrumentationTarget {
String value();
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.util.ArrayList;
import java.util.List;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.commons.LocalVariablesSorter;
import jdk.internal.org.objectweb.asm.commons.Remapper;
import jdk.internal.org.objectweb.asm.commons.SimpleRemapper;
import jdk.internal.org.objectweb.asm.tree.MethodNode;
import jdk.jfr.internal.LogLevel;
import jdk.jfr.internal.LogTag;
import jdk.jfr.internal.Logger;
/**
* Class responsible for finding the call to inline and inlining it.
*
* This code is heavily influenced by section 3.2.6 "Inline Method" in
* "Using ASM framework to implement common bytecode transformation patterns",
* E. Kuleshov, AOSD.07, March 2007, Vancouver, Canada.
* http://asm.ow2.org/index.html
*/
@Deprecated
final class JIMethodCallInliner extends LocalVariablesSorter {
private final String oldClass;
private final String newClass;
private final MethodNode inlineTarget;
private final List<CatchBlock> blocks = new ArrayList<>();
private boolean inlining;
/**
* inlineTarget defines the method to inline and also contains the actual
* code to inline.
*
* @param access
* @param desc
* @param mv
* @param inlineTarget
* @param oldClass
* @param newClass
* @param logger
*/
public JIMethodCallInliner(int access, String desc, MethodVisitor mv,
MethodNode inlineTarget, String oldClass, String newClass) {
super(Opcodes.ASM5, access, desc, mv);
this.oldClass = oldClass;
this.newClass = newClass;
this.inlineTarget = inlineTarget;
Logger.log(LogTag.JFR_SYSTEM_BYTECODE, LogLevel.DEBUG, "MethodCallInliner: targetMethod=" + newClass + "."
+ inlineTarget.name + inlineTarget.desc);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name,
String desc, boolean itf) {
// Now we are looking at method call in the source method
if (!shouldBeInlined(owner, name, desc)) {
// If this method call should not be inlined, just keep it
mv.visitMethodInsn(opcode, owner, name, desc, itf);
return;
}
// If the call should be inlined, we create a MethodInliningAdapter
// The MIA will walk the instructions in the inlineTarget and add them
// to the current method, doing the necessary name remappings.
Logger.log(LogTag.JFR_SYSTEM_BYTECODE, LogLevel.DEBUG, "Inlining call to " + name + desc);
Remapper remapper = new SimpleRemapper(oldClass, newClass);
Label end = new Label();
inlining = true;
inlineTarget.instructions.resetLabels();
JIMethodInliningAdapter mia = new JIMethodInliningAdapter(this, end,
opcode == Opcodes.INVOKESTATIC ? Opcodes.ACC_STATIC : 0, desc,
remapper);
inlineTarget.accept(mia);
inlining = false;
super.visitLabel(end);
}
/**
* Determine if the method should be inlined or not.
*/
private boolean shouldBeInlined(String owner, String name, String desc) {
return inlineTarget.desc.equals(desc) && inlineTarget.name.equals(name)
&& owner.equals(newClass.replace('.', '/'));
}
@Override
public void visitTryCatchBlock(Label start, Label end, Label handler,
String type) {
if (!inlining) {
// try-catch blocks are saved here and replayed at the end
// of the method (in visitMaxs)
blocks.add(new CatchBlock(start, end, handler, type));
} else {
super.visitTryCatchBlock(start, end, handler, type);
}
}
@Override
public void visitMaxs(int stack, int locals) {
for (CatchBlock b : blocks) {
super.visitTryCatchBlock(b.start, b.end, b.handler, b.type);
}
super.visitMaxs(stack, locals);
}
static final class CatchBlock {
final Label start;
final Label end;
final Label handler;
final String type;
CatchBlock(Label start, Label end, Label handler, String type) {
this.start = start;
this.end = end;
this.handler = handler;
this.type = type;
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.commons.LocalVariablesSorter;
import jdk.internal.org.objectweb.asm.commons.Remapper;
import jdk.internal.org.objectweb.asm.commons.RemappingMethodAdapter;
@Deprecated
final class JIMethodInliningAdapter extends RemappingMethodAdapter {
private final LocalVariablesSorter lvs;
private final Label end;
public JIMethodInliningAdapter(LocalVariablesSorter mv, Label end, int acc, String desc, Remapper remapper) {
super(acc, desc, mv, remapper);
this.lvs = mv;
this.end = end;
int offset = isStatic(acc) ? 0 : 1;
Type[] args = Type.getArgumentTypes(desc);
for (int i = args.length - 1; i >= 0; i--) {
super.visitVarInsn(args[i].getOpcode(Opcodes.ISTORE), i + offset);
}
if (offset > 0) {
super.visitVarInsn(Opcodes.ASTORE, 0);
}
}
private boolean isStatic(int acc) {
return (acc & Opcodes.ACC_STATIC) != 0;
}
@Override
public void visitInsn(int opcode) {
if (opcode == Opcodes.RETURN || opcode == Opcodes.IRETURN
|| opcode == Opcodes.ARETURN || opcode == Opcodes.LRETURN) {
super.visitJumpInsn(Opcodes.GOTO, end);
} else {
super.visitInsn(opcode);
}
}
@Override
public void visitMaxs(int stack, int locals) {
}
@Override
protected int newLocalMapping(Type type) {
return lvs.newLocal(type);
}
}

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.commons.RemappingMethodAdapter;
import jdk.internal.org.objectweb.asm.commons.SimpleRemapper;
import jdk.internal.org.objectweb.asm.tree.ClassNode;
import jdk.internal.org.objectweb.asm.tree.MethodNode;
import jdk.jfr.internal.LogLevel;
import jdk.jfr.internal.LogTag;
import jdk.jfr.internal.Logger;
/**
* This class will merge (some) methods from one class into another one.
*
* @author Staffan Larsen
*/
@Deprecated
final class JIMethodMergeAdapter extends ClassVisitor {
private final ClassNode cn;
private final List<Method> methodFilter;
private final Map<String, String> typeMap;
/**
* Methods in methodFilter that exist in cn will be merged into cv. If the method already exists,
* the original method will be deleted.
*
* @param cv
* @param cn - a ClassNode with Methods that will be merged into this class
* @param methodFilter - only methods in this list will be merged
* @param typeMappings - while merging, type references in the methods will be changed according to this map
*/
public JIMethodMergeAdapter(ClassVisitor cv, ClassNode cn, List<Method> methodFilter, JITypeMapping[] typeMappings) {
super(Opcodes.ASM5, cv);
this.cn = cn;
this.methodFilter = methodFilter;
this.typeMap = new HashMap<>();
for (JITypeMapping tm : typeMappings) {
typeMap.put(tm.from().replace('.', '/'), tm.to().replace('.', '/'));
}
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
typeMap.put(cn.name, name);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if(methodInFilter(name, desc)) {
// If the method is one that we will be replacing, delete the method
Logger.log(LogTag.JFR_SYSTEM_BYTECODE, LogLevel.DEBUG, "Deleting " + name + desc);
return null;
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
@Override
public void visitEnd() {
SimpleRemapper remapper = new SimpleRemapper(typeMap);
for (MethodNode mn : cn.methods) {
// Check if the method is in the list of methods to copy
if (methodInFilter(mn.name, mn.desc)) {
Logger.log(LogTag.JFR_SYSTEM_BYTECODE, LogLevel.DEBUG, "Copying method: " + mn.name + mn.desc);
Logger.log(LogTag.JFR_SYSTEM_BYTECODE, LogLevel.DEBUG, " with mapper: " + typeMap);
String[] exceptions = new String[mn.exceptions.size()];
mn.exceptions.toArray(exceptions);
MethodVisitor mv = cv.visitMethod(mn.access, mn.name, mn.desc, mn.signature, exceptions);
mn.instructions.resetLabels();
mn.accept(new RemappingMethodAdapter(mn.access, mn.desc, mv, remapper));
}
}
super.visitEnd();
}
private boolean methodInFilter(String name, String desc) {
for(Method m : methodFilter) {
if (m.getName().equals(name) && Type.getMethodDescriptor(m).equals(desc)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@interface JITypeMapping {
String from();
String to();
}

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.io.IOException;
import jdk.jfr.events.FileReadEvent;
import jdk.jfr.events.FileWriteEvent;
/**
* See {@link JITracer} for an explanation of this code.
*/
@JIInstrumentationTarget("java.io.RandomAccessFile")
final class RandomAccessFileInstrumentor {
private RandomAccessFileInstrumentor() {
}
private String path;
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int read() throws IOException {
FileReadEvent event = FileReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read();
}
int result = 0;
try {
event.begin();
result = read();
if (result < 0) {
event.endOfFile = true;
} else {
event.bytesRead = 1;
}
} finally {
event.path = path;
event.commit();
event.reset();
}
return result;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int read(byte b[]) throws IOException {
FileReadEvent event = FileReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read(b);
}
int bytesRead = 0;
try {
event.begin();
bytesRead = read(b);
} finally {
if (bytesRead < 0) {
event.endOfFile = true;
} else {
event.bytesRead = bytesRead;
}
event.path = path;
event.commit();
event.reset();
}
return bytesRead;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int read(byte b[], int off, int len) throws IOException {
FileReadEvent event = FileReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read(b, off, len);
}
int bytesRead = 0;
try {
event.begin();
bytesRead = read(b, off, len);
} finally {
if (bytesRead < 0) {
event.endOfFile = true;
} else {
event.bytesRead = bytesRead;
}
event.path = path;
event.commit();
event.reset();
}
return bytesRead;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public void write(int b) throws IOException {
FileWriteEvent event = FileWriteEvent.EVENT.get();
if (!event.isEnabled()) {
write(b);
return;
}
try {
event.begin();
write(b);
event.bytesWritten = 1;
} finally {
event.path = path;
event.commit();
event.reset();
}
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public void write(byte b[]) throws IOException {
FileWriteEvent event = FileWriteEvent.EVENT.get();
if (!event.isEnabled()) {
write(b);
return;
}
try {
event.begin();
write(b);
event.bytesWritten = b.length;
} finally {
event.path = path;
event.commit();
event.reset();
}
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public void write(byte b[], int off, int len) throws IOException {
FileWriteEvent event = FileWriteEvent.EVENT.get();
if (!event.isEnabled()) {
write(b, off, len);
return;
}
try {
event.begin();
write(b, off, len);
event.bytesWritten = len;
} finally {
event.path = path;
event.commit();
event.reset();
}
}
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import jdk.jfr.events.SocketReadEvent;
import jdk.jfr.events.SocketWriteEvent;
/**
* See {@link JITracer} for an explanation of this code.
*/
@JIInstrumentationTarget("sun.nio.ch.SocketChannelImpl")
final class SocketChannelImplInstrumentor {
private SocketChannelImplInstrumentor() {
}
private InetSocketAddress remoteAddress;
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int read(ByteBuffer dst) throws IOException {
SocketReadEvent event = SocketReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read(dst);
}
int bytesRead = 0;
try {
event.begin();
bytesRead = read(dst);
} finally {
event.end();
if (event.shouldCommit()) {
String hostString = remoteAddress.getAddress().toString();
int delimiterIndex = hostString.lastIndexOf('/');
event.host = hostString.substring(0, delimiterIndex);
event.address = hostString.substring(delimiterIndex + 1);
event.port = remoteAddress.getPort();
if (bytesRead < 0) {
event.endOfStream = true;
} else {
event.bytesRead = bytesRead;
}
event.timeout = 0;
event.commit();
event.reset();
}
}
return bytesRead;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
SocketReadEvent event = SocketReadEvent.EVENT.get();
if(!event.isEnabled()) {
return read(dsts, offset, length);
}
long bytesRead = 0;
try {
event.begin();
bytesRead = read(dsts, offset, length);
} finally {
event.end();
if (event.shouldCommit()) {
String hostString = remoteAddress.getAddress().toString();
int delimiterIndex = hostString.lastIndexOf('/');
event.host = hostString.substring(0, delimiterIndex);
event.address = hostString.substring(delimiterIndex + 1);
event.port = remoteAddress.getPort();
if (bytesRead < 0) {
event.endOfStream = true;
} else {
event.bytesRead = bytesRead;
}
event.timeout = 0;
event.commit();
event.reset();
}
}
return bytesRead;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public int write(ByteBuffer buf) throws IOException {
SocketWriteEvent event = SocketWriteEvent.EVENT.get();
if (!event.isEnabled()) {
return write(buf);
}
int bytesWritten = 0;
try {
event.begin();
bytesWritten = write(buf);
} finally {
event.end();
if (event.shouldCommit()) {
String hostString = remoteAddress.getAddress().toString();
int delimiterIndex = hostString.lastIndexOf('/');
event.host = hostString.substring(0, delimiterIndex);
event.address = hostString.substring(delimiterIndex + 1);
event.port = remoteAddress.getPort();
event.bytesWritten = bytesWritten < 0 ? 0 : bytesWritten;
event.commit();
event.reset();
}
}
return bytesWritten;
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
SocketWriteEvent event = SocketWriteEvent.EVENT.get();
if (!event.isEnabled()) {
return write(srcs, offset, length);
}
long bytesWritten = 0;
try {
event.begin();
bytesWritten = write(srcs, offset, length);
} finally {
event.end();
if (event.shouldCommit()) {
String hostString = remoteAddress.getAddress().toString();
int delimiterIndex = hostString.lastIndexOf('/');
event.host = hostString.substring(0, delimiterIndex);
event.address = hostString.substring(delimiterIndex + 1);
event.port = remoteAddress.getPort();
event.bytesWritten = bytesWritten < 0 ? 0 : bytesWritten;
event.commit();
event.reset();
}
}
return bytesWritten;
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.io.IOException;
import java.net.InetAddress;
import jdk.jfr.events.SocketReadEvent;
/**
* See {@link JITracer} for an explanation of this code.
*/
@JIInstrumentationTarget("java.net.SocketInputStream")
@JITypeMapping(from = "jdk.jfr.internal.instrument.SocketInputStreamInstrumentor$AbstractPlainSocketImpl",
to = "java.net.AbstractPlainSocketImpl")
final class SocketInputStreamInstrumentor {
private SocketInputStreamInstrumentor() {
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
int read(byte b[], int off, int length, int timeout) throws IOException {
SocketReadEvent event = SocketReadEvent.EVENT.get();
if (!event.isEnabled()) {
return read(b, off, length, timeout);
}
int bytesRead = 0;
try {
event.begin();
bytesRead = read(b, off, length, timeout);
} finally {
event.end();
if (event.shouldCommit()) {
String hostString = impl.address.toString();
int delimiterIndex = hostString.lastIndexOf('/');
event.host = hostString.substring(0, delimiterIndex);
event.address = hostString.substring(delimiterIndex + 1);
event.port = impl.port;
if (bytesRead < 0) {
event.endOfStream = true;
} else {
event.bytesRead = bytesRead;
}
event.timeout = timeout;
event.commit();
event.reset();
}
}
return bytesRead;
}
private AbstractPlainSocketImpl impl = null;
void silenceFindBugsUnwrittenField(InetAddress dummy) {
impl.address = dummy;
}
static class AbstractPlainSocketImpl {
InetAddress address;
int port;
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2013, 2018, 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.instrument;
import java.io.IOException;
import java.net.InetAddress;
import jdk.jfr.events.SocketWriteEvent;
/**
* See {@link JITracer} for an explanation of this code.
*/
@JIInstrumentationTarget("java.net.SocketOutputStream")
@JITypeMapping(from = "jdk.jfr.internal.instrument.SocketOutputStreamInstrumentor$AbstractPlainSocketImpl",
to = "java.net.AbstractPlainSocketImpl")
final class SocketOutputStreamInstrumentor {
private SocketOutputStreamInstrumentor() {
}
@SuppressWarnings("deprecation")
@JIInstrumentationMethod
private void socketWrite(byte b[], int off, int len) throws IOException {
SocketWriteEvent event = SocketWriteEvent.EVENT.get();
if (!event.isEnabled()) {
socketWrite(b, off, len);
return;
}
int bytesWritten = 0;
try {
event.begin();
socketWrite(b, off, len);
bytesWritten = len;
} finally {
event.end() ;
if (event.shouldCommit()) {
String hostString = impl.address.toString();
int delimiterIndex = hostString.lastIndexOf('/');
event.host = hostString.substring(0, delimiterIndex);
event.address = hostString.substring(delimiterIndex + 1);
event.port = impl.port;
event.bytesWritten = bytesWritten < 0 ? 0 : bytesWritten;
event.commit();
event.reset();
}
}
}
private AbstractPlainSocketImpl impl = null;
void silenceFindBugsUnwrittenField(InetAddress dummy) {
impl.address = dummy;
}
static class AbstractPlainSocketImpl {
InetAddress address;
int port;
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2012, 2018, 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.instrument;
import java.util.concurrent.atomic.AtomicLong;
import jdk.jfr.events.ErrorThrownEvent;
import jdk.jfr.events.ExceptionThrownEvent;
public final class ThrowableTracer {
private static AtomicLong numThrowables = new AtomicLong(0);
public static void traceError(Error e, String message) {
if (e instanceof OutOfMemoryError) {
return;
}
ErrorThrownEvent errorEvent = new ErrorThrownEvent();
errorEvent.message = message;
errorEvent.thrownClass = e.getClass();
errorEvent.commit();
ExceptionThrownEvent exceptionEvent = new ExceptionThrownEvent();
exceptionEvent.message = message;
exceptionEvent.thrownClass = e.getClass();
exceptionEvent.commit();
numThrowables.incrementAndGet();
}
public static void traceThrowable(Throwable t, String message) {
ExceptionThrownEvent event = new ExceptionThrownEvent();
event.message = message;
event.thrownClass = t.getClass();
event.commit();
numThrowables.incrementAndGet();
}
public static long numThrowables() {
return numThrowables.get();
}
}