xref: /aosp_15_r20/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java (revision 89a6322812dc8573315e60046e7959c50dad91d4)
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package dalvik.system;
18 
19 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
20 
21 import android.annotation.SystemApi;
22 import android.annotation.UserIdInt;
23 import android.compat.annotation.UnsupportedAppUsage;
24 
25 import libcore.util.NonNull;
26 import libcore.util.Nullable;
27 
28 import java.io.FileDescriptor;
29 import java.io.IOException;
30 import java.lang.reflect.Method;
31 import java.util.HashMap;
32 import java.util.Map;
33 
34 import dalvik.annotation.optimization.FastNative;
35 
36 /**
37  * Provides access to some VM-specific debug features. Though this class and
38  * many of its members are public, this class is meant to be wrapped in a more
39  * friendly way for use by application developers. On the Android platform, the
40  * recommended way to access this functionality is through the class
41  * <code>android.os.Debug</code>.
42  *
43  * @hide
44  */
45 @SystemApi(client = MODULE_LIBRARIES)
46 public final class VMDebug {
47     /**
48      * flag for startMethodTracing(), which adds the results from
49      * startAllocCounting to the trace key file.
50      *
51      * @hide
52      */
53     @SystemApi(client = MODULE_LIBRARIES)
54     // Must match android.os.Debug.TRACE_COUNT_ALLOCS.
55     public static final int TRACE_COUNT_ALLOCS = 1;
56 
57     /* constants for getAllocCount */
58     private static final int KIND_ALLOCATED_OBJECTS     = 1<<0;
59     private static final int KIND_ALLOCATED_BYTES       = 1<<1;
60     private static final int KIND_FREED_OBJECTS         = 1<<2;
61     private static final int KIND_FREED_BYTES           = 1<<3;
62     private static final int KIND_GC_INVOCATIONS        = 1<<4;
63     private static final int KIND_CLASS_INIT_COUNT      = 1<<5;
64     private static final int KIND_CLASS_INIT_TIME       = 1<<6;
65     private static final int KIND_EXT_ALLOCATED_OBJECTS = 1<<12;
66     private static final int KIND_EXT_ALLOCATED_BYTES   = 1<<13;
67     private static final int KIND_EXT_FREED_OBJECTS     = 1<<14;
68     private static final int KIND_EXT_FREED_BYTES       = 1<<15;
69 
70     /**
71      * Constant for {@link #getAllocCount(int)}
72      * to get the number of all allocated objects.
73      *
74      * @hide
75      */
76     @SystemApi(client = MODULE_LIBRARIES)
77     public static final int KIND_GLOBAL_ALLOCATED_OBJECTS =
78         KIND_ALLOCATED_OBJECTS;
79 
80     /**
81      * Constant for {@link #getAllocCount(int)}
82      * to get the cumulative size of all objects allocated.
83      *
84      * @hide
85      */
86     @SystemApi(client = MODULE_LIBRARIES)
87     public static final int KIND_GLOBAL_ALLOCATED_BYTES =
88         KIND_ALLOCATED_BYTES;
89 
90     /**
91      * Constant for {@link #getAllocCount(int)}
92      * to get the number of freed objects.
93      *
94      * @hide
95      */
96     @SystemApi(client = MODULE_LIBRARIES)
97     public static final int KIND_GLOBAL_FREED_OBJECTS =
98         KIND_FREED_OBJECTS;
99 
100     /**
101      * Constant for {@link #getAllocCount(int)}
102      * to get the cumulative size of all freed objects.
103      *
104      * @hide
105      */
106     @SystemApi(client = MODULE_LIBRARIES)
107     public static final int KIND_GLOBAL_FREED_BYTES =
108         KIND_FREED_BYTES;
109 
110     /**
111      * Constant for {@link #getAllocCount(int)}
112      * to get the number of times an allocation triggered a blocking GC.
113      *
114      * @hide
115      */
116     @SystemApi(client = MODULE_LIBRARIES)
117     public static final int KIND_GLOBAL_GC_INVOCATIONS =
118         KIND_GC_INVOCATIONS;
119 
120     /**
121      * Constant for {@link #getAllocCount(int)}
122      * to get the number of initialized classes.
123      *
124      * @hide
125      */
126     @SystemApi(client = MODULE_LIBRARIES)
127     public static final int KIND_GLOBAL_CLASS_INIT_COUNT =
128         KIND_CLASS_INIT_COUNT;
129 
130     /**
131      * Constant for {@link #getAllocCount(int)}
132      * to get the cumulative time spent in class initialization.
133      *
134      * @hide
135      */
136     @SystemApi(client = MODULE_LIBRARIES)
137     public static final int KIND_GLOBAL_CLASS_INIT_TIME =
138         KIND_CLASS_INIT_TIME;
139 
140     /**
141      * Constant for {@link #getAllocCount(int)}
142      * to get the number of all allocated objects for current thread.
143      *
144      * @hide
145      */
146     @SystemApi(client = MODULE_LIBRARIES)
147     public static final int KIND_THREAD_ALLOCATED_OBJECTS =
148         KIND_ALLOCATED_OBJECTS << 16;
149 
150     /**
151      * Constant for {@link #getAllocCount(int)}
152      * to get the cumulative size of all objects allocated for current thread.
153      *
154      * @hide
155      */
156     @SystemApi(client = MODULE_LIBRARIES)
157     public static final int KIND_THREAD_ALLOCATED_BYTES =
158         KIND_ALLOCATED_BYTES << 16;
159 
160     /**
161      * Constant for {@link #getAllocCount(int)}
162      * to get the number of times an allocation triggered a blocking GC for current thread.
163      *
164      * @hide
165      */
166     @SystemApi(client = MODULE_LIBRARIES)
167     public static final int KIND_THREAD_GC_INVOCATIONS =
168         KIND_GC_INVOCATIONS << 16;
169 
170     /**
171      * Constant for {@link #getAllocCount(int)} to get all possible stats.
172      *
173      * @hide
174      */
175     @SystemApi(client = MODULE_LIBRARIES)
176     public static final int KIND_ALL_COUNTS = 0xffffffff;
177 
178     /* all methods are static */
VMDebug()179     private VMDebug() {}
180 
181     /**
182      * Request JDWP agent to suspend all Java Thread and send VM_START.
183      *
184      * @hide
185      */
186     @SystemApi(client = MODULE_LIBRARIES)
suspendAllAndSendVmStart()187     public static native void suspendAllAndSendVmStart();
188 
189     /**
190      * Returns the time since the last known debugger activity.
191      *
192      * @return the time in milliseconds, or -1 if the debugger is not connected
193      *
194      * @hide
195      */
196     @SystemApi(client = MODULE_LIBRARIES)
197     @FastNative
lastDebuggerActivity()198     public static native long lastDebuggerActivity();
199 
200     /**
201      * Determines if debugging is enabled in this VM.  If debugging is not
202      * enabled, a debugger cannot be attached.
203      *
204      * @return true if debugging is enabled
205      *
206      * @hide
207      */
208     @SystemApi(client = MODULE_LIBRARIES)
209     @FastNative
isDebuggingEnabled()210     public static native boolean isDebuggingEnabled();
211 
212     /**
213      * Determines if a debugger is currently attached.
214      *
215      * @return true if (and only if) a debugger is connected
216      *
217      * @hide
218      */
219     @UnsupportedAppUsage
220     @SystemApi(client = MODULE_LIBRARIES)
221     @FastNative
isDebuggerConnected()222     public static native boolean isDebuggerConnected();
223 
224     /**
225      * Returns an array of strings that identify VM features.  This is
226      * used by DDMS to determine what sorts of operations the VM can
227      * perform.
228      *
229      * @return array of strings identifying VM features
230      *
231      * @hide
232      */
233     @SystemApi(client = MODULE_LIBRARIES)
getVmFeatureList()234     public static native String[] getVmFeatureList();
235 
236     /**
237      * Start method tracing, specifying a file name as well as a default
238      * buffer size. See <a
239      * href="{@docRoot}guide/developing/tools/traceview.html"> Running the
240      * Traceview Debugging Program</a> for information about reading
241      * trace files.
242      *
243      * <p>You can use either a fully qualified path and
244      * name, or just a name. If only a name is specified, the file will
245      * be created under the /sdcard/ directory. If a name is not given,
246      * the default is /sdcard/dmtrace.trace.</p>
247      *
248      * @param traceFileName   name to give the trace file
249      * @param bufferSize      the maximum size of both files combined. If passed
250      *                        as {@code 0}, it defaults to 8MB.
251      * @param flags           flags to control method tracing. The only one that
252      *                        is currently defined is {@link #TRACE_COUNT_ALLOCS}.
253      * @param samplingEnabled if true, sample profiling is enabled. Otherwise,
254      *                        method instrumentation is used.
255      * @param intervalUs      the time between samples in microseconds when
256      *                        sampling is enabled.
257      *
258      * @hide
259      */
260     @SystemApi(client = MODULE_LIBRARIES)
startMethodTracing(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs)261     public static void startMethodTracing(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs) {
262         startMethodTracingFilename(traceFileName, checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs);
263     }
264 
265     /**
266      * Like {@link #startMethodTracing(String, int, int)}, but taking an already-opened
267      * {@code FileDescriptor} in which the trace is written.  The file name is also
268      * supplied simply for logging.  Makes a dup of the file descriptor.
269      * Streams tracing data to the file if streamingOutput is true.
270      *
271      * @param traceFileName   name to give the trace file
272      * @param fd              already opened {@code FileDescriptor} in which trace is written
273      * @param bufferSize      the maximum size of both files combined. If passed
274      *                        as {@code 0}, it defaults to 8MB.
275      * @param flags           flags to control method tracing. The only one that
276      *                        is currently defined is {@link #TRACE_COUNT_ALLOCS}.
277      * @param samplingEnabled if true, sample profiling is enabled. Otherwise,
278      *                        method instrumentation is used.
279      * @param intervalUs      the time between samples in microseconds when
280      *                        sampling is enabled.
281      * @param streamingOutput streams tracing data to the duped {@code fd} file descriptor
282      *                        if {@code streamingOutput} is {@code true}.
283      *
284      * @hide
285      */
286     @SystemApi(client = MODULE_LIBRARIES)
startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs, boolean streamingOutput)287     public static void startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize,
288                                           int flags, boolean samplingEnabled, int intervalUs,
289                                           boolean streamingOutput) {
290         if (fd == null) {
291             throw new NullPointerException("fd == null");
292         }
293         startMethodTracingFd(traceFileName, fd.getInt$(), checkBufferSize(bufferSize), flags,
294                              samplingEnabled, intervalUs, streamingOutput);
295     }
296 
297     /**
298      * Starts method tracing without a backing file.  When {@link #stopMethodTracing()}
299      * is called, the result is sent directly to DDMS.  (If DDMS is not
300      * attached when tracing ends, the profiling data will be discarded.)
301      *
302      * @param bufferSize      the maximum size of both files combined. If passed
303      *                        as {@code 0}, it defaults to 8MB.
304      * @param flags           flags to control method tracing. The only one that
305      *                        is currently defined is {@link #TRACE_COUNT_ALLOCS}.
306      * @param samplingEnabled if true, sample profiling is enabled. Otherwise,
307      *                        method instrumentation is used.
308      * @param intervalUs      the time between samples in microseconds when
309      *                        sampling is enabled.
310      *
311      * @hide
312      */
313     @SystemApi(client = MODULE_LIBRARIES)
startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs)314     public static void startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs) {
315         startMethodTracingDdmsImpl(checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs);
316     }
317 
checkBufferSize(int bufferSize)318     private static int checkBufferSize(int bufferSize) {
319         if (bufferSize == 0) {
320             // Default to 8MB per the documentation.
321             bufferSize = 8 * 1024 * 1024;
322         }
323         if (bufferSize < 1024) {
324             throw new IllegalArgumentException("buffer size < 1024: " + bufferSize);
325         }
326         return bufferSize;
327     }
328 
startMethodTracingDdmsImpl(int bufferSize, int flags, boolean samplingEnabled, int intervalUs)329     private static native void startMethodTracingDdmsImpl(int bufferSize, int flags, boolean samplingEnabled, int intervalUs);
startMethodTracingFd(String traceFileName, int fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs, boolean streamingOutput)330     private static native void startMethodTracingFd(String traceFileName, int fd, int bufferSize,
331             int flags, boolean samplingEnabled, int intervalUs, boolean streamingOutput);
startMethodTracingFilename(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs)332     private static native void startMethodTracingFilename(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs);
333 
334     /**
335      * Determine whether method tracing is currently active and what type is
336      * active.
337      *
338      * @hide
339      */
340     @SystemApi(client = MODULE_LIBRARIES)
getMethodTracingMode()341     public static native int getMethodTracingMode();
342 
343     /**
344      * Stops method tracing.
345      *
346      * @hide
347      */
348     @SystemApi(client = MODULE_LIBRARIES)
stopMethodTracing()349     public static native void stopMethodTracing();
350 
351     /**
352      * Get an indication of thread CPU usage. The value returned indicates the
353      * amount of time that the current thread has spent executing code or
354      * waiting for certain types of I/O.
355      * <p>
356      * The time is expressed in nanoseconds, and is only meaningful when
357      * compared to the result from an earlier call. Note that nanosecond
358      * resolution does not imply nanosecond accuracy.
359      *
360      * @return the CPU usage. A value of -1 means the system does not support
361      *         this feature.
362      *
363      * @hide
364      */
365     @SystemApi(client = MODULE_LIBRARIES)
366     @FastNative
threadCpuTimeNanos()367     public static native long threadCpuTimeNanos();
368 
369     /**
370      * Starts counting the number and aggregate size of memory allocations.
371      *
372      * @hide
373      */
374     @SystemApi(client = MODULE_LIBRARIES)
startAllocCounting()375     public static native void startAllocCounting();
376 
377     /**
378      * Stops counting the number and aggregate size of memory allocations.
379      *
380      * @hide
381      */
382     @SystemApi(client = MODULE_LIBRARIES)
stopAllocCounting()383     public static native void stopAllocCounting();
384 
385     /**
386      * Returns information on the number of objects allocated by the runtime between a
387      * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
388      *
389      * @param kind either {@code KIND_GLOBAL_*} or {@code KIND_THREAD_*}.
390      *
391      * @hide
392      */
393     @SystemApi(client = MODULE_LIBRARIES)
getAllocCount(int kind)394     public static native int getAllocCount(int kind);
395 
396     /**
397      * Resets counting the number and aggregate size of memory allocations for the given kinds.
398      *
399      * @param kinds a union of {@code KIND_GLOBAL_*} and {@code KIND_THREAD_*}.
400      *
401      * @hide
402      */
403     @SystemApi(client = MODULE_LIBRARIES)
resetAllocCount(int kinds)404     public static native void resetAllocCount(int kinds);
405 
406     /**
407      * Represents the location of a java method within a process'
408      * memory.
409      *
410      * @hide
411      */
412     @SystemApi(client = MODULE_LIBRARIES)
413     public static class ExecutableMethodFileOffsets {
414         private final @NonNull String mContainerPath;
415         private final long mContainerOffset;
416         private final long mMethodOffset;
417 
ExecutableMethodFileOffsets( @onNull String containerPath, long containerOffset, long methodOffset)418         private ExecutableMethodFileOffsets(
419                 @NonNull String containerPath, long containerOffset, long methodOffset) {
420             this.mContainerPath = containerPath;
421             this.mContainerOffset = containerOffset;
422             this.mMethodOffset = methodOffset;
423         }
424 
425         /**
426          * The OS path of the containing file (could be virtual).
427          *
428          * @hide
429          */
430         @SystemApi(client = MODULE_LIBRARIES)
getContainerPath()431         public @NonNull String getContainerPath() {
432             return mContainerPath;
433         }
434 
435         /**
436          * The offset of the containing file within the process' memory.
437          *
438          * @hide
439          */
440         @SystemApi(client = MODULE_LIBRARIES)
getContainerOffset()441         public long getContainerOffset() {
442             return mContainerOffset;
443         }
444 
445         /**
446          * The offset of the method within the containing file.
447          *
448          * @hide
449          */
450         @SystemApi(client = MODULE_LIBRARIES)
getMethodOffset()451         public long getMethodOffset() {
452             return mMethodOffset;
453         }
454     }
455 
456     private static native @Nullable ExecutableMethodFileOffsets
getExecutableMethodFileOffsetsNative(Method javaMethod)457         getExecutableMethodFileOffsetsNative(Method javaMethod);
458 
459     /**
460      * Fetches offset information about the location of the native executable code within the
461      * running process' memory.
462      *
463      * @param javaMethod method for which info is to be identified.
464      * @return {@link ExecutableMethodFileOffsets} containing offset information for the specified
465      *         method, or null if the method is not AOT compiled.
466      * @throws RuntimeException for unexpected failures in ART retrieval of info.
467      *
468      * @hide
469      */
470     @SystemApi(client = MODULE_LIBRARIES)
getExecutableMethodFileOffsets( @onNull Method javaMethod)471     public static @Nullable ExecutableMethodFileOffsets getExecutableMethodFileOffsets(
472             @NonNull Method javaMethod) {
473         return getExecutableMethodFileOffsetsNative(javaMethod);
474     }
475 
476     /**
477      * This method exists for binary compatibility.  It was part of
478      * the allocation limits API which was removed in Android 3.0 (Honeycomb).
479      *
480      * @hide
481      */
482     @Deprecated
setAllocationLimit(int limit)483     public static int setAllocationLimit(int limit) {
484         return -1;
485     }
486 
487     /**
488      * This method exists for binary compatibility.  It was part of
489      * the allocation limits API which was removed in Android 3.0 (Honeycomb).
490      *
491      * @hide
492      */
493     @Deprecated
setGlobalAllocationLimit(int limit)494     public static int setGlobalAllocationLimit(int limit) {
495         return -1;
496     }
497 
498     /**
499      * Count the number of instructions executed between two points.
500      *
501      * @hide
502      */
503     @Deprecated
startInstructionCounting()504     public static void startInstructionCounting() {}
505 
506     /**
507      *
508      * @hide
509      */
510     @Deprecated
stopInstructionCounting()511     public static void stopInstructionCounting() {}
512 
513     /**
514      *
515      * @hide
516      */
517     @Deprecated
getInstructionCount(int[] counts)518     public static void getInstructionCount(int[] counts) {}
519 
520     /**
521      *
522      * @hide
523      */
524     @Deprecated
resetInstructionCount()525     public static void resetInstructionCount() {}
526 
527     /**
528      * Dumps a list of loaded class to the log file.
529      *
530      * @param flags a union of {@link android.os.Debug.SHOW_FULL_DETAIL},
531      *    {@link android.os.Debug.SHOW_CLASSLOADER}, and {@link android.os.Debug.SHOW_INITIALIZED}.
532      *
533      * @hide
534      */
535     @SystemApi(client = MODULE_LIBRARIES)
536     @FastNative
printLoadedClasses(int flags)537     public static native void printLoadedClasses(int flags);
538 
539     /**
540      * Gets the number of loaded classes.
541      *
542      * @return the number of loaded classes
543      *
544      * @hide
545      */
546     @SystemApi(client = MODULE_LIBRARIES)
547     @FastNative
getLoadedClassCount()548     public static native int getLoadedClassCount();
549 
550     /**
551      * Dumps "hprof" data to the specified file.  This may cause a GC.
552      *
553      * The VM may create a temporary file in the same directory.
554      *
555      * @param filename Full pathname of output file (e.g. "/sdcard/dump.hprof").
556      * @throws UnsupportedOperationException if the VM was built without
557      *         HPROF support.
558      * @throws IOException if an error occurs while opening or writing files.
559      *
560      * @hide
561      */
562     @SystemApi(client = MODULE_LIBRARIES)
dumpHprofData(String filename)563     public static void dumpHprofData(String filename) throws IOException {
564         if (filename == null) {
565             throw new NullPointerException("filename == null");
566         }
567         dumpHprofData(filename, null);
568     }
569 
570     /**
571      * Collects "hprof" heap data and sends it to DDMS.  This may cause a GC.
572      *
573      * @throws UnsupportedOperationException if the VM was built without
574      *         HPROF support.
575      *
576      * @hide
577      */
578     @SystemApi(client = MODULE_LIBRARIES)
dumpHprofDataDdms()579     public static native void dumpHprofDataDdms();
580 
581     /**
582      * Dumps "hprof" heap data to a file, by name or descriptor.
583      *
584      * @param fileName Name of output file.  If fd is non-null, the
585      *        file name is only used in log messages (and may be null).
586      * @param fd Descriptor of open file that will receive the output.
587      *        If this is null, the fileName is used instead.
588      * @throws {@link IOException} if an error occurs while opening or writing files.
589      *
590      * @hide
591      */
592     @SystemApi(client = MODULE_LIBRARIES)
dumpHprofData(String fileName, FileDescriptor fd)593     public static void dumpHprofData(String fileName, FileDescriptor fd)
594             throws IOException {
595        dumpHprofData(fileName, fd != null ? fd.getInt$() : -1);
596     }
597 
dumpHprofData(String fileName, int fd)598     private static native void dumpHprofData(String fileName, int fd)
599             throws IOException;
600 
601     /**
602      * Dumps the contents of the VM reference tables (e.g. JNI locals and
603      * globals) to the log file.
604      *
605      * @hide
606      */
607     @UnsupportedAppUsage
608     @SystemApi(client = MODULE_LIBRARIES)
dumpReferenceTables()609     public static native void dumpReferenceTables();
610 
611     /**
612      * Counts the instances of a class.
613      * It is the caller's responsibility to do GC if they don't want unreachable
614      * objects to get counted.
615      *
616      * @param klass the class to be counted.
617      * @param assignable if true, any instance whose class is assignable to
618      *                   {@code klass}, as defined by {@link Class#isAssignableFrom},
619      *                   is counted. If false, only instances whose class is
620      *                   equal to {@code klass} are counted.
621      * @return the number of matching instances.
622      *
623      * @hide
624      */
625     @SystemApi(client = MODULE_LIBRARIES)
countInstancesOfClass(Class klass, boolean assignable)626     public static native long countInstancesOfClass(Class klass, boolean assignable);
627 
628     /**
629      * Counts the instances of classes.
630      * It is the caller's responsibility to do GC if they don't want unreachable
631      * objects to get counted.
632      *
633      * @param classes the classes to be counted.
634      * @param assignable if true, any instance whose class is assignable to
635      *                   {@code classes[i]}, as defined by {@link Class#isAssignableFrom},
636      *                   is counted. If false, only instances whose class is
637      *                   equal to {@code classes[i]} are counted.
638      * @return an array containing the number of matching instances. The value
639      *         for index {@code i} is the number of instances of
640      *         the class {@code classes[i]}
641      *
642      * @hide
643      */
644     @SystemApi(client = MODULE_LIBRARIES)
countInstancesOfClasses(Class[] classes, boolean assignable)645     public static native long[] countInstancesOfClasses(Class[] classes, boolean assignable);
646 
647     /* Map from the names of the runtime stats supported by getRuntimeStat() to their IDs */
648     private static final HashMap<String, Integer> runtimeStatsMap = new HashMap<>();
649 
650     static {
651         runtimeStatsMap.put("art.gc.gc-count", 0);
652         runtimeStatsMap.put("art.gc.gc-time", 1);
653         runtimeStatsMap.put("art.gc.bytes-allocated", 2);
654         runtimeStatsMap.put("art.gc.bytes-freed", 3);
655         runtimeStatsMap.put("art.gc.blocking-gc-count", 4);
656         runtimeStatsMap.put("art.gc.blocking-gc-time", 5);
657         runtimeStatsMap.put("art.gc.gc-count-rate-histogram", 6);
658         runtimeStatsMap.put("art.gc.blocking-gc-count-rate-histogram", 7);
659         runtimeStatsMap.put("art.gc.objects-allocated", 8);
660         runtimeStatsMap.put("art.gc.total-time-waiting-for-gc", 9);
661         runtimeStatsMap.put("art.gc.pre-oome-gc-count", 10);
662     }
663 
664     /**
665      * Returns the value of a particular runtime statistic or {@code null} if no
666      * such runtime statistic exists.
667      *
668      * @param statName the name of the runtime statistic to look up.
669      *
670      * @return the value of the runtime statistic.
671      *
672      * @hide
673      */
674     @SystemApi(client = MODULE_LIBRARIES)
getRuntimeStat(String statName)675     public static String getRuntimeStat(String statName) {
676         if (statName == null) {
677             throw new NullPointerException("statName == null");
678         }
679         Integer statId = runtimeStatsMap.get(statName);
680         if (statId != null) {
681             return getRuntimeStatInternal(statId);
682         }
683         return null;
684     }
685 
686     /**
687      * Returns a map of the names/values of the runtime statistics
688      * that {@link #getRuntimeStat()} supports.
689      *
690      * @return a map of the names/values of the supported runtime statistics.
691      *
692      * @hide
693      */
694     @SystemApi(client = MODULE_LIBRARIES)
getRuntimeStats()695     public static Map<String, String> getRuntimeStats() {
696         HashMap<String, String> map = new HashMap<>();
697         String[] values = getRuntimeStatsInternal();
698         for (String name : runtimeStatsMap.keySet()) {
699             int id = runtimeStatsMap.get(name);
700             String value = values[id];
701             map.put(name, value);
702         }
703         return map;
704     }
705 
getRuntimeStatInternal(int statId)706     private static native String getRuntimeStatInternal(int statId);
getRuntimeStatsInternal()707     private static native String[] getRuntimeStatsInternal();
708 
709     /**
710      * Attaches an agent to the VM.
711      *
712      * @param agent       The path to the agent .so file plus optional agent arguments.
713      * @param classLoader The classloader to use as a loading context.
714      *
715      * @throws IOException if an error occurs while opening {@code agent} file.
716      *
717      * @hide
718      */
719     @SystemApi(client = MODULE_LIBRARIES)
attachAgent(String agent, ClassLoader classLoader)720     public static void attachAgent(String agent, ClassLoader classLoader) throws IOException {
721         nativeAttachAgent(agent, classLoader);
722     }
723 
nativeAttachAgent(String agent, ClassLoader classLoader)724     private static native void nativeAttachAgent(String agent, ClassLoader classLoader)
725             throws IOException;
726 
727     /**
728      * Exempts a class from any future non-SDK API access checks.
729      * Methods declared in the class will be allowed to perform
730      * reflection/JNI against the framework completely unrestricted.
731      * Note that this does not affect uses of non-SDK APIs that the class links against.
732      * Note that this does not affect methods declared outside this class, e.g.
733      * inherited from a superclass or an implemented interface.
734      *
735      * @param klass The class whose methods should be exempted.
736      *
737      * @hide
738      */
739     @UnsupportedAppUsage
allowHiddenApiReflectionFrom(Class<?> klass)740     public static native void allowHiddenApiReflectionFrom(Class<?> klass);
741 
742     /**
743      * Sets the number of frames recorded for allocation tracking.
744      *
745      * @param stackDepth The number of frames captured for each stack trace.
746      *
747      * @hide
748      */
749     @SystemApi(client = MODULE_LIBRARIES)
setAllocTrackerStackDepth(int stackDepth)750     public static native void setAllocTrackerStackDepth(int stackDepth);
751 
752     /**
753      * Called every time the Process is renamed (via android.os.Process)
754      * This is a no-op on host.
755      *
756      * @param processName The new name of the process.
757      *
758      * @hide
759      **/
760     @SystemApi(client = MODULE_LIBRARIES)
setCurrentProcessName(@onNull String processName)761     public static native void setCurrentProcessName(@NonNull String processName);
762 
763     /**
764      * Called every time an app is added to the current Process
765      * This is a no-op on host.
766      *
767      * @param packageName The package name of the added app.
768      *
769      * @hide
770      **/
771     @SystemApi(client = MODULE_LIBRARIES)
addApplication(@onNull String packageName)772     public static native void addApplication(@NonNull String packageName);
773 
774     /**
775      * Called every time an app is removed from the current Process
776      * This is a no-op on host.
777      *
778      * @param packageName The package name of the removed app.
779      *
780      * @hide
781      **/
782     @SystemApi(client = MODULE_LIBRARIES)
removeApplication(@onNull String packageName)783     public static native void removeApplication(@NonNull String packageName);
784 
785     /**
786      * Called as soon as Zygote specialize and knows the Android User ID.
787      * This is a no-op on host.
788      *
789      * @param userId The Android User ID.
790      *
791      * @hide
792      **/
793     @SystemApi(client = MODULE_LIBRARIES)
setUserId(@serIdInt int userId)794     public static native void setUserId(@UserIdInt int userId);
795 
796     /**
797      * Signal to ART we are waiting for the debugger
798      * This is a no-op on host.
799      *
800      * @hide
801      */
802     @SystemApi(client = MODULE_LIBRARIES)
setWaitingForDebugger(boolean waiting)803     public static native void setWaitingForDebugger(boolean waiting);
804 
805 
806     /**
807      * A class to encapsulate different modes of trace output. Currently traceFileName and file
808      * descriptor are supported.
809      *
810      * @hide
811      */
812    @SystemApi(client = MODULE_LIBRARIES)
813     public static class TraceDestination {
814         private final String traceFileName;
815         private final FileDescriptor fd;
816 
TraceDestination(String traceFileName, FileDescriptor fd)817         private TraceDestination(String traceFileName, FileDescriptor fd) {
818             this.traceFileName = traceFileName;
819             this.fd = fd;
820         }
821 
822         /** @hide */
getFd()823         public int getFd() {
824             return fd.getInt$();
825         }
826 
827         /** @hide */
getFileName()828         public String getFileName() {
829             return traceFileName;
830         }
831 
832         /**
833          * Returns a TraceDestination that uses a fileName. Use this to provide a fileName to dump
834          * the generated trace.
835          *
836          * @hide
837          */
838         @SystemApi(client = MODULE_LIBRARIES)
fromFileName(@onNull String traceFileName)839         public static @NonNull TraceDestination fromFileName(@NonNull String traceFileName) {
840             return new TraceDestination(traceFileName,  null);
841         }
842 
843         /**
844          * Returns a TraceDestination that uses a file descriptor. Use this to provide a file
845          * descriptor to dump the generated trace.
846          *
847          * @hide
848          */
849         @SystemApi(client = MODULE_LIBRARIES)
fromFileDescriptor(@onNull FileDescriptor fd)850         public static @NonNull TraceDestination fromFileDescriptor(@NonNull FileDescriptor fd) {
851             return new TraceDestination(null, fd);
852         }
853     }
854 
855     /**
856      * Start an ART trace of executed dex methods. This uses a circular buffer to store entries
857      * so it will only hold the most recently executed ones. The tracing is not precise.
858      * If a low overhead tracing is already in progress then this request is ignored but an error
859      * will be logged. The ongoing trace will not be impacted. For example, if there are two calls
860      * to {@link #startLowOverheadTrace} without a {@link #stopLowOverheadTrace} in between, the
861      * second request is ignored after logging an error. The first one will continue to trace until
862      * the next {@link #stopLowOverheadTrace} call.
863      *
864      * @hide
865      */
866     @SystemApi(client = MODULE_LIBRARIES)
startLowOverheadTrace()867     public static void startLowOverheadTrace() {
868         startLowOverheadTraceImpl();
869     }
870 
871     /**
872      * Stop an ongoing ART trace of executed dex methods. If there is no ongoing trace then this
873      * request is ignored and an error will be logged.
874      *
875      * @hide
876      */
877     @SystemApi(client = MODULE_LIBRARIES)
stopLowOverheadTrace()878     public static void stopLowOverheadTrace() {
879         stopLowOverheadTraceImpl();
880     }
881 
882     /**
883      * Dump the collected trace into the trace file provided.
884      *
885      * The trace destination can be a file descriptor or a file name. If the file name or the file
886      * descriptor aren't valid we log an error and ignore the request. When a filename is provided
887      * and a file already exists this method unlinks the file and creates a new file for writing.
888      * This method unlinks instead of overwriting to prevent any problems if there are other uses
889      * of the file. If the file does not exist then a new file is created. If for any reason the
890      * file cannot be created then this method logs an error and the method returns.
891      *
892      * @hide
893      */
894     @SystemApi(client = MODULE_LIBRARIES)
dumpLowOverheadTrace(@onNull TraceDestination traceOutput)895     public static void dumpLowOverheadTrace(@NonNull TraceDestination traceOutput) {
896         if (traceOutput.getFd() == -1) {
897             dumpLowOverheadTraceImpl(traceOutput.getFileName());
898         } else {
899             dumpLowOverheadTraceFdImpl(traceOutput.getFd());
900         }
901     }
902 
startLowOverheadTraceImpl()903     private static native void startLowOverheadTraceImpl();
stopLowOverheadTraceImpl()904     private static native void stopLowOverheadTraceImpl();
dumpLowOverheadTraceImpl(String traceFileName)905     private static native void dumpLowOverheadTraceImpl(String traceFileName);
dumpLowOverheadTraceFdImpl(int fd)906     private static native void dumpLowOverheadTraceFdImpl(int fd);
907 
908 }
909