Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/StackWalker/StackWalkTest.java
41149 views
1
/*
2
* Copyright (c) 2015, 2017, 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
import static java.lang.StackWalker.Option.*;
25
import java.lang.StackWalker.StackFrame;
26
import java.util.Arrays;
27
import java.util.EnumSet;
28
import java.util.HashSet;
29
import java.util.List;
30
import java.util.Random;
31
import java.util.Set;
32
import java.util.TreeSet;
33
34
import jdk.test.lib.RandomFactory;
35
36
/**
37
* @test
38
* @bug 8140450
39
* @summary Stack Walk Test (use -Dseed=X to set PRNG seed)
40
* @library /test/lib
41
* @build jdk.test.lib.RandomFactory
42
* @compile StackRecorderUtil.java
43
* @run main/othervm StackWalkTest
44
* @run main/othervm/java.security.policy=stackwalktest.policy StackWalkTest
45
* @run main/othervm StackWalkTest -random:50
46
* @run main/othervm/java.security.policy=stackwalktest.policy StackWalkTest -random:50
47
* @author danielfuchs, bchristi
48
* @key randomness
49
*/
50
public class StackWalkTest {
51
private static boolean random = false;
52
private static boolean verbose = false;
53
private static int randomRuns = 50;
54
55
private static final int MAX_RANDOM_DEPTH = 1000;
56
57
static final Set<String> infrastructureClasses = new TreeSet<>(Arrays.asList(
58
"jdk.internal.reflect.NativeMethodAccessorImpl",
59
"jdk.internal.reflect.DelegatingMethodAccessorImpl",
60
"java.lang.reflect.Method",
61
"com.sun.javatest.regtest.MainWrapper$MainThread",
62
"com.sun.javatest.regtest.agent.MainWrapper$MainThread",
63
"java.lang.Thread"
64
));
65
static final List<Class<?>> streamPipelines = Arrays.asList(
66
classForName("java.util.stream.AbstractPipeline"),
67
classForName("java.util.stream.TerminalOp")
68
);
69
static Class<?> classForName(String name) {
70
try {
71
return Class.forName(name);
72
} catch (ClassNotFoundException e){
73
throw new RuntimeException(e);
74
}
75
}
76
77
private static boolean isStreamPipeline(Class<?> clazz) {
78
for (Class<?> c : streamPipelines) {
79
if (c.isAssignableFrom(clazz)) {
80
return true;
81
}
82
}
83
return false;
84
}
85
86
StackRecorderUtil recorder;
87
int count = 0;
88
boolean didWalk = false;
89
90
final int estDepth;
91
final Set<StackWalker.Option> swOptions;
92
93
public StackWalkTest() {
94
this(EnumSet.noneOf(StackWalker.Option.class), -1);
95
}
96
97
public StackWalkTest(Set<StackWalker.Option> swOptions) {
98
this(swOptions, -1);
99
}
100
101
public StackWalkTest(int estimatedDepth) {
102
this(EnumSet.noneOf(StackWalker.Option.class), -1);
103
}
104
105
public StackWalkTest(Set<StackWalker.Option> swOptions, int estimatedDepth) {
106
this.swOptions = swOptions;
107
this.estDepth = estimatedDepth;
108
}
109
110
private StackWalker createStackWalker() {
111
// test all StackWalker factory methods
112
if (this.estDepth < 0) {
113
if (swOptions.isEmpty()) {
114
return StackWalker.getInstance();
115
} else {
116
return StackWalker.getInstance(swOptions);
117
}
118
}
119
return StackWalker.getInstance(swOptions, estDepth);
120
}
121
public void consume(StackFrame sf) {
122
if (count == 0 && swOptions.contains(StackWalker.Option.RETAIN_CLASS_REFERENCE)
123
&& isStreamPipeline(sf.getDeclaringClass())) {
124
return;
125
}
126
if (verbose) {
127
System.out.println("\t" + sf.getClassName() + "." + sf.getMethodName());
128
}
129
if (count >= recorder.frameCount()) {
130
// We've gone past main()...
131
if (infrastructureClasses.contains(sf.getClassName())) {
132
// safe to ignore
133
return;
134
}
135
}
136
try {
137
recorder.compareFrame(count, sf);
138
} catch (IndexOutOfBoundsException e) {
139
// Extra non-infra frame in stream
140
throw new RuntimeException("extra non-infra stack frame at count "
141
+ count + ": <" + sf + ">", e);
142
}
143
count++;
144
}
145
146
public class Call {
147
public void walk(int total, int markAt) {
148
recorder.add(Call.class, "walk", "StackWalkTest.java");
149
long swFrameCount = createStackWalker().walk(s -> s.count());
150
151
if (verbose) {
152
System.out.println("Call.walk() total=" + total + ", markAt=" + markAt);
153
System.out.println("recorder frames:");
154
for (StackRecorderUtil.TestFrame f : recorder) {
155
System.out.println("\t" + f.declaringClass + "." + f.methodName);
156
}
157
System.out.println("\nStackWalker recorded " + swFrameCount + " frames");
158
System.out.flush();
159
}
160
long recFrameCount = (long)recorder.frameCount();
161
if (swFrameCount < recFrameCount) {
162
throw new RuntimeException("StackWalker recorded fewer frames ("+
163
swFrameCount + ") than recorded ("+ recorder.frameCount() +
164
") - " + "estimatedDepth set to " + estDepth);
165
}
166
if (verbose) {
167
System.out.println("StackWalker frames:");
168
}
169
createStackWalker().forEach(StackWalkTest.this::consume);
170
didWalk = true;
171
}
172
public void call(int total, int current, int markAt) {
173
recorder.add(Call.class, "call", "StackWalkTest.java");
174
if (current < total) {
175
testCall.call(total, current+1, markAt);
176
} else {
177
walk(total, markAt);
178
}
179
}
180
}
181
182
public class Marker extends Call {
183
@Override
184
public void call(int total, int current, int markAt) {
185
recorder.add(Marker.class, "call", "StackWalkTest.java");
186
if (current < total) {
187
testCall.call(total, current+1, markAt);
188
} else {
189
walk(total, markAt);
190
}
191
}
192
}
193
private Call markerCall = new Marker();
194
195
public class Test extends Call {
196
@Override
197
public void call(int total, int current, int markAt) {
198
recorder.add(Test.class, "call", "StackWalkTest.java");
199
if (current < total) {
200
int nexti = current + 1;
201
if (nexti==markAt) {
202
markerCall.call(total, nexti, markAt);
203
} else {
204
testCall.call2(total, nexti, markAt);
205
}
206
} else {
207
walk(total, markAt);
208
}
209
}
210
public void call2(int total, int current, int markAt) {
211
recorder.add(Test.class, "call2", "StackWalkTest.java");
212
if (current < total) {
213
int nexti = current + 1;
214
if (nexti==markAt) {
215
markerCall.call(total, nexti, markAt);
216
} else {
217
test2Call.call(total, nexti, markAt);
218
}
219
} else {
220
walk(total, markAt);
221
}
222
}
223
}
224
private Test testCall = new Test();
225
226
/** Inherits call() from Call */
227
public class Test2 extends Call {}
228
private Test2 test2Call = new Test2();
229
230
public void runTest(Class callerClass, String callerMethod, int stackDepth,
231
int markAt) {
232
if (didWalk) {
233
throw new IllegalStateException("StackWalkTest already used");
234
}
235
// Test may run into StackOverflow when running in -Xcomp mode on deep stack
236
assert stackDepth <= 1000;
237
assert markAt <= stackDepth : "markAt(" + markAt + ") > stackDepth("
238
+ stackDepth + ")";
239
System.out.print("runTest(" + swOptions
240
+ "), estimatedDepth=" + estDepth);
241
242
recorder = new StackRecorderUtil(swOptions);
243
recorder.add(callerClass, callerMethod, "StackWalkTest.java");
244
recorder.add(StackWalkTest.class, "runTest", "StackWalkTest.java");
245
246
Test test1 = new Test();
247
test1.call(stackDepth, 0, markAt);
248
249
System.out.println(" finished");
250
if (!didWalk) {
251
throw new IllegalStateException("Test wasn't actually performed");
252
}
253
}
254
255
public static void main(String[] args) {
256
String rand = "-random";
257
String randItems = "-random:";
258
for(String arg : args) {
259
if (arg.startsWith(rand)) {
260
random = true;
261
try {
262
if(arg.startsWith(randItems)) {
263
randomRuns = Integer.valueOf(arg.substring(randItems.length()));
264
}
265
} catch(NumberFormatException e) {}
266
} else if("-verbose".equals(arg)) {
267
verbose = true;
268
}
269
}
270
if (random) {
271
Random rng = RandomFactory.getRandom();
272
for (int iters = 0; iters < randomRuns; iters++) {
273
Set<StackWalker.Option> opts = new HashSet<>();
274
if (rng.nextBoolean()) {
275
opts.add(RETAIN_CLASS_REFERENCE);
276
}
277
278
int depth = 1 + rng.nextInt(MAX_RANDOM_DEPTH);
279
280
StackWalkTest swt;
281
if (rng.nextBoolean() && depth > 1) {
282
// Test that specifying an estimatedDepth doesn't prevent
283
// full stack traversal
284
swt = new StackWalkTest(opts, 1+rng.nextInt(depth-1));
285
} else {
286
swt = new StackWalkTest(opts);
287
}
288
289
int markAt = rng.nextInt(depth+1);
290
System.out.print(depth + "@" + markAt + " ");
291
System.out.flush();
292
swt.runTest(StackWalkTest.class, "main", depth, markAt);
293
}
294
} else {
295
// Long stack, default maxDepth
296
StackWalkTest swt;
297
swt = new StackWalkTest();
298
swt.runTest(StackWalkTest.class, "main", 1000, 10);
299
300
// Long stack, matching maxDepth
301
swt = new StackWalkTest(2000);
302
swt.runTest(StackWalkTest.class, "main", 1000, 10);
303
304
// Long stack, maximum maxDepth
305
swt = new StackWalkTest(Integer.MAX_VALUE);
306
swt.runTest(StackWalkTest.class, "main", 1000, 10);
307
308
//
309
// Single batch
310
//
311
swt = new StackWalkTest(); // default maxDepth
312
swt.runTest(StackWalkTest.class, "main", 6, 3);
313
314
swt = new StackWalkTest(4); // maxDepth < stack
315
swt.runTest(StackWalkTest.class, "main", 6, 3);
316
317
swt = new StackWalkTest(2); // maxDepth < marker
318
swt.runTest(StackWalkTest.class, "main", 6, 4);
319
320
//
321
// 2 batches
322
//
323
swt = new StackWalkTest(); // default maxDepth
324
swt.runTest(StackWalkTest.class, "main", 24, 10);
325
swt = new StackWalkTest(18); // maxDepth < stack
326
swt.runTest(StackWalkTest.class, "main", 24, 10);
327
swt = new StackWalkTest(8); // maxDepth < marker
328
swt.runTest(StackWalkTest.class, "main", 24, 10);
329
330
//
331
// 3 batch
332
//
333
swt = new StackWalkTest(); // default maxDepth
334
swt.runTest(StackWalkTest.class, "main", 60, 20);
335
swt = new StackWalkTest(35); // maxDepth < stack
336
swt.runTest(StackWalkTest.class, "main", 60, 20);
337
swt = new StackWalkTest(8); // maxDepth < marker
338
swt.runTest(StackWalkTest.class, "main", 60, 20);
339
340
//
341
// StackWalker.Options
342
//
343
swt = new StackWalkTest();
344
swt.runTest(StackWalkTest.class, "main", 50, 10);
345
346
swt = new StackWalkTest(EnumSet.of(RETAIN_CLASS_REFERENCE));
347
swt.runTest(StackWalkTest.class, "main", 80, 40);
348
349
swt = new StackWalkTest(EnumSet.of(RETAIN_CLASS_REFERENCE), 50);
350
swt.runTest(StackWalkTest.class, "main", 1000, 524);
351
}
352
}
353
}
354
355