feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
144
jdkSrc/jdk8/jdk/jfr/internal/instrument/JDKEvents.java
Normal file
144
jdkSrc/jdk8/jdk/jfr/internal/instrument/JDKEvents.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
113
jdkSrc/jdk8/jdk/jfr/internal/instrument/JIInliner.java
Normal file
113
jdkSrc/jdk8/jdk/jfr/internal/instrument/JIInliner.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
149
jdkSrc/jdk8/jdk/jfr/internal/instrument/JIMethodCallInliner.java
Normal file
149
jdkSrc/jdk8/jdk/jfr/internal/instrument/JIMethodCallInliner.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
35
jdkSrc/jdk8/jdk/jfr/internal/instrument/JITypeMapping.java
Normal file
35
jdkSrc/jdk8/jdk/jfr/internal/instrument/JITypeMapping.java
Normal 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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
64
jdkSrc/jdk8/jdk/jfr/internal/instrument/ThrowableTracer.java
Normal file
64
jdkSrc/jdk8/jdk/jfr/internal/instrument/ThrowableTracer.java
Normal 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user