8319374: JFR: Remove instrumentation for exception events
Reviewed-by: mgronlun, alanb
This commit is contained in:
parent
cd9719bc1d
commit
e841897247
src
java.base/share/classes
java/lang
jdk/internal/event
jdk.jfr/share/classes/jdk/jfr
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 2023, 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
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
package java.lang;
|
||||
|
||||
import jdk.internal.event.ThrowableTracer;
|
||||
|
||||
/**
|
||||
* An {@code Error} is a subclass of {@code Throwable}
|
||||
* that indicates serious problems that a reasonable application
|
||||
@ -53,6 +55,9 @@ public class Error extends Throwable {
|
||||
*/
|
||||
public Error() {
|
||||
super();
|
||||
if (Throwable.jfrTracing) {
|
||||
ThrowableTracer.traceError(getClass(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,6 +70,9 @@ public class Error extends Throwable {
|
||||
*/
|
||||
public Error(String message) {
|
||||
super(message);
|
||||
if (Throwable.jfrTracing) {
|
||||
ThrowableTracer.traceError(getClass(), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,6 +91,9 @@ public class Error extends Throwable {
|
||||
*/
|
||||
public Error(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
if (Throwable.jfrTracing) {
|
||||
ThrowableTracer.traceError(getClass(), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,6 +111,9 @@ public class Error extends Throwable {
|
||||
*/
|
||||
public Error(Throwable cause) {
|
||||
super(cause);
|
||||
if (Throwable.jfrTracing) {
|
||||
ThrowableTracer.traceError(getClass(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,5 +135,8 @@ public class Error extends Throwable {
|
||||
boolean enableSuppression,
|
||||
boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
if (Throwable.jfrTracing) {
|
||||
ThrowableTracer.traceError(getClass(), message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2023, 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
|
||||
@ -28,6 +28,7 @@ package java.lang;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.event.ThrowableTracer;
|
||||
import jdk.internal.misc.InternalLock;
|
||||
|
||||
/**
|
||||
@ -118,6 +119,11 @@ public class Throwable implements Serializable {
|
||||
@java.io.Serial
|
||||
private static final long serialVersionUID = -3042686055658047285L;
|
||||
|
||||
/**
|
||||
* Flag that determines if exceptions should be traced by JFR
|
||||
*/
|
||||
static volatile boolean jfrTracing;
|
||||
|
||||
/**
|
||||
* The JVM saves some indication of the stack backtrace in this slot.
|
||||
*/
|
||||
@ -256,6 +262,9 @@ public class Throwable implements Serializable {
|
||||
*/
|
||||
public Throwable() {
|
||||
fillInStackTrace();
|
||||
if (jfrTracing) {
|
||||
ThrowableTracer.traceThrowable(getClass(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -272,6 +281,9 @@ public class Throwable implements Serializable {
|
||||
public Throwable(String message) {
|
||||
fillInStackTrace();
|
||||
detailMessage = message;
|
||||
if (jfrTracing) {
|
||||
ThrowableTracer.traceThrowable(getClass(), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -295,6 +307,9 @@ public class Throwable implements Serializable {
|
||||
fillInStackTrace();
|
||||
detailMessage = message;
|
||||
this.cause = cause;
|
||||
if (jfrTracing) {
|
||||
ThrowableTracer.traceThrowable(getClass(), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -318,6 +333,9 @@ public class Throwable implements Serializable {
|
||||
fillInStackTrace();
|
||||
detailMessage = (cause==null ? null : cause.toString());
|
||||
this.cause = cause;
|
||||
if (jfrTracing) {
|
||||
ThrowableTracer.traceThrowable(getClass(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -370,8 +388,12 @@ public class Throwable implements Serializable {
|
||||
}
|
||||
detailMessage = message;
|
||||
this.cause = cause;
|
||||
if (!enableSuppression)
|
||||
if (!enableSuppression) {
|
||||
suppressedExceptions = null;
|
||||
}
|
||||
if (jfrTracing) {
|
||||
ThrowableTracer.traceThrowable(getClass(), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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.internal.event;
|
||||
|
||||
/**
|
||||
* Event recording error exceptions.
|
||||
*/
|
||||
public final class ErrorThrownEvent extends Event {
|
||||
public String message;
|
||||
public Class<?> thrownClass;
|
||||
|
||||
public static void commit(long start, String message, Class<?> thrownClass) {
|
||||
// Generated by JFR
|
||||
}
|
||||
|
||||
public static boolean enabled() {
|
||||
// Generated by JFR
|
||||
return false;
|
||||
}
|
||||
|
||||
public static long timestamp() {
|
||||
// Generated by JFR
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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.internal.event;
|
||||
|
||||
/**
|
||||
* Event recording number of exceptions that has been created.
|
||||
*/
|
||||
public class ExceptionStatisticsEvent extends Event {
|
||||
|
||||
public long throwables;
|
||||
|
||||
public static void commit(long timestamp, long throwables) {
|
||||
// Generated by JFR
|
||||
}
|
||||
|
||||
public static boolean enabled() {
|
||||
// Generated by JFR
|
||||
return false;
|
||||
}
|
||||
|
||||
public static long timestamp() {
|
||||
// Generated by JFR
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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.internal.event;
|
||||
|
||||
/**
|
||||
* Event recording all exception.
|
||||
*/
|
||||
public final class ExceptionThrownEvent extends Event {
|
||||
public String message;
|
||||
public Class<?> thrownClass;
|
||||
|
||||
public static void commit(long start, String message, Class<?> thrownClass) {
|
||||
// Generated by JFR
|
||||
}
|
||||
|
||||
public static boolean enabled() {
|
||||
// Generated by JFR
|
||||
return false;
|
||||
}
|
||||
|
||||
public static long timestamp() {
|
||||
// Generated by JFR
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -22,47 +22,50 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package jdk.internal.event;
|
||||
|
||||
package jdk.jfr.internal.instrument;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import jdk.jfr.events.EventConfigurations;
|
||||
import jdk.jfr.events.ErrorThrownEvent;
|
||||
import jdk.jfr.events.ExceptionThrownEvent;
|
||||
import jdk.jfr.internal.event.EventConfiguration;
|
||||
|
||||
/**
|
||||
* Helper class for exception events.
|
||||
*/
|
||||
public final class ThrowableTracer {
|
||||
|
||||
private static final AtomicLong numThrowables = new AtomicLong();
|
||||
|
||||
public static void traceError(Error e, String message) {
|
||||
if (e instanceof OutOfMemoryError) {
|
||||
public static void enable() throws NoSuchFieldException, IllegalAccessException {
|
||||
Field field = Throwable.class.getDeclaredField("jfrTracing");
|
||||
field.setAccessible(true);
|
||||
field.setBoolean(null, true);
|
||||
}
|
||||
|
||||
public static void traceError(Class<?> clazz, String message) {
|
||||
if (OutOfMemoryError.class.isAssignableFrom(clazz)) {
|
||||
return;
|
||||
}
|
||||
long timestamp = EventConfiguration.timestamp();
|
||||
|
||||
EventConfiguration eventConfiguration1 = EventConfigurations.ERROR_THROWN;
|
||||
if (eventConfiguration1.isEnabled()) {
|
||||
ErrorThrownEvent.commit(timestamp, message, e.getClass());
|
||||
if (ErrorThrownEvent.enabled()) {
|
||||
long timestamp = ErrorThrownEvent.timestamp();
|
||||
ErrorThrownEvent.commit(timestamp, message, clazz);
|
||||
}
|
||||
EventConfiguration eventConfiguration2 = EventConfigurations.EXCEPTION_THROWN;
|
||||
if (eventConfiguration2.isEnabled()) {
|
||||
ExceptionThrownEvent.commit(timestamp, message, e.getClass());
|
||||
if (ExceptionThrownEvent.enabled()) {
|
||||
long timestamp = ExceptionThrownEvent.timestamp();
|
||||
ExceptionThrownEvent.commit(timestamp, message, clazz);
|
||||
}
|
||||
numThrowables.incrementAndGet();
|
||||
}
|
||||
|
||||
public static void traceThrowable(Throwable t, String message) {
|
||||
EventConfiguration eventConfiguration = EventConfigurations.EXCEPTION_THROWN;
|
||||
if (eventConfiguration.isEnabled()) {
|
||||
long timestamp = EventConfiguration.timestamp();
|
||||
ExceptionThrownEvent.commit(timestamp, message, t.getClass());
|
||||
public static void traceThrowable(Class<?> clazz, String message) {
|
||||
if (ExceptionThrownEvent.enabled()) {
|
||||
long timestamp = ExceptionThrownEvent.timestamp();
|
||||
ExceptionThrownEvent.commit(timestamp, message, clazz);
|
||||
}
|
||||
numThrowables.incrementAndGet();
|
||||
}
|
||||
|
||||
public static long numThrowables() {
|
||||
return numThrowables.get();
|
||||
public static void emitStatistics() {
|
||||
long timestamp = ExceptionStatisticsEvent.timestamp();
|
||||
ExceptionStatisticsEvent.commit(timestamp, numThrowables.get());
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ import jdk.jfr.Category;
|
||||
import jdk.jfr.Description;
|
||||
import jdk.jfr.Label;
|
||||
import jdk.jfr.Name;
|
||||
import jdk.jfr.internal.MirrorEvent;
|
||||
import jdk.jfr.internal.RemoveFields;
|
||||
import jdk.jfr.internal.Type;
|
||||
|
||||
@ -35,19 +36,12 @@ import jdk.jfr.internal.Type;
|
||||
@Label("Java Error")
|
||||
@Category("Java Application")
|
||||
@Description("An object derived from java.lang.Error has been created. OutOfMemoryErrors are ignored")
|
||||
@MirrorEvent(className = "jdk.internal.event.ErrorThrownEvent")
|
||||
@RemoveFields("duration")
|
||||
public final class ErrorThrownEvent extends AbstractJDKEvent {
|
||||
|
||||
// The order of these fields must be the same as the parameters in
|
||||
// commit(..., String, Class)
|
||||
|
||||
@Label("Message")
|
||||
public String message;
|
||||
|
||||
@Label("Class")
|
||||
public Class<?> thrownClass;
|
||||
|
||||
public static void commit(long start, String message, Class<? extends Error> thrownClass) {
|
||||
// Generated
|
||||
}
|
||||
}
|
||||
public Class<?> thrownClass;}
|
||||
|
@ -31,6 +31,4 @@ public final class EventConfigurations {
|
||||
public static final EventConfiguration FILE_READ = JVMSupport.getConfiguration(FileReadEvent.class);
|
||||
public static final EventConfiguration FILE_WRITE = JVMSupport.getConfiguration(FileWriteEvent.class);
|
||||
public static final EventConfiguration FILE_FORCE = JVMSupport.getConfiguration(FileForceEvent.class);
|
||||
public static final EventConfiguration ERROR_THROWN = JVMSupport.getConfiguration(ErrorThrownEvent.class);
|
||||
public static final EventConfiguration EXCEPTION_THROWN = JVMSupport.getConfiguration(ExceptionThrownEvent.class);
|
||||
}
|
||||
|
@ -30,12 +30,14 @@ import jdk.jfr.Description;
|
||||
import jdk.jfr.Label;
|
||||
import jdk.jfr.Name;
|
||||
import jdk.jfr.StackTrace;
|
||||
import jdk.jfr.internal.MirrorEvent;
|
||||
import jdk.jfr.internal.Type;
|
||||
|
||||
@Name(Type.EVENT_NAME_PREFIX + "ExceptionStatistics")
|
||||
@Label("Exception Statistics")
|
||||
@Category({ "Java Application", "Statistics" })
|
||||
@Description("Number of objects derived from java.lang.Throwable that have been created")
|
||||
@MirrorEvent(className = "jdk.internal.event.ExceptionStatisticsEvent")
|
||||
@StackTrace(false)
|
||||
public final class ExceptionStatisticsEvent extends AbstractPeriodicEvent {
|
||||
|
||||
|
@ -29,6 +29,7 @@ import jdk.jfr.Category;
|
||||
import jdk.jfr.Description;
|
||||
import jdk.jfr.Label;
|
||||
import jdk.jfr.Name;
|
||||
import jdk.jfr.internal.MirrorEvent;
|
||||
import jdk.jfr.internal.RemoveFields;
|
||||
import jdk.jfr.internal.Type;
|
||||
|
||||
@ -36,19 +37,13 @@ import jdk.jfr.internal.Type;
|
||||
@Label("Java Exception")
|
||||
@Category("Java Application")
|
||||
@Description("An object derived from java.lang.Exception has been created")
|
||||
@MirrorEvent(className = "jdk.internal.event.ExceptionThrownEvent")
|
||||
@RemoveFields("duration")
|
||||
public final class ExceptionThrownEvent extends AbstractJDKEvent {
|
||||
|
||||
// The order of these fields must be the same as the parameters in
|
||||
// commit(..., String, Class)
|
||||
|
||||
@Label("Message")
|
||||
public String message;
|
||||
|
||||
@Label("Class")
|
||||
public Class<?> thrownClass;
|
||||
|
||||
public static void commit(long start, String message, Class<? extends Throwable> thrownClass) {
|
||||
// Generated
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,9 @@ import java.util.Map;
|
||||
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.events.DeserializationEvent;
|
||||
import jdk.jfr.events.ErrorThrownEvent;
|
||||
import jdk.jfr.events.ExceptionStatisticsEvent;
|
||||
import jdk.jfr.events.ExceptionThrownEvent;
|
||||
import jdk.jfr.events.ProcessStartEvent;
|
||||
import jdk.jfr.events.SecurityPropertyModificationEvent;
|
||||
import jdk.jfr.events.SecurityProviderServiceEvent;
|
||||
@ -58,7 +61,10 @@ public final class MirrorEvents {
|
||||
VirtualThreadPinnedEvent.class,
|
||||
VirtualThreadSubmitFailedEvent.class,
|
||||
X509CertificateEvent.class,
|
||||
X509ValidationEvent.class
|
||||
X509ValidationEvent.class,
|
||||
ErrorThrownEvent.class,
|
||||
ExceptionStatisticsEvent.class,
|
||||
ExceptionThrownEvent.class,
|
||||
};
|
||||
|
||||
private static final Map<String, Class<? extends Event>> mirrorLookup = createLookup();
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* 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 final ConstructorWriter useInputParameter;
|
||||
private final ConstructorWriter 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.ASM7, 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;
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* 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 final boolean useInputParameter;
|
||||
private final String shortClassName;
|
||||
private final String fullClassName;
|
||||
|
||||
ConstructorWriter(Class<?> classToChange, boolean useInputParameter) {
|
||||
super(Opcodes.ASM7);
|
||||
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;
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.event.ThrowableTracer;
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.events.ActiveRecordingEvent;
|
||||
import jdk.jfr.events.ActiveSettingEvent;
|
||||
@ -39,9 +40,6 @@ import jdk.jfr.events.ContainerCPUUsageEvent;
|
||||
import jdk.jfr.events.ContainerCPUThrottlingEvent;
|
||||
import jdk.jfr.events.ContainerMemoryUsageEvent;
|
||||
import jdk.jfr.events.DirectBufferStatisticsEvent;
|
||||
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;
|
||||
@ -66,14 +64,14 @@ public final class JDKEvents {
|
||||
FileWriteEvent.class,
|
||||
SocketReadEvent.class,
|
||||
SocketWriteEvent.class,
|
||||
ExceptionThrownEvent.class,
|
||||
ExceptionStatisticsEvent.class,
|
||||
ErrorThrownEvent.class,
|
||||
ActiveSettingEvent.class,
|
||||
ActiveRecordingEvent.class,
|
||||
// jdk.internal.event.* classes need their mirror
|
||||
// event class to be listed in the MirrorEvents class.
|
||||
jdk.internal.event.DeserializationEvent.class,
|
||||
jdk.internal.event.ErrorThrownEvent.class,
|
||||
jdk.internal.event.ExceptionStatisticsEvent.class,
|
||||
jdk.internal.event.ExceptionThrownEvent.class,
|
||||
jdk.internal.event.ProcessStartEvent.class,
|
||||
jdk.internal.event.SecurityPropertyModificationEvent.class,
|
||||
jdk.internal.event.SecurityProviderServiceEvent.class,
|
||||
@ -118,11 +116,12 @@ public final class JDKEvents {
|
||||
for (Class<?> eventClass : eventClasses) {
|
||||
SecuritySupport.registerEvent((Class<? extends Event>) eventClass);
|
||||
}
|
||||
PeriodicEvents.addJDKEvent(ExceptionStatisticsEvent.class, emitExceptionStatistics);
|
||||
PeriodicEvents.addJDKEvent(jdk.internal.event.ExceptionStatisticsEvent.class, emitExceptionStatistics);
|
||||
PeriodicEvents.addJDKEvent(DirectBufferStatisticsEvent.class, emitDirectBufferStatistics);
|
||||
PeriodicEvents.addJDKEvent(InitialSecurityPropertyEvent.class, emitInitialSecurityProperties);
|
||||
|
||||
initializeContainerEvents();
|
||||
ThrowableTracer.enable();
|
||||
initializationTriggered = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -139,8 +138,6 @@ public final class JDKEvents {
|
||||
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 (IllegalStateException ise) {
|
||||
@ -174,9 +171,7 @@ public final class JDKEvents {
|
||||
}
|
||||
|
||||
private static void emitExceptionStatistics() {
|
||||
ExceptionStatisticsEvent t = new ExceptionStatisticsEvent();
|
||||
t.throwables = ThrowableTracer.numThrowables();
|
||||
t.commit();
|
||||
ThrowableTracer.emitStatistics();
|
||||
}
|
||||
|
||||
private static void emitContainerConfiguration() {
|
||||
@ -239,16 +234,6 @@ public final class JDKEvents {
|
||||
|
||||
@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];
|
||||
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
package jdk.jfr.internal.periodic;
|
||||
|
||||
import jdk.jfr.Event;
|
||||
import jdk.internal.event.Event;
|
||||
|
||||
/**
|
||||
* Periodic task that runs trusted code that doesn't require an access control
|
||||
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
package jdk.jfr.internal.periodic;
|
||||
|
||||
import jdk.jfr.Event;
|
||||
import jdk.internal.event.Event;
|
||||
import jdk.jfr.EventType;
|
||||
import jdk.jfr.internal.MetadataRepository;
|
||||
import jdk.jfr.internal.PlatformEventType;
|
||||
|
@ -29,7 +29,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import jdk.jfr.Event;
|
||||
import jdk.internal.event.Event;
|
||||
import jdk.jfr.internal.JVM;
|
||||
import jdk.jfr.internal.LogLevel;
|
||||
import jdk.jfr.internal.LogTag;
|
||||
|
@ -29,7 +29,7 @@ import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Objects;
|
||||
|
||||
import jdk.jfr.Event;
|
||||
import jdk.internal.event.Event;
|
||||
import jdk.jfr.internal.LogLevel;
|
||||
import jdk.jfr.internal.LogTag;
|
||||
import jdk.jfr.internal.Logger;
|
||||
|
Loading…
x
Reference in New Issue
Block a user