xref: /aosp_15_r20/art/test/2246-trace-stream/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2022 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.FileDescriptor;
19*795d594fSAndroid Build Coastguard Worker import java.io.FileOutputStream;
20*795d594fSAndroid Build Coastguard Worker import java.io.IOException;
21*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method;
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker public class Main {
24*795d594fSAndroid Build Coastguard Worker     private static final String TEMP_FILE_NAME_PREFIX = "test";
25*795d594fSAndroid Build Coastguard Worker     private static final String TEMP_FILE_NAME_SUFFIX = ".trace";
26*795d594fSAndroid Build Coastguard Worker     private static final int WALL_CLOCK_FLAG = 0x010;
27*795d594fSAndroid Build Coastguard Worker     private static File file;
28*795d594fSAndroid Build Coastguard Worker 
main(String[] args)29*795d594fSAndroid Build Coastguard Worker     public static void main(String[] args) throws Exception {
30*795d594fSAndroid Build Coastguard Worker         System.loadLibrary(args[0]);
31*795d594fSAndroid Build Coastguard Worker         String name = System.getProperty("java.vm.name");
32*795d594fSAndroid Build Coastguard Worker         if (!"Dalvik".equals(name)) {
33*795d594fSAndroid Build Coastguard Worker             System.out.println("This test is not supported on " + name);
34*795d594fSAndroid Build Coastguard Worker             return;
35*795d594fSAndroid Build Coastguard Worker         }
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker         ensureJitCompiled(Main.class, "$noinline$doSomeWorkJIT");
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker         System.out.println("***** streaming test - dual clock *******");
40*795d594fSAndroid Build Coastguard Worker         StreamTraceParser stream_parser = new StreamTraceParser();
41*795d594fSAndroid Build Coastguard Worker         testTracing(
42*795d594fSAndroid Build Coastguard Worker                 /* streaming=*/true, /* flags= */ 0, stream_parser,
43*795d594fSAndroid Build Coastguard Worker                 BaseTraceParser.STREAMING_DUAL_CLOCK_VERSION);
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker         System.out.println("***** streaming test - wall clock *******");
46*795d594fSAndroid Build Coastguard Worker         StreamTraceParser stream_parser_wall_clock = new StreamTraceParser();
47*795d594fSAndroid Build Coastguard Worker         testTracing(
48*795d594fSAndroid Build Coastguard Worker                 /* streaming=*/true, /* flags= */ WALL_CLOCK_FLAG, stream_parser,
49*795d594fSAndroid Build Coastguard Worker                 BaseTraceParser.STREAMING_WALL_CLOCK_VERSION);
50*795d594fSAndroid Build Coastguard Worker 
51*795d594fSAndroid Build Coastguard Worker         System.out.println("***** non streaming test - dual clock *******");
52*795d594fSAndroid Build Coastguard Worker         NonStreamTraceParser non_stream_parser = new NonStreamTraceParser();
53*795d594fSAndroid Build Coastguard Worker         testTracing(/* streaming=*/false, /* flags= */ 0, non_stream_parser,
54*795d594fSAndroid Build Coastguard Worker                 BaseTraceParser.DUAL_CLOCK_VERSION);
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker         System.out.println("***** non streaming test - wall clock *******");
57*795d594fSAndroid Build Coastguard Worker         NonStreamTraceParser non_stream_parser_wall_clock = new NonStreamTraceParser();
58*795d594fSAndroid Build Coastguard Worker         testTracing(/* streaming=*/false, /* flags= */ WALL_CLOCK_FLAG,
59*795d594fSAndroid Build Coastguard Worker                 non_stream_parser_wall_clock, BaseTraceParser.WALL_CLOCK_VERSION);
60*795d594fSAndroid Build Coastguard Worker     }
61*795d594fSAndroid Build Coastguard Worker 
testTracing(boolean streaming, int flags, BaseTraceParser parser, int expected_version)62*795d594fSAndroid Build Coastguard Worker     public static void testTracing(boolean streaming, int flags, BaseTraceParser parser,
63*795d594fSAndroid Build Coastguard Worker             int expected_version) throws Exception {
64*795d594fSAndroid Build Coastguard Worker         Main m = new Main();
65*795d594fSAndroid Build Coastguard Worker         Thread t = new Thread(() -> {
66*795d594fSAndroid Build Coastguard Worker             try {
67*795d594fSAndroid Build Coastguard Worker                 file = createTempFile();
68*795d594fSAndroid Build Coastguard Worker                 FileOutputStream out_file = new FileOutputStream(file);
69*795d594fSAndroid Build Coastguard Worker                 VMDebug.startMethodTracing(
70*795d594fSAndroid Build Coastguard Worker                         file.getPath(), out_file.getFD(), 0, flags, false, 0, streaming);
71*795d594fSAndroid Build Coastguard Worker                 Main m1 = new Main();
72*795d594fSAndroid Build Coastguard Worker                 m1.$noinline$doSomeWork();
73*795d594fSAndroid Build Coastguard Worker                 // Call JITed code multiple times to flush out any issues with timestamps.
74*795d594fSAndroid Build Coastguard Worker                 for (int i = 0; i < 20; i++) {
75*795d594fSAndroid Build Coastguard Worker                     m.$noinline$doSomeWorkJIT();
76*795d594fSAndroid Build Coastguard Worker                 }
77*795d594fSAndroid Build Coastguard Worker                 VMDebug.$noinline$stopMethodTracing();
78*795d594fSAndroid Build Coastguard Worker                 out_file.close();
79*795d594fSAndroid Build Coastguard Worker                 parser.CheckTraceFileFormat(file, expected_version, "TestThread2246");
80*795d594fSAndroid Build Coastguard Worker                 file.delete();
81*795d594fSAndroid Build Coastguard Worker             } catch (Exception e) {
82*795d594fSAndroid Build Coastguard Worker                 System.out.println("Exception in thread " + e);
83*795d594fSAndroid Build Coastguard Worker                 e.printStackTrace();
84*795d594fSAndroid Build Coastguard Worker             } finally {
85*795d594fSAndroid Build Coastguard Worker               file.delete();
86*795d594fSAndroid Build Coastguard Worker             }
87*795d594fSAndroid Build Coastguard Worker         }, "TestThread2246");
88*795d594fSAndroid Build Coastguard Worker         try {
89*795d594fSAndroid Build Coastguard Worker             if (VMDebug.getMethodTracingMode() != 0) {
90*795d594fSAndroid Build Coastguard Worker                 VMDebug.$noinline$stopMethodTracing();
91*795d594fSAndroid Build Coastguard Worker             }
92*795d594fSAndroid Build Coastguard Worker 
93*795d594fSAndroid Build Coastguard Worker             t.start();
94*795d594fSAndroid Build Coastguard Worker             t.join();
95*795d594fSAndroid Build Coastguard Worker 
96*795d594fSAndroid Build Coastguard Worker             file = createTempFile();
97*795d594fSAndroid Build Coastguard Worker             FileOutputStream main_out_file = new FileOutputStream(file);
98*795d594fSAndroid Build Coastguard Worker             VMDebug.startMethodTracing(
99*795d594fSAndroid Build Coastguard Worker                     file.getPath(), main_out_file.getFD(), 0, flags, false, 0, streaming);
100*795d594fSAndroid Build Coastguard Worker             m.$noinline$doSomeWork();
101*795d594fSAndroid Build Coastguard Worker             // Call JITed code multiple times to flush out any issues with timestamps.
102*795d594fSAndroid Build Coastguard Worker             for (int i = 0; i < 20; i++) {
103*795d594fSAndroid Build Coastguard Worker                 m.$noinline$doSomeWorkJIT();
104*795d594fSAndroid Build Coastguard Worker             }
105*795d594fSAndroid Build Coastguard Worker             m.doSomeWorkThrow();
106*795d594fSAndroid Build Coastguard Worker             VMDebug.$noinline$stopMethodTracing();
107*795d594fSAndroid Build Coastguard Worker             main_out_file.close();
108*795d594fSAndroid Build Coastguard Worker             parser.CheckTraceFileFormat(file, expected_version, "main");
109*795d594fSAndroid Build Coastguard Worker             file.delete();
110*795d594fSAndroid Build Coastguard Worker         } finally {
111*795d594fSAndroid Build Coastguard Worker           file.delete();
112*795d594fSAndroid Build Coastguard Worker         }
113*795d594fSAndroid Build Coastguard Worker     }
114*795d594fSAndroid Build Coastguard Worker 
createTempFile()115*795d594fSAndroid Build Coastguard Worker     private static File createTempFile() throws Exception {
116*795d594fSAndroid Build Coastguard Worker         try {
117*795d594fSAndroid Build Coastguard Worker             return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
118*795d594fSAndroid Build Coastguard Worker         } catch (IOException e) {
119*795d594fSAndroid Build Coastguard Worker             System.setProperty("java.io.tmpdir", "/data/local/tmp");
120*795d594fSAndroid Build Coastguard Worker             try {
121*795d594fSAndroid Build Coastguard Worker                 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
122*795d594fSAndroid Build Coastguard Worker             } catch (IOException e2) {
123*795d594fSAndroid Build Coastguard Worker                 System.setProperty("java.io.tmpdir", "/sdcard");
124*795d594fSAndroid Build Coastguard Worker                 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
125*795d594fSAndroid Build Coastguard Worker             }
126*795d594fSAndroid Build Coastguard Worker         }
127*795d594fSAndroid Build Coastguard Worker     }
128*795d594fSAndroid Build Coastguard Worker 
callOuterFunction()129*795d594fSAndroid Build Coastguard Worker     public void callOuterFunction() {
130*795d594fSAndroid Build Coastguard Worker         callLeafFunction();
131*795d594fSAndroid Build Coastguard Worker     }
132*795d594fSAndroid Build Coastguard Worker 
callLeafFunction()133*795d594fSAndroid Build Coastguard Worker     public void callLeafFunction() {}
134*795d594fSAndroid Build Coastguard Worker 
$noinline$doSomeWork()135*795d594fSAndroid Build Coastguard Worker     public void $noinline$doSomeWork() {
136*795d594fSAndroid Build Coastguard Worker         callOuterFunction();
137*795d594fSAndroid Build Coastguard Worker         callLeafFunction();
138*795d594fSAndroid Build Coastguard Worker     }
139*795d594fSAndroid Build Coastguard Worker 
$noinline$doSomeWorkJIT()140*795d594fSAndroid Build Coastguard Worker     public void $noinline$doSomeWorkJIT() {
141*795d594fSAndroid Build Coastguard Worker         callOuterFunction();
142*795d594fSAndroid Build Coastguard Worker         callLeafFunction();
143*795d594fSAndroid Build Coastguard Worker     }
144*795d594fSAndroid Build Coastguard Worker 
callThrowFunction()145*795d594fSAndroid Build Coastguard Worker     public void callThrowFunction() throws Exception {
146*795d594fSAndroid Build Coastguard Worker         throw new Exception("test");
147*795d594fSAndroid Build Coastguard Worker     }
148*795d594fSAndroid Build Coastguard Worker 
doSomeWorkThrow()149*795d594fSAndroid Build Coastguard Worker     public void doSomeWorkThrow() {
150*795d594fSAndroid Build Coastguard Worker         try {
151*795d594fSAndroid Build Coastguard Worker             callThrowFunction();
152*795d594fSAndroid Build Coastguard Worker         } catch (Exception e) {
153*795d594fSAndroid Build Coastguard Worker         }
154*795d594fSAndroid Build Coastguard Worker     }
155*795d594fSAndroid Build Coastguard Worker 
156*795d594fSAndroid Build Coastguard Worker     private static class VMDebug {
157*795d594fSAndroid Build Coastguard Worker         private static final Method startMethodTracingMethod;
158*795d594fSAndroid Build Coastguard Worker         private static final Method stopMethodTracingMethod;
159*795d594fSAndroid Build Coastguard Worker         private static final Method getMethodTracingModeMethod;
160*795d594fSAndroid Build Coastguard Worker         static {
161*795d594fSAndroid Build Coastguard Worker             try {
162*795d594fSAndroid Build Coastguard Worker                 Class<?> c = Class.forName("dalvik.system.VMDebug");
163*795d594fSAndroid Build Coastguard Worker                 startMethodTracingMethod = c.getDeclaredMethod("startMethodTracing", String.class,
164*795d594fSAndroid Build Coastguard Worker                         FileDescriptor.class, Integer.TYPE, Integer.TYPE, Boolean.TYPE,
165*795d594fSAndroid Build Coastguard Worker                         Integer.TYPE, Boolean.TYPE);
166*795d594fSAndroid Build Coastguard Worker                 stopMethodTracingMethod = c.getDeclaredMethod("stopMethodTracing");
167*795d594fSAndroid Build Coastguard Worker                 getMethodTracingModeMethod = c.getDeclaredMethod("getMethodTracingMode");
168*795d594fSAndroid Build Coastguard Worker             } catch (Exception e) {
169*795d594fSAndroid Build Coastguard Worker                 throw new RuntimeException(e);
170*795d594fSAndroid Build Coastguard Worker             }
171*795d594fSAndroid Build Coastguard Worker         }
172*795d594fSAndroid Build Coastguard Worker 
startMethodTracing(String filename, FileDescriptor fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs, boolean streaming)173*795d594fSAndroid Build Coastguard Worker         public static void startMethodTracing(String filename, FileDescriptor fd, int bufferSize,
174*795d594fSAndroid Build Coastguard Worker                 int flags, boolean samplingEnabled, int intervalUs, boolean streaming)
175*795d594fSAndroid Build Coastguard Worker                 throws Exception {
176*795d594fSAndroid Build Coastguard Worker             startMethodTracingMethod.invoke(
177*795d594fSAndroid Build Coastguard Worker                     null, filename, fd, bufferSize, flags, samplingEnabled, intervalUs, streaming);
178*795d594fSAndroid Build Coastguard Worker         }
$noinline$stopMethodTracing()179*795d594fSAndroid Build Coastguard Worker         public static void $noinline$stopMethodTracing() throws Exception {
180*795d594fSAndroid Build Coastguard Worker             stopMethodTracingMethod.invoke(null);
181*795d594fSAndroid Build Coastguard Worker         }
getMethodTracingMode()182*795d594fSAndroid Build Coastguard Worker         public static int getMethodTracingMode() throws Exception {
183*795d594fSAndroid Build Coastguard Worker             return (int) getMethodTracingModeMethod.invoke(null);
184*795d594fSAndroid Build Coastguard Worker         }
185*795d594fSAndroid Build Coastguard Worker     }
186*795d594fSAndroid Build Coastguard Worker 
ensureJitCompiled(Class<?> cls, String methodName)187*795d594fSAndroid Build Coastguard Worker     private static native void ensureJitCompiled(Class<?> cls, String methodName);
188*795d594fSAndroid Build Coastguard Worker }
189