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