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