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