11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.jfr.internal.instrument;
27
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import jdk.jfr.Event;
32 import jdk.jfr.events.ActiveRecordingEvent;
33 import jdk.jfr.events.ActiveSettingEvent;
34 import jdk.jfr.events.ErrorThrownEvent;
35 import jdk.jfr.events.ExceptionStatisticsEvent;
36 import jdk.jfr.events.ExceptionThrownEvent;
37 import jdk.jfr.events.FileForceEvent;
38 import jdk.jfr.events.FileReadEvent;
39 import jdk.jfr.events.FileWriteEvent;
40 import jdk.jfr.events.SecurityPropertyModificationEvent;
41 import jdk.jfr.events.SocketReadEvent;
42 import jdk.jfr.events.SocketWriteEvent;
43 import jdk.jfr.events.TLSHandshakeEvent;
44 import jdk.jfr.events.X509CertificateEvent;
45 import jdk.jfr.events.X509ValidationEvent;
46 import jdk.jfr.internal.JVM;
47 import jdk.jfr.internal.LogLevel;
48 import jdk.jfr.internal.LogTag;
49 import jdk.jfr.internal.Logger;
50 import jdk.jfr.internal.RequestEngine;
51 import jdk.jfr.internal.SecuritySupport;
52
53 public final class JDKEvents {
56 SecurityPropertyModificationEvent.class,
57 TLSHandshakeEvent.class,
58 X509CertificateEvent.class,
59 X509ValidationEvent.class
60 };
61
62 private static final Class<?>[] eventClasses = {
63 FileForceEvent.class,
64 FileReadEvent.class,
65 FileWriteEvent.class,
66 SocketReadEvent.class,
67 SocketWriteEvent.class,
68 ExceptionThrownEvent.class,
69 ExceptionStatisticsEvent.class,
70 ErrorThrownEvent.class,
71 ActiveSettingEvent.class,
72 ActiveRecordingEvent.class,
73 jdk.internal.event.SecurityPropertyModificationEvent.class,
74 jdk.internal.event.TLSHandshakeEvent.class,
75 jdk.internal.event.X509CertificateEvent.class,
76 jdk.internal.event.X509ValidationEvent.class
77 };
78
79 // This is a list of the classes with instrumentation code that should be applied.
80 private static final Class<?>[] instrumentationClasses = new Class<?>[] {
81 FileInputStreamInstrumentor.class,
82 FileOutputStreamInstrumentor.class,
83 RandomAccessFileInstrumentor.class,
84 FileChannelImplInstrumentor.class,
85 SocketInputStreamInstrumentor.class,
86 SocketOutputStreamInstrumentor.class,
87 SocketChannelImplInstrumentor.class
88 };
89
90 private static final Class<?>[] targetClasses = new Class<?>[instrumentationClasses.length];
91 private static final JVM jvm = JVM.getJVM();
92 private static final Runnable emitExceptionStatistics = JDKEvents::emitExceptionStatistics;
93 private static boolean initializationTriggered;
94
95 @SuppressWarnings("unchecked")
96 public synchronized static void initialize() {
97 try {
98 if (initializationTriggered == false) {
99 for (Class<?> mirrorEventClass : mirrorEventClasses) {
100 SecuritySupport.registerMirror(((Class<? extends Event>)mirrorEventClass));
101 }
102 for (Class<?> eventClass : eventClasses) {
103 SecuritySupport.registerEvent((Class<? extends Event>) eventClass);
104 }
105 initializationTriggered = true;
106 RequestEngine.addTrustedJDKHook(ExceptionStatisticsEvent.class, emitExceptionStatistics);
107 }
108 } catch (Exception e) {
109 Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Could not initialize JDK events. " + e.getMessage());
110 }
111 }
112
113 public static void addInstrumentation() {
114 try {
115 List<Class<?>> list = new ArrayList<>();
116 for (int i = 0; i < instrumentationClasses.length; i++) {
117 JIInstrumentationTarget tgt = instrumentationClasses[i].getAnnotation(JIInstrumentationTarget.class);
118 Class<?> clazz = Class.forName(tgt.value());
119 targetClasses[i] = clazz;
120 list.add(clazz);
121 }
122 list.add(java.lang.Throwable.class);
123 list.add(java.lang.Error.class);
124 Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Retransformed JDK classes");
125 jvm.retransformClasses(list.toArray(new Class<?>[list.size()]));
126 } catch (IllegalStateException ise) {
143 return ConstructorTracerWriter.generateBytes(java.lang.Throwable.class, oldBytes);
144 }
145
146 if (java.lang.Error.class == klass) {
147 Logger.log(LogTag.JFR_SYSTEM, LogLevel.TRACE, "Instrumenting java.lang.Error");
148 return ConstructorTracerWriter.generateBytes(java.lang.Error.class, oldBytes);
149 }
150
151 for (int i = 0; i < targetClasses.length; i++) {
152 if (targetClasses[i].equals(klass)) {
153 Class<?> c = instrumentationClasses[i];
154 Logger.log(LogTag.JFR_SYSTEM, LogLevel.TRACE, () -> "Processing instrumentation class: " + c);
155 return new JIClassInstrumentation(instrumentationClasses[i], klass, oldBytes).getNewBytes();
156 }
157 }
158 return oldBytes;
159 }
160
161 public static void remove() {
162 RequestEngine.removeHook(JDKEvents::emitExceptionStatistics);
163 }
164 }
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.jfr.internal.instrument;
27
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import jdk.internal.access.JavaNioAccess;
32 import jdk.internal.access.SharedSecrets;
33 import jdk.internal.misc.VM;
34
35 import jdk.jfr.Event;
36 import jdk.jfr.events.ActiveRecordingEvent;
37 import jdk.jfr.events.ActiveSettingEvent;
38 import jdk.jfr.events.DirectMemoryStatisticsEvent;
39 import jdk.jfr.events.ErrorThrownEvent;
40 import jdk.jfr.events.ExceptionStatisticsEvent;
41 import jdk.jfr.events.ExceptionThrownEvent;
42 import jdk.jfr.events.FileForceEvent;
43 import jdk.jfr.events.FileReadEvent;
44 import jdk.jfr.events.FileWriteEvent;
45 import jdk.jfr.events.SecurityPropertyModificationEvent;
46 import jdk.jfr.events.SocketReadEvent;
47 import jdk.jfr.events.SocketWriteEvent;
48 import jdk.jfr.events.TLSHandshakeEvent;
49 import jdk.jfr.events.X509CertificateEvent;
50 import jdk.jfr.events.X509ValidationEvent;
51 import jdk.jfr.internal.JVM;
52 import jdk.jfr.internal.LogLevel;
53 import jdk.jfr.internal.LogTag;
54 import jdk.jfr.internal.Logger;
55 import jdk.jfr.internal.RequestEngine;
56 import jdk.jfr.internal.SecuritySupport;
57
58 public final class JDKEvents {
61 SecurityPropertyModificationEvent.class,
62 TLSHandshakeEvent.class,
63 X509CertificateEvent.class,
64 X509ValidationEvent.class
65 };
66
67 private static final Class<?>[] eventClasses = {
68 FileForceEvent.class,
69 FileReadEvent.class,
70 FileWriteEvent.class,
71 SocketReadEvent.class,
72 SocketWriteEvent.class,
73 ExceptionThrownEvent.class,
74 ExceptionStatisticsEvent.class,
75 ErrorThrownEvent.class,
76 ActiveSettingEvent.class,
77 ActiveRecordingEvent.class,
78 jdk.internal.event.SecurityPropertyModificationEvent.class,
79 jdk.internal.event.TLSHandshakeEvent.class,
80 jdk.internal.event.X509CertificateEvent.class,
81 jdk.internal.event.X509ValidationEvent.class,
82 DirectMemoryStatisticsEvent.class
83 };
84
85 // This is a list of the classes with instrumentation code that should be applied.
86 private static final Class<?>[] instrumentationClasses = new Class<?>[] {
87 FileInputStreamInstrumentor.class,
88 FileOutputStreamInstrumentor.class,
89 RandomAccessFileInstrumentor.class,
90 FileChannelImplInstrumentor.class,
91 SocketInputStreamInstrumentor.class,
92 SocketOutputStreamInstrumentor.class,
93 SocketChannelImplInstrumentor.class
94 };
95
96 private static final Class<?>[] targetClasses = new Class<?>[instrumentationClasses.length];
97 private static final JVM jvm = JVM.getJVM();
98 private static final Runnable emitExceptionStatistics = JDKEvents::emitExceptionStatistics;
99 private static final Runnable emitDirectMemoryStatistics = JDKEvents::emitDirectMemoryStatistics;
100 private static boolean initializationTriggered;
101
102 @SuppressWarnings("unchecked")
103 public synchronized static void initialize() {
104 try {
105 if (initializationTriggered == false) {
106 for (Class<?> mirrorEventClass : mirrorEventClasses) {
107 SecuritySupport.registerMirror(((Class<? extends Event>)mirrorEventClass));
108 }
109 for (Class<?> eventClass : eventClasses) {
110 SecuritySupport.registerEvent((Class<? extends Event>) eventClass);
111 }
112 initializationTriggered = true;
113 RequestEngine.addTrustedJDKHook(ExceptionStatisticsEvent.class, emitExceptionStatistics);
114 RequestEngine.addTrustedJDKHook(DirectMemoryStatisticsEvent.class, emitDirectMemoryStatistics);
115 }
116 } catch (Exception e) {
117 Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Could not initialize JDK events. " + e.getMessage());
118 }
119 }
120
121 public static void addInstrumentation() {
122 try {
123 List<Class<?>> list = new ArrayList<>();
124 for (int i = 0; i < instrumentationClasses.length; i++) {
125 JIInstrumentationTarget tgt = instrumentationClasses[i].getAnnotation(JIInstrumentationTarget.class);
126 Class<?> clazz = Class.forName(tgt.value());
127 targetClasses[i] = clazz;
128 list.add(clazz);
129 }
130 list.add(java.lang.Throwable.class);
131 list.add(java.lang.Error.class);
132 Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Retransformed JDK classes");
133 jvm.retransformClasses(list.toArray(new Class<?>[list.size()]));
134 } catch (IllegalStateException ise) {
151 return ConstructorTracerWriter.generateBytes(java.lang.Throwable.class, oldBytes);
152 }
153
154 if (java.lang.Error.class == klass) {
155 Logger.log(LogTag.JFR_SYSTEM, LogLevel.TRACE, "Instrumenting java.lang.Error");
156 return ConstructorTracerWriter.generateBytes(java.lang.Error.class, oldBytes);
157 }
158
159 for (int i = 0; i < targetClasses.length; i++) {
160 if (targetClasses[i].equals(klass)) {
161 Class<?> c = instrumentationClasses[i];
162 Logger.log(LogTag.JFR_SYSTEM, LogLevel.TRACE, () -> "Processing instrumentation class: " + c);
163 return new JIClassInstrumentation(instrumentationClasses[i], klass, oldBytes).getNewBytes();
164 }
165 }
166 return oldBytes;
167 }
168
169 public static void remove() {
170 RequestEngine.removeHook(JDKEvents::emitExceptionStatistics);
171 RequestEngine.removeHook(emitDirectMemoryStatistics);
172 }
173
174 private static void emitDirectMemoryStatistics() {
175 DirectMemoryStatisticsEvent e = new DirectMemoryStatisticsEvent();
176 JavaNioAccess.BufferPool pool = SharedSecrets.getJavaNioAccess().getDirectBufferPool();
177 e.count = pool.getCount();
178 e.totalCapacity = pool.getTotalCapacity();
179 e.memoryUsed = pool.getMemoryUsed();
180 e.maxCapacity = VM.maxDirectMemory();
181 e.commit();
182 }
183 }
|