| Alex Light | abbc4bc | 2017-10-05 17:07:40 -0700 | [diff] [blame] | 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 { |
| 21 | public abstract void doSayHi(); |
| 22 | |
| 23 | public void sayHi() { |
| 24 | System.out.println("hello"); |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | static final class TransformConcrete extends TransformAbstract { |
| 29 | public final void doSayHi() { |
| 30 | System.out.print("Running sayHi() - "); |
| 31 | sayHi(); |
| 32 | } |
| 33 | } |
| 34 | |
| 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 | |
| 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 | |
| 93 | private static native boolean hasSingleImplementation(Class<?> clazz, String method_name); |
| 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 | } |