1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker import java.io.File; 18*795d594fSAndroid Build Coastguard Worker import java.io.IOException; 19*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method; 20*795d594fSAndroid Build Coastguard Worker import java.util.Arrays; 21*795d594fSAndroid Build Coastguard Worker import java.util.ArrayList; 22*795d594fSAndroid Build Coastguard Worker import java.util.Map; 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker public class Main { 25*795d594fSAndroid Build Coastguard Worker private static final String TEMP_FILE_NAME_PREFIX = "test"; 26*795d594fSAndroid Build Coastguard Worker private static final String TEMP_FILE_NAME_SUFFIX = ".trace"; 27*795d594fSAndroid Build Coastguard Worker main(String[] args)28*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) throws Exception { 29*795d594fSAndroid Build Coastguard Worker String name = System.getProperty("java.vm.name"); 30*795d594fSAndroid Build Coastguard Worker if (!"Dalvik".equals(name)) { 31*795d594fSAndroid Build Coastguard Worker System.out.println("This test is not supported on " + name); 32*795d594fSAndroid Build Coastguard Worker return; 33*795d594fSAndroid Build Coastguard Worker } 34*795d594fSAndroid Build Coastguard Worker testMethodTracing(); 35*795d594fSAndroid Build Coastguard Worker testCountInstances(); 36*795d594fSAndroid Build Coastguard Worker testRuntimeStat(); 37*795d594fSAndroid Build Coastguard Worker testRuntimeStats(); 38*795d594fSAndroid Build Coastguard Worker testGetAllocCount(); 39*795d594fSAndroid Build Coastguard Worker testGetVmFeatureList(); 40*795d594fSAndroid Build Coastguard Worker testDebuggerDetails(); 41*795d594fSAndroid Build Coastguard Worker } 42*795d594fSAndroid Build Coastguard Worker createTempFile()43*795d594fSAndroid Build Coastguard Worker private static File createTempFile() throws Exception { 44*795d594fSAndroid Build Coastguard Worker try { 45*795d594fSAndroid Build Coastguard Worker return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 46*795d594fSAndroid Build Coastguard Worker } catch (IOException e) { 47*795d594fSAndroid Build Coastguard Worker System.setProperty("java.io.tmpdir", "/data/local/tmp"); 48*795d594fSAndroid Build Coastguard Worker try { 49*795d594fSAndroid Build Coastguard Worker return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 50*795d594fSAndroid Build Coastguard Worker } catch (IOException e2) { 51*795d594fSAndroid Build Coastguard Worker System.setProperty("java.io.tmpdir", "/sdcard"); 52*795d594fSAndroid Build Coastguard Worker return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 53*795d594fSAndroid Build Coastguard Worker } 54*795d594fSAndroid Build Coastguard Worker } 55*795d594fSAndroid Build Coastguard Worker } 56*795d594fSAndroid Build Coastguard Worker testMethodTracing()57*795d594fSAndroid Build Coastguard Worker private static void testMethodTracing() throws Exception { 58*795d594fSAndroid Build Coastguard Worker File tempFile = null; 59*795d594fSAndroid Build Coastguard Worker try { 60*795d594fSAndroid Build Coastguard Worker tempFile = createTempFile(); 61*795d594fSAndroid Build Coastguard Worker testMethodTracingToFile(tempFile); 62*795d594fSAndroid Build Coastguard Worker } finally { 63*795d594fSAndroid Build Coastguard Worker if (tempFile != null) { 64*795d594fSAndroid Build Coastguard Worker tempFile.delete(); 65*795d594fSAndroid Build Coastguard Worker } 66*795d594fSAndroid Build Coastguard Worker } 67*795d594fSAndroid Build Coastguard Worker } 68*795d594fSAndroid Build Coastguard Worker testMethodTracingToFile(File tempFile)69*795d594fSAndroid Build Coastguard Worker private static void testMethodTracingToFile(File tempFile) throws Exception { 70*795d594fSAndroid Build Coastguard Worker String tempFileName = tempFile.getPath(); 71*795d594fSAndroid Build Coastguard Worker 72*795d594fSAndroid Build Coastguard Worker if (VMDebug.getMethodTracingMode() != 0) { 73*795d594fSAndroid Build Coastguard Worker VMDebug.stopMethodTracing(); 74*795d594fSAndroid Build Coastguard Worker } 75*795d594fSAndroid Build Coastguard Worker 76*795d594fSAndroid Build Coastguard Worker System.out.println("Confirm enable/disable"); 77*795d594fSAndroid Build Coastguard Worker System.out.println("status=" + VMDebug.getMethodTracingMode()); 78*795d594fSAndroid Build Coastguard Worker VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0); 79*795d594fSAndroid Build Coastguard Worker System.out.println("status=" + VMDebug.getMethodTracingMode()); 80*795d594fSAndroid Build Coastguard Worker VMDebug.stopMethodTracing(); 81*795d594fSAndroid Build Coastguard Worker System.out.println("status=" + VMDebug.getMethodTracingMode()); 82*795d594fSAndroid Build Coastguard Worker if (tempFile.length() == 0) { 83*795d594fSAndroid Build Coastguard Worker System.out.println("ERROR: tracing output file is empty"); 84*795d594fSAndroid Build Coastguard Worker } 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker System.out.println("Confirm sampling"); 87*795d594fSAndroid Build Coastguard Worker VMDebug.startMethodTracing(tempFileName, 0, 0, true, 1000); 88*795d594fSAndroid Build Coastguard Worker System.out.println("status=" + VMDebug.getMethodTracingMode()); 89*795d594fSAndroid Build Coastguard Worker VMDebug.stopMethodTracing(); 90*795d594fSAndroid Build Coastguard Worker System.out.println("status=" + VMDebug.getMethodTracingMode()); 91*795d594fSAndroid Build Coastguard Worker if (tempFile.length() == 0) { 92*795d594fSAndroid Build Coastguard Worker System.out.println("ERROR: sample tracing output file is empty"); 93*795d594fSAndroid Build Coastguard Worker } 94*795d594fSAndroid Build Coastguard Worker 95*795d594fSAndroid Build Coastguard Worker System.out.println("Test starting when already started"); 96*795d594fSAndroid Build Coastguard Worker VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0); 97*795d594fSAndroid Build Coastguard Worker System.out.println("status=" + VMDebug.getMethodTracingMode()); 98*795d594fSAndroid Build Coastguard Worker VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0); 99*795d594fSAndroid Build Coastguard Worker System.out.println("status=" + VMDebug.getMethodTracingMode()); 100*795d594fSAndroid Build Coastguard Worker 101*795d594fSAndroid Build Coastguard Worker System.out.println("Test stopping when already stopped"); 102*795d594fSAndroid Build Coastguard Worker VMDebug.stopMethodTracing(); 103*795d594fSAndroid Build Coastguard Worker System.out.println("status=" + VMDebug.getMethodTracingMode()); 104*795d594fSAndroid Build Coastguard Worker VMDebug.stopMethodTracing(); 105*795d594fSAndroid Build Coastguard Worker System.out.println("status=" + VMDebug.getMethodTracingMode()); 106*795d594fSAndroid Build Coastguard Worker 107*795d594fSAndroid Build Coastguard Worker System.out.println("Test tracing with empty filename"); 108*795d594fSAndroid Build Coastguard Worker try { 109*795d594fSAndroid Build Coastguard Worker VMDebug.startMethodTracing("", 0, 0, false, 0); 110*795d594fSAndroid Build Coastguard Worker System.out.println("Should have thrown an exception"); 111*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 112*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected exception"); 113*795d594fSAndroid Build Coastguard Worker } 114*795d594fSAndroid Build Coastguard Worker 115*795d594fSAndroid Build Coastguard Worker System.out.println("Test tracing with bogus (< 1024 && != 0) filesize"); 116*795d594fSAndroid Build Coastguard Worker try { 117*795d594fSAndroid Build Coastguard Worker VMDebug.startMethodTracing(tempFileName, 1000, 0, false, 0); 118*795d594fSAndroid Build Coastguard Worker System.out.println("Should have thrown an exception"); 119*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 120*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected exception"); 121*795d594fSAndroid Build Coastguard Worker } 122*795d594fSAndroid Build Coastguard Worker 123*795d594fSAndroid Build Coastguard Worker try { 124*795d594fSAndroid Build Coastguard Worker VMDebug.startMethodTracingDdms(1000, 0, false, 0); 125*795d594fSAndroid Build Coastguard Worker System.out.println("Should have thrown an exception"); 126*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 127*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected exception"); 128*795d594fSAndroid Build Coastguard Worker } 129*795d594fSAndroid Build Coastguard Worker 130*795d594fSAndroid Build Coastguard Worker System.out.println("Test sampling with bogus (<= 0) interval"); 131*795d594fSAndroid Build Coastguard Worker try { 132*795d594fSAndroid Build Coastguard Worker VMDebug.startMethodTracing(tempFileName, 0, 0, true, 0); 133*795d594fSAndroid Build Coastguard Worker System.out.println("Should have thrown an exception"); 134*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 135*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected exception"); 136*795d594fSAndroid Build Coastguard Worker } 137*795d594fSAndroid Build Coastguard Worker try { 138*795d594fSAndroid Build Coastguard Worker VMDebug.startMethodTracingDdms(0, 0, true, 0); 139*795d594fSAndroid Build Coastguard Worker System.out.println("Should have thrown an exception"); 140*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 141*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected exception"); 142*795d594fSAndroid Build Coastguard Worker } 143*795d594fSAndroid Build Coastguard Worker 144*795d594fSAndroid Build Coastguard Worker tempFile.delete(); 145*795d594fSAndroid Build Coastguard Worker } 146*795d594fSAndroid Build Coastguard Worker checkNumber(String s)147*795d594fSAndroid Build Coastguard Worker private static void checkNumber(String s) throws Exception { 148*795d594fSAndroid Build Coastguard Worker if (s == null) { 149*795d594fSAndroid Build Coastguard Worker System.out.println("Got null string"); 150*795d594fSAndroid Build Coastguard Worker return; 151*795d594fSAndroid Build Coastguard Worker } 152*795d594fSAndroid Build Coastguard Worker long n = Long.parseLong(s); 153*795d594fSAndroid Build Coastguard Worker if (n < 0) { 154*795d594fSAndroid Build Coastguard Worker System.out.println("Got negative number " + n); 155*795d594fSAndroid Build Coastguard Worker } 156*795d594fSAndroid Build Coastguard Worker } 157*795d594fSAndroid Build Coastguard Worker checkBiggerThanZero(int i)158*795d594fSAndroid Build Coastguard Worker private static void checkBiggerThanZero(int i) throws Exception { 159*795d594fSAndroid Build Coastguard Worker if (i <= 0) { 160*795d594fSAndroid Build Coastguard Worker System.out.println("Got zero or smaller " + i); 161*795d594fSAndroid Build Coastguard Worker } 162*795d594fSAndroid Build Coastguard Worker } 163*795d594fSAndroid Build Coastguard Worker checkZero(int i)164*795d594fSAndroid Build Coastguard Worker private static void checkZero(int i) throws Exception { 165*795d594fSAndroid Build Coastguard Worker if (i != 0) { 166*795d594fSAndroid Build Coastguard Worker System.out.println("Got non-zero result after reset " + i); 167*795d594fSAndroid Build Coastguard Worker } 168*795d594fSAndroid Build Coastguard Worker } 169*795d594fSAndroid Build Coastguard Worker checkHistogram(String s)170*795d594fSAndroid Build Coastguard Worker private static void checkHistogram(String s) throws Exception { 171*795d594fSAndroid Build Coastguard Worker if (s == null || s.length() == 0) { 172*795d594fSAndroid Build Coastguard Worker System.out.println("Got null or empty string"); 173*795d594fSAndroid Build Coastguard Worker return; 174*795d594fSAndroid Build Coastguard Worker } 175*795d594fSAndroid Build Coastguard Worker String[] buckets = s.split(","); 176*795d594fSAndroid Build Coastguard Worker long last_key = 0; 177*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < buckets.length; ++i) { 178*795d594fSAndroid Build Coastguard Worker String bucket = buckets[i]; 179*795d594fSAndroid Build Coastguard Worker if (bucket.length() == 0) { 180*795d594fSAndroid Build Coastguard Worker System.out.println("Got empty bucket"); 181*795d594fSAndroid Build Coastguard Worker continue; 182*795d594fSAndroid Build Coastguard Worker } 183*795d594fSAndroid Build Coastguard Worker String[] kv = bucket.split(":"); 184*795d594fSAndroid Build Coastguard Worker if (kv.length != 2 || kv[0].length() == 0 || kv[1].length() == 0) { 185*795d594fSAndroid Build Coastguard Worker System.out.println("Got bad bucket " + bucket); 186*795d594fSAndroid Build Coastguard Worker continue; 187*795d594fSAndroid Build Coastguard Worker } 188*795d594fSAndroid Build Coastguard Worker long key = Long.parseLong(kv[0]); 189*795d594fSAndroid Build Coastguard Worker long value = Long.parseLong(kv[1]); 190*795d594fSAndroid Build Coastguard Worker if (key < 0 || value < 0) { 191*795d594fSAndroid Build Coastguard Worker System.out.println("Got negative key or value " + bucket); 192*795d594fSAndroid Build Coastguard Worker continue; 193*795d594fSAndroid Build Coastguard Worker } 194*795d594fSAndroid Build Coastguard Worker if (key < last_key) { 195*795d594fSAndroid Build Coastguard Worker System.out.println("Got decreasing key " + bucket); 196*795d594fSAndroid Build Coastguard Worker continue; 197*795d594fSAndroid Build Coastguard Worker } 198*795d594fSAndroid Build Coastguard Worker last_key = key; 199*795d594fSAndroid Build Coastguard Worker } 200*795d594fSAndroid Build Coastguard Worker } 201*795d594fSAndroid Build Coastguard Worker testRuntimeStat()202*795d594fSAndroid Build Coastguard Worker private static void testRuntimeStat() throws Exception { 203*795d594fSAndroid Build Coastguard Worker // Invoke at least one GC and wait for 20 seconds or so so we get at 204*795d594fSAndroid Build Coastguard Worker // least one bucket in the histograms. 205*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 20; ++i) { 206*795d594fSAndroid Build Coastguard Worker Runtime.getRuntime().gc(); 207*795d594fSAndroid Build Coastguard Worker Thread.sleep(1000L); 208*795d594fSAndroid Build Coastguard Worker } 209*795d594fSAndroid Build Coastguard Worker String gc_count = VMDebug.getRuntimeStat("art.gc.gc-count"); 210*795d594fSAndroid Build Coastguard Worker String gc_time = VMDebug.getRuntimeStat("art.gc.gc-time"); 211*795d594fSAndroid Build Coastguard Worker String bytes_allocated = VMDebug.getRuntimeStat("art.gc.bytes-allocated"); 212*795d594fSAndroid Build Coastguard Worker String bytes_freed = VMDebug.getRuntimeStat("art.gc.bytes-freed"); 213*795d594fSAndroid Build Coastguard Worker String blocking_gc_count = VMDebug.getRuntimeStat("art.gc.blocking-gc-count"); 214*795d594fSAndroid Build Coastguard Worker String blocking_gc_time = VMDebug.getRuntimeStat("art.gc.blocking-gc-time"); 215*795d594fSAndroid Build Coastguard Worker String gc_count_rate_histogram = VMDebug.getRuntimeStat("art.gc.gc-count-rate-histogram"); 216*795d594fSAndroid Build Coastguard Worker String blocking_gc_count_rate_histogram = 217*795d594fSAndroid Build Coastguard Worker VMDebug.getRuntimeStat("art.gc.blocking-gc-count-rate-histogram"); 218*795d594fSAndroid Build Coastguard Worker checkNumber(gc_count); 219*795d594fSAndroid Build Coastguard Worker checkNumber(gc_time); 220*795d594fSAndroid Build Coastguard Worker checkNumber(bytes_allocated); 221*795d594fSAndroid Build Coastguard Worker checkNumber(bytes_freed); 222*795d594fSAndroid Build Coastguard Worker checkNumber(blocking_gc_count); 223*795d594fSAndroid Build Coastguard Worker checkNumber(blocking_gc_time); 224*795d594fSAndroid Build Coastguard Worker checkHistogram(gc_count_rate_histogram); 225*795d594fSAndroid Build Coastguard Worker checkHistogram(blocking_gc_count_rate_histogram); 226*795d594fSAndroid Build Coastguard Worker } 227*795d594fSAndroid Build Coastguard Worker testRuntimeStats()228*795d594fSAndroid Build Coastguard Worker private static void testRuntimeStats() throws Exception { 229*795d594fSAndroid Build Coastguard Worker // Invoke at least one GC and wait for 20 seconds or so so we get at 230*795d594fSAndroid Build Coastguard Worker // least one bucket in the histograms. 231*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 20; ++i) { 232*795d594fSAndroid Build Coastguard Worker Runtime.getRuntime().gc(); 233*795d594fSAndroid Build Coastguard Worker Thread.sleep(1000L); 234*795d594fSAndroid Build Coastguard Worker } 235*795d594fSAndroid Build Coastguard Worker Map<String, String> map = VMDebug.getRuntimeStats(); 236*795d594fSAndroid Build Coastguard Worker String gc_count = map.get("art.gc.gc-count"); 237*795d594fSAndroid Build Coastguard Worker String gc_time = map.get("art.gc.gc-time"); 238*795d594fSAndroid Build Coastguard Worker String bytes_allocated = map.get("art.gc.bytes-allocated"); 239*795d594fSAndroid Build Coastguard Worker String bytes_freed = map.get("art.gc.bytes-freed"); 240*795d594fSAndroid Build Coastguard Worker String blocking_gc_count = map.get("art.gc.blocking-gc-count"); 241*795d594fSAndroid Build Coastguard Worker String blocking_gc_time = map.get("art.gc.blocking-gc-time"); 242*795d594fSAndroid Build Coastguard Worker String gc_count_rate_histogram = map.get("art.gc.gc-count-rate-histogram"); 243*795d594fSAndroid Build Coastguard Worker String blocking_gc_count_rate_histogram = 244*795d594fSAndroid Build Coastguard Worker map.get("art.gc.blocking-gc-count-rate-histogram"); 245*795d594fSAndroid Build Coastguard Worker checkNumber(gc_count); 246*795d594fSAndroid Build Coastguard Worker checkNumber(gc_time); 247*795d594fSAndroid Build Coastguard Worker checkNumber(bytes_allocated); 248*795d594fSAndroid Build Coastguard Worker checkNumber(bytes_freed); 249*795d594fSAndroid Build Coastguard Worker checkNumber(blocking_gc_count); 250*795d594fSAndroid Build Coastguard Worker checkNumber(blocking_gc_time); 251*795d594fSAndroid Build Coastguard Worker checkHistogram(gc_count_rate_histogram); 252*795d594fSAndroid Build Coastguard Worker checkHistogram(blocking_gc_count_rate_histogram); 253*795d594fSAndroid Build Coastguard Worker } 254*795d594fSAndroid Build Coastguard Worker 255*795d594fSAndroid Build Coastguard Worker /* constants for getAllocCount */ 256*795d594fSAndroid Build Coastguard Worker private static final int KIND_ALLOCATED_OBJECTS = 1<<0; 257*795d594fSAndroid Build Coastguard Worker private static final int KIND_ALLOCATED_BYTES = 1<<1; 258*795d594fSAndroid Build Coastguard Worker private static final int KIND_FREED_OBJECTS = 1<<2; 259*795d594fSAndroid Build Coastguard Worker private static final int KIND_FREED_BYTES = 1<<3; 260*795d594fSAndroid Build Coastguard Worker private static final int RESET_ALL = 0xffffffff; 261*795d594fSAndroid Build Coastguard Worker testGetAllocCount()262*795d594fSAndroid Build Coastguard Worker private static void testGetAllocCount() throws Exception { 263*795d594fSAndroid Build Coastguard Worker VMDebug.startAllocCounting(); 264*795d594fSAndroid Build Coastguard Worker 265*795d594fSAndroid Build Coastguard Worker ClassA a1 = new ClassA(); 266*795d594fSAndroid Build Coastguard Worker Object obj1 = new Object(); 267*795d594fSAndroid Build Coastguard Worker Runtime.getRuntime().gc(); 268*795d594fSAndroid Build Coastguard Worker 269*795d594fSAndroid Build Coastguard Worker int alloc_objects = VMDebug.getAllocCount(KIND_ALLOCATED_OBJECTS); 270*795d594fSAndroid Build Coastguard Worker int alloc_bytes = VMDebug.getAllocCount(KIND_ALLOCATED_BYTES); 271*795d594fSAndroid Build Coastguard Worker int freed_objects = VMDebug.getAllocCount(KIND_FREED_OBJECTS); 272*795d594fSAndroid Build Coastguard Worker int freed_bytes = VMDebug.getAllocCount(KIND_FREED_BYTES); 273*795d594fSAndroid Build Coastguard Worker checkBiggerThanZero(alloc_objects); 274*795d594fSAndroid Build Coastguard Worker checkBiggerThanZero(alloc_bytes); 275*795d594fSAndroid Build Coastguard Worker checkBiggerThanZero(freed_objects); 276*795d594fSAndroid Build Coastguard Worker checkBiggerThanZero(freed_bytes); 277*795d594fSAndroid Build Coastguard Worker 278*795d594fSAndroid Build Coastguard Worker VMDebug.stopAllocCounting(); 279*795d594fSAndroid Build Coastguard Worker VMDebug.resetAllocCount(RESET_ALL); 280*795d594fSAndroid Build Coastguard Worker checkZero(VMDebug.getAllocCount(KIND_ALLOCATED_OBJECTS)); 281*795d594fSAndroid Build Coastguard Worker checkZero(VMDebug.getAllocCount(KIND_ALLOCATED_BYTES)); 282*795d594fSAndroid Build Coastguard Worker checkZero(VMDebug.getAllocCount(KIND_FREED_OBJECTS)); 283*795d594fSAndroid Build Coastguard Worker checkZero(VMDebug.getAllocCount(KIND_FREED_BYTES)); 284*795d594fSAndroid Build Coastguard Worker 285*795d594fSAndroid Build Coastguard Worker // Even if we create new classes the count should remain 0. 286*795d594fSAndroid Build Coastguard Worker ClassA a2 = new ClassA(); 287*795d594fSAndroid Build Coastguard Worker Object obj2 = new Object(); 288*795d594fSAndroid Build Coastguard Worker 289*795d594fSAndroid Build Coastguard Worker checkZero(VMDebug.getAllocCount(KIND_ALLOCATED_OBJECTS)); 290*795d594fSAndroid Build Coastguard Worker } 291*795d594fSAndroid Build Coastguard Worker testGetVmFeatureList()292*795d594fSAndroid Build Coastguard Worker private static void testGetVmFeatureList() throws Exception { 293*795d594fSAndroid Build Coastguard Worker String[] feature_list = VMDebug.getVmFeatureList(); 294*795d594fSAndroid Build Coastguard Worker if (feature_list.length == 0) { 295*795d594fSAndroid Build Coastguard Worker System.out.println("Got empty feature list"); 296*795d594fSAndroid Build Coastguard Worker } 297*795d594fSAndroid Build Coastguard Worker } 298*795d594fSAndroid Build Coastguard Worker testDebuggerDetails()299*795d594fSAndroid Build Coastguard Worker private static void testDebuggerDetails() throws Exception { 300*795d594fSAndroid Build Coastguard Worker boolean debugger_connected = VMDebug.isDebuggerConnected(); 301*795d594fSAndroid Build Coastguard Worker boolean debugging_enabled = VMDebug.isDebuggingEnabled(); 302*795d594fSAndroid Build Coastguard Worker long last_activity = VMDebug.lastDebuggerActivity(); 303*795d594fSAndroid Build Coastguard Worker if (debugger_connected && last_activity < 0) { 304*795d594fSAndroid Build Coastguard Worker System.out.println("Last debugging activity expected but not found"); 305*795d594fSAndroid Build Coastguard Worker } 306*795d594fSAndroid Build Coastguard Worker if (!debugger_connected && last_activity != -1) { 307*795d594fSAndroid Build Coastguard Worker System.out.println("Found unexpected last activity"); 308*795d594fSAndroid Build Coastguard Worker } 309*795d594fSAndroid Build Coastguard Worker if (VMDebug.threadCpuTimeNanos() <= 0) { 310*795d594fSAndroid Build Coastguard Worker System.out.println("Could not get CPU thread time"); 311*795d594fSAndroid Build Coastguard Worker } 312*795d594fSAndroid Build Coastguard Worker VMDebug.dumpHprofDataDdms(); 313*795d594fSAndroid Build Coastguard Worker VMDebug.dumpReferenceTables(); 314*795d594fSAndroid Build Coastguard Worker } 315*795d594fSAndroid Build Coastguard Worker 316*795d594fSAndroid Build Coastguard Worker static class ClassA { } 317*795d594fSAndroid Build Coastguard Worker static class ClassB { } 318*795d594fSAndroid Build Coastguard Worker static class ClassC extends ClassA { } 319*795d594fSAndroid Build Coastguard Worker testCountInstances()320*795d594fSAndroid Build Coastguard Worker private static void testCountInstances() throws Exception { 321*795d594fSAndroid Build Coastguard Worker ArrayList<Object> l = new ArrayList<Object>(); 322*795d594fSAndroid Build Coastguard Worker l.add(new ClassA()); 323*795d594fSAndroid Build Coastguard Worker l.add(new ClassB()); 324*795d594fSAndroid Build Coastguard Worker l.add(new ClassA()); 325*795d594fSAndroid Build Coastguard Worker l.add(new ClassC()); 326*795d594fSAndroid Build Coastguard Worker Runtime.getRuntime().gc(); 327*795d594fSAndroid Build Coastguard Worker System.out.println("Instances of ClassA " + 328*795d594fSAndroid Build Coastguard Worker VMDebug.countInstancesofClass(ClassA.class, false)); 329*795d594fSAndroid Build Coastguard Worker System.out.println("Instances of ClassB " + 330*795d594fSAndroid Build Coastguard Worker VMDebug.countInstancesofClass(ClassB.class, false)); 331*795d594fSAndroid Build Coastguard Worker System.out.println("Instances of null " + VMDebug.countInstancesofClass(null, false)); 332*795d594fSAndroid Build Coastguard Worker System.out.println("Instances of ClassA assignable " + 333*795d594fSAndroid Build Coastguard Worker VMDebug.countInstancesofClass(ClassA.class, true)); 334*795d594fSAndroid Build Coastguard Worker Class<?>[] classes = new Class<?>[] {ClassA.class, ClassB.class, null}; 335*795d594fSAndroid Build Coastguard Worker long[] counts = VMDebug.countInstancesofClasses(classes, false); 336*795d594fSAndroid Build Coastguard Worker System.out.println("Array counts " + Arrays.toString(counts)); 337*795d594fSAndroid Build Coastguard Worker counts = VMDebug.countInstancesofClasses(classes, true); 338*795d594fSAndroid Build Coastguard Worker System.out.println("Array counts assignable " + Arrays.toString(counts)); 339*795d594fSAndroid Build Coastguard Worker int class_count = VMDebug.getLoadedClassCount(); 340*795d594fSAndroid Build Coastguard Worker checkBiggerThanZero(class_count); 341*795d594fSAndroid Build Coastguard Worker } 342*795d594fSAndroid Build Coastguard Worker 343*795d594fSAndroid Build Coastguard Worker static class ClassD { 344*795d594fSAndroid Build Coastguard Worker public int mask; 345*795d594fSAndroid Build Coastguard Worker ClassD(int mask)346*795d594fSAndroid Build Coastguard Worker public ClassD(int mask) { 347*795d594fSAndroid Build Coastguard Worker this.mask = mask; 348*795d594fSAndroid Build Coastguard Worker } 349*795d594fSAndroid Build Coastguard Worker } 350*795d594fSAndroid Build Coastguard Worker 351*795d594fSAndroid Build Coastguard Worker static class ClassE extends ClassD { ClassE(int mask)352*795d594fSAndroid Build Coastguard Worker public ClassE(int mask) { 353*795d594fSAndroid Build Coastguard Worker super(mask); 354*795d594fSAndroid Build Coastguard Worker } 355*795d594fSAndroid Build Coastguard Worker } 356*795d594fSAndroid Build Coastguard Worker 357*795d594fSAndroid Build Coastguard Worker private static class VMDebug { 358*795d594fSAndroid Build Coastguard Worker private static final Method startMethodTracingMethod; 359*795d594fSAndroid Build Coastguard Worker private static final Method startMethodTracingDdmsMethod; 360*795d594fSAndroid Build Coastguard Worker private static final Method stopMethodTracingMethod; 361*795d594fSAndroid Build Coastguard Worker private static final Method getMethodTracingModeMethod; 362*795d594fSAndroid Build Coastguard Worker private static final Method getRuntimeStatMethod; 363*795d594fSAndroid Build Coastguard Worker private static final Method getRuntimeStatsMethod; 364*795d594fSAndroid Build Coastguard Worker private static final Method countInstancesOfClassMethod; 365*795d594fSAndroid Build Coastguard Worker private static final Method countInstancesOfClassesMethod; 366*795d594fSAndroid Build Coastguard Worker private static final Method getAllocCountMethod; 367*795d594fSAndroid Build Coastguard Worker private static final Method startAllocCountingMethod; 368*795d594fSAndroid Build Coastguard Worker private static final Method stopAllocCountingMethod; 369*795d594fSAndroid Build Coastguard Worker private static final Method setAllocTrackerStackDepthMethod; 370*795d594fSAndroid Build Coastguard Worker private static final Method resetAllocCountMethod; 371*795d594fSAndroid Build Coastguard Worker private static final Method getLoadedClassCountMethod; 372*795d594fSAndroid Build Coastguard Worker private static final Method getVmFeatureListMethod; 373*795d594fSAndroid Build Coastguard Worker private static final Method isDebuggerConnectedMethod; 374*795d594fSAndroid Build Coastguard Worker private static final Method isDebuggingEnabledMethod; 375*795d594fSAndroid Build Coastguard Worker private static final Method lastDebuggerActivityMethod; 376*795d594fSAndroid Build Coastguard Worker private static final Method threadCpuTimeNanosMethod; 377*795d594fSAndroid Build Coastguard Worker private static final Method dumpHprofDataDdmsMethod; 378*795d594fSAndroid Build Coastguard Worker private static final Method dumpReferenceTablesMethod; 379*795d594fSAndroid Build Coastguard Worker static { 380*795d594fSAndroid Build Coastguard Worker try { 381*795d594fSAndroid Build Coastguard Worker Class<?> c = Class.forName("dalvik.system.VMDebug"); 382*795d594fSAndroid Build Coastguard Worker startMethodTracingMethod = c.getDeclaredMethod("startMethodTracing", String.class, 383*795d594fSAndroid Build Coastguard Worker Integer.TYPE, Integer.TYPE, Boolean.TYPE, Integer.TYPE); 384*795d594fSAndroid Build Coastguard Worker startMethodTracingDdmsMethod = c.getDeclaredMethod("startMethodTracingDdms", 385*795d594fSAndroid Build Coastguard Worker Integer.TYPE, Integer.TYPE, Boolean.TYPE, Integer.TYPE); 386*795d594fSAndroid Build Coastguard Worker stopMethodTracingMethod = c.getDeclaredMethod("stopMethodTracing"); 387*795d594fSAndroid Build Coastguard Worker getMethodTracingModeMethod = c.getDeclaredMethod("getMethodTracingMode"); 388*795d594fSAndroid Build Coastguard Worker getRuntimeStatMethod = c.getDeclaredMethod("getRuntimeStat", String.class); 389*795d594fSAndroid Build Coastguard Worker getRuntimeStatsMethod = c.getDeclaredMethod("getRuntimeStats"); 390*795d594fSAndroid Build Coastguard Worker countInstancesOfClassMethod = c.getDeclaredMethod("countInstancesOfClass", 391*795d594fSAndroid Build Coastguard Worker Class.class, Boolean.TYPE); 392*795d594fSAndroid Build Coastguard Worker countInstancesOfClassesMethod = c.getDeclaredMethod("countInstancesOfClasses", 393*795d594fSAndroid Build Coastguard Worker Class[].class, Boolean.TYPE); 394*795d594fSAndroid Build Coastguard Worker getAllocCountMethod = c.getDeclaredMethod("getAllocCount", 395*795d594fSAndroid Build Coastguard Worker Integer.TYPE); 396*795d594fSAndroid Build Coastguard Worker startAllocCountingMethod = c.getDeclaredMethod("startAllocCounting"); 397*795d594fSAndroid Build Coastguard Worker stopAllocCountingMethod = c.getDeclaredMethod("stopAllocCounting"); 398*795d594fSAndroid Build Coastguard Worker setAllocTrackerStackDepthMethod = c.getDeclaredMethod("setAllocTrackerStackDepth", 399*795d594fSAndroid Build Coastguard Worker Integer.TYPE); 400*795d594fSAndroid Build Coastguard Worker resetAllocCountMethod = c.getDeclaredMethod("resetAllocCount", 401*795d594fSAndroid Build Coastguard Worker Integer.TYPE); 402*795d594fSAndroid Build Coastguard Worker getLoadedClassCountMethod = c.getDeclaredMethod("getLoadedClassCount"); 403*795d594fSAndroid Build Coastguard Worker getVmFeatureListMethod = c.getDeclaredMethod("getVmFeatureList"); 404*795d594fSAndroid Build Coastguard Worker isDebuggerConnectedMethod = c.getDeclaredMethod("isDebuggerConnected"); 405*795d594fSAndroid Build Coastguard Worker isDebuggingEnabledMethod = c.getDeclaredMethod("isDebuggingEnabled"); 406*795d594fSAndroid Build Coastguard Worker lastDebuggerActivityMethod = c.getDeclaredMethod("lastDebuggerActivity"); 407*795d594fSAndroid Build Coastguard Worker threadCpuTimeNanosMethod = c.getDeclaredMethod("threadCpuTimeNanos"); 408*795d594fSAndroid Build Coastguard Worker dumpHprofDataDdmsMethod = c.getDeclaredMethod("dumpHprofDataDdms"); 409*795d594fSAndroid Build Coastguard Worker dumpReferenceTablesMethod = c.getDeclaredMethod("dumpReferenceTables"); 410*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 411*795d594fSAndroid Build Coastguard Worker throw new RuntimeException(e); 412*795d594fSAndroid Build Coastguard Worker } 413*795d594fSAndroid Build Coastguard Worker } 414*795d594fSAndroid Build Coastguard Worker startMethodTracing(String filename, int bufferSize, int flags, boolean samplingEnabled, int intervalUs)415*795d594fSAndroid Build Coastguard Worker public static void startMethodTracing(String filename, int bufferSize, int flags, 416*795d594fSAndroid Build Coastguard Worker boolean samplingEnabled, int intervalUs) throws Exception { 417*795d594fSAndroid Build Coastguard Worker startMethodTracingMethod.invoke(null, filename, bufferSize, flags, samplingEnabled, 418*795d594fSAndroid Build Coastguard Worker intervalUs); 419*795d594fSAndroid Build Coastguard Worker } startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs)420*795d594fSAndroid Build Coastguard Worker public static void startMethodTracingDdms(int bufferSize, int flags, 421*795d594fSAndroid Build Coastguard Worker boolean samplingEnabled, int intervalUs) throws Exception { 422*795d594fSAndroid Build Coastguard Worker startMethodTracingDdmsMethod.invoke(null, bufferSize, flags, samplingEnabled, 423*795d594fSAndroid Build Coastguard Worker intervalUs); 424*795d594fSAndroid Build Coastguard Worker } stopMethodTracing()425*795d594fSAndroid Build Coastguard Worker public static void stopMethodTracing() throws Exception { 426*795d594fSAndroid Build Coastguard Worker stopMethodTracingMethod.invoke(null); 427*795d594fSAndroid Build Coastguard Worker } getMethodTracingMode()428*795d594fSAndroid Build Coastguard Worker public static int getMethodTracingMode() throws Exception { 429*795d594fSAndroid Build Coastguard Worker return (int) getMethodTracingModeMethod.invoke(null); 430*795d594fSAndroid Build Coastguard Worker } getRuntimeStat(String statName)431*795d594fSAndroid Build Coastguard Worker public static String getRuntimeStat(String statName) throws Exception { 432*795d594fSAndroid Build Coastguard Worker return (String) getRuntimeStatMethod.invoke(null, statName); 433*795d594fSAndroid Build Coastguard Worker } getRuntimeStats()434*795d594fSAndroid Build Coastguard Worker public static Map<String, String> getRuntimeStats() throws Exception { 435*795d594fSAndroid Build Coastguard Worker return (Map<String, String>) getRuntimeStatsMethod.invoke(null); 436*795d594fSAndroid Build Coastguard Worker } countInstancesofClass(Class<?> c, boolean assignable)437*795d594fSAndroid Build Coastguard Worker public static long countInstancesofClass(Class<?> c, boolean assignable) throws Exception { 438*795d594fSAndroid Build Coastguard Worker return (long) countInstancesOfClassMethod.invoke(null, new Object[]{c, assignable}); 439*795d594fSAndroid Build Coastguard Worker } countInstancesofClasses(Class<?>[] classes, boolean assignable)440*795d594fSAndroid Build Coastguard Worker public static long[] countInstancesofClasses(Class<?>[] classes, boolean assignable) 441*795d594fSAndroid Build Coastguard Worker throws Exception { 442*795d594fSAndroid Build Coastguard Worker return (long[]) countInstancesOfClassesMethod.invoke( 443*795d594fSAndroid Build Coastguard Worker null, new Object[]{classes, assignable}); 444*795d594fSAndroid Build Coastguard Worker } getAllocCount(Integer kind)445*795d594fSAndroid Build Coastguard Worker public static int getAllocCount(Integer kind) throws Exception { 446*795d594fSAndroid Build Coastguard Worker return (int) getAllocCountMethod.invoke(null, kind); 447*795d594fSAndroid Build Coastguard Worker } startAllocCounting()448*795d594fSAndroid Build Coastguard Worker public static void startAllocCounting() throws Exception { 449*795d594fSAndroid Build Coastguard Worker startAllocCountingMethod.invoke(null); 450*795d594fSAndroid Build Coastguard Worker } stopAllocCounting()451*795d594fSAndroid Build Coastguard Worker public static void stopAllocCounting() throws Exception { 452*795d594fSAndroid Build Coastguard Worker stopAllocCountingMethod.invoke(null); 453*795d594fSAndroid Build Coastguard Worker } setAllocTrackerStackDepth(Integer stackDepth)454*795d594fSAndroid Build Coastguard Worker public static void setAllocTrackerStackDepth(Integer stackDepth) throws Exception { 455*795d594fSAndroid Build Coastguard Worker setAllocTrackerStackDepthMethod.invoke(null, stackDepth); 456*795d594fSAndroid Build Coastguard Worker } resetAllocCount(Integer kind)457*795d594fSAndroid Build Coastguard Worker public static void resetAllocCount(Integer kind) throws Exception { 458*795d594fSAndroid Build Coastguard Worker resetAllocCountMethod.invoke(null, kind); 459*795d594fSAndroid Build Coastguard Worker } getLoadedClassCount()460*795d594fSAndroid Build Coastguard Worker public static int getLoadedClassCount() throws Exception { 461*795d594fSAndroid Build Coastguard Worker return (int) getLoadedClassCountMethod.invoke(null); 462*795d594fSAndroid Build Coastguard Worker } getVmFeatureList()463*795d594fSAndroid Build Coastguard Worker public static String[] getVmFeatureList() throws Exception { 464*795d594fSAndroid Build Coastguard Worker return (String[]) getVmFeatureListMethod.invoke(null); 465*795d594fSAndroid Build Coastguard Worker } isDebuggerConnected()466*795d594fSAndroid Build Coastguard Worker public static boolean isDebuggerConnected() throws Exception { 467*795d594fSAndroid Build Coastguard Worker return (boolean) isDebuggerConnectedMethod.invoke(null); 468*795d594fSAndroid Build Coastguard Worker } isDebuggingEnabled()469*795d594fSAndroid Build Coastguard Worker public static boolean isDebuggingEnabled() throws Exception { 470*795d594fSAndroid Build Coastguard Worker return (boolean) isDebuggingEnabledMethod.invoke(null); 471*795d594fSAndroid Build Coastguard Worker } lastDebuggerActivity()472*795d594fSAndroid Build Coastguard Worker public static long lastDebuggerActivity() throws Exception { 473*795d594fSAndroid Build Coastguard Worker return (long) lastDebuggerActivityMethod.invoke(null); 474*795d594fSAndroid Build Coastguard Worker } threadCpuTimeNanos()475*795d594fSAndroid Build Coastguard Worker public static long threadCpuTimeNanos() throws Exception { 476*795d594fSAndroid Build Coastguard Worker return (long) threadCpuTimeNanosMethod.invoke(null); 477*795d594fSAndroid Build Coastguard Worker } dumpHprofDataDdms()478*795d594fSAndroid Build Coastguard Worker public static void dumpHprofDataDdms() throws Exception { 479*795d594fSAndroid Build Coastguard Worker dumpHprofDataDdmsMethod.invoke(null); 480*795d594fSAndroid Build Coastguard Worker } dumpReferenceTables()481*795d594fSAndroid Build Coastguard Worker public static void dumpReferenceTables() throws Exception { 482*795d594fSAndroid Build Coastguard Worker dumpReferenceTablesMethod.invoke(null); 483*795d594fSAndroid Build Coastguard Worker } 484*795d594fSAndroid Build Coastguard Worker } 485*795d594fSAndroid Build Coastguard Worker } 486