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