1545412b4b250d6024ff071c094c226187860a086Igor Murashkin// Copyright (C) 2017 The Android Open Source Project 2545412b4b250d6024ff071c094c226187860a086Igor Murashkin// 3545412b4b250d6024ff071c094c226187860a086Igor Murashkin// Licensed under the Apache License, Version 2.0 (the "License"); 4545412b4b250d6024ff071c094c226187860a086Igor Murashkin// you may not use this file except in compliance with the License. 5545412b4b250d6024ff071c094c226187860a086Igor Murashkin// You may obtain a copy of the License at 6545412b4b250d6024ff071c094c226187860a086Igor Murashkin// 7545412b4b250d6024ff071c094c226187860a086Igor Murashkin// http://www.apache.org/licenses/LICENSE-2.0 8545412b4b250d6024ff071c094c226187860a086Igor Murashkin// 9545412b4b250d6024ff071c094c226187860a086Igor Murashkin// Unless required by applicable law or agreed to in writing, software 10545412b4b250d6024ff071c094c226187860a086Igor Murashkin// distributed under the License is distributed on an "AS IS" BASIS, 11545412b4b250d6024ff071c094c226187860a086Igor Murashkin// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12545412b4b250d6024ff071c094c226187860a086Igor Murashkin// See the License for the specific language governing permissions and 13545412b4b250d6024ff071c094c226187860a086Igor Murashkin// limitations under the License. 14545412b4b250d6024ff071c094c226187860a086Igor Murashkinimport java.lang.reflect.Method; 15545412b4b250d6024ff071c094c226187860a086Igor Murashkinimport java.util.ArrayList; 16545412b4b250d6024ff071c094c226187860a086Igor Murashkinimport java.util.Collections; 17545412b4b250d6024ff071c094c226187860a086Igor Murashkin 18545412b4b250d6024ff071c094c226187860a086Igor Murashkinpublic class Main { 19545412b4b250d6024ff071c094c226187860a086Igor Murashkin 20545412b4b250d6024ff071c094c226187860a086Igor Murashkin static class OatMethodAndOffset implements Comparable<OatMethodAndOffset> { 21545412b4b250d6024ff071c094c226187860a086Igor Murashkin Method method; 22545412b4b250d6024ff071c094c226187860a086Igor Murashkin long codeOffset; 23545412b4b250d6024ff071c094c226187860a086Igor Murashkin 24545412b4b250d6024ff071c094c226187860a086Igor Murashkin public OatMethodAndOffset(Method method, long codeOffset) { 25545412b4b250d6024ff071c094c226187860a086Igor Murashkin this.method = method; 26545412b4b250d6024ff071c094c226187860a086Igor Murashkin this.codeOffset = codeOffset; 27545412b4b250d6024ff071c094c226187860a086Igor Murashkin } 28545412b4b250d6024ff071c094c226187860a086Igor Murashkin 29545412b4b250d6024ff071c094c226187860a086Igor Murashkin // e.g. "Foo::Bar()" 30545412b4b250d6024ff071c094c226187860a086Igor Murashkin public String methodReferenceString() { 31545412b4b250d6024ff071c094c226187860a086Igor Murashkin return method.getDeclaringClass().getName() + "::" + method.getName(); 32545412b4b250d6024ff071c094c226187860a086Igor Murashkin } 33545412b4b250d6024ff071c094c226187860a086Igor Murashkin 34545412b4b250d6024ff071c094c226187860a086Igor Murashkin @Override 35545412b4b250d6024ff071c094c226187860a086Igor Murashkin public int compareTo(OatMethodAndOffset other) { 36545412b4b250d6024ff071c094c226187860a086Igor Murashkin return Long.compareUnsigned(codeOffset, other.codeOffset); 37545412b4b250d6024ff071c094c226187860a086Igor Murashkin } 38545412b4b250d6024ff071c094c226187860a086Igor Murashkin } 39545412b4b250d6024ff071c094c226187860a086Igor Murashkin 40545412b4b250d6024ff071c094c226187860a086Igor Murashkin // Print the list of methods in Generated.class, sorted by their OAT code address. 41545412b4b250d6024ff071c094c226187860a086Igor Murashkin public static void main(String[] args) { 42545412b4b250d6024ff071c094c226187860a086Igor Murashkin System.loadLibrary(args[0]); 43545412b4b250d6024ff071c094c226187860a086Igor Murashkin 44545412b4b250d6024ff071c094c226187860a086Igor Murashkin // Make sure to check "Test.class" because Main.class still has JNI which could be compiled 45545412b4b250d6024ff071c094c226187860a086Igor Murashkin // even if the rest of the classes are not. 46545412b4b250d6024ff071c094c226187860a086Igor Murashkin if (!hasOatCompiledCode(Test.class)) { 47545412b4b250d6024ff071c094c226187860a086Igor Murashkin System.out.println("No OAT class"); 48545412b4b250d6024ff071c094c226187860a086Igor Murashkin return; 49545412b4b250d6024ff071c094c226187860a086Igor Murashkin } 50545412b4b250d6024ff071c094c226187860a086Igor Murashkin 51545412b4b250d6024ff071c094c226187860a086Igor Murashkin // We only care about explicitly defined methods from Generated.java. 52545412b4b250d6024ff071c094c226187860a086Igor Murashkin Method[] interesting_methods; 53545412b4b250d6024ff071c094c226187860a086Igor Murashkin try { 54545412b4b250d6024ff071c094c226187860a086Igor Murashkin interesting_methods = Test.getTestMethods(); 55545412b4b250d6024ff071c094c226187860a086Igor Murashkin } catch (NoSuchMethodException e) { 56545412b4b250d6024ff071c094c226187860a086Igor Murashkin e.printStackTrace(); 57545412b4b250d6024ff071c094c226187860a086Igor Murashkin return; 58545412b4b250d6024ff071c094c226187860a086Igor Murashkin } 59545412b4b250d6024ff071c094c226187860a086Igor Murashkin 60545412b4b250d6024ff071c094c226187860a086Igor Murashkin // Get the list of oat code methods for each Java method. 61545412b4b250d6024ff071c094c226187860a086Igor Murashkin ArrayList<OatMethodAndOffset> offsets_list = new ArrayList<OatMethodAndOffset>(); 62545412b4b250d6024ff071c094c226187860a086Igor Murashkin for (Method m : interesting_methods) { 63545412b4b250d6024ff071c094c226187860a086Igor Murashkin offsets_list.add(new OatMethodAndOffset(m, getOatMethodQuickCode(m))); 64545412b4b250d6024ff071c094c226187860a086Igor Murashkin } 65545412b4b250d6024ff071c094c226187860a086Igor Murashkin 66545412b4b250d6024ff071c094c226187860a086Igor Murashkin // Sort by the offset address. 67545412b4b250d6024ff071c094c226187860a086Igor Murashkin Collections.sort(offsets_list); 68545412b4b250d6024ff071c094c226187860a086Igor Murashkin 69545412b4b250d6024ff071c094c226187860a086Igor Murashkin // Print each method as a method reference string. 70545412b4b250d6024ff071c094c226187860a086Igor Murashkin for (OatMethodAndOffset m : offsets_list) { 71545412b4b250d6024ff071c094c226187860a086Igor Murashkin System.out.println(m.methodReferenceString()); 72545412b4b250d6024ff071c094c226187860a086Igor Murashkin } 73545412b4b250d6024ff071c094c226187860a086Igor Murashkin } 74545412b4b250d6024ff071c094c226187860a086Igor Murashkin 75545412b4b250d6024ff071c094c226187860a086Igor Murashkin // Does Main.class have an OatClass with actually compiled code? 76545412b4b250d6024ff071c094c226187860a086Igor Murashkin private static native boolean hasOatCompiledCode(Class kls); 77545412b4b250d6024ff071c094c226187860a086Igor Murashkin // Get the OatMethod's pointer to code. We get 'real' memory address, not relative offset, 78545412b4b250d6024ff071c094c226187860a086Igor Murashkin // but it's still good since we never compare multiple OAT files here. 79545412b4b250d6024ff071c094c226187860a086Igor Murashkin private static native long getOatMethodQuickCode(Method method); 80545412b4b250d6024ff071c094c226187860a086Igor Murashkin} 81