xref: /aosp_15_r20/art/test/099-vmdebug/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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