Home | History | Annotate | Download | only in src
      1 // Copyright (C) 2017 The Android Open Source Project
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 import java.lang.reflect.Method;
     15 import java.util.ArrayList;
     16 import java.util.Collections;
     17 
     18 public class Main {
     19 
     20   static class OatMethodAndOffset implements Comparable<OatMethodAndOffset> {
     21     Method method;
     22     long codeOffset;
     23 
     24     public OatMethodAndOffset(Method method, long codeOffset) {
     25       this.method = method;
     26       this.codeOffset = codeOffset;
     27     }
     28 
     29     // e.g. "Foo::Bar()"
     30     public String methodReferenceString() {
     31       return method.getDeclaringClass().getName() + "::" + method.getName();
     32     }
     33 
     34     @Override
     35     public int compareTo(OatMethodAndOffset other) {
     36       return Long.compareUnsigned(codeOffset, other.codeOffset);
     37     }
     38   }
     39 
     40   // Print the list of methods in Generated.class, sorted by their OAT code address.
     41   public static void main(String[] args) {
     42     System.loadLibrary(args[0]);
     43 
     44     // Make sure to check "Test.class" because Main.class still has JNI which could be compiled
     45     // even if the rest of the classes are not.
     46     if (!hasOatCompiledCode(Test.class)) {
     47       System.out.println("No OAT class");
     48       return;
     49     }
     50 
     51     // We only care about explicitly defined methods from Generated.java.
     52     Method[] interesting_methods;
     53     try {
     54       interesting_methods = Test.getTestMethods();
     55     } catch (NoSuchMethodException e) {
     56       e.printStackTrace();
     57       return;
     58     }
     59 
     60     // Get the list of oat code methods for each Java method.
     61     ArrayList<OatMethodAndOffset> offsets_list = new ArrayList<OatMethodAndOffset>();
     62     for (Method m : interesting_methods) {
     63       offsets_list.add(new OatMethodAndOffset(m, getOatMethodQuickCode(m)));
     64     }
     65 
     66     // Sort by the offset address.
     67     Collections.sort(offsets_list);
     68 
     69     // Print each method as a method reference string.
     70     for (OatMethodAndOffset m : offsets_list) {
     71       System.out.println(m.methodReferenceString());
     72     }
     73   }
     74 
     75   // Does Main.class have an OatClass with actually compiled code?
     76   private static native boolean hasOatCompiledCode(Class kls);
     77   // Get the OatMethod's pointer to code. We get 'real' memory address, not relative offset,
     78   // but it's still good since we never compare multiple OAT files here.
     79   private static native long getOatMethodQuickCode(Method method);
     80 }
     81