|
1 /* |
|
2 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
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; |
|
27 |
|
28 import java.io.IOException; |
|
29 import java.util.List; |
|
30 |
|
31 import jdk.internal.HotSpotIntrinsicCandidate; |
|
32 import jdk.jfr.Event; |
|
33 |
|
34 /** |
|
35 * Interface against the JVM. |
|
36 * |
|
37 */ |
|
38 public final class JVM { |
|
39 private static final JVM jvm = new JVM(); |
|
40 |
|
41 // JVM signals file changes by doing Object#notifu on this object |
|
42 static final Object FILE_DELTA_CHANGE = new Object(); |
|
43 |
|
44 static final long RESERVED_CLASS_ID_LIMIT = 400; |
|
45 |
|
46 private volatile boolean recording; |
|
47 private volatile boolean nativeOK; |
|
48 |
|
49 private static native void registerNatives(); |
|
50 |
|
51 static { |
|
52 registerNatives(); |
|
53 for (LogTag tag : LogTag.values()) { |
|
54 subscribeLogLevel(tag, tag.id); |
|
55 } |
|
56 Options.ensureInitialized(); |
|
57 } |
|
58 |
|
59 /** |
|
60 * Get the one and only JVM. |
|
61 * |
|
62 * @return the JVM |
|
63 */ |
|
64 public static JVM getJVM() { |
|
65 return jvm; |
|
66 } |
|
67 |
|
68 private JVM() { |
|
69 } |
|
70 |
|
71 /** |
|
72 * Begin recording events |
|
73 * |
|
74 * Requires that JFR has been started with {@link #createNativeJFR()} |
|
75 */ |
|
76 public native void beginRecording(); |
|
77 |
|
78 /** |
|
79 * Return ticks |
|
80 * |
|
81 * @return the time, in ticks |
|
82 * |
|
83 */ |
|
84 @HotSpotIntrinsicCandidate |
|
85 public static native long counterTime(); |
|
86 |
|
87 |
|
88 /** |
|
89 * Emits native periodic event. |
|
90 * |
|
91 * @param eventTypeId type id |
|
92 * |
|
93 * @param timestamp commit time for event |
|
94 * @param when when it is being done {@link Periodic.When} |
|
95 * |
|
96 * @return true if the event was committed |
|
97 */ |
|
98 public native boolean emitEvent(long eventTypeId, long timestamp, long when); |
|
99 |
|
100 /** |
|
101 * End recording events, which includes flushing data in thread buffers |
|
102 * |
|
103 * Requires that JFR has been started with {@link #createNativeJFR()} |
|
104 * |
|
105 */ |
|
106 public native void endRecording(); |
|
107 |
|
108 /** |
|
109 * Return a list of all classes deriving from {@link Event} |
|
110 * |
|
111 * @return list of event classes. |
|
112 */ |
|
113 public native List<Class<? extends Event>> getAllEventClasses(); |
|
114 |
|
115 /** |
|
116 * Return a count of the number of unloaded classes deriving from {@link Event} |
|
117 * |
|
118 * @return number of unloaded event classes. |
|
119 */ |
|
120 public native long getUnloadedEventClassCount(); |
|
121 |
|
122 /** |
|
123 * Return a unique identifier for a class. The class is marked as being |
|
124 * "in use" in JFR. |
|
125 * |
|
126 * @param clazz clazz |
|
127 * |
|
128 * @return a unique class identifier |
|
129 */ |
|
130 @HotSpotIntrinsicCandidate |
|
131 public static native long getClassId(Class<?> clazz); |
|
132 |
|
133 // temporary workaround until we solve intrinsics supporting epoch shift tagging |
|
134 public static native long getClassIdNonIntrinsic(Class<?> clazz); |
|
135 |
|
136 /** |
|
137 * Return process identifier. |
|
138 * |
|
139 * @return process identifier |
|
140 */ |
|
141 public native String getPid(); |
|
142 |
|
143 /** |
|
144 * Return unique identifier for stack trace. |
|
145 * |
|
146 * Requires that JFR has been started with {@link #createNativeJFR()} |
|
147 * |
|
148 * @param skipCount number of frames to skip |
|
149 * @return a unique stack trace identifier |
|
150 */ |
|
151 public native long getStackTraceId(int skipCount); |
|
152 |
|
153 /** |
|
154 * Return identifier for thread |
|
155 * |
|
156 * @param t thread |
|
157 * @return a unique thread identifier |
|
158 */ |
|
159 public native long getThreadId(Thread t); |
|
160 |
|
161 /** |
|
162 * Frequency, ticks per second |
|
163 * |
|
164 * @return frequency |
|
165 */ |
|
166 public native long getTicksFrequency(); |
|
167 |
|
168 /** |
|
169 * Write message to log. Should swallow null or empty message, and be able |
|
170 * to handle any Java character and not crash with very large message |
|
171 * |
|
172 * @param tagSetId the tagset id |
|
173 * @param level on level |
|
174 * @param message log message |
|
175 * |
|
176 */ |
|
177 public static native void log(int tagSetId, int level, String message); |
|
178 |
|
179 /** |
|
180 * Subscribe to LogLevel updates for LogTag |
|
181 * |
|
182 * @param lt the log tag to subscribe |
|
183 * @param tagSetId the tagset id |
|
184 */ |
|
185 public static native void subscribeLogLevel(LogTag lt, int tagSetId); |
|
186 |
|
187 /** |
|
188 * Call to invoke event tagging and retransformation of the passed classes |
|
189 * |
|
190 * @param classes |
|
191 */ |
|
192 public native synchronized void retransformClasses(Class<?>[] classes); |
|
193 |
|
194 /** |
|
195 * Enable event |
|
196 * |
|
197 * @param eventTypeId event type id |
|
198 * |
|
199 * @param enabled enable event |
|
200 */ |
|
201 public native void setEnabled(long eventTypeId, boolean enabled); |
|
202 |
|
203 /** |
|
204 * Interval at which the JVM should notify on {@link #FILE_DELTA_CHANGE} |
|
205 * |
|
206 * @param delta number of bytes, reset after file rotation |
|
207 */ |
|
208 public native void setFileNotification(long delta); |
|
209 |
|
210 /** |
|
211 * Set the number of global buffers to use |
|
212 * |
|
213 * @param count |
|
214 * |
|
215 * @throws IllegalArgumentException if count is not within a valid range |
|
216 * @throws IllegalStateException if value can't be changed |
|
217 */ |
|
218 public native void setGlobalBufferCount(long count) throws IllegalArgumentException, IllegalStateException; |
|
219 |
|
220 /** |
|
221 * Set size of a global buffer |
|
222 * |
|
223 * @param size |
|
224 * |
|
225 * @throws IllegalArgumentException if buffer size is not within a valid |
|
226 * range |
|
227 */ |
|
228 public native void setGlobalBufferSize(long size) throws IllegalArgumentException; |
|
229 |
|
230 /** |
|
231 * Set overall memory size |
|
232 * |
|
233 * @param size |
|
234 * |
|
235 * @throws IllegalArgumentException if memory size is not within a valid |
|
236 * range |
|
237 */ |
|
238 public native void setMemorySize(long size) throws IllegalArgumentException; |
|
239 |
|
240 /** |
|
241 |
|
242 /** |
|
243 * Set interval for method samples, in milliseconds. |
|
244 * |
|
245 * Setting interval to 0 turns off the method sampler. |
|
246 * |
|
247 * @param intervalMillis the sampling interval |
|
248 */ |
|
249 public native void setMethodSamplingInterval(long type, long intervalMillis); |
|
250 |
|
251 /** |
|
252 * Sets the file where data should be written. |
|
253 * |
|
254 * Requires that JFR has been started with {@link #createNativeJFR()} |
|
255 * |
|
256 * <pre> |
|
257 * Recording Previous Current Action |
|
258 * ============================================== |
|
259 * true null null Ignore, keep recording in-memory |
|
260 * true null file1 Start disk recording |
|
261 * true file null Copy out metadata to disk and continue in-memory recording |
|
262 * true file1 file2 Copy out metadata and start with new File (file2) |
|
263 * false * null Ignore, but start recording to memory with {@link #beginRecording()} |
|
264 * false * file Ignore, but start recording to disk with {@link #beginRecording()} |
|
265 * |
|
266 * </pre> |
|
267 * |
|
268 * recording can be set to true/false with {@link #beginRecording()} |
|
269 * {@link #endRecording()} |
|
270 * |
|
271 * @param file the file where data should be written, or null if it should |
|
272 * not be copied out (in memory). |
|
273 * |
|
274 * @throws IOException |
|
275 */ |
|
276 public native void setOutput(String file); |
|
277 |
|
278 /** |
|
279 * Controls if a class deriving from jdk.jfr.Event should |
|
280 * always be instrumented on class load. |
|
281 * |
|
282 * @param force, true to force initialization, false otherwise |
|
283 */ |
|
284 public native void setForceInstrumentation(boolean force); |
|
285 |
|
286 /** |
|
287 * Turn on/off thread sampling. |
|
288 * |
|
289 * @param sampleThreads true if threads should be sampled, false otherwise. |
|
290 * |
|
291 * @throws IllegalStateException if state can't be changed. |
|
292 */ |
|
293 public native void setSampleThreads(boolean sampleThreads) throws IllegalStateException; |
|
294 |
|
295 /** |
|
296 * Turn on/off compressed integers. |
|
297 * |
|
298 * @param compressed true if compressed integers should be used, false |
|
299 * otherwise. |
|
300 * |
|
301 * @throws IllegalStateException if state can't be changed. |
|
302 */ |
|
303 public native void setCompressedIntegers(boolean compressed) throws IllegalStateException; |
|
304 |
|
305 /** |
|
306 * Set stack depth. |
|
307 * |
|
308 * @param depth |
|
309 * |
|
310 * @throws IllegalArgumentException if not within a valid range |
|
311 * @throws IllegalStateException if depth can't be changed |
|
312 */ |
|
313 public native void setStackDepth(int depth) throws IllegalArgumentException, IllegalStateException; |
|
314 |
|
315 /** |
|
316 * Turn on stack trace for an event |
|
317 * |
|
318 * @param eventTypeId the event id |
|
319 * |
|
320 * @param enabled if stack traces should be enabled |
|
321 */ |
|
322 public native void setStackTraceEnabled(long eventTypeId, boolean enabled); |
|
323 |
|
324 /** |
|
325 * Set thread buffer size. |
|
326 * |
|
327 * @param size |
|
328 * |
|
329 * @throws IllegalArgumentException if size is not within a valid range |
|
330 * @throws IllegalStateException if size can't be changed |
|
331 */ |
|
332 public native void setThreadBufferSize(long size) throws IllegalArgumentException, IllegalStateException; |
|
333 |
|
334 /** |
|
335 * Set threshold for event, |
|
336 * |
|
337 * Long.MAXIMUM_VALUE = no limit |
|
338 * |
|
339 * @param eventTypeId the id of the event type |
|
340 * @param ticks threshold in ticks, |
|
341 * @return true, if it could be set |
|
342 */ |
|
343 public native boolean setThreshold(long eventTypeId, long ticks); |
|
344 |
|
345 /** |
|
346 * Store the metadata descriptor that is to be written at the end of a |
|
347 * chunk, data should be written after GMT offset and size of metadata event |
|
348 * should be adjusted |
|
349 * |
|
350 * Requires that JFR has been started with {@link #createNativeJFR()} |
|
351 * |
|
352 * @param bytes binary representation of metadata descriptor |
|
353 * |
|
354 * @param binary representation of descriptor |
|
355 */ |
|
356 public native void storeMetadataDescriptor(byte[] bytes); |
|
357 |
|
358 public void endRecording_() { |
|
359 endRecording(); |
|
360 recording = false; |
|
361 } |
|
362 |
|
363 public void beginRecording_() { |
|
364 beginRecording(); |
|
365 recording = true; |
|
366 } |
|
367 |
|
368 public boolean isRecording() { |
|
369 return recording; |
|
370 } |
|
371 |
|
372 /** |
|
373 * If the JVM supports JVM TI and retransformation has not been disabled this |
|
374 * method will return true. This flag can not change during the lifetime of |
|
375 * the JVM. |
|
376 * |
|
377 * @return if transform is allowed |
|
378 */ |
|
379 public native boolean getAllowedToDoEventRetransforms(); |
|
380 |
|
381 /** |
|
382 * Set up native resources, data structures, threads etc. for JFR |
|
383 * |
|
384 * @param simulateFailure simulate a initialization failure and rollback in |
|
385 * native, used for testing purposes |
|
386 * |
|
387 * @throws IllegalStateException if native part of JFR could not be created. |
|
388 * |
|
389 */ |
|
390 private native boolean createJFR(boolean simulateFailure) throws IllegalStateException; |
|
391 |
|
392 /** |
|
393 * Destroys native part of JFR. If already destroy, call is ignored. |
|
394 * |
|
395 * Requires that JFR has been started with {@link #createNativeJFR()} |
|
396 * |
|
397 * @return if an instance was actually destroyed. |
|
398 * |
|
399 */ |
|
400 private native boolean destroyJFR(); |
|
401 |
|
402 public boolean createFailedNativeJFR() throws IllegalStateException { |
|
403 return createJFR(true); |
|
404 } |
|
405 |
|
406 public void createNativeJFR() { |
|
407 nativeOK = createJFR(false); |
|
408 } |
|
409 |
|
410 public boolean destroyNativeJFR() { |
|
411 boolean result = destroyJFR(); |
|
412 nativeOK = !result; |
|
413 return result; |
|
414 } |
|
415 |
|
416 public boolean hasNativeJFR() { |
|
417 return nativeOK; |
|
418 } |
|
419 |
|
420 /** |
|
421 * Cheap test to check if JFR functionality is available. |
|
422 * |
|
423 * @return |
|
424 */ |
|
425 public native boolean isAvailable(); |
|
426 |
|
427 /** |
|
428 * To convert ticks to wall clock time. |
|
429 */ |
|
430 public native double getTimeConversionFactor(); |
|
431 |
|
432 /** |
|
433 * Return a unique identifier for a class. Compared to {@link #getClassId()} |
|
434 * , this method does not tag the class as being "in-use". |
|
435 * |
|
436 * @param clazz class |
|
437 * |
|
438 * @return a unique class identifier |
|
439 */ |
|
440 public native long getTypeId(Class<?> clazz); |
|
441 |
|
442 /** |
|
443 * Fast path fetching the EventWriter using VM intrinsics |
|
444 * |
|
445 * @return thread local EventWriter |
|
446 */ |
|
447 @HotSpotIntrinsicCandidate |
|
448 public static native Object getEventWriter(); |
|
449 |
|
450 /** |
|
451 * Create a new EventWriter |
|
452 * |
|
453 * @return thread local EventWriter |
|
454 */ |
|
455 public static native EventWriter newEventWriter(); |
|
456 |
|
457 /** |
|
458 * Flushes the EventWriter for this thread. |
|
459 */ |
|
460 public static native boolean flush(EventWriter writer, int uncommittedSize, int requestedSize); |
|
461 |
|
462 /** |
|
463 * Sets the location of the disk repository, to be used at an emergency |
|
464 * dump. |
|
465 * |
|
466 * @param dirText |
|
467 */ |
|
468 public native void setRepositoryLocation(String dirText); |
|
469 |
|
470 /** |
|
471 * Access to VM termination support. |
|
472 * |
|
473 *@param errorMsg descriptive message to be include in VM termination sequence |
|
474 */ |
|
475 public native void abort(String errorMsg); |
|
476 |
|
477 /** |
|
478 * Adds a string to the string constant pool. |
|
479 * |
|
480 * If the same string is added twice, two entries will be created. |
|
481 * |
|
482 * @param id identifier associated with the string, not negative |
|
483 * |
|
484 * @param s string constant to be added, not null |
|
485 * |
|
486 * @return the current epoch of this insertion attempt |
|
487 */ |
|
488 public static native boolean addStringConstant(boolean epoch, long id, String s); |
|
489 /** |
|
490 * Gets the address of the jboolean epoch. |
|
491 * |
|
492 * The epoch alternates every checkpoint. |
|
493 * |
|
494 * @return The address of the jboolean. |
|
495 */ |
|
496 public native long getEpochAddress(); |
|
497 |
|
498 public native void uncaughtException(Thread thread, Throwable t); |
|
499 /** |
|
500 * Sets cutoff for event. |
|
501 * |
|
502 * Determines how long the event should be allowed to run. |
|
503 * |
|
504 * Long.MAXIMUM_VALUE = no limit |
|
505 * |
|
506 * @param eventTypeId the id of the event type |
|
507 * @param cutoffTicks cutoff in ticks, |
|
508 * @return true, if it could be set |
|
509 */ |
|
510 public native boolean setCutoff(long eventTypeId, long cutoffTicks); |
|
511 |
|
512 /** |
|
513 * Emit old object sample events. |
|
514 * |
|
515 * @param cutoff the cutoff in ticks |
|
516 * @param emitAll emit all samples in old object queue |
|
517 */ |
|
518 public native void emitOldObjectSamples(long cutoff, boolean emitAll); |
|
519 } |