blob: add2ff6fb67c03ede54afc9cb542d545ae98e5a6 [file] [log] [blame]
Jeff Haod063d912014-09-08 09:38:18 -07001/*
2 * Copyright (C) 2014 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
17import java.io.File;
18import java.io.IOException;
19import java.lang.reflect.Method;
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -070020import java.util.Map;
Jeff Haod063d912014-09-08 09:38:18 -070021
22public class Main {
Sebastien Hertzef3b1772015-06-30 13:57:39 +020023 private static final String TEMP_FILE_NAME_PREFIX = "test";
24 private static final String TEMP_FILE_NAME_SUFFIX = ".trace";
25
Jeff Haod063d912014-09-08 09:38:18 -070026 public static void main(String[] args) throws Exception {
27 String name = System.getProperty("java.vm.name");
28 if (!"Dalvik".equals(name)) {
29 System.out.println("This test is not supported on " + name);
30 return;
31 }
32 testMethodTracing();
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -070033 testRuntimeStat();
Jeff Haod063d912014-09-08 09:38:18 -070034 }
35
Andreas Gampe74035032015-01-27 16:12:08 -080036 private static File createTempFile() throws Exception {
Jeff Hao8cf89c42014-09-09 13:07:59 -070037 try {
Sebastien Hertzef3b1772015-06-30 13:57:39 +020038 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
Jeff Hao8cf89c42014-09-09 13:07:59 -070039 } catch (IOException e) {
Andreas Gampe74035032015-01-27 16:12:08 -080040 System.setProperty("java.io.tmpdir", "/data/local/tmp");
41 try {
Sebastien Hertzef3b1772015-06-30 13:57:39 +020042 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
Andreas Gampe74035032015-01-27 16:12:08 -080043 } catch (IOException e2) {
44 System.setProperty("java.io.tmpdir", "/sdcard");
Sebastien Hertzef3b1772015-06-30 13:57:39 +020045 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
Andreas Gampe74035032015-01-27 16:12:08 -080046 }
Jeff Haod063d912014-09-08 09:38:18 -070047 }
Andreas Gampe74035032015-01-27 16:12:08 -080048 }
49
50 private static void testMethodTracing() throws Exception {
Sebastien Hertzef3b1772015-06-30 13:57:39 +020051 File tempFile = null;
52 try {
53 tempFile = createTempFile();
54 testMethodTracingToFile(tempFile);
55 } finally {
56 if (tempFile != null) {
57 tempFile.delete();
58 }
59 }
60 }
61
62 private static void testMethodTracingToFile(File tempFile) throws Exception {
Jeff Hao8cf89c42014-09-09 13:07:59 -070063 String tempFileName = tempFile.getPath();
Jeff Haod063d912014-09-08 09:38:18 -070064
Jeff Haocbe15be2014-09-08 15:32:39 -070065 if (VMDebug.getMethodTracingMode() != 0) {
66 VMDebug.stopMethodTracing();
67 }
68
Jeff Haod063d912014-09-08 09:38:18 -070069 System.out.println("Confirm enable/disable");
70 System.out.println("status=" + VMDebug.getMethodTracingMode());
71 VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0);
72 System.out.println("status=" + VMDebug.getMethodTracingMode());
73 VMDebug.stopMethodTracing();
74 System.out.println("status=" + VMDebug.getMethodTracingMode());
75 if (tempFile.length() == 0) {
76 System.out.println("ERROR: tracing output file is empty");
77 }
78
79 System.out.println("Confirm sampling");
80 VMDebug.startMethodTracing(tempFileName, 0, 0, true, 1000);
81 System.out.println("status=" + VMDebug.getMethodTracingMode());
82 VMDebug.stopMethodTracing();
83 System.out.println("status=" + VMDebug.getMethodTracingMode());
84 if (tempFile.length() == 0) {
85 System.out.println("ERROR: sample tracing output file is empty");
86 }
87
88 System.out.println("Test starting when already started");
89 VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0);
90 System.out.println("status=" + VMDebug.getMethodTracingMode());
91 VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0);
92 System.out.println("status=" + VMDebug.getMethodTracingMode());
93
94 System.out.println("Test stopping when already stopped");
95 VMDebug.stopMethodTracing();
96 System.out.println("status=" + VMDebug.getMethodTracingMode());
97 VMDebug.stopMethodTracing();
98 System.out.println("status=" + VMDebug.getMethodTracingMode());
99
100 System.out.println("Test tracing with empty filename");
101 try {
102 VMDebug.startMethodTracing("", 0, 0, false, 0);
103 System.out.println("Should have thrown an exception");
104 } catch (Exception e) {
105 System.out.println("Got expected exception");
106 }
107
108 System.out.println("Test tracing with bogus (< 1024 && != 0) filesize");
109 try {
110 VMDebug.startMethodTracing(tempFileName, 1000, 0, false, 0);
111 System.out.println("Should have thrown an exception");
112 } catch (Exception e) {
113 System.out.println("Got expected exception");
114 }
115
116 System.out.println("Test sampling with bogus (<= 0) interval");
117 try {
118 VMDebug.startMethodTracing(tempFileName, 0, 0, true, 0);
119 System.out.println("Should have thrown an exception");
120 } catch (Exception e) {
121 System.out.println("Got expected exception");
122 }
123
124 tempFile.delete();
125 }
126
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -0700127 private static void checkNumber(String s) throws Exception {
128 if (s == null) {
129 System.out.println("Got null string");
130 return;
131 }
132 long n = Long.valueOf(s);
133 if (n < 0) {
134 System.out.println("Got negative number " + n);
135 }
136 }
137
138 private static void checkHistogram(String s) throws Exception {
139 if (s == null || s.length() == 0) {
140 System.out.println("Got null or empty string");
141 return;
142 }
143 String[] buckets = s.split(",");
144 long last_key = 0;
145 for (int i = 0; i < buckets.length; ++i) {
146 String bucket = buckets[i];
147 if (bucket.length() == 0) {
148 System.out.println("Got empty bucket");
149 continue;
150 }
151 String[] kv = bucket.split(":");
152 if (kv.length != 2 || kv[0].length() == 0 || kv[1].length() == 0) {
153 System.out.println("Got bad bucket " + bucket);
154 continue;
155 }
156 long key = Long.valueOf(kv[0]);
157 long value = Long.valueOf(kv[1]);
158 if (key < 0 || value < 0) {
159 System.out.println("Got negative key or value " + bucket);
160 continue;
161 }
162 if (key < last_key) {
163 System.out.println("Got decreasing key " + bucket);
164 continue;
165 }
166 last_key = key;
167 }
168 }
169
170 private static void testRuntimeStat() throws Exception {
171 // Invoke at least one GC and wait for 20 seconds or so so we get at
172 // least one bucket in the histograms.
173 for (int i = 0; i < 20; ++i) {
174 Runtime.getRuntime().gc();
175 Thread.sleep(1000L);
176 }
177 String gc_count = VMDebug.getRuntimeStat("art.gc.gc-count");
178 String gc_time = VMDebug.getRuntimeStat("art.gc.gc-time");
179 String bytes_allocated = VMDebug.getRuntimeStat("art.gc.bytes-allocated");
180 String bytes_freed = VMDebug.getRuntimeStat("art.gc.bytes-freed");
181 String blocking_gc_count = VMDebug.getRuntimeStat("art.gc.blocking-gc-count");
182 String blocking_gc_time = VMDebug.getRuntimeStat("art.gc.blocking-gc-time");
183 String gc_count_rate_histogram = VMDebug.getRuntimeStat("art.gc.gc-count-rate-histogram");
184 String blocking_gc_count_rate_histogram =
185 VMDebug.getRuntimeStat("art.gc.blocking-gc-count-rate-histogram");
186 checkNumber(gc_count);
187 checkNumber(gc_time);
188 checkNumber(bytes_allocated);
189 checkNumber(bytes_freed);
190 checkNumber(blocking_gc_count);
191 checkNumber(blocking_gc_time);
192 checkHistogram(gc_count_rate_histogram);
193 checkHistogram(blocking_gc_count_rate_histogram);
194 }
195
196 private static void testRuntimeStats() throws Exception {
197 // Invoke at least one GC and wait for 20 seconds or so so we get at
198 // least one bucket in the histograms.
199 for (int i = 0; i < 20; ++i) {
200 Runtime.getRuntime().gc();
201 Thread.sleep(1000L);
202 }
203 Map<String, String> map = VMDebug.getRuntimeStats();
204 String gc_count = map.get("art.gc.gc-count");
205 String gc_time = map.get("art.gc.gc-time");
206 String bytes_allocated = map.get("art.gc.bytes-allocated");
207 String bytes_freed = map.get("art.gc.bytes-freed");
208 String blocking_gc_count = map.get("art.gc.blocking-gc-count");
209 String blocking_gc_time = map.get("art.gc.blocking-gc-time");
210 String gc_count_rate_histogram = map.get("art.gc.gc-count-rate-histogram");
211 String blocking_gc_count_rate_histogram =
212 map.get("art.gc.blocking-gc-count-rate-histogram");
213 checkNumber(gc_count);
214 checkNumber(gc_time);
215 checkNumber(bytes_allocated);
216 checkNumber(bytes_freed);
217 checkNumber(blocking_gc_count);
218 checkNumber(blocking_gc_time);
219 checkHistogram(gc_count_rate_histogram);
220 checkHistogram(blocking_gc_count_rate_histogram);
221 }
222
Jeff Haod063d912014-09-08 09:38:18 -0700223 private static class VMDebug {
224 private static final Method startMethodTracingMethod;
225 private static final Method stopMethodTracingMethod;
226 private static final Method getMethodTracingModeMethod;
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -0700227 private static final Method getRuntimeStatMethod;
228 private static final Method getRuntimeStatsMethod;
Jeff Haod063d912014-09-08 09:38:18 -0700229 static {
230 try {
231 Class c = Class.forName("dalvik.system.VMDebug");
232 startMethodTracingMethod = c.getDeclaredMethod("startMethodTracing", String.class,
233 Integer.TYPE, Integer.TYPE, Boolean.TYPE, Integer.TYPE);
234 stopMethodTracingMethod = c.getDeclaredMethod("stopMethodTracing");
235 getMethodTracingModeMethod = c.getDeclaredMethod("getMethodTracingMode");
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -0700236 getRuntimeStatMethod = c.getDeclaredMethod("getRuntimeStat", String.class);
237 getRuntimeStatsMethod = c.getDeclaredMethod("getRuntimeStats");
Jeff Haod063d912014-09-08 09:38:18 -0700238 } catch (Exception e) {
239 throw new RuntimeException(e);
240 }
241 }
242
243 public static void startMethodTracing(String filename, int bufferSize, int flags,
244 boolean samplingEnabled, int intervalUs) throws Exception {
245 startMethodTracingMethod.invoke(null, filename, bufferSize, flags, samplingEnabled,
246 intervalUs);
247 }
248 public static void stopMethodTracing() throws Exception {
249 stopMethodTracingMethod.invoke(null);
250 }
251 public static int getMethodTracingMode() throws Exception {
252 return (int) getMethodTracingModeMethod.invoke(null);
253 }
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -0700254 public static String getRuntimeStat(String statName) throws Exception {
255 return (String) getRuntimeStatMethod.invoke(null, statName);
256 }
257 public static Map<String, String> getRuntimeStats() throws Exception {
258 return (Map<String, String>) getRuntimeStatsMethod.invoke(null);
259 }
Jeff Haod063d912014-09-08 09:38:18 -0700260 }
261}