blob: 70734943a0020e899a38077f9367d1673d001d29 [file] [log] [blame]
Alex Light986914b2019-11-19 01:12:25 +00001/*
2 * Copyright (C) 2016 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
17package art;
18
19import java.lang.reflect.Field;
20import java.util.ArrayList;
21import java.util.Base64;
22import java.util.concurrent.CountDownLatch;
23public class Test1995 {
24 private static final int NUM_THREADS = 20;
Alex Light93be70e2020-01-07 17:05:42 +000025 // Don't perform more than this many repeats per thread to prevent OOMEs
26 private static final int TASK_COUNT_LIMIT = 1000;
Alex Light986914b2019-11-19 01:12:25 +000027
28 public static final class Transform {
29 public String greetingEnglish;
30 public Transform() {
31 this.greetingEnglish = "Hello";
32 }
33 public String sayHi() {
34 return greetingEnglish + " from " + Thread.currentThread().getName();
35 }
36 }
37
38 /**
39 * base64 encoded class/dex file for
40 * public static final class Transform {
41 * public String greetingEnglish;
42 * public String greetingFrench;
43 * public String greetingDanish;
44 * public String greetingJapanese;
45 *
46 * public Transform() {
47 * this.greetingEnglish = "Hello World";
48 * this.greetingFrench = "Bonjour le Monde";
49 * this.greetingDanish = "Hej Verden";
50 * this.greetingJapanese = "こんにちは世界";
51 * }
52 * public String sayHi() {
53 * return sayHiEnglish() + ", " + sayHiFrench() + ", " + sayHiDanish() + ", " + sayHiJapanese() + " from " + Thread.currentThread().getName();
54 * }
55 * public String sayHiEnglish() {
56 * return greetingEnglish;
57 * }
58 * public String sayHiDanish() {
59 * return greetingDanish;
60 * }
61 * public String sayHiJapanese() {
62 * return greetingJapanese;
63 * }
64 * public String sayHiFrench() {
65 * return greetingFrench;
66 * }
67 * }
68 */
69 private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
70"ZGV4CjAzNQCsHrUqkb8cYgT2oYN7HlVbeOxJT/kONRvgBgAAcAAAAHhWNBIAAAAAAAAAABwGAAAl" +
71"AAAAcAAAAAkAAAAEAQAABAAAACgBAAAEAAAAWAEAAAwAAAB4AQAAAQAAANgBAADoBAAA+AEAAEoD" +
72"AABSAwAAVgMAAF4DAABwAwAAfAMAAIkDAACMAwAAkAMAAKoDAAC6AwAA3gMAAP4DAAASBAAAJgQA" +
73"AEEEAABVBAAAZAQAAG8EAAByBAAAfwQAAIcEAACWBAAAnwQAAK8EAADABAAA0AQAAOIEAADoBAAA" +
74"7wQAAPwEAAAKBQAAFwUAACYFAAAwBQAANwUAAK8FAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAO" +
75"AAAADwAAABIAAAAGAAAABQAAAAAAAAAHAAAABgAAAEQDAAAGAAAABwAAAAAAAAASAAAACAAAAAAA" +
76"AAAAAAUAFwAAAAAABQAYAAAAAAAFABkAAAAAAAUAGgAAAAAAAwACAAAAAAAAABwAAAAAAAAAHQAA" +
77"AAAAAAAeAAAAAAAAAB8AAAAAAAAAIAAAAAQAAwACAAAABgADAAIAAAAGAAEAFAAAAAYAAAAhAAAA" +
78"BwACABUAAAAHAAAAFgAAAAAAAAARAAAABAAAAAAAAAAQAAAADAYAANUFAAAAAAAABwABAAIAAAAt" +
79"AwAAQQAAAG4QAwAGAAwAbhAEAAYADAFuEAIABgAMAm4QBQAGAAwDcQAKAAAADARuEAsABAAMBCIF" +
80"BgBwEAcABQBuIAgABQAaAAEAbiAIAAUAbiAIABUAbiAIAAUAbiAIACUAbiAIAAUAbiAIADUAGgAA" +
81"AG4gCAAFAG4gCABFAG4QCQAFAAwAEQAAAAIAAQAAAAAAMQMAAAMAAABUEAAAEQAAAAIAAQAAAAAA" +
82"NQMAAAMAAABUEAEAEQAAAAIAAQAAAAAAOQMAAAMAAABUEAIAEQAAAAIAAQAAAAAAPQMAAAMAAABU" +
83"EAMAEQAAAAIAAQABAAAAJAMAABQAAABwEAYAAQAaAAUAWxABABoAAwBbEAIAGgAEAFsQAAAaACQA" +
84"WxADAA4ACQAOPEtLS0sAEAAOABYADgATAA4AHAAOABkADgAAAAABAAAABQAGIGZyb20gAAIsIAAG" +
85"PGluaXQ+ABBCb25qb3VyIGxlIE1vbmRlAApIZWogVmVyZGVuAAtIZWxsbyBXb3JsZAABTAACTEwA" +
86"GExhcnQvVGVzdDE5OTUkVHJhbnNmb3JtOwAOTGFydC9UZXN0MTk5NTsAIkxkYWx2aWsvYW5ub3Rh" +
87"dGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwASTGph" +
88"dmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAGUxqYXZhL2xhbmcvU3RyaW5nQnVp" +
89"bGRlcjsAEkxqYXZhL2xhbmcvVGhyZWFkOwANVGVzdDE5OTUuamF2YQAJVHJhbnNmb3JtAAFWAAth" +
90"Y2Nlc3NGbGFncwAGYXBwZW5kAA1jdXJyZW50VGhyZWFkAAdnZXROYW1lAA5ncmVldGluZ0Rhbmlz" +
91"aAAPZ3JlZXRpbmdFbmdsaXNoAA5ncmVldGluZ0ZyZW5jaAAQZ3JlZXRpbmdKYXBhbmVzZQAEbmFt" +
92"ZQAFc2F5SGkAC3NheUhpRGFuaXNoAAxzYXlIaUVuZ2xpc2gAC3NheUhpRnJlbmNoAA1zYXlIaUph" +
93"cGFuZXNlAAh0b1N0cmluZwAFdmFsdWUAdn5+RDh7ImNvbXBpbGF0aW9uLW1vZGUiOiJkZWJ1ZyIs" +
94"Im1pbi1hcGkiOjEsInNoYS0xIjoiNjBkYTRkNjdiMzgxYzQyNDY3NzU3YzQ5ZmI2ZTU1NzU2ZDg4" +
95"YTJmMyIsInZlcnNpb24iOiIxLjcuMTItZGV2In0AB+OBk+OCk+OBq+OBoeOBr+S4lueVjAACAgEi" +
96"GAECAwITBBkbFxEABAEFAAEBAQEBAQEAgYAE7AUBAfgDAQGMBQEBpAUBAbwFAQHUBQAAAAAAAgAA" +
97"AMYFAADMBQAAAAYAAAAAAAAAAAAAAAAAABAAAAAAAAAAAQAAAAAAAAABAAAAJQAAAHAAAAACAAAA" +
98"CQAAAAQBAAADAAAABAAAACgBAAAEAAAABAAAAFgBAAAFAAAADAAAAHgBAAAGAAAAAQAAANgBAAAB" +
99"IAAABgAAAPgBAAADIAAABgAAACQDAAABEAAAAQAAAEQDAAACIAAAJQAAAEoDAAAEIAAAAgAAAMYF" +
100"AAAAIAAAAQAAANUFAAADEAAAAgAAAPwFAAAGIAAAAQAAAAwGAAAAEAAAAQAAABwGAAA=");
101
102
103 public static void run() throws Exception {
104 Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
105 doTest();
106 }
107
108 public static final class MyThread extends Thread {
109 public MyThread(CountDownLatch delay, int id) {
110 super("Thread: " + id);
111 this.thr_id = id;
Alex Light93be70e2020-01-07 17:05:42 +0000112 this.results = new ArrayList<>(TASK_COUNT_LIMIT);
Alex Light986914b2019-11-19 01:12:25 +0000113 this.finish = false;
114 this.delay = delay;
115 }
116
117 public void run() {
118 delay.countDown();
Alex Light93be70e2020-01-07 17:05:42 +0000119 while (!finish && results.size() < TASK_COUNT_LIMIT) {
Alex Light986914b2019-11-19 01:12:25 +0000120 Transform t = new Transform();
121 results.add(t.sayHi());
122 }
123 }
124
125 public void finish() throws Exception {
126 finish = true;
127 this.join();
128 }
129
130 public void Check() throws Exception {
131 for (String s : results) {
132 if (!s.equals("Hello from " + getName()) &&
133 !s.equals("Hello, null, null, null from " + getName()) &&
134 !s.equals("Hello World, Bonjour le Monde, Hej Verden, こんにちは世界 from " + getName())) {
135 System.out.println("FAIL " + thr_id + ": Unexpected result: " + s);
136 }
137 }
138 }
139
140 public ArrayList<String> results;
141 public volatile boolean finish;
142 public int thr_id;
143 public CountDownLatch delay;
144 }
145
146 public static MyThread[] startThreads(int num_threads) throws Exception {
147 CountDownLatch cdl = new CountDownLatch(num_threads);
148 MyThread[] res = new MyThread[num_threads];
149 for (int i = 0; i < num_threads; i++) {
150 res[i] = new MyThread(cdl, i);
151 res[i].start();
152 }
153 cdl.await();
154 return res;
155 }
156 public static void finishThreads(MyThread[] thrs) throws Exception {
157 for (MyThread t : thrs) {
158 t.finish();
159 }
160 for (MyThread t : thrs) {
161 t.Check();
162 }
163 }
164
165 public static void doTest() throws Exception {
166 MyThread[] threads = startThreads(NUM_THREADS);
167 Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES);
168 finishThreads(threads);
169 }
170}