Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java
41155 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
* @key randomness
27
* @modules java.base/jdk.internal.misc:+open
28
*
29
* @summary converted from VM Testbase metaspace/staticReferences.
30
* VM Testbase keywords: [nonconcurrent, javac, no_cds]
31
*
32
* @requires vm.opt.final.ClassUnloading
33
* @library /vmTestbase /test/lib
34
* @build sun.hotspot.WhiteBox
35
* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox
36
* @run main/othervm
37
* -Xmx800m
38
* -Xbootclasspath/a:.
39
* -XX:+UnlockDiagnosticVMOptions
40
* -XX:+WhiteBoxAPI
41
* StaticReferences
42
*/
43
44
import java.lang.invoke.MethodHandles;
45
import java.lang.invoke.MethodHandles.Lookup;
46
import java.lang.ref.WeakReference;
47
import java.lang.ref.Reference;
48
import java.lang.reflect.Field;
49
import java.lang.reflect.Modifier;
50
import java.util.HashMap;
51
import java.util.LinkedList;
52
import java.util.List;
53
import java.util.Map;
54
import java.util.Random;
55
56
import vm.share.InMemoryJavaCompiler;
57
import nsk.share.gc.GCTestBase;
58
import nsk.share.test.ExecutionController;
59
import nsk.share.test.Stresser;
60
import nsk.share.test.TestBase;
61
import nsk.share.test.Tests;
62
import vm.share.gc.TriggerUnloadingHelper;
63
import vm.share.gc.TriggerUnloadingWithWhiteBox;
64
65
/**
66
* Test checks that static fields will be initialized in new loaded class. Test performs in loop the following routine:
67
* 1.) Load class either by regular classloader or by defineHiddenClass.
68
* 2.) Trigger unloading. Class must be alive. Next step will check that static fields were not lost.
69
* 3.) Change static fields.
70
* 4.) Unload class.
71
* 5.) Load class again as in step 1.
72
* 6.) Check that static fields were initialized.
73
*/
74
@SuppressWarnings("rawtypes")
75
public class StaticReferences extends GCTestBase {
76
77
private static final int UNLOADING_ATTEMPTS_LIMIT = 50;
78
79
private static final Object[] NO_CP_PATCHES = new Object[0];
80
81
private static String[] args;
82
83
private static final int LIMIT = 20;
84
85
private List<Object> keepAlive = new LinkedList<Object>();
86
87
private Random random;
88
89
private TriggerUnloadingHelper triggerUnloadingHelper = new TriggerUnloadingWithWhiteBox();
90
91
private String[] typesArray = new String[] {"Object object", "boolean boolean", "byte byte", "char char", "double double", "float float", "int int", "long long", "short short"};
92
93
public static void main(String[] args) {
94
StaticReferences.args = args;
95
Tests.runTest(new StaticReferences(), args);
96
}
97
98
@Override
99
public void run() {
100
random = new Random(runParams.getSeed());
101
ExecutionController stresser = new Stresser(args);
102
stresser.start(1);
103
104
// Generate and compile classes
105
List<byte[]> bytecodeList = new LinkedList<byte[]>();
106
int[] fieldQuantities = new int[9];
107
long startTimeStamp = System.currentTimeMillis();
108
for (int i = 0; i < LIMIT; i++) {
109
if (!stresser.continueExecution()) {
110
return;
111
}
112
for (int j = 0; j < fieldQuantities.length; j++) {
113
fieldQuantities[j] = 1 + random.nextInt(20);
114
}
115
bytecodeList.add(generateAndCompile(fieldQuantities));
116
}
117
log.info("Compilation finished in " + ((System.currentTimeMillis() - startTimeStamp)/1000/60.0) + " minutes ");
118
119
// Core of test
120
for (byte[] classBytecode : bytecodeList) {
121
boolean hidden = random.nextBoolean();
122
123
log.info("Load class first time");
124
Class clazz = loadClass(classBytecode, hidden);
125
126
log.info("Trigger unloading");
127
triggerUnloadingHelper.triggerUnloading(stresser);
128
if (!stresser.continueExecution()) {
129
return;
130
}
131
132
log.info("Set up static fields. This will check that static fields are reachable.");
133
setupFields(clazz);
134
135
log.info("Cleanup references");
136
Reference<Class> weakReference = new WeakReference<Class>(clazz);
137
clazz = null;
138
139
log.info("Trigger unloading again");
140
int numberOfAttemps = 0;
141
while (weakReference.get() != null && numberOfAttemps < UNLOADING_ATTEMPTS_LIMIT) {
142
if (!stresser.continueExecution()) {
143
return;
144
}
145
triggerUnloadingHelper.triggerUnloading(stresser);
146
}
147
if (numberOfAttemps >= UNLOADING_ATTEMPTS_LIMIT) {
148
setFailed(true);
149
throw new RuntimeException("Test failed: was unable to unload class with " + UNLOADING_ATTEMPTS_LIMIT + " attempts.");
150
}
151
152
log.info("Load class second time");
153
clazz = loadClass(classBytecode, hidden);
154
155
log.info("check fields reinitialized");
156
checkStaticFields(clazz);
157
158
keepAlive.add(clazz);
159
}
160
}
161
162
private Class loadClass(byte[] classBytecode, boolean hidden) {
163
Class clazz;
164
if (hidden) {
165
Lookup lookup = MethodHandles.lookup();
166
try {
167
clazz = lookup.defineHiddenClass(classBytecode, false).lookupClass();
168
} catch (IllegalAccessException e) {
169
e.printStackTrace();
170
throw new RuntimeException(
171
"Lookup.defineHiddenClass failed: " + e.getMessage());
172
}
173
} else {
174
OneUsageClassloader classloader = new OneUsageClassloader();
175
clazz = classloader.define(classBytecode);
176
}
177
return clazz;
178
}
179
180
private void checkStaticFields(Class clazz) {
181
for (Field field : clazz.getFields()) {
182
try {
183
if (Modifier.isStatic(field.getModifiers())) {
184
Class fieldType = field.getType();
185
if ((fieldType.equals(Object.class) && field.get(null) != null )
186
|| (fieldType.equals(int.class) && field.getInt(null) != 0)
187
|| (fieldType.equals(boolean.class) && field.getBoolean(null) != false)
188
|| (fieldType.equals(char.class) && field.getChar(null) != 0)
189
|| (fieldType.equals(long.class) && field.getLong(null) != 0)
190
|| (fieldType.equals(short.class) && field.getShort(null) != 0)
191
|| (fieldType.equals(float.class) && field.getFloat(null) != 0.0f)
192
|| (fieldType.equals(double.class) && field.getDouble(null) != 0.0)
193
|| (fieldType.equals(byte.class) && field.getByte(null) != 0)) {
194
setFailed(true);
195
throw new RuntimeException("Failing test: field "
196
+ field.getName() + " of type "
197
+ field.getType() + " in class "
198
+ field.getDeclaringClass().getName()
199
+ " was not cleared");
200
}
201
}
202
} catch (IllegalArgumentException | IllegalAccessException e) {
203
e.printStackTrace();
204
throw new RuntimeException("Was unable to set static field "
205
+ field.getName() + " of type "
206
+ field.getType().getName() + " in class "
207
+ field.getDeclaringClass().getName(), e);
208
}
209
}
210
}
211
212
private byte[] generateAndCompile(int[] fieldQuantities) {
213
Map<String, CharSequence> sources = new HashMap<String, CharSequence>();
214
sources.put("A", generateSource(fieldQuantities));
215
return InMemoryJavaCompiler.compile(sources).values().iterator().next();
216
}
217
218
private StringBuffer generateSource(int[] fieldQuantities) {
219
StringBuffer result = new StringBuffer("public class A { \n");
220
int fieldsCounter = 0;
221
for (int i = 0; i < typesArray.length; i++) {
222
for (int j = 0; j < fieldQuantities[i]; j++) {
223
result.append(" public static " + typesArray[i] + fieldsCounter++ + ";\n");
224
}
225
}
226
result.append(" } ");
227
return result;
228
}
229
230
private void setupFields(Class clazz) {
231
for (Field field : clazz.getFields()) {
232
try {
233
if (Modifier.isStatic(field.getModifiers())) {
234
Class fieldType = field.getType();
235
if (fieldType.equals(Object.class)) {
236
field.set(null, this);
237
} else if (fieldType.equals(int.class)) {
238
field.setInt(null, 42);
239
} else if (fieldType.equals(boolean.class)) {
240
field.setBoolean(null, true);
241
} else if (fieldType.equals(char.class)) {
242
field.setChar(null, 'c');
243
} else if (fieldType.equals(long.class)) {
244
field.setLong(null, (long) 42);
245
} else if (fieldType.equals(short.class)) {
246
field.setShort(null, (short) 42);
247
} else if (fieldType.equals(float.class)) {
248
field.setFloat(null, 42.42f);
249
} else if (fieldType.equals(double.class)) {
250
field.setDouble(null, 42.42);
251
} else if (fieldType.equals(byte.class)) {
252
field.setByte(null, (byte) 42);
253
}
254
}
255
} catch (IllegalArgumentException | IllegalAccessException e) {
256
e.printStackTrace();
257
throw new RuntimeException(
258
"Was unable to set static field " + field.getName()
259
+ " of type " + field.getType().getName()
260
+ " in class "
261
+ field.getDeclaringClass().getName(), e);
262
}
263
}
264
}
265
266
}
267
268