1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker package art; 18*795d594fSAndroid Build Coastguard Worker 19*795d594fSAndroid Build Coastguard Worker import java.util.Base64; 20*795d594fSAndroid Build Coastguard Worker public class Test1990 { 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker static class Transform { saySomething()23*795d594fSAndroid Build Coastguard Worker public static void saySomething() { 24*795d594fSAndroid Build Coastguard Worker System.out.println("hello"); 25*795d594fSAndroid Build Coastguard Worker } 26*795d594fSAndroid Build Coastguard Worker } 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker /** 29*795d594fSAndroid Build Coastguard Worker * base64 encoded class/dex file for 30*795d594fSAndroid Build Coastguard Worker * static class Transform { 31*795d594fSAndroid Build Coastguard Worker * public static void saySomething() { 32*795d594fSAndroid Build Coastguard Worker * System.out.println("I say hello and " + sayGoodbye()); 33*795d594fSAndroid Build Coastguard Worker * } 34*795d594fSAndroid Build Coastguard Worker * public static String sayGoodbye() { 35*795d594fSAndroid Build Coastguard Worker * return "you say goodbye!"; 36*795d594fSAndroid Build Coastguard Worker * } 37*795d594fSAndroid Build Coastguard Worker * } 38*795d594fSAndroid Build Coastguard Worker */ 39*795d594fSAndroid Build Coastguard Worker // NB The actual dex codes are as follows. This is an explanation of the error this test checks. 40*795d594fSAndroid Build Coastguard Worker // 41*795d594fSAndroid Build Coastguard Worker // The exact order of instructions is important. Notice the 'invoke-static sayGoodbye' 42*795d594fSAndroid Build Coastguard Worker // (instruction 0002) dominates the rest of the block. During the first (runnable) verification 43*795d594fSAndroid Build Coastguard Worker // step the verifier will first check and verify there are no hard-failures in this class. Next it 44*795d594fSAndroid Build Coastguard Worker // will realize it cannot find the sayGoodbye method on the loaded & resolved Transform class. 45*795d594fSAndroid Build Coastguard Worker // This is (correctly) recognized as a soft-verification failure but then the verifier decides the 46*795d594fSAndroid Build Coastguard Worker // rest of the method is dead-code. This means the verifier will not perform any of the 47*795d594fSAndroid Build Coastguard Worker // soft-failure checks on the rest of the method (since control would never reach there). 48*795d594fSAndroid Build Coastguard Worker // 49*795d594fSAndroid Build Coastguard Worker // Later after performing the redefinition we do a reverify. At this time we held an exclusive 50*795d594fSAndroid Build Coastguard Worker // mutator-lock though so it cannot resolve classes and will not add anything to the dex-cache. 51*795d594fSAndroid Build Coastguard Worker // Here we can get past instruction 0002 and successfully determine the rest of the function is 52*795d594fSAndroid Build Coastguard Worker // fine. In the process we filled in the methods into the dex-cache but not the classes. This 53*795d594fSAndroid Build Coastguard Worker // caused this test to crash when run through the interpreter. 54*795d594fSAndroid Build Coastguard Worker // 55*795d594fSAndroid Build Coastguard Worker // #2 : (in Lart/Test1990$Transform;) 56*795d594fSAndroid Build Coastguard Worker // name : 'saySomething' 57*795d594fSAndroid Build Coastguard Worker // type : '()V' 58*795d594fSAndroid Build Coastguard Worker // access : 0x0009 (PUBLIC STATIC) 59*795d594fSAndroid Build Coastguard Worker // code - 60*795d594fSAndroid Build Coastguard Worker // registers : 4 61*795d594fSAndroid Build Coastguard Worker // ins : 0 62*795d594fSAndroid Build Coastguard Worker // outs : 2 63*795d594fSAndroid Build Coastguard Worker // insns size : 27 16-bit code units 64*795d594fSAndroid Build Coastguard Worker // 0001d0: |[0001d0] art.Test1990$Transform.saySomething:()V 65*795d594fSAndroid Build Coastguard Worker // 0001e0: 6200 0000 |0000: sget-object v0, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000 66*795d594fSAndroid Build Coastguard Worker // 0001e4: 7100 0100 0000 |0002: invoke-static {}, Lart/Test1990$Transform;.sayGoodbye:()Ljava/lang/String; // method@0001 67*795d594fSAndroid Build Coastguard Worker // 0001ea: 0c01 |0005: move-result-object v1 68*795d594fSAndroid Build Coastguard Worker // 0001ec: 2202 0700 |0006: new-instance v2, Ljava/lang/StringBuilder; // type@0007 69*795d594fSAndroid Build Coastguard Worker // 0001f0: 7010 0500 0200 |0008: invoke-direct {v2}, Ljava/lang/StringBuilder;.<init>:()V // method@0005 70*795d594fSAndroid Build Coastguard Worker // 0001f6: 1a03 0100 |000b: const-string v3, "I say hello and " // string@0001 71*795d594fSAndroid Build Coastguard Worker // 0001fa: 6e20 0600 3200 |000d: invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; // method@0006 72*795d594fSAndroid Build Coastguard Worker // 000200: 6e20 0600 1200 |0010: invoke-virtual {v2, v1}, Ljava/lang/StringBuilder;.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; // method@0006 73*795d594fSAndroid Build Coastguard Worker // 000206: 6e10 0700 0200 |0013: invoke-virtual {v2}, Ljava/lang/StringBuilder;.toString:()Ljava/lang/String; // method@0007 74*795d594fSAndroid Build Coastguard Worker // 00020c: 0c01 |0016: move-result-object v1 75*795d594fSAndroid Build Coastguard Worker // 00020e: 6e20 0300 1000 |0017: invoke-virtual {v0, v1}, Ljava/io/PrintStream;.println:(Ljava/lang/String;)V // method@0003 76*795d594fSAndroid Build Coastguard Worker // 000214: 0e00 |001a: return-void 77*795d594fSAndroid Build Coastguard Worker // catches : (none) 78*795d594fSAndroid Build Coastguard Worker // positions : 79*795d594fSAndroid Build Coastguard Worker // 0x0000 line=5 80*795d594fSAndroid Build Coastguard Worker // 0x001a line=6 81*795d594fSAndroid Build Coastguard Worker // locals : 82*795d594fSAndroid Build Coastguard Worker 83*795d594fSAndroid Build Coastguard Worker // Virtual methods - 84*795d594fSAndroid Build Coastguard Worker // source_file_idx : 13 (Test1990.java) 85*795d594fSAndroid Build Coastguard Worker private static final byte[] DEX_BYTES = Base64.getDecoder().decode( 86*795d594fSAndroid Build Coastguard Worker "ZGV4CjAzNQCV0LekDslEGFglxYgCw7HSyxVegIDjERswBQAAcAAAAHhWNBIAAAAAAAAAAGwEAAAc" + 87*795d594fSAndroid Build Coastguard Worker "AAAAcAAAAAoAAADgAAAABAAAAAgBAAABAAAAOAEAAAgAAABAAQAAAQAAAIABAACQAwAAoAEAAC4C" + 88*795d594fSAndroid Build Coastguard Worker "AAA2AgAASAIAAEsCAABPAgAAaQIAAHkCAACdAgAAvQIAANQCAADoAgAA/AIAABcDAAArAwAAOgMA" + 89*795d594fSAndroid Build Coastguard Worker "AEUDAABIAwAATAMAAFkDAABhAwAAZwMAAGwDAAB1AwAAgQMAAI8DAACZAwAAoAMAALIDAAAEAAAA" + 90*795d594fSAndroid Build Coastguard Worker "BQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAAPAAAAAgAAAAYAAAAAAAAAAwAAAAcAAAAo" + 91*795d594fSAndroid Build Coastguard Worker "AgAADwAAAAkAAAAAAAAAEAAAAAkAAAAoAgAACAAEABQAAAAAAAIAAAAAAAAAAAAWAAAAAAACABcA" + 92*795d594fSAndroid Build Coastguard Worker "AAAEAAMAFQAAAAUAAgAAAAAABwACAAAAAAAHAAEAEgAAAAcAAAAYAAAAAAAAAAAAAAAFAAAAAAAA" + 93*795d594fSAndroid Build Coastguard Worker "AA0AAABcBAAAOQQAAAAAAAABAAAAAAAAABoCAAADAAAAGgAaABEAAAABAAEAAQAAABYCAAAEAAAA" + 94*795d594fSAndroid Build Coastguard Worker "cBAEAAAADgAEAAAAAgAAAB4CAAAbAAAAYgAAAHEAAQAAAAwBIgIHAHAQBQACABoDAQBuIAYAMgBu" + 95*795d594fSAndroid Build Coastguard Worker "IAYAEgBuEAcAAgAMAW4gAwAQAA4AAwAOAAgADgAFAA4BGg8AAAAAAQAAAAYABjxpbml0PgAQSSBz" + 96*795d594fSAndroid Build Coastguard Worker "YXkgaGVsbG8gYW5kIAABTAACTEwAGExhcnQvVGVzdDE5OTAkVHJhbnNmb3JtOwAOTGFydC9UZXN0" + 97*795d594fSAndroid Build Coastguard Worker "MTk5MDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3Rh" + 98*795d594fSAndroid Build Coastguard Worker "dGlvbi9Jbm5lckNsYXNzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVj" + 99*795d594fSAndroid Build Coastguard Worker "dDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAZTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwASTGphdmEv" + 100*795d594fSAndroid Build Coastguard Worker "bGFuZy9TeXN0ZW07AA1UZXN0MTk5MC5qYXZhAAlUcmFuc2Zvcm0AAVYAAlZMAAthY2Nlc3NGbGFn" + 101*795d594fSAndroid Build Coastguard Worker "cwAGYXBwZW5kAARuYW1lAANvdXQAB3ByaW50bG4ACnNheUdvb2RieWUADHNheVNvbWV0aGluZwAI" + 102*795d594fSAndroid Build Coastguard Worker "dG9TdHJpbmcABXZhbHVlABB5b3Ugc2F5IGdvb2RieWUhAHZ+fkQ4eyJjb21waWxhdGlvbi1tb2Rl" + 103*795d594fSAndroid Build Coastguard Worker "IjoiZGVidWciLCJtaW4tYXBpIjoxLCJzaGEtMSI6IjYwZGE0ZDY3YjM4MWM0MjQ2Nzc1N2M0OWZi" + 104*795d594fSAndroid Build Coastguard Worker "NmU1NTc1NmQ4OGEyZjMiLCJ2ZXJzaW9uIjoiMS43LjEyLWRldiJ9AAICARkYAQIDAhEECBMXDgAA" + 105*795d594fSAndroid Build Coastguard Worker "AwAAgIAEuAMBCaADAQnQAwAAAAAAAgAAACoEAAAwBAAAUAQAAAAAAAAAAAAAAAAAABAAAAAAAAAA" + 106*795d594fSAndroid Build Coastguard Worker "AQAAAAAAAAABAAAAHAAAAHAAAAACAAAACgAAAOAAAAADAAAABAAAAAgBAAAEAAAAAQAAADgBAAAF" + 107*795d594fSAndroid Build Coastguard Worker "AAAACAAAAEABAAAGAAAAAQAAAIABAAABIAAAAwAAAKABAAADIAAAAwAAABYCAAABEAAAAQAAACgC" + 108*795d594fSAndroid Build Coastguard Worker "AAACIAAAHAAAAC4CAAAEIAAAAgAAACoEAAAAIAAAAQAAADkEAAADEAAAAgAAAEwEAAAGIAAAAQAA" + 109*795d594fSAndroid Build Coastguard Worker "AFwEAAAAEAAAAQAAAGwEAAA="); 110*795d594fSAndroid Build Coastguard Worker 111*795d594fSAndroid Build Coastguard Worker 112*795d594fSAndroid Build Coastguard Worker run()113*795d594fSAndroid Build Coastguard Worker public static void run() throws Exception { 114*795d594fSAndroid Build Coastguard Worker Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE); 115*795d594fSAndroid Build Coastguard Worker doTest(new Transform()); 116*795d594fSAndroid Build Coastguard Worker } 117*795d594fSAndroid Build Coastguard Worker doTest(Transform t)118*795d594fSAndroid Build Coastguard Worker public static void doTest(Transform t) throws Exception { 119*795d594fSAndroid Build Coastguard Worker Transform.saySomething(); 120*795d594fSAndroid Build Coastguard Worker Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES); 121*795d594fSAndroid Build Coastguard Worker Transform.saySomething(); 122*795d594fSAndroid Build Coastguard Worker } 123*795d594fSAndroid Build Coastguard Worker } 124