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 import java.io.File; 17 import java.io.IOException; 18 import java.lang.reflect.Method; 19 20 public class Main { 21 main(String[] args)22 public static void main(String[] args) throws Exception { 23 System.loadLibrary(args[0]); 24 25 File file = null; 26 try { 27 file = createTempFile(); 28 // String codePath = getDexBaseLocation(); 29 String codePath = System.getenv("DEX_LOCATION") + "/595-profile-saving.jar"; 30 VMRuntime.registerAppInfo(file.getPath(), 31 new String[] {codePath}); 32 33 // Test that the profile saves an app method with a profiling info. 34 Method appMethod = Main.class.getDeclaredMethod("testAddMethodToProfile", 35 File.class, Method.class); 36 testAddMethodToProfile(file, appMethod); 37 38 // Test that the profile saves a boot class path method with a profiling info. 39 Method bootMethod = File.class.getDeclaredMethod("delete"); 40 if (bootMethod.getDeclaringClass().getClassLoader() != Object.class.getClassLoader()) { 41 System.out.println("Class loader does not match boot class"); 42 } 43 testAddMethodToProfile(file, bootMethod); 44 45 System.out.println("IsForBootImage: " + isForBootImage(file.getPath())); 46 } finally { 47 if (file != null) { 48 file.delete(); 49 } 50 } 51 } 52 testAddMethodToProfile(File file, Method m)53 static void testAddMethodToProfile(File file, Method m) { 54 // Make sure we have a profile info for this method without the need to loop. 55 ensureProfilingInfo(m); 56 // Make sure the profile gets saved. 57 ensureProfileProcessing(); 58 // Verify that the profile was saved and contains the method. 59 if (!presentInProfile(file.getPath(), m)) { 60 throw new RuntimeException("Method with index " + m + " not in the profile"); 61 } 62 } 63 64 // Ensure a method has a profiling info. ensureProfilingInfo(Method method)65 public static native void ensureProfilingInfo(Method method); 66 // Ensures the profile saver does its usual processing. ensureProfileProcessing()67 public static native void ensureProfileProcessing(); 68 // Checks if the profiles saver knows about the method. presentInProfile(String profile, Method method)69 public static native boolean presentInProfile(String profile, Method method); 70 // Returns true if the profile is for the boot image. isForBootImage(String profile)71 public static native boolean isForBootImage(String profile); 72 73 private static final String TEMP_FILE_NAME_PREFIX = "dummy"; 74 private static final String TEMP_FILE_NAME_SUFFIX = "-file"; 75 getProfileInfoDump( String filename)76 static native String getProfileInfoDump( 77 String filename); 78 createTempFile()79 private static File createTempFile() throws Exception { 80 try { 81 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 82 } catch (IOException e) { 83 System.setProperty("java.io.tmpdir", "/data/local/tmp"); 84 try { 85 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 86 } catch (IOException e2) { 87 System.setProperty("java.io.tmpdir", "/sdcard"); 88 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 89 } 90 } 91 } 92 93 private static class VMRuntime { 94 private static final Method registerAppInfoMethod; 95 static { 96 try { 97 Class<? extends Object> c = Class.forName("dalvik.system.VMRuntime"); 98 registerAppInfoMethod = c.getDeclaredMethod("registerAppInfo", 99 String.class, String[].class); 100 } catch (Exception e) { 101 throw new RuntimeException(e); 102 } 103 } 104 registerAppInfo(String profile, String[] codePaths)105 public static void registerAppInfo(String profile, String[] codePaths) 106 throws Exception { 107 registerAppInfoMethod.invoke(null, profile, codePaths); 108 } 109 } 110 } 111