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