1 /*
2  * Copyright (C) 2017 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 art.Redefinition;
18 import java.util.Base64;
19 public class Main {
20   static abstract class TransformAbstract {
doSayHi()21     public abstract void doSayHi();
22 
sayHi()23     public void sayHi() {
24       System.out.println("hello");
25     }
26   }
27 
28   static final class TransformConcrete extends TransformAbstract {
doSayHi()29     public final void doSayHi() {
30       System.out.print("Running sayHi() - ");
31       sayHi();
32     }
33   }
34 
ensureJitCompiled(Class k, String m)35   public static native void ensureJitCompiled(Class k, String m);
36 
37   /**
38    * base64 encoded class/dex file for
39    * static abstract class TransformAbstract {
40    *   public abstract void doSayHi();
41    *   public void sayHi() {
42    *    System.out.println("Goodbye");
43    *   }
44    * }
45    */
46   private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
47     "yv66vgAAADQAIQoABgAPCQAQABEIABIKABMAFAcAFgcAGQEABjxpbml0PgEAAygpVgEABENvZGUB" +
48     "AA9MaW5lTnVtYmVyVGFibGUBAAdkb1NheUhpAQAFc2F5SGkBAApTb3VyY2VGaWxlAQAJTWFpbi5q" +
49     "YXZhDAAHAAgHABoMABsAHAEAB0dvb2RieWUHAB0MAB4AHwcAIAEAFk1haW4kVHJhbnNmb3JtQWJz" +
50     "dHJhY3QBABFUcmFuc2Zvcm1BYnN0cmFjdAEADElubmVyQ2xhc3NlcwEAEGphdmEvbGFuZy9PYmpl" +
51     "Y3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2" +
52     "YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAARNYWlu" +
53     "BCAABQAGAAAAAAADAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAAHAQB" +
54     "AAsACAAAAAEADAAIAAEACQAAACUAAgABAAAACbIAAhIDtgAEsQAAAAEACgAAAAoAAgAAAB8ACAAg" +
55     "AAIADQAAAAIADgAYAAAACgABAAUAFQAXBAg=");
56   private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
57     "ZGV4CjAzNQCQkoTiKzIz0l96rtsnUxdY4Kwx+YINWFHEAwAAcAAAAHhWNBIAAAAAAAAAAAADAAAV" +
58     "AAAAcAAAAAkAAADEAAAAAgAAAOgAAAABAAAAAAEAAAUAAAAIAQAAAQAAADABAAB0AgAAUAEAAKoB" +
59     "AACyAQAAuwEAANUBAADdAQAAAQIAACECAAA4AgAATAIAAGACAAB0AgAAfwIAAJICAACVAgAAmQIA" +
60     "AKYCAACvAgAAtQIAALoCAADDAgAAygIAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAA" +
61     "DAAAAAwAAAAIAAAAAAAAAA0AAAAIAAAApAEAAAcABAARAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAT" +
62     "AAAABAABABIAAAAFAAAAAAAAAAAAAAAABAAABQAAAAAAAAAKAAAAlAEAAOwCAAAAAAAAAgAAANwC" +
63     "AADiAgAAAQABAAEAAADRAgAABAAAAHAQBAAAAA4AAwABAAIAAADWAgAACAAAAGIAAAAaAQEAbiAD" +
64     "ABAADgBQAQAAAAAAAAAAAAAAAAAAAQAAAAYABjxpbml0PgAHR29vZGJ5ZQAYTE1haW4kVHJhbnNm" +
65     "b3JtQWJzdHJhY3Q7AAZMTWFpbjsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsA" +
66     "HkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJM" +
67     "amF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07" +
68     "AAlNYWluLmphdmEAEVRyYW5zZm9ybUFic3RyYWN0AAFWAAJWTAALYWNjZXNzRmxhZ3MAB2RvU2F5" +
69     "SGkABG5hbWUAA291dAAHcHJpbnRsbgAFc2F5SGkABXZhbHVlABwABw4AHwAHDngAAgIBFBgBAgMC" +
70     "DiQIBBAXCwAAAQIAgIAE3AIBgQgAAQH0AgAAEAAAAAAAAAABAAAAAAAAAAEAAAAVAAAAcAAAAAIA" +
71     "AAAJAAAAxAAAAAMAAAACAAAA6AAAAAQAAAABAAAAAAEAAAUAAAAFAAAACAEAAAYAAAABAAAAMAEA" +
72     "AAMQAAABAAAAUAEAAAEgAAACAAAAXAEAAAYgAAABAAAAlAEAAAEQAAABAAAApAEAAAIgAAAVAAAA" +
73     "qgEAAAMgAAACAAAA0QIAAAQgAAACAAAA3AIAAAAgAAABAAAA7AIAAAAQAAABAAAAAAMAAA==");
74 
main(String[] args)75   public static void main(String[] args) throws Exception {
76     System.loadLibrary(args[0]);
77     Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
78 
79     ensureJitCompiled(TransformAbstract.class, "sayHi");
80     ensureJitCompiled(TransformConcrete.class, "doSayHi");
81 
82     TransformAbstract t1 = new TransformConcrete();
83     t1.doSayHi();
84 
85     assertSingleImplementation(TransformAbstract.class, "doSayHi", true);
86 
87     System.out.println("redefining TransformAbstract");
88     Redefinition.doCommonClassRedefinition(TransformAbstract.class, CLASS_BYTES, DEX_BYTES);
89 
90     t1.doSayHi();
91   }
92 
hasSingleImplementation(Class<?> clazz, String method_name)93   private static native boolean hasSingleImplementation(Class<?> clazz, String method_name);
assertSingleImplementation(Class<?> clazz, String method_name, boolean b)94   private static void assertSingleImplementation(Class<?> clazz, String method_name, boolean b) {
95     if (hasSingleImplementation(clazz, method_name) != b) {
96       System.out.println(clazz + "." + method_name +
97           " doesn't have single implementation value of " + b);
98     }
99   }
100 }
101