1 /* 2 * Copyright (C) 2019 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 package art; 18 19 import dalvik.system.InMemoryDexClassLoader; 20 import java.nio.ByteBuffer; 21 import java.util.ArrayList; 22 import java.util.Base64; 23 import java.util.concurrent.CountDownLatch; 24 import java.util.function.Supplier; 25 import java.util.concurrent.atomic.*; 26 import java.lang.ref.*; 27 28 public class Test2006 { 29 public static final CountDownLatch start_latch = new CountDownLatch(1); 30 public static final CountDownLatch redefine_latch = new CountDownLatch(1); 31 public static final CountDownLatch finish_latch = new CountDownLatch(1); 32 public static volatile int start_counter = 0; 33 public static volatile int finish_counter = 0; 34 public static class Transform { Transform()35 public Transform() { } finalize()36 protected void finalize() throws Throwable { 37 System.out.println("Finalizing"); 38 start_counter++; 39 start_latch.countDown(); 40 redefine_latch.await(); 41 finish_counter++; 42 finish_latch.countDown(); 43 } 44 } 45 46 /** 47 * base64 encoded class/dex file for 48 * public static class Transform { 49 * public String greeting; 50 * 51 * public Transform() { 52 * greeting = "Hello"; 53 * } 54 * protected void finalize() { 55 * System.out.println("NOTHING HERE!"); 56 * } 57 * } 58 */ 59 private static final byte[] DEX_BYTES = 60 Base64.getDecoder() 61 .decode( 62 "ZGV4CjAzNQDtxu0Tsy2rLn9iTZHx3r+yuY0IuN+y1el4BAAAcAAAAHhWNBIAAAAAAAAAALQDAAAX" + 63 "AAAAcAAAAAkAAADMAAAAAgAAAPAAAAACAAAACAEAAAQAAAAYAQAAAQAAADgBAAAgAwAAWAEAAKoB" + 64 "AACyAQAAuQEAANMBAADjAQAABwIAACcCAAA+AgAAUgIAAGYCAAB6AgAAiQIAAJgCAACjAgAApgIA" + 65 "AKoCAAC3AgAAwQIAAMsCAADRAgAA1gIAAN8CAADmAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAA" + 66 "CAAAAAkAAAANAAAADQAAAAgAAAAAAAAADgAAAAgAAACkAQAAAAAGABEAAAAHAAQAEwAAAAAAAAAA" + 67 "AAAAAAAAABAAAAAEAAEAFAAAAAUAAAAAAAAAAAAAAAEAAAAFAAAAAAAAAAsAAACkAwAAhAMAAAAA" + 68 "AAACAAEAAQAAAJgBAAAIAAAAcBADAAEAGgABAFsQAAAOAAMAAQACAAAAngEAAAgAAABiAAEAGgEK" + 69 "AG4gAgAQAA4ABgAOPEsACgAOeAAAAQAAAAYABjxpbml0PgAFSGVsbG8AGExhcnQvVGVzdDIwMDYk" + 70 "VHJhbnNmb3JtOwAOTGFydC9UZXN0MjAwNjsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdD" + 71 "bGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAVTGphdmEvaW8vUHJpbnRTdHJl" + 72 "YW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9T" + 73 "eXN0ZW07AA1OT1RISU5HIEhFUkUhAA1UZXN0MjAwNi5qYXZhAAlUcmFuc2Zvcm0AAVYAAlZMAAth" + 74 "Y2Nlc3NGbGFncwAIZmluYWxpemUACGdyZWV0aW5nAARuYW1lAANvdXQAB3ByaW50bG4ABXZhbHVl" + 75 "AIwBfn5EOHsiY29tcGlsYXRpb24tbW9kZSI6ImRlYnVnIiwiaGFzLWNoZWNrc3VtcyI6ZmFsc2Us" + 76 "Im1pbi1hcGkiOjEsInNoYS0xIjoiMTI5ZWU5ZjY3NTZjMzlkZjU3ZmYwNzg1ZDI1NmIyMzc3MjY0" + 77 "MmI3YyIsInZlcnNpb24iOiIyLjAuMTAtZGV2In0AAgIBFRgBAgMCDwQJEhcMAAEBAQABAIGABNgC" + 78 "AQT4AgAAAAACAAAAdQMAAHsDAACYAwAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAX" + 79 "AAAAcAAAAAIAAAAJAAAAzAAAAAMAAAACAAAA8AAAAAQAAAACAAAACAEAAAUAAAAEAAAAGAEAAAYA" + 80 "AAABAAAAOAEAAAEgAAACAAAAWAEAAAMgAAACAAAAmAEAAAEQAAABAAAApAEAAAIgAAAXAAAAqgEA" + 81 "AAQgAAACAAAAdQMAAAAgAAABAAAAhAMAAAMQAAACAAAAlAMAAAYgAAABAAAApAMAAAAQAAABAAAA" + 82 "tAMAAA=="); 83 run()84 public static void run() throws Exception { 85 Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE); 86 doTest(); 87 } 88 89 public static final class GcThread extends Thread { 90 public volatile boolean finished = false; run()91 public void run() { 92 while (!finished) { 93 Runtime.getRuntime().gc(); 94 System.runFinalization(); 95 } 96 } 97 } 98 doTest()99 public static void doTest() throws Exception { 100 GcThread gc_thr = new GcThread(); 101 gc_thr.start(); 102 mktransform(); 103 start_latch.await(); 104 System.out.println("start_counter: " + start_counter); 105 Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES); 106 redefine_latch.countDown(); 107 finish_latch.await(); 108 System.out.println("Finish_counter: " + finish_counter); 109 gc_thr.finished = true; 110 gc_thr.join(); 111 } mktransform()112 public static void mktransform() throws Exception { 113 Transform tr = new Transform(); 114 } 115 } 116