blob: ba613ae5691f62320310a914f4c3e08a9ea4e1b5 [file] [log] [blame]
Calin Juravle27e17fd2015-11-25 15:59:14 +00001/*
2 * Copyright (C) 2015 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;
20import java.util.HashMap;
21
22public class Main {
23
24 public void coldMethod() {
25 hotMethod();
26 }
27
28 public String hotMethod() {
29 HashMap<String, String> map = new HashMap<String, String>();
30 for (int i = 0; i < 10; i++) {
31 map.put("" + i, "" + i + 1);
32 }
33 return map.get("1");
34 }
35
36 private static final String PKG_NAME = "test.package";
37 private static final String PROFILE_FILE = PKG_NAME + ".prof";
38 private static final String TEMP_FILE_NAME_PREFIX = "dummy";
39 private static final String TEMP_FILE_NAME_SUFFIX = ".file";
40 private static final int JIT_INVOCATION_COUNT = 101;
41
42 /* needs to match Runtime:: kProfileBackground */
43 private static final int PROFILE_BACKGROUND = 1;
44
45 public static void main(String[] args) throws Exception {
46 System.loadLibrary(args[0]);
47
48 File file = null;
49 File profileDir = null;
50 File profileFile = null;
51 try {
52 // We don't know where we have rights to create the code_cache. So create
53 // a dummy temporary file and get its parent directory. That will serve as
54 // the app directory.
55 file = createTempFile();
56 String appDir = file.getParent();
57 profileDir = new File(appDir, "code_cache");
58 profileDir.mkdir();
59
60 // Registering the app info will set the profile file name.
61 VMRuntime.registerAppInfo(PKG_NAME, appDir);
62
63 // Make sure the hot methods are jitted.
64 Main m = new Main();
65 OtherDex o = new OtherDex();
66 for (int i = 0; i < JIT_INVOCATION_COUNT; i++) {
67 m.hotMethod();
68 o.hotMethod();
69 }
70
71 // Updating the process state to BACKGROUND will trigger profile saving.
72 VMRuntime.updateProcessState(PROFILE_BACKGROUND);
73
74 // Check that the profile file exists.
75 profileFile = new File(profileDir, PROFILE_FILE);
76 if (!profileFile.exists()) {
77 throw new RuntimeException("No profile file found");
78 }
79 // Dump the profile file.
80 // We know what methods are hot and we compare with the golden `expected` output.
81 System.out.println(getProfileInfoDump(profileFile.getPath(), m.getClass(), o.getClass()));
82 } finally {
83 if (file != null) {
84 file.delete();
85 }
86 if (profileFile != null) {
87 profileFile.delete();
88 }
89 if (profileDir != null) {
90 profileDir.delete();
91 }
92 }
93 }
94
95 private static class VMRuntime {
96 private static final Method registerAppInfoMethod;
97 private static final Method updateProcessStateMethod;
98 private static final Method getRuntimeMethod;
99 static {
100 try {
101 Class c = Class.forName("dalvik.system.VMRuntime");
102 registerAppInfoMethod = c.getDeclaredMethod("registerAppInfo",
103 String.class, String.class, String.class);
104 updateProcessStateMethod = c.getDeclaredMethod("updateProcessState", Integer.TYPE);
105 getRuntimeMethod = c.getDeclaredMethod("getRuntime");
106 } catch (Exception e) {
107 throw new RuntimeException(e);
108 }
109 }
110
111 public static void registerAppInfo(String pkgName, String appDir) throws Exception {
112 registerAppInfoMethod.invoke(null, pkgName, appDir, null);
113 }
114 public static void updateProcessState(int state) throws Exception {
115 Object runtime = getRuntimeMethod.invoke(null);
116 updateProcessStateMethod.invoke(runtime, state);
117 }
118 }
119
120 static native String getProfileInfoDump(
121 String filename, Class<?> clsFromPrimary, Class<?> clsFromSecondary);
122
123 private static File createTempFile() throws Exception {
124 try {
125 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
126 } catch (IOException e) {
127 System.setProperty("java.io.tmpdir", "/data/local/tmp");
128 try {
129 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
130 } catch (IOException e2) {
131 System.setProperty("java.io.tmpdir", "/sdcard");
132 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
133 }
134 }
135 }
136}