Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/RedefineTest.java
41159 views
1
/*
2
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
*
27
* @modules java.base/jdk.internal.org.objectweb.asm:+open java.base/jdk.internal.org.objectweb.asm.util:+open
28
* @library /vmTestbase /test/lib
29
*
30
* @comment build retransform.jar in current dir
31
* @run driver vm.runtime.defmeth.shared.BuildJar
32
*
33
* @run driver jdk.test.lib.FileInstaller . .
34
* @run main/othervm/native
35
* -agentlib:redefineClasses
36
* -javaagent:retransform.jar
37
* vm.runtime.defmeth.RedefineTest
38
*/
39
package vm.runtime.defmeth;
40
41
import java.util.HashMap;
42
import java.util.List;
43
import java.util.Map;
44
import java.util.Set;
45
46
import nsk.share.Pair;
47
import vm.runtime.defmeth.shared.DefMethTest;
48
import vm.runtime.defmeth.shared.DefMethTestFailure;
49
import vm.runtime.defmeth.shared.MemoryClassLoader;
50
import vm.runtime.defmeth.shared.annotation.NotApplicableFor;
51
import vm.runtime.defmeth.shared.builder.TestBuilder;
52
import vm.runtime.defmeth.shared.executor.TestExecutor;
53
import vm.runtime.defmeth.shared.data.Clazz;
54
import vm.runtime.defmeth.shared.data.ConcreteClass;
55
import vm.runtime.defmeth.shared.data.Interface;
56
import vm.runtime.defmeth.shared.data.Tester;
57
58
import static jdk.internal.org.objectweb.asm.Opcodes.*;
59
import static vm.runtime.defmeth.shared.ExecutionMode.*;
60
61
/*
62
* Basic scenarios on class redefinition.
63
*/
64
public class RedefineTest extends DefMethTest {
65
66
public static void main(String[] args) {
67
DefMethTest.runTest(RedefineTest.class,
68
/* majorVer */ Set.of(MIN_MAJOR_VER, MAX_MAJOR_VER),
69
/* flags */ Set.of(0, ACC_SYNCHRONIZED),
70
/* redefine */ Set.of(true),
71
/* execMode */ Set.of(DIRECT, INVOKE_EXACT, INVOKE_GENERIC, INDY));
72
}
73
74
@Override
75
protected void configure() {
76
// There are no testers being generated for reflection-based scenarios,
77
// so scenarios on class redefinition don't work
78
String mode = factory.getExecutionMode();
79
if ("REFLECTION".equals(mode) || "INVOKE_WITH_ARGS".equals(mode)) {
80
getLog().warn("RedefineTest isn't applicable to reflection-based execution scenario (REDEFINE & INVOKE_WITH_ARGS).");
81
}
82
}
83
84
/**
85
* Run test {@code b1} w/ redefined {@code classes} from {@code b2}.
86
*
87
* @param b1
88
* @param b2
89
* @param classes
90
*/
91
private void redefineAndRun(TestBuilder b1, TestBuilder b2, Clazz... classes) {
92
TestExecutor executor = b1.prepare();
93
94
getLog().info("Before");
95
List<Pair<Tester,Throwable>> errorsBefore =
96
executor.run(); // run b1
97
98
// redefine in b1
99
MemoryClassLoader cl = executor.getLoader(); // b1.cl
100
Map<String,byte[]> cf = b2.produce(); //
101
Map<String,byte[]> forRedef = new HashMap<>();
102
for (Clazz clz : classes) {
103
String name = clz.name();
104
forRedef.put(name, cf.get(name));
105
}
106
107
cl.modifyClasses(forRedef, factory.isRetransformClasses());
108
109
getLog().info("After");
110
List<Pair<Tester,Throwable>> errorsAfter =
111
executor.run();
112
113
if (!errorsBefore.isEmpty()) {
114
throw new DefMethTestFailure(errorsBefore);
115
}
116
117
if (!errorsAfter.isEmpty()) {
118
throw new DefMethTestFailure(errorsAfter);
119
}
120
}
121
122
/*
123
* Before redefinition:
124
* interface I { public int m() { return 1; } }
125
* class C extends I { public int m() { return 2; } }
126
*
127
* TEST: I i = new C(); i.m() == 2
128
* TEST: C c = new C(); c.m() == 2
129
*
130
* After redefinition:
131
* interface I { public int m() { return 1; } }
132
* class C extends I { public int m() { return 3; } }
133
*
134
* TEST: I i = new C(); i.m() == 3
135
* TEST: C c = new C(); c.m() == 3
136
*/
137
@NotApplicableFor(modes = { REFLECTION, INVOKE_WITH_ARGS }) // reflection-based scenarios rely on checks in bytecode
138
public void testRedefineConcreteMethod() {
139
TestBuilder before = factory.getBuilder();
140
{ // Before redefinition
141
Interface I = before.intf("I")
142
.defaultMethod("m", "()I").returns(1).build()
143
.build();
144
ConcreteClass C = before.clazz("C").implement(I)
145
.concreteMethod("m", "()I").returns(2).build()
146
.build();
147
148
before.test().callSite(I, C, "m", "()I").returns(2).done()
149
.test().callSite(C, C, "m", "()I").returns(2).done();
150
}
151
152
{ // After redefinition
153
TestBuilder after = factory.getBuilder();
154
155
Interface I = after.intf("I")
156
.defaultMethod("m", "()I").returns(1).build()
157
.build();
158
ConcreteClass C = after.clazz("C").implement(I)
159
.concreteMethod("m", "()I").returns(3).build()
160
.build();
161
162
Tester T1 = after.test().callSite(I, C, "m", "()I").returns(3).build();
163
Tester T2 = after.test().callSite(C, C, "m", "()I").returns(3).build();
164
165
redefineAndRun(before, after, C, T1, T2);
166
}
167
}
168
169
/*
170
* Before redefinition:
171
* interface I { public int m() { return 1; } }
172
* class C extends I { public int m() { return 2; } }
173
*
174
* TEST: I i = new C(); i.m() == 2
175
* TEST: C c = new C(); c.m() == 2
176
*
177
* After redefinition:
178
* interface I { public int m() { return 3; } }
179
* class C extends I { public int m() { return 2; } }
180
*
181
* TEST: I i = new C(); i.m() == 2
182
* TEST: C c = new C(); c.m() == 2
183
*/
184
@NotApplicableFor(modes = { REFLECTION, INVOKE_WITH_ARGS }) // reflection-based scenarios rely on checks in bytecode
185
public void testRedefineDefaultMethod() {
186
TestBuilder before = factory.getBuilder();
187
{ // Before redefinition
188
Interface I = before.intf("I")
189
.defaultMethod("m", "()I").returns(1).build()
190
.build();
191
ConcreteClass C = before.clazz("C").implement(I)
192
.concreteMethod("m", "()I").returns(2).build()
193
.build();
194
195
before.test().callSite(I, C, "m", "()I").returns(2).done()
196
.test().callSite(C, C, "m", "()I").returns(2).done();
197
}
198
199
{ // After redefinition
200
TestBuilder after = factory.getBuilder();
201
202
Interface I = after.intf("I")
203
.defaultMethod("m", "()I").returns(3).build()
204
.build();
205
ConcreteClass C = after.clazz("C").implement(I)
206
.concreteMethod("m", "()I").returns(2).build()
207
.build();
208
209
redefineAndRun(before, after, C);
210
}
211
}
212
213
/*
214
* Before redefinition:
215
* interface I { public int m() { return 1; } }
216
* class C extends I {}
217
*
218
* TEST: I i = new C(); i.m() == 1
219
* TEST: C c = new C(); c.m() == 1
220
*
221
* After redefinition:
222
* interface I { public int m() { return 2; } }
223
* class C extends I {}
224
*
225
* TEST: I i = new C(); i.m() == 2
226
* TEST: C c = new C(); c.m() == 2
227
*/
228
@NotApplicableFor(modes = { REFLECTION, INVOKE_WITH_ARGS }) // reflection-based scenarios rely on checks in bytecode
229
public void testRedefineDefMethInConcreteClass() {
230
TestBuilder before = factory.getBuilder();
231
{ // Before redefinition
232
Interface I = before.intf("I")
233
.defaultMethod("m", "()I").returns(1).build()
234
.build();
235
ConcreteClass C = before.clazz("C").implement(I).build();
236
237
before.test().callSite(I, C, "m", "()I").returns(1).done()
238
.test().callSite(C, C, "m", "()I").returns(1).done();
239
}
240
241
{ // After redefinition
242
TestBuilder after = factory.getBuilder();
243
244
Interface I = after.intf("I")
245
.defaultMethod("m", "()I").returns(2).build()
246
.build();
247
ConcreteClass C = after.clazz("C").implement(I).build();
248
249
Tester T1 = after.test().callSite(I, C, "m", "()I").returns(2).build();
250
Tester T2 = after.test().callSite(C, C, "m", "()I").returns(2).build();
251
252
redefineAndRun(before, after, I, T1, T2);
253
}
254
}
255
}
256
257