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 Test2007 { 29 public static final CountDownLatch finish_latch = new CountDownLatch(1); 30 public static volatile int counter = 0; 31 public static Object theObject = null; 32 public static class Transform { Transform()33 public Transform() { } finalize()34 protected void finalize() throws Throwable { 35 System.out.println("Should never be called!"); 36 // Do nothing. 37 } 38 } 39 40 /** 41 * base64 encoded class/dex file for 42 * public static class Transform { 43 * public String greeting; 44 * 45 * public Transform() { 46 * greeting = "Hello"; 47 * } 48 * protected void finalize() throws Throwable { 49 * System.out.println("Finalizing"); 50 * counter++; 51 * finish_latch.countDown(); 52 * } 53 * } 54 */ 55 private static final byte[] DEX_BYTES = 56 Base64.getDecoder() 57 .decode( 58 "ZGV4CjAzNQCC9DECxo2lTpw7FCCSqZArgZe8ab49ywRoBQAAcAAAAHhWNBIAAAAAAAAAAKQEAAAe" + 59 "AAAAcAAAAA0AAADoAAAAAgAAABwBAAAEAAAANAEAAAUAAABUAQAAAQAAAHwBAADMAwAAnAEAAAYC" + 60 "AAAOAgAAGgIAACECAAAkAgAAPgIAAE4CAAByAgAAkgIAAK4CAADFAgAA2QIAAO0CAAABAwAAGAMA" + 61 "AD8DAABOAwAAWQMAAFwDAABgAwAAbQMAAHgDAACBAwAAiwMAAJkDAACjAwAAqQMAAK4DAAC3AwAA" + 62 "vgMAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAABEAAAAR" + 63 "AAAADAAAAAAAAAASAAAADAAAAAACAAABAAgAGAAAAAIAAAAVAAAAAgALABcAAAAJAAYAGgAAAAEA" + 64 "AAAAAAAAAQAAABYAAAAGAAEAGwAAAAcAAAAAAAAACwAAABQAAAABAAAAAQAAAAcAAAAAAAAADwAA" + 65 "AIwEAABkBAAAAAAAAAIAAQABAAAA8gEAAAgAAABwEAMAAQAaAAIAWxAAAA4AAwABAAIAAAD4AQAA" + 66 "EwAAAGIAAwAaAQEAbiACABAAYAABANgAAAFnAAEAYgACAG4QBAAAAA4ADAAOPEsAEAAOeGlaAAAB" + 67 "AAAACAAGPGluaXQ+AApGaW5hbGl6aW5nAAVIZWxsbwABSQAYTGFydC9UZXN0MjAwNyRUcmFuc2Zv" + 68 "cm07AA5MYXJ0L1Rlc3QyMDA3OwAiTGRhbHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAe" + 69 "TGRhbHZpay9hbm5vdGF0aW9uL0lubmVyQ2xhc3M7ABpMZGFsdmlrL2Fubm90YXRpb24vVGhyb3dz" + 70 "OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcv" + 71 "U3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07ABVMamF2YS9sYW5nL1Rocm93YWJsZTsAJUxqYXZh" + 72 "L3V0aWwvY29uY3VycmVudC9Db3VudERvd25MYXRjaDsADVRlc3QyMDA3LmphdmEACVRyYW5zZm9y" + 73 "bQABVgACVkwAC2FjY2Vzc0ZsYWdzAAljb3VudERvd24AB2NvdW50ZXIACGZpbmFsaXplAAxmaW5p" + 74 "c2hfbGF0Y2gACGdyZWV0aW5nAARuYW1lAANvdXQAB3ByaW50bG4ABXZhbHVlAIwBfn5EOHsiY29t" + 75 "cGlsYXRpb24tbW9kZSI6ImRlYnVnIiwiaGFzLWNoZWNrc3VtcyI6ZmFsc2UsIm1pbi1hcGkiOjEs" + 76 "InNoYS0xIjoiMTI5ZWU5ZjY3NTZjMzlkZjU3ZmYwNzg1ZDI1NmIyMzc3MjY0MmI3YyIsInZlcnNp" + 77 "b24iOiIyLjAuMTAtZGV2In0AAgUBHBwBGAoCAwEcGAICBAITBAkZFxAAAQEBAAEAgYAEnAMBBLwD" + 78 "AAAAAAEAAABNBAAAAgAAAFUEAABbBAAAgAQAAAAAAAABAAAAAAAAAAEAAAB4BAAAEAAAAAAAAAAB" + 79 "AAAAAAAAAAEAAAAeAAAAcAAAAAIAAAANAAAA6AAAAAMAAAACAAAAHAEAAAQAAAAEAAAANAEAAAUA" + 80 "AAAFAAAAVAEAAAYAAAABAAAAfAEAAAEgAAACAAAAnAEAAAMgAAACAAAA8gEAAAEQAAABAAAAAAIA" + 81 "AAIgAAAeAAAABgIAAAQgAAADAAAATQQAAAAgAAABAAAAZAQAAAMQAAADAAAAdAQAAAYgAAABAAAA" + 82 "jAQAAAAQAAABAAAApAQAAA=="); 83 84 run()85 public static void run() throws Exception { 86 Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE); 87 doTest(); 88 } 89 90 public static final class GcThread extends Thread { 91 public volatile boolean finished = false; run()92 public void run() { 93 while (!finished) { 94 Runtime.getRuntime().gc(); 95 System.runFinalization(); 96 } 97 } 98 } 99 doTest()100 public static void doTest() throws Exception { 101 // Try GC forever 102 GcThread gc_thr = new GcThread(); 103 gc_thr.start(); 104 // Make a transform 105 mktransform(); 106 Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES); 107 theObject = null; 108 finish_latch.await(); 109 System.out.println("counter: " + counter); 110 // Make sure we don't have any remaining things to finalize, eg obsolete objects or something. 111 Runtime.getRuntime().gc(); 112 System.runFinalization(); 113 gc_thr.finished = true; 114 gc_thr.join(); 115 } 116 117 // Make sure there is never a transform in the frame of doTest. mktransform()118 public static void mktransform() throws Exception { 119 theObject = new Transform(); 120 } 121 } 122