1 /*
2  * Copyright (C) 2016 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 
17 import java.io.File;
18 import java.io.IOException;
19 import java.lang.reflect.Method;
20 
21 public class Main {
22 
main(String[] args)23   public static void main(String[] args) throws Exception {
24     System.loadLibrary(args[0]);
25 
26     File file = null;
27     try {
28       file = createTempFile();
29       // String codePath = getDexBaseLocation();
30       String codePath = System.getenv("DEX_LOCATION") + "/595-profile-saving.jar";
31       VMRuntime.registerAppInfo(file.getPath(),
32                                 new String[] {codePath});
33 
34       int methodIdx = $opt$noinline$testProfile();
35       ensureProfileProcessing();
36       if (!presentInProfile(file.getPath(), methodIdx)) {
37         throw new RuntimeException("Method with index " + methodIdx + " not in the profile");
38       }
39     } finally {
40       if (file != null) {
41         file.delete();
42       }
43     }
44   }
45 
$opt$noinline$testProfile()46   public static int $opt$noinline$testProfile() {
47     if (doThrow) throw new Error();
48     // Make sure we have a profile info for this method without the need to loop.
49     return ensureProfilingInfo("$opt$noinline$testProfile");
50   }
51 
52   // Return the dex method index.
ensureProfilingInfo(String methodName)53   public static native int ensureProfilingInfo(String methodName);
54   // Ensures the profile saver does its usual processing.
ensureProfileProcessing()55   public static native void ensureProfileProcessing();
56   // Checks if the profiles saver knows about the method.
presentInProfile(String profile, int methodIdx)57   public static native boolean presentInProfile(String profile, int methodIdx);
58 
59   public static boolean doThrow = false;
60   private static final String TEMP_FILE_NAME_PREFIX = "dummy";
61   private static final String TEMP_FILE_NAME_SUFFIX = "-file";
62 
getProfileInfoDump( String filename)63   static native String getProfileInfoDump(
64       String filename);
65 
createTempFile()66   private static File createTempFile() throws Exception {
67     try {
68       return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
69     } catch (IOException e) {
70       System.setProperty("java.io.tmpdir", "/data/local/tmp");
71       try {
72         return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
73       } catch (IOException e2) {
74         System.setProperty("java.io.tmpdir", "/sdcard");
75         return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
76       }
77     }
78   }
79 
80   private static class VMRuntime {
81     private static final Method registerAppInfoMethod;
82     static {
83       try {
84         Class<? extends Object> c = Class.forName("dalvik.system.VMRuntime");
85         registerAppInfoMethod = c.getDeclaredMethod("registerAppInfo",
86             String.class, String[].class);
87       } catch (Exception e) {
88         throw new RuntimeException(e);
89       }
90     }
91 
registerAppInfo(String profile, String[] codePaths)92     public static void registerAppInfo(String profile, String[] codePaths)
93         throws Exception {
94       registerAppInfoMethod.invoke(null, profile, codePaths);
95     }
96   }
97 }
98