Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/com/sun/jdi/EATests.java
41152 views
1
/*
2
* Copyright (c) 2020 SAP SE. 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
/**
26
* @test
27
* @bug 8227745
28
* @summary Collection of test cases that check if optimizations based on escape analysis are reverted just before non-escaping objects escape through JVMTI.
29
* @author Richard Reingruber richard DOT reingruber AT sap DOT com
30
*
31
* @requires ((vm.compMode == "Xmixed") & vm.compiler2.enabled)
32
* @library /test/lib /test/hotspot/jtreg
33
*
34
* @run build TestScaffold VMConnection TargetListener TargetAdapter sun.hotspot.WhiteBox
35
* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox
36
* @run compile -g EATests.java
37
* @run driver EATests
38
* -XX:+UnlockDiagnosticVMOptions
39
* -Xms256m -Xmx256m
40
* -Xbootclasspath/a:.
41
* -XX:CompileCommand=dontinline,*::dontinline_*
42
* -XX:+WhiteBoxAPI
43
* -Xbatch
44
* -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
45
* @run driver EATests
46
* -XX:+UnlockDiagnosticVMOptions
47
* -Xms256m -Xmx256m
48
* -Xbootclasspath/a:.
49
* -XX:CompileCommand=dontinline,*::dontinline_*
50
* -XX:+WhiteBoxAPI
51
* -Xbatch
52
* -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:-EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking -XX:-UseOptoBiasInlining
53
* @run driver EATests
54
* -XX:+UnlockDiagnosticVMOptions
55
* -Xms256m -Xmx256m
56
* -Xbootclasspath/a:.
57
* -XX:CompileCommand=dontinline,*::dontinline_*
58
* -XX:+WhiteBoxAPI
59
* -Xbatch
60
* -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
61
* @run driver EATests
62
* -XX:+UnlockDiagnosticVMOptions
63
* -Xms256m -Xmx256m
64
* -Xbootclasspath/a:.
65
* -XX:CompileCommand=dontinline,*::dontinline_*
66
* -XX:+WhiteBoxAPI
67
* -Xbatch
68
* -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
69
* @run driver EATests
70
* -XX:+UnlockDiagnosticVMOptions
71
* -Xms256m -Xmx256m
72
* -Xbootclasspath/a:.
73
* -XX:CompileCommand=dontinline,*::dontinline_*
74
* -XX:+WhiteBoxAPI
75
* -Xbatch
76
* -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
77
* @run driver EATests
78
* -XX:+UnlockDiagnosticVMOptions
79
* -Xms256m -Xmx256m
80
* -Xbootclasspath/a:.
81
* -XX:CompileCommand=dontinline,*::dontinline_*
82
* -XX:+WhiteBoxAPI
83
* -Xbatch
84
* -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
85
* @run driver EATests
86
* -XX:+UnlockDiagnosticVMOptions
87
* -Xms256m -Xmx256m
88
* -Xbootclasspath/a:.
89
* -XX:CompileCommand=dontinline,*::dontinline_*
90
* -XX:+WhiteBoxAPI
91
* -Xbatch
92
* -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
93
*
94
* @comment Excercise -XX:+DeoptimizeObjectsALot. Mostly to prevent bit-rot because the option is meant to stress object deoptimization
95
* with non-synthetic workloads.
96
* @run driver EATests
97
* -XX:+UnlockDiagnosticVMOptions
98
* -Xms256m -Xmx256m
99
* -Xbootclasspath/a:.
100
* -XX:CompileCommand=dontinline,*::dontinline_*
101
* -XX:+WhiteBoxAPI
102
* -Xbatch
103
* -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
104
* -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeObjectsALot
105
*
106
*/
107
/**
108
* @test
109
* @bug 8227745
110
*
111
* @summary This is another configuration of EATests.java to test Graal. Some testcases are expected
112
* to fail because Graal does not provide all information about non-escaping objects in
113
* scope. These are skipped.
114
*
115
* @author Richard Reingruber richard DOT reingruber AT sap DOT com
116
*
117
* @requires ((vm.compMode == "Xmixed") & vm.graal.enabled)
118
*
119
* @library /test/lib /test/hotspot/jtreg
120
*
121
* @run build TestScaffold VMConnection TargetListener TargetAdapter sun.hotspot.WhiteBox
122
* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox
123
* @run compile -g EATests.java
124
*
125
* @comment Test with Graal. Some testcases are expected to fail because Graal does not provide all information about non-escaping
126
* objects in scope. These are skipped.
127
* @run driver EATests
128
* -XX:+UnlockDiagnosticVMOptions
129
* -Xms256m -Xmx256m
130
* -Xbootclasspath/a:.
131
* -XX:CompileCommand=dontinline,*::dontinline_*
132
* -XX:+WhiteBoxAPI
133
* -Xbatch
134
* -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
135
*/
136
137
import com.sun.jdi.*;
138
import com.sun.jdi.event.*;
139
import compiler.testlibrary.CompilerUtils;
140
import compiler.whitebox.CompilerWhiteBoxTest;
141
142
import java.lang.reflect.Array;
143
import java.util.Arrays;
144
import java.util.List;
145
import java.util.Map;
146
import java.util.function.Function;
147
148
import jdk.test.lib.Asserts;
149
import sun.hotspot.WhiteBox;
150
import sun.hotspot.gc.GC;
151
152
153
//
154
// ANALYZING TEST FAILURES
155
//
156
// - Executing just a single test case with the property EATests.onlytestcase.
157
//
158
// Example: java -DEATests.onlytestcase=<test case name> ... EATests
159
//
160
// - Interactive execution allows for attaching a native debugger, e.g. gdb
161
//
162
// Example: java -DEATests.interactive=true ... EATests
163
//
164
// - Java arguments to the test are passed as vm options to the debuggee:
165
//
166
// Example: java ... EATests -XX:+UseNewCode
167
//
168
169
170
171
/////////////////////////////////////////////////////////////////////////////
172
//
173
// Shared base class for test cases for both, debugger and debuggee.
174
//
175
/////////////////////////////////////////////////////////////////////////////
176
177
class EATestCaseBaseShared {
178
// In interactive mode we wait for a keypress before every test case.
179
public static final boolean INTERACTIVE =
180
System.getProperty("EATests.interactive") != null &&
181
System.getProperty("EATests.interactive").equals("true");
182
183
// If the property is given, then just the test case it refers to is executed.
184
// Use it to diagnose test failures.
185
public static final String RUN_ONLY_TEST_CASE_PROPERTY = "EATests.onlytestcase";
186
public static final String RUN_ONLY_TEST_CASE = System.getProperty(RUN_ONLY_TEST_CASE_PROPERTY);
187
188
public final String testCaseName;
189
190
public EATestCaseBaseShared() {
191
String clName = getClass().getName();
192
int tidx = clName.lastIndexOf("Target");
193
testCaseName = tidx > 0 ? clName.substring(0, tidx) : clName;
194
}
195
196
public boolean shouldSkip() {
197
return EATestCaseBaseShared.RUN_ONLY_TEST_CASE != null &&
198
EATestCaseBaseShared.RUN_ONLY_TEST_CASE.length() > 0 &&
199
!testCaseName.equals(EATestCaseBaseShared.RUN_ONLY_TEST_CASE);
200
}
201
}
202
203
/////////////////////////////////////////////////////////////////////////////
204
//
205
// Target main class, i.e. the program to be debugged.
206
//
207
/////////////////////////////////////////////////////////////////////////////
208
209
class EATestsTarget {
210
211
public static void main(String[] args) {
212
EATestCaseBaseTarget.staticSetUp();
213
EATestCaseBaseTarget.staticSetUpDone();
214
215
// Materializing test cases, i.e. reallocating objects on the heap
216
new EAMaterializeLocalVariableUponGetTarget() .run();
217
new EAGetWithoutMaterializeTarget() .run();
218
new EAMaterializeLocalAtObjectReturnTarget() .run();
219
new EAMaterializeLocalAtObjectPollReturnReturnTarget() .run();
220
new EAMaterializeIntArrayTarget() .run();
221
new EAMaterializeLongArrayTarget() .run();
222
new EAMaterializeFloatArrayTarget() .run();
223
new EAMaterializeDoubleArrayTarget() .run();
224
new EAMaterializeObjectArrayTarget() .run();
225
new EAMaterializeObjectWithConstantAndNotConstantValuesTarget() .run();
226
new EAMaterializeObjReferencedBy2LocalsTarget() .run();
227
new EAMaterializeObjReferencedBy2LocalsAndModifyTarget() .run();
228
new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesTarget() .run();
229
new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModifyTarget() .run();
230
new EAMaterializeObjReferencedFromOperandStackTarget() .run();
231
new EAMaterializeLocalVariableUponGetAfterSetIntegerTarget() .run();
232
233
// Relocking test cases
234
new EARelockingSimpleTarget() .run();
235
new EARelockingSimple_2Target() .run();
236
new EARelockingRecursiveTarget() .run();
237
new EARelockingNestedInflatedTarget() .run();
238
new EARelockingNestedInflated_02Target() .run();
239
new EARelockingArgEscapeLWLockedInCalleeFrameTarget() .run();
240
new EARelockingArgEscapeLWLockedInCalleeFrame_2Target() .run();
241
new EARelockingArgEscapeLWLockedInCalleeFrame_3Target() .run();
242
new EARelockingArgEscapeLWLockedInCalleeFrame_4Target() .run();
243
new EAGetOwnedMonitorsTarget() .run();
244
new EAEntryCountTarget() .run();
245
new EARelockingObjectCurrentlyWaitingOnTarget() .run();
246
247
// Test cases that require deoptimization even though neither
248
// locks nor allocations are eliminated at the point where
249
// escape state is changed.
250
new EADeoptFrameAfterReadLocalObject_01Target() .run();
251
new EADeoptFrameAfterReadLocalObject_01BTarget() .run();
252
new EADeoptFrameAfterReadLocalObject_02Target() .run();
253
new EADeoptFrameAfterReadLocalObject_02BTarget() .run();
254
new EADeoptFrameAfterReadLocalObject_02CTarget() .run();
255
new EADeoptFrameAfterReadLocalObject_03Target() .run();
256
257
// PopFrame test cases
258
new EAPopFrameNotInlinedTarget() .run();
259
new EAPopFrameNotInlinedReallocFailureTarget() .run();
260
new EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget() .run();
261
262
// ForceEarlyReturn test cases
263
new EAForceEarlyReturnNotInlinedTarget() .run();
264
new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget() .run();
265
new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget().run();
266
267
// Instances of ReferenceType
268
new EAGetInstancesOfReferenceTypeTarget() .run();
269
}
270
}
271
272
/////////////////////////////////////////////////////////////////////////////
273
//
274
// Debugger main class
275
//
276
/////////////////////////////////////////////////////////////////////////////
277
278
public class EATests extends TestScaffold {
279
280
public TargetVMOptions targetVMOptions;
281
public ThreadReference targetMainThread;
282
283
EATests(String args[]) {
284
super(args);
285
}
286
287
public static void main(String[] args) throws Exception {
288
if (EATestCaseBaseShared.RUN_ONLY_TEST_CASE != null) {
289
args = Arrays.copyOf(args, args.length + 1);
290
args[args.length - 1] = "-D" + EATestCaseBaseShared.RUN_ONLY_TEST_CASE_PROPERTY + "=" + EATestCaseBaseShared.RUN_ONLY_TEST_CASE;
291
}
292
new EATests(args).startTests();
293
}
294
295
public static class TargetVMOptions {
296
297
public final boolean UseJVMCICompiler;
298
public final boolean EliminateAllocations;
299
public final boolean DeoptimizeObjectsALot;
300
public final boolean DoEscapeAnalysis;
301
public final boolean ZGCIsSelected;
302
303
public TargetVMOptions(EATests env, ClassType testCaseBaseTargetClass) {
304
Value val;
305
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("DoEscapeAnalysis"));
306
DoEscapeAnalysis = ((PrimitiveValue) val).booleanValue();
307
// Escape analysis is a prerequisite for scalar replacement (EliminateAllocations)
308
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("EliminateAllocations"));
309
EliminateAllocations = DoEscapeAnalysis && ((PrimitiveValue) val).booleanValue();
310
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("DeoptimizeObjectsALot"));
311
DeoptimizeObjectsALot = ((PrimitiveValue) val).booleanValue();
312
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("UseJVMCICompiler"));
313
UseJVMCICompiler = ((PrimitiveValue) val).booleanValue();
314
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("ZGCIsSelected"));
315
ZGCIsSelected = ((PrimitiveValue) val).booleanValue();
316
}
317
318
}
319
320
// Execute known test cases
321
protected void runTests() throws Exception {
322
String targetProgName = EATestsTarget.class.getName();
323
msg("starting to main method in class " + targetProgName);
324
startToMain(targetProgName);
325
msg("resuming to EATestCaseBaseTarget.staticSetUpDone()V");
326
targetMainThread = resumeTo("EATestCaseBaseTarget", "staticSetUpDone", "()V").thread();
327
Location loc = targetMainThread.frame(0).location();
328
Asserts.assertEQ("staticSetUpDone", loc.method().name());
329
330
targetVMOptions = new TargetVMOptions(this, (ClassType) loc.declaringType());
331
332
// Materializing test cases, i.e. reallocating objects on the heap
333
new EAMaterializeLocalVariableUponGet() .run(this);
334
new EAGetWithoutMaterialize() .run(this);
335
new EAMaterializeLocalAtObjectReturn() .run(this);
336
new EAMaterializeLocalAtObjectPollReturnReturn() .run(this);
337
new EAMaterializeIntArray() .run(this);
338
new EAMaterializeLongArray() .run(this);
339
new EAMaterializeFloatArray() .run(this);
340
new EAMaterializeDoubleArray() .run(this);
341
new EAMaterializeObjectArray() .run(this);
342
new EAMaterializeObjectWithConstantAndNotConstantValues() .run(this);
343
new EAMaterializeObjReferencedBy2Locals() .run(this);
344
new EAMaterializeObjReferencedBy2LocalsAndModify() .run(this);
345
new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFrames() .run(this);
346
new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModify() .run(this);
347
new EAMaterializeObjReferencedFromOperandStack() .run(this);
348
new EAMaterializeLocalVariableUponGetAfterSetInteger() .run(this);
349
350
// Relocking test cases
351
new EARelockingSimple() .run(this);
352
new EARelockingSimple_2() .run(this);
353
new EARelockingRecursive() .run(this);
354
new EARelockingNestedInflated() .run(this);
355
new EARelockingNestedInflated_02() .run(this);
356
new EARelockingArgEscapeLWLockedInCalleeFrame() .run(this);
357
new EARelockingArgEscapeLWLockedInCalleeFrame_2() .run(this);
358
new EARelockingArgEscapeLWLockedInCalleeFrame_3() .run(this);
359
new EARelockingArgEscapeLWLockedInCalleeFrame_4() .run(this);
360
new EAGetOwnedMonitors() .run(this);
361
new EAEntryCount() .run(this);
362
new EARelockingObjectCurrentlyWaitingOn() .run(this);
363
364
// Test cases that require deoptimization even though neither
365
// locks nor allocations are eliminated at the point where
366
// escape state is changed.
367
new EADeoptFrameAfterReadLocalObject_01() .run(this);
368
new EADeoptFrameAfterReadLocalObject_01B() .run(this);
369
new EADeoptFrameAfterReadLocalObject_02() .run(this);
370
new EADeoptFrameAfterReadLocalObject_02B() .run(this);
371
new EADeoptFrameAfterReadLocalObject_02C() .run(this);
372
new EADeoptFrameAfterReadLocalObject_03() .run(this);
373
374
// PopFrame test cases
375
new EAPopFrameNotInlined() .run(this);
376
new EAPopFrameNotInlinedReallocFailure() .run(this);
377
new EAPopInlinedMethodWithScalarReplacedObjectsReallocFailure() .run(this);
378
379
// ForceEarlyReturn test cases
380
new EAForceEarlyReturnNotInlined() .run(this);
381
new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjects() .run(this);
382
new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailure().run(this);
383
384
// Instances of ReferenceType
385
new EAGetInstancesOfReferenceType() .run(this);
386
387
// resume the target listening for events
388
listenUntilVMDisconnect();
389
}
390
391
// Print a Message
392
public void msg(String m) {
393
System.out.println();
394
System.out.println("###(Debugger) " + m);
395
System.out.println();
396
}
397
398
// Highlighted message.
399
public void msgHL(String m) {
400
System.out.println();
401
System.out.println();
402
System.out.println("##########################################################");
403
System.out.println("### " + m);
404
System.out.println("### ");
405
System.out.println();
406
System.out.println();
407
}
408
}
409
410
/////////////////////////////////////////////////////////////////////////////
411
//
412
// Base class for debugger side of test cases.
413
//
414
/////////////////////////////////////////////////////////////////////////////
415
416
abstract class EATestCaseBaseDebugger extends EATestCaseBaseShared {
417
418
protected EATests env;
419
420
public ObjectReference testCase;
421
422
public static final String TARGET_TESTCASE_BASE_NAME = EATestCaseBaseTarget.class.getName();
423
424
public static final String XYVAL_NAME = XYVal.class.getName();
425
426
public abstract void runTestCase() throws Exception;
427
428
public void run(EATests env) {
429
this.env = env;
430
if (shouldSkip()) {
431
msg("skipping " + testCaseName);
432
return;
433
}
434
try {
435
msgHL("Executing test case " + getClass().getName());
436
env.testFailed = false;
437
438
if (INTERACTIVE)
439
env.waitForInput();
440
441
resumeToWarmupDone();
442
runTestCase();
443
Asserts.assertTrue(env.targetMainThread.isSuspended(), "must be suspended after the testcase");
444
resumeToTestCaseDone();
445
checkPostConditions();
446
} catch (Exception e) {
447
Asserts.fail("Unexpected exception in test case " + getClass().getName(), e);
448
}
449
}
450
451
/**
452
* Set a breakpoint in the given method and resume all threads. The
453
* breakpoint is configured to suspend just the thread that reaches it
454
* instead of all threads. This is important when running with graal.
455
*/
456
public BreakpointEvent resumeTo(String clsName, String methodName, String signature) {
457
boolean suspendThreadOnly = true;
458
return env.resumeTo(clsName, methodName, signature, suspendThreadOnly);
459
}
460
461
public void resumeToWarmupDone() throws Exception {
462
msg("resuming to " + TARGET_TESTCASE_BASE_NAME + ".warmupDone()V");
463
resumeTo(TARGET_TESTCASE_BASE_NAME, "warmupDone", "()V");
464
testCase = env.targetMainThread.frame(0).thisObject();
465
}
466
467
public void resumeToTestCaseDone() {
468
msg("resuming to " + TARGET_TESTCASE_BASE_NAME + ".testCaseDone()V");
469
resumeTo(TARGET_TESTCASE_BASE_NAME, "testCaseDone", "()V");
470
}
471
472
public void checkPostConditions() throws Exception {
473
Asserts.assertFalse(env.getExceptionCaught(), "Uncaught exception in Debuggee");
474
475
String testName = getClass().getName();
476
if (!env.testFailed) {
477
env.println(testName + ": passed");
478
} else {
479
throw new Exception(testName + ": failed");
480
}
481
}
482
483
public void printStack(ThreadReference thread) throws Exception {
484
msg("Debuggee Stack:");
485
List<StackFrame> stack_frames = thread.frames();
486
int i = 0;
487
for (StackFrame ff : stack_frames) {
488
System.out.println("frame[" + i++ +"]: " + ff.location().method() + " (bci:" + ff.location().codeIndex() + ")");
489
}
490
}
491
492
public void msg(String m) {
493
env.msg(m);
494
}
495
496
public void msgHL(String m) {
497
env.msgHL(m);
498
}
499
500
// See Field Descriptors in The Java Virtual Machine Specification
501
// (https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.3.2)
502
enum FD {
503
I, // int
504
J, // long
505
F, // float
506
D, // double
507
}
508
509
// Map field descriptor to jdi type string
510
public static final Map<FD, String> FD2JDIArrType = Map.of(FD.I, "int[]", FD.J, "long[]", FD.F, "float[]", FD.D, "double[]");
511
512
// Map field descriptor to PrimitiveValue getter
513
public static final Function<PrimitiveValue, Integer> v2I = PrimitiveValue::intValue;
514
public static final Function<PrimitiveValue, Long> v2J = PrimitiveValue::longValue;
515
public static final Function<PrimitiveValue, Float> v2F = PrimitiveValue::floatValue;
516
public static final Function<PrimitiveValue, Double> v2D = PrimitiveValue::doubleValue;
517
Map<FD, Function<PrimitiveValue, ?>> FD2getter = Map.of(FD.I, v2I, FD.J, v2J, FD.F, v2F, FD.D, v2D);
518
519
/**
520
* Retrieve array of primitive values referenced by a local variable in target and compare with
521
* an array of expected values.
522
* @param frame Frame in the target holding the local variable
523
* @param lName Name of the local variable referencing the array to be retrieved
524
* @param desc Array element type given as field descriptor.
525
* @param expVals Array of expected values.
526
* @throws Exception
527
*/
528
protected void checkLocalPrimitiveArray(StackFrame frame, String lName, FD desc, Object expVals) throws Exception {
529
String lType = FD2JDIArrType.get(desc);
530
Asserts.assertNotNull(lType, "jdi type not found");
531
Asserts.assertEQ(EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, frame .location().method().name());
532
List<LocalVariable> localVars = frame.visibleVariables();
533
msg("Check if the local array variable '" + lName + "' in " + EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME + " has the expected elements: ");
534
boolean found = false;
535
for (LocalVariable lv : localVars) {
536
if (lv.name().equals(lName)) {
537
found = true;
538
Value lVal = frame.getValue(lv);
539
Asserts.assertNotNull(lVal);
540
Asserts.assertEQ(lVal.type().name(), lType);
541
ArrayReference aRef = (ArrayReference) lVal;
542
Asserts.assertEQ(3, aRef.length());
543
// now check the elements
544
for (int i = 0; i < aRef.length(); i++) {
545
Object actVal = FD2getter.get(desc).apply((PrimitiveValue)aRef.getValue(i));
546
Object expVal = Array.get(expVals, i);
547
Asserts.assertEQ(expVal, actVal, "checking element at index " + i);
548
}
549
}
550
}
551
Asserts.assertTrue(found);
552
msg("OK.");
553
}
554
555
/**
556
* Retrieve array of objects referenced by a local variable in target and compare with an array
557
* of expected values.
558
* @param frame Frame in the target holding the local variable
559
* @param lName Name of the local variable referencing the array to be retrieved
560
* @param lType Local type, e.g. java.lang.Long[]
561
* @param expVals Array of expected values.
562
* @throws Exception
563
*/
564
protected void checkLocalObjectArray(StackFrame frame, String lName, String lType, ObjectReference[] expVals) throws Exception {
565
Asserts.assertEQ(EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, frame .location().method().name());
566
List<LocalVariable> localVars = frame.visibleVariables();
567
msg("Check if the local array variable '" + lName + "' in " + EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME + " has the expected elements: ");
568
boolean found = false;
569
for (LocalVariable lv : localVars) {
570
if (lv.name().equals(lName)) {
571
found = true;
572
Value lVal = frame.getValue(lv);
573
Asserts.assertNotNull(lVal);
574
Asserts.assertEQ(lType, lVal.type().name());
575
ArrayReference aRef = (ArrayReference) lVal;
576
Asserts.assertEQ(3, aRef.length());
577
// now check the elements
578
for (int i = 0; i < aRef.length(); i++) {
579
ObjectReference actVal = (ObjectReference)aRef.getValue(i);
580
Asserts.assertSame(expVals[i], actVal, "checking element at index " + i);
581
}
582
}
583
}
584
Asserts.assertTrue(found);
585
msg("OK.");
586
}
587
588
/**
589
* Retrieve a reference held by a local variable in the given frame. Check if the frame's method
590
* is the expected method if the retrieved local value has the expected type and is not null.
591
* @param frame The frame to retrieve the local variable value from.
592
* @param expectedMethodName The name of the frames method should match the expectedMethodName.
593
* @param lName The name of the local variable which is read.
594
* @param expectedType Is the expected type of the object referenced by the local variable.
595
* @return
596
* @throws Exception
597
*/
598
protected ObjectReference getLocalRef(StackFrame frame, String expectedMethodName, String lName, String expectedType) throws Exception {
599
Asserts.assertEQ(expectedMethodName, frame.location().method().name());
600
List<LocalVariable> localVars = frame.visibleVariables();
601
msg("Get and check local variable '" + lName + "' in " + expectedMethodName);
602
ObjectReference lRef = null;
603
for (LocalVariable lv : localVars) {
604
if (lv.name().equals(lName)) {
605
Value lVal = frame.getValue(lv);
606
Asserts.assertNotNull(lVal);
607
Asserts.assertEQ(expectedType, lVal.type().name());
608
lRef = (ObjectReference) lVal;
609
break;
610
}
611
}
612
Asserts.assertNotNull(lRef, "Local variable '" + lName + "' not found");
613
msg("OK.");
614
return lRef;
615
}
616
617
/**
618
* Retrieve a reference held by a local variable in the given frame. Check if the frame's method
619
* matches {@link EATestCaseBaseTarget#TESTMETHOD_DEFAULT_NAME} if the retrieved local value has
620
* the expected type and is not null.
621
* @param frame The frame to retrieve the local variable value from.
622
* @param expectedMethodName The name of the frames method should match the expectedMethodName.
623
* @param lName The name of the local variable which is read.
624
* @param expectedType Is the expected type of the object referenced by the local variable.
625
* @return
626
* @throws Exception
627
*/
628
protected ObjectReference getLocalRef(StackFrame frame, String lType, String lName) throws Exception {
629
return getLocalRef(frame, EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, lName, lType);
630
}
631
632
/**
633
* Set the value of a local variable in the given frame. Check if the frame's method is the expected method.
634
* @param frame The frame holding the local variable.
635
* @param expectedMethodName The expected name of the frame's method.
636
* @param lName The name of the local variable to change.
637
* @param val The new value of the local variable.
638
* @throws Exception
639
*/
640
public void setLocal(StackFrame frame, String expectedMethodName, String lName, Value val) throws Exception {
641
Asserts.assertEQ(expectedMethodName, frame.location().method().name());
642
List<LocalVariable> localVars = frame.visibleVariables();
643
msg("Set local variable '" + lName + "' = " + val + " in " + expectedMethodName);
644
for (LocalVariable lv : localVars) {
645
if (lv.name().equals(lName)) {
646
frame.setValue(lv, val);
647
break;
648
}
649
}
650
msg("OK.");
651
}
652
653
/**
654
* Set the value of a local variable in the given frame. Check if the frame's method matches
655
* {@link EATestCaseBaseTarget#TESTMETHOD_DEFAULT_NAME}.
656
* @param frame The frame holding the local variable.
657
* @param expectedMethodName The expected name of the frame's method.
658
* @param lName The name of the local variable to change.
659
* @param val The new value of the local variable.
660
* @throws Exception
661
*/
662
public void setLocal(StackFrame frame, String lName, Value val) throws Exception {
663
setLocal(frame, EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, lName, val);
664
}
665
666
/**
667
* Check if a field has the expected primitive value.
668
* @param o Object holding the field.
669
* @param desc Field descriptor.
670
* @param fName Field name
671
* @param expVal Expected primitive value
672
* @throws Exception
673
*/
674
protected void checkPrimitiveField(ObjectReference o, FD desc, String fName, Object expVal) throws Exception {
675
msg("check field " + fName);
676
ReferenceType rt = o.referenceType();
677
Field fld = rt.fieldByName(fName);
678
Value val = o.getValue(fld);
679
Object actVal = FD2getter.get(desc).apply((PrimitiveValue) val);
680
Asserts.assertEQ(expVal, actVal, "field '" + fName + "' has unexpected value.");
681
msg("ok");
682
}
683
684
/**
685
* Check if a field references the expected object.
686
* @param obj Object holding the field.
687
* @param fName Field name
688
* @param expVal Object expected to be referenced by the field
689
* @throws Exception
690
*/
691
protected void checkObjField(ObjectReference obj, String fName, ObjectReference expVal) throws Exception {
692
msg("check field " + fName);
693
ReferenceType rt = obj.referenceType();
694
Field fld = rt.fieldByName(fName);
695
Value actVal = obj.getValue(fld);
696
Asserts.assertEQ(expVal, actVal, "field '" + fName + "' has unexpected value.");
697
msg("ok");
698
}
699
700
protected void setField(ObjectReference obj, String fName, Value val) throws Exception {
701
msg("set field " + fName + " = " + val);
702
ReferenceType rt = obj.referenceType();
703
Field fld = rt.fieldByName(fName);
704
obj.setValue(fld, val);
705
msg("ok");
706
}
707
708
protected Value getField(ObjectReference obj, String fName) throws Exception {
709
msg("get field " + fName);
710
ReferenceType rt = obj.referenceType();
711
Field fld = rt.fieldByName(fName);
712
Value val = obj.getValue(fld);
713
msg("result : " + val);
714
return val;
715
}
716
717
/**
718
* Free the memory consumed in the target by {@link EATestCaseBaseTarget#consumedMemory}
719
* @throws Exception
720
*/
721
public void freeAllMemory() throws Exception {
722
msg("free consumed memory");
723
setField(testCase, "consumedMemory", null);
724
}
725
726
/**
727
* @return The value of {@link EATestCaseBaseTarget#targetIsInLoop}. The target must set that field to true as soon as it
728
* enters the endless loop.
729
* @throws Exception
730
*/
731
public boolean targetHasEnteredEndlessLoop() throws Exception {
732
Value v = getField(testCase, "targetIsInLoop");
733
return ((PrimitiveValue) v).booleanValue();
734
}
735
736
/**
737
* Poll {@link EATestCaseBaseTarget#targetIsInLoop} and return if it is found to be true.
738
* @throws Exception
739
*/
740
public void waitUntilTargetHasEnteredEndlessLoop() throws Exception {
741
while(!targetHasEnteredEndlessLoop()) {
742
msg("Target has not yet entered the loop. Sleep 200ms.");
743
try { Thread.sleep(200); } catch (InterruptedException e) { /*ignore */ }
744
}
745
}
746
747
/**
748
* Set {@link EATestCaseBaseTarget#doLoop} to <code>false</code>. This will allow the target to
749
* leave the endless loop.
750
* @throws Exception
751
*/
752
public void terminateEndlessLoop() throws Exception {
753
msg("terminate loop");
754
setField(testCase, "doLoop", env.vm().mirrorOf(false));
755
}
756
}
757
758
/////////////////////////////////////////////////////////////////////////////
759
//
760
// Base class for debuggee side of test cases.
761
//
762
/////////////////////////////////////////////////////////////////////////////
763
764
abstract class EATestCaseBaseTarget extends EATestCaseBaseShared implements Runnable {
765
766
/**
767
* The target must set that field to true as soon as it enters the endless loop.
768
*/
769
public volatile boolean targetIsInLoop;
770
771
/**
772
* Used for busy loops. See {@link #dontinline_endlessLoop()}.
773
*/
774
public volatile long loopCount;
775
776
/**
777
* Used in {@link EATestCaseBaseDebugger#terminateEndlessLoop()} to signal target to leave the endless loop.
778
*/
779
public volatile boolean doLoop;
780
781
public long checkSum;
782
783
public static final String TESTMETHOD_DEFAULT_NAME = "dontinline_testMethod";
784
785
public static final WhiteBox WB = WhiteBox.getWhiteBox();
786
787
public static boolean unbox(Boolean value, boolean dflt) {
788
return value == null ? dflt : value;
789
}
790
791
// Some of the fields are only read by the debugger
792
public static final boolean UseJVMCICompiler = unbox(WB.getBooleanVMFlag("UseJVMCICompiler"), false);
793
public static final boolean DoEscapeAnalysis = unbox(WB.getBooleanVMFlag("DoEscapeAnalysis"), UseJVMCICompiler);
794
public static final boolean EliminateAllocations = unbox(WB.getBooleanVMFlag("EliminateAllocations"), UseJVMCICompiler);
795
public static final boolean DeoptimizeObjectsALot = WB.getBooleanVMFlag("DeoptimizeObjectsALot");
796
public static final long BiasedLockingBulkRebiasThreshold = WB.getIntxVMFlag("BiasedLockingBulkRebiasThreshold");
797
public static final long BiasedLockingBulkRevokeThreshold = WB.getIntxVMFlag("BiasedLockingBulkRevokeThreshold");
798
public static final boolean ZGCIsSelected = GC.Z.isSelected();
799
800
public String testMethodName;
801
public int testMethodDepth;
802
803
// Results produced by dontinline_testMethod()
804
public int iResult;
805
public long lResult;
806
public float fResult;
807
public double dResult;
808
809
810
public boolean warmupDone;
811
812
public volatile Object biasToBeRevoked;
813
814
// an object with an inflated monitor
815
public static XYVal inflatedLock;
816
public static Thread inflatorThread;
817
public static boolean inflatedLockIsPermanentlyInflated;
818
819
public static int NOT_CONST_1I = 1;
820
public static long NOT_CONST_1L = 1L;
821
public static float NOT_CONST_1F = 1.1F;
822
public static double NOT_CONST_1D = 1.1D;
823
824
public static Long NOT_CONST_1_OBJ = Long.valueOf(1);
825
826
827
public static final Long CONST_2_OBJ = Long.valueOf(2);
828
public static final Long CONST_3_OBJ = Long.valueOf(3);
829
830
/**
831
* Main driver of a test case.
832
* <ul>
833
* <li> Skips test case if not selected (see {@link EATestCaseBaseShared#RUN_ONLY_TEST_CASE}
834
* <li> Call {@link #setUp()}
835
* <li> warm-up and compile {@link #dontinline_testMethod()} (see {@link #compileTestMethod()}
836
* <li> calling {@link #dontinline_testMethod()}
837
* <li> checking the result (see {@link #checkResult()}
838
* <ul>
839
*/
840
public void run() {
841
try {
842
if (shouldSkip()) {
843
msg("skipping " + testCaseName);
844
return;
845
}
846
setUp();
847
msg(testCaseName + " is up and running.");
848
compileTestMethod();
849
msg(testCaseName + " warmup done.");
850
warmupDone();
851
checkCompLevel();
852
dontinline_testMethod();
853
checkResult();
854
msg(testCaseName + " done.");
855
testCaseDone();
856
} catch (Exception e) {
857
Asserts.fail("Caught unexpected exception", e);
858
}
859
}
860
861
public static void staticSetUp() {
862
inflatedLock = new XYVal(1, 1);
863
synchronized (inflatedLock) {
864
inflatorThread = new Thread("Lock Inflator (test thread)") {
865
@Override
866
public void run() {
867
synchronized (inflatedLock) {
868
inflatedLockIsPermanentlyInflated = true;
869
inflatedLock.notify(); // main thread
870
while (true) {
871
try {
872
// calling wait() on a monitor will cause inflation into a heavy monitor
873
inflatedLock.wait();
874
} catch (InterruptedException e) { /* ignored */ }
875
}
876
}
877
}
878
};
879
inflatorThread.setDaemon(true);
880
inflatorThread.start();
881
882
// wait until the lock is permanently inflated by the inflatorThread
883
while(!inflatedLockIsPermanentlyInflated) {
884
try {
885
inflatedLock.wait(); // until inflated
886
} catch (InterruptedException e1) { /* ignored */ }
887
}
888
}
889
}
890
891
// Debugger will set breakpoint here to sync with target.
892
public static void staticSetUpDone() {
893
}
894
895
public void setUp() {
896
testMethodDepth = 1;
897
testMethodName = TESTMETHOD_DEFAULT_NAME;
898
}
899
900
public abstract void dontinline_testMethod() throws Exception;
901
902
public int dontinline_brkpt_iret() {
903
dontinline_brkpt();
904
return 42;
905
}
906
907
/**
908
* It is a common protocol to have the debugger set a breakpoint in this method and have {@link
909
* #dontinline_testMethod()} call it and then perform some test actions on debugger side.
910
* After that it is checked if a frame of {@link #dontinline_testMethod()} is found at the
911
* expected depth on stack and if it is (not) marked for deoptimization as expected.
912
*/
913
public void dontinline_brkpt() {
914
// will set breakpoint here after warmup
915
if (warmupDone) {
916
// check if test method is at expected depth
917
StackTraceElement[] frames = Thread.currentThread().getStackTrace();
918
int stackTraceDepth = testMethodDepth + 1; // ignore java.lang.Thread.getStackTrace()
919
Asserts.assertEQ(testMethodName, frames[stackTraceDepth].getMethodName(),
920
testCaseName + ": test method not found at depth " + testMethodDepth);
921
// check if the frame is (not) deoptimized as expected
922
if (!DeoptimizeObjectsALot) {
923
if (testFrameShouldBeDeoptimized()) {
924
Asserts.assertTrue(WB.isFrameDeoptimized(testMethodDepth+1),
925
testCaseName + ": expected test method frame at depth " + testMethodDepth + " to be deoptimized");
926
} else {
927
Asserts.assertFalse(WB.isFrameDeoptimized(testMethodDepth+1),
928
testCaseName + ": expected test method frame at depth " + testMethodDepth + " not to be deoptimized");
929
}
930
}
931
}
932
}
933
934
/**
935
* Some test cases run busy endless loops by initializing {@link #loopCount}
936
* to {@link Long#MAX_VALUE} after warm-up and then counting down to 0 in their main test method.
937
* During warm-up {@link #loopCount} is initialized to a small value.
938
*/
939
public long dontinline_endlessLoop() {
940
long cs = checkSum;
941
doLoop = true;
942
while (loopCount-- > 0 && doLoop) {
943
targetIsInLoop = true;
944
checkSum += checkSum % ++cs;
945
}
946
loopCount = 3;
947
targetIsInLoop = false;
948
return checkSum;
949
}
950
951
public boolean testFrameShouldBeDeoptimized() {
952
return DoEscapeAnalysis;
953
}
954
955
public void warmupDone() {
956
warmupDone = true;
957
}
958
959
// Debugger will set breakpoint here to sync with target.
960
public void testCaseDone() {
961
}
962
963
public void compileTestMethod() throws Exception {
964
int callCount = CompilerWhiteBoxTest.THRESHOLD;
965
while (callCount-- > 0) {
966
dontinline_testMethod();
967
}
968
}
969
970
public void checkCompLevel() {
971
java.lang.reflect.Method m = null;
972
try {
973
m = getClass().getMethod(TESTMETHOD_DEFAULT_NAME);
974
} catch (NoSuchMethodException | SecurityException e) {
975
Asserts.fail("could not check compilation level of", e);
976
}
977
int highestLevel = CompilerUtils.getMaxCompilationLevel();
978
int compLevel = WB.getMethodCompilationLevel(m);
979
if (!UseJVMCICompiler) {
980
Asserts.assertEQ(highestLevel, compLevel,
981
m + " not on expected compilation level");
982
} else {
983
// Background compilation (-Xbatch) will block a thread with timeout
984
// (see CompileBroker::wait_for_jvmci_completion()). Therefore it is
985
// possible to reach here before the main test method is compiled.
986
// In that case we wait for it to be compiled.
987
while (compLevel != highestLevel) {
988
msg(TESTMETHOD_DEFAULT_NAME + " is compiled on level " + compLevel +
989
". Wait until highes level (" + highestLevel + ") is reached.");
990
try {
991
Thread.sleep(200);
992
} catch (InterruptedException e) { /* ignored */ }
993
compLevel = WB.getMethodCompilationLevel(m);
994
}
995
}
996
}
997
998
// to be overridden as appropriate
999
public int getExpectedIResult() {
1000
return 0;
1001
}
1002
1003
// to be overridden as appropriate
1004
public long getExpectedLResult() {
1005
return 0;
1006
}
1007
1008
// to be overridden as appropriate
1009
public float getExpectedFResult() {
1010
return 0f;
1011
}
1012
1013
// to be overridden as appropriate
1014
public double getExpectedDResult() {
1015
return 0d;
1016
}
1017
1018
private void checkResult() {
1019
Asserts.assertEQ(getExpectedIResult(), iResult, "checking iResult");
1020
Asserts.assertEQ(getExpectedLResult(), lResult, "checking lResult");
1021
Asserts.assertEQ(getExpectedFResult(), fResult, "checking fResult");
1022
Asserts.assertEQ(getExpectedDResult(), dResult, "checking dResult");
1023
}
1024
1025
public void msg(String m) {
1026
System.out.println();
1027
System.out.println("###(Target) " + m);
1028
System.out.println();
1029
}
1030
1031
// The object passed will be ArgEscape if it was NoEscape before.
1032
public final void dontinline_make_arg_escape(XYVal xy) {
1033
}
1034
1035
/**
1036
* Call a method indirectly using reflection. The indirection is a limit for escape
1037
* analysis in the sense that the VM need not search beyond for frames that might have
1038
* an object being read by an JVMTI agent as ArgEscape.
1039
* @param receiver The receiver object of the call.
1040
* @param methodName The name of the method to be called.
1041
*/
1042
public final void dontinline_call_with_entry_frame(Object receiver, String methodName) {
1043
Asserts.assertTrue(warmupDone, "We want to take the slow path through jni, so don't call in warmup");
1044
1045
Class<?> cls = receiver.getClass();
1046
Class<?>[] none = {};
1047
1048
java.lang.reflect.Method m;
1049
try {
1050
m = cls.getDeclaredMethod(methodName, none);
1051
m.invoke(receiver);
1052
} catch (Exception e) {
1053
Asserts.fail("Call through reflection failed", e);
1054
}
1055
}
1056
1057
/**
1058
* Trigger bulk rebiasing for the given class by creating new instances and calling <code> hashCode() </code> on them.
1059
* @param cls The class to bulk rebias
1060
*/
1061
public void dontinline_bulkRebiasAfterWarmup(Class<?> cls) {
1062
if (warmupDone) {
1063
try {
1064
for (int i=0; i < BiasedLockingBulkRebiasThreshold+2; i++) {
1065
biasToBeRevoked = cls.getDeclaredConstructor(int.class, int.class).newInstance(1, 1);
1066
synchronized (biasToBeRevoked) { // bias towards current thread
1067
checkSum++;
1068
}
1069
biasToBeRevoked.hashCode(); // calling hashCode triggers revocation
1070
}
1071
} catch (Throwable e) {
1072
Asserts.fail("failed to create new instance of " + cls.getName(), e);
1073
}
1074
}
1075
}
1076
1077
/**
1078
* Trigger bulk revoke of biases for the given class by creating new instances and calling <code> hashCode() </code> on them.
1079
* @param cls The class to bulk rebias
1080
*/
1081
public void dontinline_bulkRevokeAfterWarmup(Class<?> cls) {
1082
if (warmupDone) {
1083
try {
1084
for (int i=0; i < BiasedLockingBulkRevokeThreshold+2; i++) {
1085
biasToBeRevoked = cls.getDeclaredConstructor(int.class, int.class).newInstance(1, 1);
1086
synchronized (biasToBeRevoked) { // bias towards current thread
1087
checkSum++;
1088
}
1089
biasToBeRevoked.hashCode(); // calling hashCode triggers revocation
1090
}
1091
} catch (Throwable e) {
1092
Asserts.fail("failed to create new instance of " + cls.getName(), e);
1093
}
1094
}
1095
}
1096
1097
static class LinkedList {
1098
LinkedList l;
1099
public long[] array;
1100
public LinkedList(LinkedList l, int size) {
1101
this.array = size > 0 ? new long[size] : null;
1102
this.l = l;
1103
}
1104
}
1105
1106
public LinkedList consumedMemory;
1107
1108
public void consumeAllMemory() {
1109
msg("consume all memory");
1110
int size = 128 * 1024 * 1024;
1111
while(true) {
1112
try {
1113
while(true) {
1114
consumedMemory = new LinkedList(consumedMemory, size);
1115
}
1116
} catch(OutOfMemoryError oom) {
1117
if (size == 0) break;
1118
}
1119
size = size / 2;
1120
}
1121
}
1122
}
1123
1124
/////////////////////////////////////////////////////////////////////////////
1125
//
1126
// Test Cases
1127
//
1128
/////////////////////////////////////////////////////////////////////////////
1129
1130
// make sure a compiled frame is not deoptimized if an escaping local is accessed
1131
class EAGetWithoutMaterializeTarget extends EATestCaseBaseTarget {
1132
1133
public XYVal getAway;
1134
1135
public void dontinline_testMethod() {
1136
XYVal xy = new XYVal(4, 2);
1137
getAway = xy; // allocated object escapes
1138
dontinline_brkpt();
1139
iResult = xy.x + xy.y;
1140
}
1141
1142
@Override
1143
public int getExpectedIResult() {
1144
return 4 + 2;
1145
}
1146
1147
@Override
1148
public boolean testFrameShouldBeDeoptimized() {
1149
return false;
1150
}
1151
}
1152
1153
class EAGetWithoutMaterialize extends EATestCaseBaseDebugger {
1154
1155
public void runTestCase() throws Exception {
1156
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1157
printStack(bpe.thread());
1158
ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
1159
checkPrimitiveField(o, FD.I, "x", 4);
1160
checkPrimitiveField(o, FD.I, "y", 2);
1161
}
1162
}
1163
1164
/////////////////////////////////////////////////////////////////////////////
1165
1166
//
1167
// Tests the following:
1168
//
1169
// 1. Debugger can obtain a reference to a scalar replaced object R from java thread J.
1170
// See runTestCase.
1171
//
1172
// 2. Subsequent modifications of R by J are noticed by the debugger.
1173
// See checkPostConditions.
1174
//
1175
class EAMaterializeLocalVariableUponGet extends EATestCaseBaseDebugger {
1176
1177
private ObjectReference o;
1178
1179
public void runTestCase() throws Exception {
1180
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1181
printStack(bpe.thread());
1182
// check 1.
1183
o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
1184
// o is referenced in checkPostConditions() and must not be gc'ed.
1185
o.disableCollection();
1186
checkPrimitiveField(o, FD.I, "x", 4);
1187
checkPrimitiveField(o, FD.I, "y", 2);
1188
}
1189
1190
@Override
1191
public void checkPostConditions() throws Exception {
1192
super.checkPostConditions();
1193
// check 2.
1194
checkPrimitiveField(o, FD.I, "x", 5);
1195
}
1196
}
1197
1198
class EAMaterializeLocalVariableUponGetTarget extends EATestCaseBaseTarget {
1199
1200
public void dontinline_testMethod() {
1201
XYVal xy = new XYVal(4, 2);
1202
dontinline_brkpt(); // Debugger obtains scalar replaced object at this point.
1203
xy.x += 1; // Change scalar replaced object after debugger obtained a reference to it.
1204
iResult = xy.x + xy.y;
1205
}
1206
1207
@Override
1208
public int getExpectedIResult() {
1209
return 4 + 2 + 1;
1210
}
1211
}
1212
1213
/////////////////////////////////////////////////////////////////////////////
1214
1215
// Test if an eliminated object can be reallocated in a frame with an active
1216
// call that will return another object
1217
class EAMaterializeLocalAtObjectReturn extends EATestCaseBaseDebugger {
1218
public void runTestCase() throws Exception {
1219
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1220
printStack(bpe.thread());
1221
ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "xy");
1222
checkPrimitiveField(o, FD.I, "x", 4);
1223
checkPrimitiveField(o, FD.I, "y", 2);
1224
}
1225
}
1226
1227
class EAMaterializeLocalAtObjectReturnTarget extends EATestCaseBaseTarget {
1228
@Override
1229
public void setUp() {
1230
super.setUp();
1231
testMethodDepth = 2;
1232
}
1233
1234
public void dontinline_testMethod() {
1235
XYVal xy = new XYVal(4, 2);
1236
Integer io = // Read xy here triggers reallocation
1237
dontinline_brkpt_return_Integer();
1238
iResult = xy.x + xy.y + io;
1239
}
1240
1241
public Integer dontinline_brkpt_return_Integer() {
1242
// We can't break directly in this method, as this results in making
1243
// the test method not entrant caused by an existing dependency
1244
dontinline_brkpt();
1245
return Integer.valueOf(23);
1246
}
1247
1248
@Override
1249
public int getExpectedIResult() {
1250
return 4 + 2 + 23;
1251
}
1252
}
1253
1254
/////////////////////////////////////////////////////////////////////////////
1255
1256
// Test if an eliminated object can be reallocated *just* before a call returns an object.
1257
// (See CompiledMethod::is_at_poll_return())
1258
// Details: the callee method has just one safepoint poll at the return. The other safepoint
1259
// is at the end of an iteration of the endless loop. We can detect if we suspended the target
1260
// there because the local xy is out of scope there.
1261
class EAMaterializeLocalAtObjectPollReturnReturn extends EATestCaseBaseDebugger {
1262
public void runTestCase() throws Exception {
1263
msg("Resume " + env.targetMainThread);
1264
env.vm().resume();
1265
waitUntilTargetHasEnteredEndlessLoop();
1266
ObjectReference o = null;
1267
int retryCount = 0;
1268
do {
1269
env.targetMainThread.suspend();
1270
printStack(env.targetMainThread);
1271
try {
1272
o = getLocalRef(env.targetMainThread.frame(0), XYVAL_NAME, "xy");
1273
} catch (Exception e) {
1274
++retryCount;
1275
msg("The local variable xy is out of scope because we suspended at the wrong bci. Resume and try again! (" + retryCount + ")");
1276
env.targetMainThread.resume();
1277
if ((retryCount % 10) == 0) {
1278
Thread.sleep(200);
1279
}
1280
}
1281
} while (o == null);
1282
checkPrimitiveField(o, FD.I, "x", 4);
1283
checkPrimitiveField(o, FD.I, "y", 2);
1284
terminateEndlessLoop();
1285
}
1286
}
1287
1288
class EAMaterializeLocalAtObjectPollReturnReturnTarget extends EATestCaseBaseTarget {
1289
@Override
1290
public void setUp() {
1291
super.setUp();
1292
loopCount = 3;
1293
doLoop = true;
1294
}
1295
1296
public void warmupDone() {
1297
super.warmupDone();
1298
msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
1299
loopCount = Long.MAX_VALUE; // endless loop
1300
}
1301
1302
public void dontinline_testMethod() {
1303
long result = 0;
1304
while (doLoop && loopCount-- > 0) {
1305
targetIsInLoop = true;
1306
XYVal xy = new XYVal(4, 2);
1307
Integer io = // Read xy here triggers reallocation just before the call returns
1308
dontinline_brkpt_return_Integer();
1309
result += xy.x + xy.y + io;
1310
} // Here is a second safepoint. We were suspended here if xy is not in scope.
1311
targetIsInLoop = false;
1312
lResult = result;
1313
}
1314
1315
public Integer dontinline_brkpt_return_Integer() {
1316
return Integer.valueOf(23);
1317
}
1318
1319
@Override
1320
public long getExpectedLResult() {
1321
return (Long.MAX_VALUE - loopCount) * (4+2+23);
1322
}
1323
}
1324
1325
/////////////////////////////////////////////////////////////////////////////
1326
// Test case collection that tests rematerialization of different
1327
// array types where the first element is always not constant and the
1328
// other elements are constants. Not constant values are stored in
1329
// the stack frame for rematerialization whereas constants are kept
1330
// in the debug info of the nmethod.
1331
1332
class EAMaterializeIntArrayTarget extends EATestCaseBaseTarget {
1333
1334
public void dontinline_testMethod() {
1335
int nums[] = {NOT_CONST_1I , 2, 3};
1336
dontinline_brkpt();
1337
iResult = nums[0] + nums[1] + nums[2];
1338
}
1339
1340
@Override
1341
public int getExpectedIResult() {
1342
return NOT_CONST_1I + 2 + 3;
1343
}
1344
}
1345
1346
class EAMaterializeIntArray extends EATestCaseBaseDebugger {
1347
public void runTestCase() throws Exception {
1348
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1349
printStack(bpe.thread());
1350
int[] expectedVals = {1, 2, 3};
1351
checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.I, expectedVals);
1352
}
1353
}
1354
1355
/////////////////////////////////////////////////////////////////////////////
1356
1357
class EAMaterializeLongArrayTarget extends EATestCaseBaseTarget {
1358
1359
public void dontinline_testMethod() {
1360
long nums[] = {NOT_CONST_1L , 2, 3};
1361
dontinline_brkpt();
1362
lResult = nums[0] + nums[1] + nums[2];
1363
}
1364
1365
@Override
1366
public long getExpectedLResult() {
1367
return NOT_CONST_1L + 2 + 3;
1368
}
1369
}
1370
1371
class EAMaterializeLongArray extends EATestCaseBaseDebugger {
1372
public void runTestCase() throws Exception {
1373
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1374
printStack(bpe.thread());
1375
long[] expectedVals = {1, 2, 3};
1376
checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.J, expectedVals);
1377
}
1378
}
1379
1380
/////////////////////////////////////////////////////////////////////////////
1381
1382
class EAMaterializeFloatArrayTarget extends EATestCaseBaseTarget {
1383
1384
public void dontinline_testMethod() {
1385
float nums[] = {NOT_CONST_1F , 2.2f, 3.3f};
1386
dontinline_brkpt();
1387
fResult = nums[0] + nums[1] + nums[2];
1388
}
1389
1390
@Override
1391
public float getExpectedFResult() {
1392
return NOT_CONST_1F + 2.2f + 3.3f;
1393
}
1394
}
1395
1396
class EAMaterializeFloatArray extends EATestCaseBaseDebugger {
1397
public void runTestCase() throws Exception {
1398
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1399
printStack(bpe.thread());
1400
float[] expectedVals = {1.1f, 2.2f, 3.3f};
1401
checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.F, expectedVals);
1402
}
1403
}
1404
1405
/////////////////////////////////////////////////////////////////////////////
1406
1407
class EAMaterializeDoubleArrayTarget extends EATestCaseBaseTarget {
1408
1409
public void dontinline_testMethod() {
1410
double nums[] = {NOT_CONST_1D , 2.2d, 3.3d};
1411
dontinline_brkpt();
1412
dResult = nums[0] + nums[1] + nums[2];
1413
}
1414
1415
@Override
1416
public double getExpectedDResult() {
1417
return NOT_CONST_1D + 2.2d + 3.3d;
1418
}
1419
}
1420
1421
class EAMaterializeDoubleArray extends EATestCaseBaseDebugger {
1422
public void runTestCase() throws Exception {
1423
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1424
printStack(bpe.thread());
1425
double[] expectedVals = {1.1d, 2.2d, 3.3d};
1426
checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.D, expectedVals);
1427
}
1428
}
1429
1430
/////////////////////////////////////////////////////////////////////////////
1431
1432
class EAMaterializeObjectArrayTarget extends EATestCaseBaseTarget {
1433
1434
public void dontinline_testMethod() {
1435
Long nums[] = {NOT_CONST_1_OBJ , CONST_2_OBJ, CONST_3_OBJ};
1436
dontinline_brkpt();
1437
lResult = nums[0] + nums[1] + nums[2];
1438
}
1439
1440
@Override
1441
public long getExpectedLResult() {
1442
return 1 + 2 + 3;
1443
}
1444
}
1445
1446
class EAMaterializeObjectArray extends EATestCaseBaseDebugger {
1447
public void runTestCase() throws Exception {
1448
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1449
printStack(bpe.thread());
1450
ReferenceType clazz = bpe.thread().frame(0).location().declaringType();
1451
ObjectReference[] expectedVals = {
1452
(ObjectReference) clazz.getValue(clazz.fieldByName("NOT_CONST_1_OBJ")),
1453
(ObjectReference) clazz.getValue(clazz.fieldByName("CONST_2_OBJ")),
1454
(ObjectReference) clazz.getValue(clazz.fieldByName("CONST_3_OBJ"))
1455
};
1456
checkLocalObjectArray(bpe.thread().frame(1), "nums", "java.lang.Long[]", expectedVals);
1457
}
1458
}
1459
1460
/////////////////////////////////////////////////////////////////////////////
1461
1462
// Materialize an object whose fields have constant and not constant values at
1463
// the point where the object is materialized.
1464
class EAMaterializeObjectWithConstantAndNotConstantValuesTarget extends EATestCaseBaseTarget {
1465
1466
public void dontinline_testMethod() {
1467
ILFDO o = new ILFDO(NOT_CONST_1I, 2,
1468
NOT_CONST_1L, 2L,
1469
NOT_CONST_1F, 2.1F,
1470
NOT_CONST_1D, 2.1D,
1471
NOT_CONST_1_OBJ, CONST_2_OBJ
1472
);
1473
dontinline_brkpt();
1474
dResult =
1475
o.i + o.i2 + o.l + o.l2 + o.f + o.f2 + o.d + o.d2 + o.o + o.o2;
1476
}
1477
1478
@Override
1479
public double getExpectedDResult() {
1480
return NOT_CONST_1I + 2 + NOT_CONST_1L + 2L + NOT_CONST_1F + 2.1F + NOT_CONST_1D + 2.1D + NOT_CONST_1_OBJ + CONST_2_OBJ;
1481
}
1482
}
1483
1484
class EAMaterializeObjectWithConstantAndNotConstantValues extends EATestCaseBaseDebugger {
1485
public void runTestCase() throws Exception {
1486
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1487
printStack(bpe.thread());
1488
ObjectReference o = getLocalRef(bpe.thread().frame(1), "ILFDO", "o");
1489
checkPrimitiveField(o, FD.I, "i", 1);
1490
checkPrimitiveField(o, FD.I, "i2", 2);
1491
checkPrimitiveField(o, FD.J, "l", 1L);
1492
checkPrimitiveField(o, FD.J, "l2", 2L);
1493
checkPrimitiveField(o, FD.F, "f", 1.1f);
1494
checkPrimitiveField(o, FD.F, "f2", 2.1f);
1495
checkPrimitiveField(o, FD.D, "d", 1.1d);
1496
checkPrimitiveField(o, FD.D, "d2", 2.1d);
1497
ReferenceType clazz = bpe.thread().frame(1).location().declaringType();
1498
ObjectReference[] expVals = {
1499
(ObjectReference) clazz.getValue(clazz.fieldByName("NOT_CONST_1_OBJ")),
1500
(ObjectReference) clazz.getValue(clazz.fieldByName("CONST_2_OBJ")),
1501
};
1502
checkObjField(o, "o", expVals[0]);
1503
checkObjField(o, "o2", expVals[1]);
1504
}
1505
}
1506
1507
/////////////////////////////////////////////////////////////////////////////
1508
1509
// Two local variables reference the same object.
1510
// Check if the debugger obtains the same object when reading the two variables
1511
class EAMaterializeObjReferencedBy2LocalsTarget extends EATestCaseBaseTarget {
1512
1513
public void dontinline_testMethod() {
1514
XYVal xy = new XYVal(2, 3);
1515
XYVal alias = xy;
1516
dontinline_brkpt();
1517
iResult = xy.x + alias.x;
1518
}
1519
1520
@Override
1521
public int getExpectedIResult() {
1522
return 2 + 2;
1523
}
1524
}
1525
1526
class EAMaterializeObjReferencedBy2Locals extends EATestCaseBaseDebugger {
1527
1528
public void runTestCase() throws Exception {
1529
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1530
printStack(bpe.thread());
1531
ObjectReference xy = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
1532
ObjectReference alias = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "alias");
1533
Asserts.assertSame(xy, alias, "xy and alias are expected to reference the same object");
1534
}
1535
1536
}
1537
1538
/////////////////////////////////////////////////////////////////////////////
1539
1540
// Two local variables reference the same object.
1541
// Check if it has the expected effect in the target if the debugger modifies the object.
1542
class EAMaterializeObjReferencedBy2LocalsAndModifyTarget extends EATestCaseBaseTarget {
1543
1544
public void dontinline_testMethod() {
1545
XYVal xy = new XYVal(2, 3);
1546
XYVal alias = xy;
1547
dontinline_brkpt(); // debugger: alias.x = 42
1548
iResult = xy.x + alias.x;
1549
}
1550
1551
@Override
1552
public int getExpectedIResult() {
1553
return 42 + 42;
1554
}
1555
}
1556
1557
class EAMaterializeObjReferencedBy2LocalsAndModify extends EATestCaseBaseDebugger {
1558
1559
public void runTestCase() throws Exception {
1560
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1561
printStack(bpe.thread());
1562
ObjectReference alias = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "alias");
1563
setField(alias, "x", env.vm().mirrorOf(42));
1564
}
1565
}
1566
1567
/////////////////////////////////////////////////////////////////////////////
1568
1569
// Two local variables of the same compiled frame but in different virtual frames reference the same
1570
// object.
1571
// Check if the debugger obtains the same object when reading the two variables
1572
class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesTarget extends EATestCaseBaseTarget {
1573
1574
@Override
1575
public void setUp() {
1576
super.setUp();
1577
testMethodDepth = 2;
1578
}
1579
1580
public void dontinline_testMethod() {
1581
XYVal xy = new XYVal(2, 3);
1582
testMethod_inlined(xy);
1583
iResult += xy.x;
1584
}
1585
1586
public void testMethod_inlined(XYVal xy) {
1587
XYVal alias = xy;
1588
dontinline_brkpt();
1589
iResult = alias.x;
1590
}
1591
1592
@Override
1593
public int getExpectedIResult() {
1594
return 2 + 2;
1595
}
1596
}
1597
1598
class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFrames extends EATestCaseBaseDebugger {
1599
1600
public void runTestCase() throws Exception {
1601
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1602
printStack(bpe.thread());
1603
ObjectReference xy = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "xy");
1604
ObjectReference alias = getLocalRef(bpe.thread().frame(1), "testMethod_inlined", "alias", XYVAL_NAME);
1605
Asserts.assertSame(xy, alias, "xy and alias are expected to reference the same object");
1606
}
1607
1608
}
1609
1610
/////////////////////////////////////////////////////////////////////////////
1611
1612
// Two local variables of the same compiled frame but in different virtual frames reference the same
1613
// object.
1614
// Check if it has the expected effect in the target if the debugger modifies the object.
1615
class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModifyTarget extends EATestCaseBaseTarget {
1616
1617
@Override
1618
public void setUp() {
1619
super.setUp();
1620
testMethodDepth = 2;
1621
}
1622
1623
public void dontinline_testMethod() {
1624
XYVal xy = new XYVal(2, 3);
1625
testMethod_inlined(xy); // debugger: xy.x = 42
1626
iResult += xy.x;
1627
}
1628
1629
public void testMethod_inlined(XYVal xy) {
1630
XYVal alias = xy;
1631
dontinline_brkpt();
1632
iResult = alias.x;
1633
}
1634
1635
@Override
1636
public int getExpectedIResult() {
1637
return 42 + 42;
1638
}
1639
}
1640
1641
class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModify extends EATestCaseBaseDebugger {
1642
1643
public void runTestCase() throws Exception {
1644
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1645
printStack(bpe.thread());
1646
ObjectReference alias = getLocalRef(bpe.thread().frame(1), "testMethod_inlined", "alias", XYVAL_NAME);
1647
setField(alias, "x", env.vm().mirrorOf(42));
1648
}
1649
1650
}
1651
1652
/////////////////////////////////////////////////////////////////////////////
1653
1654
// Test materialization of an object referenced only from expression stack
1655
class EAMaterializeObjReferencedFromOperandStackTarget extends EATestCaseBaseTarget {
1656
1657
@Override
1658
public void setUp() {
1659
super.setUp();
1660
testMethodDepth = 2;
1661
}
1662
1663
public void dontinline_testMethod() {
1664
@SuppressWarnings("unused")
1665
XYVal xy1 = new XYVal(2, 3);
1666
// Debugger breaks in call to dontinline_brkpt_ret_100() and reads
1667
// the value of the local 'xy1'. This triggers materialization
1668
// of the object on the operand stack
1669
iResult = testMethodInlined(new XYVal(4, 2), dontinline_brkpt_ret_100());
1670
}
1671
1672
public int testMethodInlined(XYVal xy2, int dontinline_brkpt_ret_100) {
1673
return xy2.x + dontinline_brkpt_ret_100;
1674
}
1675
1676
public int dontinline_brkpt_ret_100() {
1677
dontinline_brkpt();
1678
return 100;
1679
}
1680
1681
@Override
1682
public int getExpectedIResult() {
1683
return 4 + 100;
1684
}
1685
}
1686
1687
class EAMaterializeObjReferencedFromOperandStack extends EATestCaseBaseDebugger {
1688
1689
public void runTestCase() throws Exception {
1690
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1691
printStack(bpe.thread());
1692
ObjectReference xy1 = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "xy1");
1693
checkPrimitiveField(xy1, FD.I, "x", 2);
1694
checkPrimitiveField(xy1, FD.I, "y", 3);
1695
}
1696
1697
}
1698
1699
/////////////////////////////////////////////////////////////////////////////
1700
1701
/**
1702
* Tests a regression in the implementation by setting the value of a local int which triggers the
1703
* creation of a deferred update and then getting the reference to a scalar replaced object. The
1704
* issue was that the scalar replaced object was not reallocated. Because of the deferred update it
1705
* was assumed that the reallocation already happened.
1706
*/
1707
class EAMaterializeLocalVariableUponGetAfterSetInteger extends EATestCaseBaseDebugger {
1708
1709
public void runTestCase() throws Exception {
1710
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1711
printStack(bpe.thread());
1712
setLocal(bpe.thread().frame(1), "i", env.vm().mirrorOf(43));
1713
ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
1714
checkPrimitiveField(o, FD.I, "x", 4);
1715
checkPrimitiveField(o, FD.I, "y", 2);
1716
}
1717
}
1718
1719
class EAMaterializeLocalVariableUponGetAfterSetIntegerTarget extends EATestCaseBaseTarget {
1720
1721
public void dontinline_testMethod() {
1722
XYVal xy = new XYVal(4, 2);
1723
int i = 42;
1724
dontinline_brkpt();
1725
iResult = xy.x + xy.y + i;
1726
}
1727
1728
@Override
1729
public int getExpectedIResult() {
1730
return 4 + 2 + 43;
1731
}
1732
1733
@Override
1734
public boolean testFrameShouldBeDeoptimized() {
1735
return true; // setting local variable i always triggers deoptimization
1736
}
1737
}
1738
1739
/////////////////////////////////////////////////////////////////////////////
1740
//
1741
// Locking Tests
1742
//
1743
/////////////////////////////////////////////////////////////////////////////
1744
1745
class EARelockingSimple extends EATestCaseBaseDebugger {
1746
1747
public void runTestCase() throws Exception {
1748
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1749
printStack(bpe.thread());
1750
@SuppressWarnings("unused")
1751
ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "l1");
1752
}
1753
}
1754
1755
class EARelockingSimpleTarget extends EATestCaseBaseTarget {
1756
1757
public void dontinline_testMethod() {
1758
XYVal l1 = new XYVal(4, 2);
1759
synchronized (l1) {
1760
dontinline_brkpt();
1761
}
1762
}
1763
}
1764
1765
/////////////////////////////////////////////////////////////////////////////
1766
1767
/**
1768
* Test if the bias of an object O that escapes globally is revoked correctly if local objects
1769
* escape through JVMTI. O is referenced by field l0.
1770
* This tests a regression of a previous version of the implementation.
1771
*/
1772
class EARelockingSimple_2 extends EATestCaseBaseDebugger {
1773
1774
public void runTestCase() throws Exception {
1775
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1776
printStack(bpe.thread());
1777
@SuppressWarnings("unused")
1778
ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "l1");
1779
}
1780
}
1781
1782
class EARelockingSimple_2Target extends EATestCaseBaseTarget {
1783
1784
public XYVal l0;
1785
1786
public void dontinline_testMethod() {
1787
l0 = new XYVal(4, 2); // GobalEscape
1788
XYVal l1 = new XYVal(4, 2);
1789
synchronized (l0) {
1790
synchronized (l1) {
1791
dontinline_brkpt();
1792
}
1793
}
1794
}
1795
}
1796
1797
/////////////////////////////////////////////////////////////////////////////
1798
1799
// Test recursive locking
1800
class EARelockingRecursiveTarget extends EATestCaseBaseTarget {
1801
1802
@Override
1803
public void setUp() {
1804
super.setUp();
1805
testMethodDepth = 2;
1806
}
1807
1808
public void dontinline_testMethod() {
1809
XYVal l1 = new XYVal(4, 2);
1810
synchronized (l1) {
1811
testMethod_inlined(l1);
1812
}
1813
}
1814
1815
public void testMethod_inlined(XYVal l2) {
1816
synchronized (l2) {
1817
dontinline_brkpt();
1818
}
1819
}
1820
}
1821
1822
class EARelockingRecursive extends EATestCaseBaseDebugger {
1823
1824
public void runTestCase() throws Exception {
1825
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1826
printStack(bpe.thread());
1827
@SuppressWarnings("unused")
1828
ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
1829
}
1830
}
1831
1832
/////////////////////////////////////////////////////////////////////////////
1833
1834
// Object ref l1 is retrieved by the debugger at a location where nested locks are omitted. The
1835
// accessed object is globally reachable already before the access, therefore no relocking is done.
1836
class EARelockingNestedInflatedTarget extends EATestCaseBaseTarget {
1837
1838
@Override
1839
public void setUp() {
1840
super.setUp();
1841
testMethodDepth = 2;
1842
}
1843
1844
@Override
1845
public boolean testFrameShouldBeDeoptimized() {
1846
// Access does not trigger deopt., as escape state is already global escape.
1847
return false;
1848
}
1849
1850
public void dontinline_testMethod() {
1851
XYVal l1 = inflatedLock;
1852
synchronized (l1) {
1853
testMethod_inlined(l1);
1854
}
1855
}
1856
1857
public void testMethod_inlined(XYVal l2) {
1858
synchronized (l2) { // eliminated nested locking
1859
dontinline_brkpt();
1860
}
1861
}
1862
}
1863
1864
class EARelockingNestedInflated extends EATestCaseBaseDebugger {
1865
1866
public void runTestCase() throws Exception {
1867
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1868
printStack(bpe.thread());
1869
@SuppressWarnings("unused")
1870
ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
1871
}
1872
}
1873
1874
/////////////////////////////////////////////////////////////////////////////
1875
1876
/**
1877
* Like {@link EARelockingNestedInflated} with the difference that there is
1878
* a scalar replaced object in the scope from which the object with eliminated nested locking
1879
* is read. This triggers materialization and relocking.
1880
*/
1881
class EARelockingNestedInflated_02 extends EATestCaseBaseDebugger {
1882
1883
public void runTestCase() throws Exception {
1884
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1885
printStack(bpe.thread());
1886
@SuppressWarnings("unused")
1887
ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
1888
}
1889
}
1890
1891
class EARelockingNestedInflated_02Target extends EATestCaseBaseTarget {
1892
1893
@Override
1894
public void setUp() {
1895
super.setUp();
1896
testMethodDepth = 2;
1897
}
1898
1899
public void dontinline_testMethod() {
1900
@SuppressWarnings("unused")
1901
XYVal xy = new XYVal(1, 1); // scalar replaced
1902
XYVal l1 = inflatedLock; // read by debugger
1903
synchronized (l1) {
1904
testMethod_inlined(l1);
1905
}
1906
}
1907
1908
public void testMethod_inlined(XYVal l2) {
1909
synchronized (l2) { // eliminated nested locking
1910
dontinline_brkpt();
1911
}
1912
}
1913
}
1914
1915
/////////////////////////////////////////////////////////////////////////////
1916
1917
/**
1918
* Checks if an eliminated lock of an ArgEscape object l1 can be relocked if
1919
* l1 is locked in a callee frame.
1920
*/
1921
class EARelockingArgEscapeLWLockedInCalleeFrame extends EATestCaseBaseDebugger {
1922
1923
public void runTestCase() throws Exception {
1924
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1925
printStack(bpe.thread());
1926
@SuppressWarnings("unused")
1927
ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
1928
}
1929
}
1930
1931
class EARelockingArgEscapeLWLockedInCalleeFrameTarget extends EATestCaseBaseTarget {
1932
1933
@Override
1934
public void setUp() {
1935
super.setUp();
1936
testMethodDepth = 2;
1937
}
1938
1939
public void dontinline_testMethod() {
1940
XYVal l1 = new XYVal(1, 1); // ArgEscape
1941
synchronized (l1) { // eliminated
1942
l1.dontinline_sync_method(this); // l1 escapes
1943
}
1944
}
1945
1946
@Override
1947
public boolean testFrameShouldBeDeoptimized() {
1948
// Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized
1949
return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();
1950
}
1951
}
1952
1953
/////////////////////////////////////////////////////////////////////////////
1954
1955
/**
1956
* Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame}. In addition
1957
* the test method has got a scalar replaced object with eliminated locking.
1958
* This pattern matches a regression in the implementation.
1959
*/
1960
class EARelockingArgEscapeLWLockedInCalleeFrame_2 extends EATestCaseBaseDebugger {
1961
1962
public void runTestCase() throws Exception {
1963
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1964
printStack(bpe.thread());
1965
@SuppressWarnings("unused")
1966
ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
1967
}
1968
}
1969
1970
class EARelockingArgEscapeLWLockedInCalleeFrame_2Target extends EATestCaseBaseTarget {
1971
1972
@Override
1973
public void setUp() {
1974
super.setUp();
1975
testMethodDepth = 2;
1976
}
1977
1978
public void dontinline_testMethod() {
1979
XYVal l1 = new XYVal(1, 1); // ArgEscape
1980
XYVal l2 = new XYVal(4, 2); // NoEscape, scalar replaced
1981
synchronized (l1) { // eliminated
1982
synchronized (l2) { // eliminated
1983
l1.dontinline_sync_method(this); // l1 escapes
1984
}
1985
}
1986
iResult = l2.x + l2.y;
1987
}
1988
1989
@Override
1990
public int getExpectedIResult() {
1991
return 6;
1992
}
1993
}
1994
1995
/////////////////////////////////////////////////////////////////////////////
1996
1997
/**
1998
* Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame}.
1999
* A bulk rebias operation is triggered at a position where all locks on the local object referenced
2000
* by l1 are eliminated. This leaves the object with an outdated biased locking epoch which has to be
2001
* considered when relocking.
2002
* This tests a regression in a previous version.
2003
*/
2004
class EARelockingArgEscapeLWLockedInCalleeFrame_3 extends EATestCaseBaseDebugger {
2005
2006
public static final String XYVAL_LOCAL_NAME = EARelockingArgEscapeLWLockedInCalleeFrame_3Target.XYValLocal.class.getName();
2007
2008
public void runTestCase() throws Exception {
2009
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2010
printStack(bpe.thread());
2011
@SuppressWarnings("unused")
2012
ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_LOCAL_NAME, "l1");
2013
}
2014
}
2015
2016
class EARelockingArgEscapeLWLockedInCalleeFrame_3Target extends EATestCaseBaseTarget {
2017
2018
// Using local type to avoid side effects on biased locking heuristics
2019
public static class XYValLocal extends XYVal {
2020
public XYValLocal(int x, int y) {
2021
super(x,y);
2022
}
2023
}
2024
2025
public void dontinline_testMethod() {
2026
XYVal l1 = new XYValLocal(1, 1); // ArgEscape
2027
synchronized (l1) { // eliminated
2028
l1.dontinline_sync_method_no_brkpt(this); // l1 escapes
2029
// trigger bulk rebias
2030
dontinline_bulkRebiasAfterWarmup(l1.getClass());
2031
// Now the epoch of l1 does not match the epoch of its class.
2032
// This has to be considered when relocking because of JVMTI access
2033
dontinline_brkpt();
2034
}
2035
}
2036
2037
@Override
2038
public boolean testFrameShouldBeDeoptimized() {
2039
// Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized
2040
return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();
2041
}
2042
}
2043
2044
/////////////////////////////////////////////////////////////////////////////
2045
2046
/**
2047
* Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame_3}.
2048
* But instead of a bulk rebias a bulk revoke operation is triggered.
2049
* This leaves the object with a stale bias as the prototype header of its calls lost its bias
2050
* pattern in the bulk revoke which has to be considered during relocking.
2051
* This tests a regression in a previous version.
2052
*/
2053
class EARelockingArgEscapeLWLockedInCalleeFrame_4 extends EATestCaseBaseDebugger {
2054
2055
public static final String XYVAL_LOCAL_NAME = EARelockingArgEscapeLWLockedInCalleeFrame_4Target.XYValLocal.class.getName();
2056
2057
public void runTestCase() throws Exception {
2058
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2059
printStack(bpe.thread());
2060
@SuppressWarnings("unused")
2061
ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_LOCAL_NAME, "l1");
2062
}
2063
}
2064
2065
class EARelockingArgEscapeLWLockedInCalleeFrame_4Target extends EATestCaseBaseTarget {
2066
2067
// Using local type to avoid side effects on biased locking heuristics
2068
public static class XYValLocal extends XYVal {
2069
public XYValLocal(int x, int y) {
2070
super(x,y);
2071
}
2072
}
2073
2074
public void dontinline_testMethod() {
2075
XYVal l1 = new XYValLocal(1, 1); // ArgEscape
2076
synchronized (l1) { // eliminated
2077
l1.dontinline_sync_method_no_brkpt(this); // l1 escapes
2078
// trigger bulk rebias
2079
dontinline_bulkRevokeAfterWarmup(l1.getClass());
2080
// Now the epoch of l1 does not match the epoch of its class.
2081
// This has to be considered when relocking because of JVMTI access
2082
dontinline_brkpt();
2083
}
2084
}
2085
2086
2087
@Override
2088
public boolean testFrameShouldBeDeoptimized() {
2089
// Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized
2090
return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();
2091
}
2092
}
2093
2094
/////////////////////////////////////////////////////////////////////////////
2095
2096
/**
2097
* Test relocking eliminated (nested) locks of an object on which the
2098
* target thread currently waits.
2099
*/
2100
class EARelockingObjectCurrentlyWaitingOn extends EATestCaseBaseDebugger {
2101
2102
public void runTestCase() throws Exception {
2103
env.vm().resume();
2104
boolean inWait = false;
2105
do {
2106
Thread.sleep(100);
2107
env.targetMainThread.suspend();
2108
printStack(env.targetMainThread);
2109
inWait = env.targetMainThread.frame(0).location().method().name().equals("wait");
2110
if (!inWait) {
2111
msg("Target not yet in java.lang.Object.wait(long).");
2112
env.targetMainThread.resume();
2113
}
2114
} while(!inWait);
2115
StackFrame testMethodFrame = env.targetMainThread.frame(4);
2116
// Access triggers relocking of all eliminated locks, including nested locks of l1 which references
2117
// the object on which the target main thread is currently waiting.
2118
ObjectReference l0 = getLocalRef(testMethodFrame, EARelockingObjectCurrentlyWaitingOnTarget.ForLocking.class.getName(), "l0");
2119
Asserts.assertEQ(l0.entryCount(), 1, "wrong entry count");
2120
ObjectReference l1 = getLocalRef(testMethodFrame, EARelockingObjectCurrentlyWaitingOnTarget.ForLocking.class.getName(), "l1");
2121
Asserts.assertEQ(l1.entryCount(), 0, "wrong entry count");
2122
setField(testCase, "objToNotifyOn", l1);
2123
}
2124
}
2125
2126
class EARelockingObjectCurrentlyWaitingOnTarget extends EATestCaseBaseTarget {
2127
2128
public static class ForLocking {
2129
}
2130
2131
public volatile Object objToNotifyOn; // debugger assigns value when notify thread should call objToNotifyOn.notifyAll()
2132
2133
@Override
2134
public void setUp() {
2135
super.setUp();
2136
testMethodDepth = 2;
2137
}
2138
2139
@Override
2140
public void warmupDone() {
2141
super.warmupDone();
2142
Thread t = new Thread(() -> doNotify());
2143
t.start();
2144
}
2145
2146
public void doNotify() {
2147
while (objToNotifyOn == null) {
2148
try {
2149
msg("objToNotifyOn is still null");
2150
Thread.sleep(100);
2151
} catch (InterruptedException e) { /* ignored */ }
2152
}
2153
synchronized (objToNotifyOn) {
2154
// will be received by the target main thread waiting in dontinline_waitWhenWarmupDone
2155
msg("calling objToNotifyOn.notifyAll()");
2156
objToNotifyOn.notifyAll();
2157
}
2158
}
2159
2160
@Override
2161
public boolean testFrameShouldBeDeoptimized() {
2162
return false;
2163
}
2164
2165
@Override
2166
public void dontinline_testMethod() throws Exception {
2167
ForLocking l0 = new ForLocking(); // will be scalar replaced; access triggers realloc/relock
2168
ForLocking l1 = new ForLocking();
2169
synchronized (l0) {
2170
synchronized (l1) {
2171
testMethod_inlined(l1);
2172
}
2173
}
2174
}
2175
2176
public void testMethod_inlined(ForLocking l2) throws Exception {
2177
synchronized (l2) { // eliminated nested locking
2178
dontinline_waitWhenWarmupDone(l2);
2179
}
2180
}
2181
2182
public void dontinline_waitWhenWarmupDone(ForLocking l2) throws Exception {
2183
if (warmupDone) {
2184
l2.wait();
2185
}
2186
}
2187
}
2188
2189
/////////////////////////////////////////////////////////////////////////////
2190
//
2191
// Test cases that require deoptimization even though neither locks
2192
// nor allocations are eliminated at the point where escape state is changed.
2193
//
2194
/////////////////////////////////////////////////////////////////////////////
2195
2196
/**
2197
* Let xy be NoEscape whose allocation cannot be eliminated (simulated by
2198
* -XX:-EliminateAllocations). The holding compiled frame has to be deoptimized when debugger
2199
* accesses xy because afterwards locking on xy is omitted.
2200
* Note: there are no EA based optimizations at the escape point.
2201
*/
2202
class EADeoptFrameAfterReadLocalObject_01 extends EATestCaseBaseDebugger {
2203
2204
public void runTestCase() throws Exception {
2205
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2206
printStack(bpe.thread());
2207
@SuppressWarnings("unused")
2208
ObjectReference xy = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
2209
}
2210
}
2211
2212
class EADeoptFrameAfterReadLocalObject_01Target extends EATestCaseBaseTarget {
2213
2214
public void dontinline_testMethod() {
2215
XYVal xy = new XYVal(1, 1);
2216
dontinline_brkpt(); // Debugger reads xy, when there are no virtual objects or eliminated locks in scope
2217
synchronized (xy) { // Locking is eliminated.
2218
xy.x++;
2219
xy.y++;
2220
}
2221
}
2222
}
2223
2224
/////////////////////////////////////////////////////////////////////////////
2225
2226
/**
2227
* Similar to {@link EADeoptFrameAfterReadLocalObject_01} with the difference that the debugger
2228
* reads xy from an inlined callee. So xy is NoEscape instead of ArgEscape.
2229
*/
2230
class EADeoptFrameAfterReadLocalObject_01BTarget extends EATestCaseBaseTarget {
2231
2232
@Override
2233
public void setUp() {
2234
super.setUp();
2235
testMethodDepth = 2;
2236
}
2237
2238
public void dontinline_testMethod() {
2239
XYVal xy = new XYVal(1, 1);
2240
callee(xy); // Debugger acquires ref to xy from inlined callee
2241
// xy is NoEscape, nevertheless the object is not replaced
2242
// by scalars if running with -XX:-EliminateAllocations.
2243
// In that case there are no EA based optimizations were
2244
// the debugger reads the NoEscape object.
2245
synchronized (xy) { // Locking is eliminated.
2246
xy.x++;
2247
xy.y++;
2248
}
2249
}
2250
2251
public void callee(XYVal xy) {
2252
dontinline_brkpt(); // Debugger reads xy.
2253
// There are no virtual objects or eliminated locks.
2254
}
2255
}
2256
2257
class EADeoptFrameAfterReadLocalObject_01B extends EATestCaseBaseDebugger {
2258
2259
public void runTestCase() throws Exception {
2260
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2261
printStack(bpe.thread());
2262
@SuppressWarnings("unused")
2263
ObjectReference xy = getLocalRef(bpe.thread().frame(1), "callee", "xy", XYVAL_NAME);
2264
}
2265
}
2266
2267
/////////////////////////////////////////////////////////////////////////////
2268
2269
/**
2270
* Let xy be ArgEscape. The frame dontinline_testMethod() has to be deoptimized when debugger
2271
* acquires xy from dontinline_callee() because afterwards locking on xy is omitted.
2272
* Note: there are no EA based optimizations at the escape point.
2273
*/
2274
class EADeoptFrameAfterReadLocalObject_02 extends EATestCaseBaseDebugger {
2275
2276
public void runTestCase() throws Exception {
2277
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2278
printStack(bpe.thread());
2279
@SuppressWarnings("unused")
2280
ObjectReference xy = getLocalRef(bpe.thread().frame(1), "dontinline_callee", "xy", XYVAL_NAME);
2281
}
2282
}
2283
2284
class EADeoptFrameAfterReadLocalObject_02Target extends EATestCaseBaseTarget {
2285
2286
public void dontinline_testMethod() {
2287
XYVal xy = new XYVal(1, 1);
2288
dontinline_callee(xy); // xy is ArgEscape, debugger acquires ref to xy from callee
2289
synchronized (xy) { // Locking is eliminated.
2290
xy.x++;
2291
xy.y++;
2292
}
2293
}
2294
2295
public void dontinline_callee(XYVal xy) {
2296
dontinline_brkpt(); // Debugger reads xy.
2297
// There are no virtual objects or eliminated locks.
2298
}
2299
2300
@Override
2301
public void setUp() {
2302
super.setUp();
2303
testMethodDepth = 2;
2304
}
2305
2306
@Override
2307
public boolean testFrameShouldBeDeoptimized() {
2308
// Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized
2309
return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();
2310
}
2311
}
2312
2313
/////////////////////////////////////////////////////////////////////////////
2314
2315
/**
2316
* Similar to {@link EADeoptFrameAfterReadLocalObject_02} there is an ArgEscape object xy, but in
2317
* contrast it is not in the parameter list of a call when the debugger reads an object.
2318
* Therefore the frame of the test method should not be deoptimized
2319
*/
2320
class EADeoptFrameAfterReadLocalObject_02B extends EATestCaseBaseDebugger {
2321
2322
public void runTestCase() throws Exception {
2323
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2324
printStack(bpe.thread());
2325
@SuppressWarnings("unused")
2326
ObjectReference xy = getLocalRef(bpe.thread().frame(1), "dontinline_callee", "xy", XYVAL_NAME);
2327
}
2328
}
2329
2330
class EADeoptFrameAfterReadLocalObject_02BTarget extends EATestCaseBaseTarget {
2331
2332
public void dontinline_testMethod() {
2333
XYVal xy = new XYVal(1, 1);
2334
dontinline_make_arg_escape(xy); // because of this call xy is ArgEscape
2335
dontinline_callee(); // xy is ArgEscape, but not a parameter of this call
2336
synchronized (xy) { // Locking is eliminated.
2337
xy.x++;
2338
xy.y++;
2339
}
2340
}
2341
2342
public void dontinline_callee() {
2343
@SuppressWarnings("unused")
2344
XYVal xy = new XYVal(2, 2);
2345
dontinline_brkpt(); // Debugger reads xy.
2346
// No need to deoptimize the caller frame
2347
}
2348
2349
@Override
2350
public void setUp() {
2351
super.setUp();
2352
testMethodDepth = 2;
2353
}
2354
2355
@Override
2356
public boolean testFrameShouldBeDeoptimized() {
2357
return false;
2358
}
2359
}
2360
2361
/////////////////////////////////////////////////////////////////////////////
2362
2363
/**
2364
* Similar to {@link EADeoptFrameAfterReadLocalObject_02} there is an ArgEscape object xy in
2365
* dontinline_testMethod() which is being passed as parameter when the debugger accesses a local object.
2366
* Nevertheless dontinline_testMethod must not be deoptimized because there is an entry frame
2367
* between it and the frame accessed by the debugger.
2368
*/
2369
class EADeoptFrameAfterReadLocalObject_02C extends EATestCaseBaseDebugger {
2370
2371
public void runTestCase() throws Exception {
2372
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2373
printStack(bpe.thread());
2374
@SuppressWarnings("unused")
2375
ObjectReference xy = getLocalRef(bpe.thread().frame(1), "dontinline_callee_accessed_by_debugger", "xy", XYVAL_NAME);
2376
}
2377
}
2378
2379
class EADeoptFrameAfterReadLocalObject_02CTarget extends EATestCaseBaseTarget {
2380
2381
public void dontinline_testMethod() {
2382
XYVal xy = new XYVal(1, 1);
2383
dontinline_callee(xy); // xy is ArgEscape and being passed as parameter
2384
synchronized (xy) { // Locking is eliminated.
2385
xy.x++;
2386
xy.y++;
2387
}
2388
}
2389
2390
public void dontinline_callee(XYVal xy) {
2391
if (warmupDone) {
2392
dontinline_call_with_entry_frame(this, "dontinline_callee_accessed_by_debugger");
2393
}
2394
}
2395
2396
public void dontinline_callee_accessed_by_debugger() {
2397
@SuppressWarnings("unused")
2398
XYVal xy = new XYVal(2, 2);
2399
dontinline_brkpt(); // Debugger reads xy.
2400
// No need to deoptimize the caller frame
2401
}
2402
2403
@Override
2404
public void setUp() {
2405
super.setUp();
2406
testMethodDepth = 8;
2407
}
2408
2409
@Override
2410
public boolean testFrameShouldBeDeoptimized() {
2411
return false;
2412
}
2413
}
2414
2415
/////////////////////////////////////////////////////////////////////////////
2416
2417
/**
2418
* Let xy be NoEscape whose allocation cannot be eliminated (e.g. because of
2419
* -XX:-EliminateAllocations). The holding compiled frame has to be deoptimized when debugger
2420
* accesses xy because the following field accesses get eliminated. Note: there are no EA based
2421
* optimizations at the escape point.
2422
*/
2423
class EADeoptFrameAfterReadLocalObject_03 extends EATestCaseBaseDebugger {
2424
2425
public void runTestCase() throws Exception {
2426
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2427
printStack(bpe.thread());
2428
ObjectReference xy = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
2429
setField(xy, "x", env.vm().mirrorOf(1));
2430
}
2431
}
2432
2433
class EADeoptFrameAfterReadLocalObject_03Target extends EATestCaseBaseTarget {
2434
2435
public void dontinline_testMethod() {
2436
XYVal xy = new XYVal(0, 1);
2437
dontinline_brkpt(); // Debugger reads xy, when there are no virtual objects or
2438
// eliminated locks in scope and modifies xy.x
2439
iResult = xy.x + xy.y; // Loads are replaced by constants 0 and 1.
2440
}
2441
2442
@Override
2443
public int getExpectedIResult() {
2444
return 1 + 1;
2445
}
2446
}
2447
2448
/////////////////////////////////////////////////////////////////////////////
2449
//
2450
// Monitor info tests
2451
//
2452
/////////////////////////////////////////////////////////////////////////////
2453
2454
class EAGetOwnedMonitorsTarget extends EATestCaseBaseTarget {
2455
2456
public long checkSum;
2457
2458
public void dontinline_testMethod() {
2459
XYVal l1 = new XYVal(4, 2);
2460
synchronized (l1) {
2461
dontinline_endlessLoop();
2462
}
2463
}
2464
2465
@Override
2466
public void setUp() {
2467
super.setUp();
2468
testMethodDepth = 2;
2469
loopCount = 3;
2470
}
2471
2472
public void warmupDone() {
2473
super.warmupDone();
2474
msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
2475
loopCount = Long.MAX_VALUE; // endless loop
2476
}
2477
}
2478
2479
class EAGetOwnedMonitors extends EATestCaseBaseDebugger {
2480
2481
public void runTestCase() throws Exception {
2482
msg("resume");
2483
env.vm().resume();
2484
waitUntilTargetHasEnteredEndlessLoop();
2485
// In contrast to JVMTI, JDWP requires a target thread to be suspended, before the owned monitors can be queried
2486
msg("suspend target");
2487
env.targetMainThread.suspend();
2488
msg("Get owned monitors");
2489
List<ObjectReference> monitors = env.targetMainThread.ownedMonitors();
2490
Asserts.assertEQ(monitors.size(), 1, "unexpected number of owned monitors");
2491
terminateEndlessLoop();
2492
}
2493
}
2494
2495
/////////////////////////////////////////////////////////////////////////////
2496
2497
class EAEntryCountTarget extends EATestCaseBaseTarget {
2498
2499
public long checkSum;
2500
2501
public void dontinline_testMethod() {
2502
XYVal l1 = new XYVal(4, 2);
2503
synchronized (l1) {
2504
inline_testMethod2(l1);
2505
}
2506
}
2507
2508
public void inline_testMethod2(XYVal l1) {
2509
synchronized (l1) {
2510
dontinline_endlessLoop();
2511
}
2512
}
2513
2514
@Override
2515
public void setUp() {
2516
super.setUp();
2517
testMethodDepth = 2;
2518
loopCount = 3;
2519
}
2520
2521
public void warmupDone() {
2522
super.warmupDone();
2523
msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
2524
loopCount = Long.MAX_VALUE; // endless loop
2525
}
2526
}
2527
2528
class EAEntryCount extends EATestCaseBaseDebugger {
2529
2530
public void runTestCase() throws Exception {
2531
msg("resume");
2532
env.vm().resume();
2533
waitUntilTargetHasEnteredEndlessLoop();
2534
// In contrast to JVMTI, JDWP requires a target thread to be suspended, before the owned monitors can be queried
2535
msg("suspend target");
2536
env.targetMainThread.suspend();
2537
msg("Get owned monitors");
2538
List<ObjectReference> monitors = env.targetMainThread.ownedMonitors();
2539
Asserts.assertEQ(monitors.size(), 1, "unexpected number of owned monitors");
2540
msg("Get entry count");
2541
int entryCount = monitors.get(0).entryCount();
2542
Asserts.assertEQ(entryCount, 2, "wrong entry count");
2543
terminateEndlessLoop();
2544
}
2545
}
2546
2547
/////////////////////////////////////////////////////////////////////////////
2548
//
2549
// PopFrame tests
2550
//
2551
/////////////////////////////////////////////////////////////////////////////
2552
2553
/**
2554
* PopFrame into caller frame with scalar replaced objects.
2555
*/
2556
class EAPopFrameNotInlined extends EATestCaseBaseDebugger {
2557
2558
public void runTestCase() throws Exception {
2559
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2560
printStack(bpe.thread());
2561
msg("PopFrame");
2562
bpe.thread().popFrames(bpe.thread().frame(0));
2563
msg("PopFrame DONE");
2564
}
2565
2566
@Override
2567
public boolean shouldSkip() {
2568
// And Graal currently doesn't support PopFrame
2569
return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;
2570
}
2571
}
2572
2573
class EAPopFrameNotInlinedTarget extends EATestCaseBaseTarget {
2574
2575
public void dontinline_testMethod() {
2576
XYVal xy = new XYVal(4, 2);
2577
dontinline_brkpt();
2578
iResult = xy.x + xy.y;
2579
}
2580
2581
@Override
2582
public boolean testFrameShouldBeDeoptimized() {
2583
// Test is only performed after the frame pop.
2584
// Then dontinline_testMethod is interpreted.
2585
return false;
2586
}
2587
2588
@Override
2589
public int getExpectedIResult() {
2590
return 4 + 2;
2591
}
2592
2593
@Override
2594
public boolean shouldSkip() {
2595
// And Graal currently doesn't support PopFrame
2596
return super.shouldSkip() || UseJVMCICompiler;
2597
}
2598
}
2599
2600
/////////////////////////////////////////////////////////////////////////////
2601
2602
/**
2603
* Pop frames into {@link EAPopFrameNotInlinedReallocFailureTarget#dontinline_testMethod()} which
2604
* holds scalar replaced objects. In preparation of the pop frame operations the vm eagerly
2605
* reallocates scalar replaced objects to avoid failures when actually popping the frames. We provoke
2606
* a reallocation failures and expect {@link VMOutOfMemoryException}.
2607
*/
2608
class EAPopFrameNotInlinedReallocFailure extends EATestCaseBaseDebugger {
2609
2610
public void runTestCase() throws Exception {
2611
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2612
ThreadReference thread = bpe.thread();
2613
printStack(thread);
2614
// frame[0]: EATestCaseBaseTarget.dontinline_brkpt()
2615
// frame[1]: EAPopFrameNotInlinedReallocFailureTarget.dontinline_consume_all_memory_brkpt()
2616
// frame[2]: EAPopFrameNotInlinedReallocFailureTarget.dontinline_testMethod()
2617
// frame[3]: EATestCaseBaseTarget.run()
2618
// frame[4]: EATestsTarget.main(java.lang.String[])
2619
msg("PopFrame");
2620
boolean coughtOom = false;
2621
try {
2622
// try to pop dontinline_consume_all_memory_brkpt
2623
thread.popFrames(thread.frame(1));
2624
} catch (VMOutOfMemoryException oom) {
2625
// as expected
2626
msg("cought OOM");
2627
coughtOom = true;
2628
}
2629
freeAllMemory();
2630
// We succeeded to pop just one frame. When we continue, we will call dontinline_brkpt() again.
2631
Asserts.assertTrue(coughtOom, "PopFrame should have triggered an OOM exception in target");
2632
String expectedTopFrame = "dontinline_consume_all_memory_brkpt";
2633
Asserts.assertEQ(expectedTopFrame, thread.frame(0).location().method().name());
2634
printStack(thread);
2635
}
2636
2637
@Override
2638
public boolean shouldSkip() {
2639
// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
2640
// And Graal currently doesn't provide all information about non-escaping objects in debug info
2641
return super.shouldSkip() ||
2642
!env.targetVMOptions.EliminateAllocations ||
2643
// With ZGC the OOME is not always thrown as expected
2644
env.targetVMOptions.ZGCIsSelected ||
2645
env.targetVMOptions.DeoptimizeObjectsALot ||
2646
env.targetVMOptions.UseJVMCICompiler;
2647
}
2648
}
2649
2650
class EAPopFrameNotInlinedReallocFailureTarget extends EATestCaseBaseTarget {
2651
2652
public boolean doneAlready;
2653
2654
public void dontinline_testMethod() {
2655
long a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // scalar replaced
2656
Vector10 v = new Vector10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // scalar replaced
2657
dontinline_consume_all_memory_brkpt();
2658
lResult = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]
2659
+ v.i0 + v.i1 + v.i2 + v.i3 + v.i4 + v.i5 + v.i6 + v.i7 + v.i8 + v.i9;
2660
}
2661
2662
public void dontinline_consume_all_memory_brkpt() {
2663
if (warmupDone && !doneAlready) {
2664
doneAlready = true;
2665
consumeAllMemory(); // provoke reallocation failure
2666
dontinline_brkpt();
2667
}
2668
}
2669
2670
@Override
2671
public void setUp() {
2672
super.setUp();
2673
testMethodDepth = 2;
2674
}
2675
2676
@Override
2677
public long getExpectedLResult() {
2678
long n = 10;
2679
return 2*n*(n+1)/2;
2680
}
2681
2682
@Override
2683
public boolean shouldSkip() {
2684
// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
2685
// And Graal currently doesn't provide all information about non-escaping objects in debug info
2686
return super.shouldSkip() ||
2687
!EliminateAllocations ||
2688
// With ZGC the OOME is not always thrown as expected
2689
ZGCIsSelected ||
2690
DeoptimizeObjectsALot ||
2691
UseJVMCICompiler;
2692
}
2693
}
2694
2695
/////////////////////////////////////////////////////////////////////////////
2696
2697
/**
2698
* Pop inlined top frame dropping into method with scalar replaced opjects.
2699
*/
2700
class EAPopInlinedMethodWithScalarReplacedObjectsReallocFailure extends EATestCaseBaseDebugger {
2701
2702
public void runTestCase() throws Exception {
2703
ThreadReference thread = env.targetMainThread;
2704
env.vm().resume();
2705
waitUntilTargetHasEnteredEndlessLoop();
2706
2707
thread.suspend();
2708
printStack(thread);
2709
// frame[0]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.inlinedCallForcedToReturn()
2710
// frame[1]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.dontinline_testMethod()
2711
// frame[2]: EATestCaseBaseTarget.run()
2712
2713
msg("Pop Frames");
2714
boolean coughtOom = false;
2715
try {
2716
thread.popFrames(thread.frame(0)); // Request pop frame of inlinedCallForcedToReturn()
2717
// reallocation is triggered here
2718
} catch (VMOutOfMemoryException oom) {
2719
// as expected
2720
msg("cought OOM");
2721
coughtOom = true;
2722
}
2723
printStack(thread);
2724
// frame[0]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.inlinedCallForcedToReturn()
2725
// frame[1]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.dontinline_testMethod()
2726
// frame[2]: EATestCaseBaseTarget.run()
2727
2728
freeAllMemory();
2729
setField(testCase, "loopCount", env.vm().mirrorOf(0)); // terminate loop
2730
Asserts.assertTrue(coughtOom, "PopFrame should have triggered an OOM exception in target");
2731
String expectedTopFrame = "inlinedCallForcedToReturn";
2732
Asserts.assertEQ(expectedTopFrame, thread.frame(0).location().method().name());
2733
}
2734
2735
@Override
2736
public boolean shouldSkip() {
2737
// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
2738
// And Graal currently doesn't provide all information about non-escaping objects in debug info
2739
return super.shouldSkip() ||
2740
!env.targetVMOptions.EliminateAllocations ||
2741
// With ZGC the OOME is not always thrown as expected
2742
env.targetVMOptions.ZGCIsSelected ||
2743
env.targetVMOptions.DeoptimizeObjectsALot ||
2744
env.targetVMOptions.UseJVMCICompiler;
2745
}
2746
}
2747
2748
class EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget extends EATestCaseBaseTarget {
2749
2750
public long checkSum;
2751
2752
public void dontinline_testMethod() {
2753
long a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // scalar replaced
2754
Vector10 v = new Vector10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // scalar replaced
2755
long l = inlinedCallForcedToReturn();
2756
lResult = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]
2757
+ v.i0 + v.i1 + v.i2 + v.i3 + v.i4 + v.i5 + v.i6 + v.i7 + v.i8 + v.i9;
2758
}
2759
2760
public long inlinedCallForcedToReturn() {
2761
long cs = checkSum;
2762
dontinline_consumeAllMemory();
2763
while (loopCount-- > 0) {
2764
targetIsInLoop = true;
2765
checkSum += checkSum % ++cs;
2766
}
2767
loopCount = 3;
2768
targetIsInLoop = false;
2769
return checkSum;
2770
}
2771
2772
public void dontinline_consumeAllMemory() {
2773
if (warmupDone && (loopCount > 3)) {
2774
consumeAllMemory();
2775
}
2776
}
2777
2778
@Override
2779
public long getExpectedLResult() {
2780
long n = 10;
2781
return 2*n*(n+1)/2;
2782
}
2783
2784
@Override
2785
public void setUp() {
2786
super.setUp();
2787
loopCount = 3;
2788
}
2789
2790
public void warmupDone() {
2791
super.warmupDone();
2792
msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
2793
loopCount = Long.MAX_VALUE; // endless loop
2794
}
2795
2796
@Override
2797
public boolean shouldSkip() {
2798
// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
2799
// And Graal currently doesn't provide all information about non-escaping objects in debug info
2800
return super.shouldSkip() ||
2801
!EliminateAllocations ||
2802
// With ZGC the OOME is not always thrown as expected
2803
ZGCIsSelected ||
2804
DeoptimizeObjectsALot ||
2805
UseJVMCICompiler;
2806
}
2807
}
2808
2809
/////////////////////////////////////////////////////////////////////////////
2810
//
2811
// ForceEarlyReturn tests
2812
//
2813
/////////////////////////////////////////////////////////////////////////////
2814
2815
/**
2816
* ForceEarlyReturn into caller frame with scalar replaced objects.
2817
*/
2818
class EAForceEarlyReturnNotInlined extends EATestCaseBaseDebugger {
2819
2820
public void runTestCase() throws Exception {
2821
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2822
ThreadReference thread = bpe.thread();
2823
printStack(thread);
2824
// frame[0]: EATestCaseBaseTarget.dontinline_brkpt()
2825
// frame[1]: EATestCaseBaseTarget.dontinline_brkpt_iret()
2826
// frame[2]: EAForceEarlyReturnNotInlinedTarget.dontinline_testMethod()
2827
// frame[3]: EATestCaseBaseTarget.run()
2828
// frame[4]: EATestsTarget.main(java.lang.String[])
2829
2830
msg("Step out");
2831
env.stepOut(thread); // return from dontinline_brkpt
2832
printStack(thread);
2833
msg("ForceEarlyReturn");
2834
thread.forceEarlyReturn(env.vm().mirrorOf(43)); // return from dontinline_brkpt_iret,
2835
// does not trigger reallocation in contrast to PopFrame
2836
msg("Step over line");
2837
env.stepOverLine(thread); // reallocation is triggered here
2838
printStack(thread);
2839
msg("ForceEarlyReturn DONE");
2840
}
2841
2842
@Override
2843
public boolean shouldSkip() {
2844
// Graal currently doesn't support Force Early Return
2845
return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;
2846
}
2847
}
2848
2849
class EAForceEarlyReturnNotInlinedTarget extends EATestCaseBaseTarget {
2850
2851
public void dontinline_testMethod() {
2852
XYVal xy = new XYVal(4, 2);
2853
int i = dontinline_brkpt_iret();
2854
iResult = xy.x + xy.y + i;
2855
}
2856
2857
@Override
2858
public int getExpectedIResult() {
2859
return 4 + 2 + 43;
2860
}
2861
2862
@Override
2863
public void setUp() {
2864
super.setUp();
2865
testMethodDepth = 2;
2866
}
2867
2868
public boolean testFrameShouldBeDeoptimized() {
2869
return true; // because of stepping
2870
}
2871
2872
@Override
2873
public boolean shouldSkip() {
2874
// Graal currently doesn't support Force Early Return
2875
return super.shouldSkip() || UseJVMCICompiler;
2876
}
2877
}
2878
2879
/////////////////////////////////////////////////////////////////////////////
2880
2881
/**
2882
* ForceEarlyReturn at safepoint in frame with scalar replaced objects.
2883
*/
2884
class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjects extends EATestCaseBaseDebugger {
2885
2886
public void runTestCase() throws Exception {
2887
ThreadReference thread = env.targetMainThread;
2888
env.vm().resume();
2889
waitUntilTargetHasEnteredEndlessLoop();
2890
2891
thread.suspend();
2892
printStack(thread);
2893
// frame[0]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget.inlinedCallForcedToReturn()
2894
// frame[1]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget.dontinline_testMethod()
2895
// frame[2]: EATestCaseBaseTarget.run()
2896
2897
msg("ForceEarlyReturn");
2898
thread.forceEarlyReturn(env.vm().mirrorOf(43)); // Request force return 43 from inlinedCallForcedToReturn()
2899
// reallocation is triggered here
2900
msg("Step over instruction to do the forced return");
2901
env.stepOverInstruction(thread);
2902
printStack(thread);
2903
msg("ForceEarlyReturn DONE");
2904
}
2905
2906
@Override
2907
public boolean shouldSkip() {
2908
// Graal currently doesn't support Force Early Return
2909
return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;
2910
}
2911
}
2912
2913
class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget extends EATestCaseBaseTarget {
2914
2915
public int checkSum;
2916
2917
public void dontinline_testMethod() {
2918
XYVal xy = new XYVal(4, 2);
2919
int i = inlinedCallForcedToReturn();
2920
iResult = xy.x + xy.y + i;
2921
}
2922
2923
public int inlinedCallForcedToReturn() { // forced to return 43
2924
int i = checkSum;
2925
while (loopCount-- > 0) {
2926
targetIsInLoop = true;
2927
checkSum += checkSum % ++i;
2928
}
2929
loopCount = 3;
2930
targetIsInLoop = false;
2931
return checkSum;
2932
}
2933
2934
@Override
2935
public int getExpectedIResult() {
2936
return 4 + 2 + 43;
2937
}
2938
2939
@Override
2940
public void setUp() {
2941
super.setUp();
2942
testMethodDepth = 2;
2943
loopCount = 3;
2944
}
2945
2946
public void warmupDone() {
2947
super.warmupDone();
2948
msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
2949
loopCount = Long.MAX_VALUE; // endless loop
2950
}
2951
2952
public boolean testFrameShouldBeDeoptimized() {
2953
return true; // because of stepping
2954
}
2955
2956
@Override
2957
public boolean shouldSkip() {
2958
// Graal currently doesn't support Force Early Return
2959
return super.shouldSkip() || UseJVMCICompiler;
2960
}
2961
}
2962
2963
/////////////////////////////////////////////////////////////////////////////
2964
2965
/**
2966
* ForceEarlyReturn with reallocation failure.
2967
*/
2968
class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailure extends EATestCaseBaseDebugger {
2969
2970
public void runTestCase() throws Exception {
2971
ThreadReference thread = env.targetMainThread;
2972
env.vm().resume();
2973
waitUntilTargetHasEnteredEndlessLoop();
2974
2975
thread.suspend();
2976
printStack(thread);
2977
// frame[0]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.inlinedCallForcedToReturn()
2978
// frame[1]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.dontinline_testMethod()
2979
// frame[2]: EATestCaseBaseTarget.run()
2980
2981
msg("ForceEarlyReturn");
2982
boolean coughtOom = false;
2983
try {
2984
thread.forceEarlyReturn(env.vm().mirrorOf(43)); // Request force return 43 from inlinedCallForcedToReturn()
2985
// reallocation is triggered here
2986
} catch (VMOutOfMemoryException oom) {
2987
// as expected
2988
msg("cought OOM");
2989
coughtOom = true;
2990
}
2991
freeAllMemory();
2992
Asserts.assertTrue(coughtOom, "ForceEarlyReturn should have triggered an OOM exception in target");
2993
printStack(thread);
2994
msg("ForceEarlyReturn(2)");
2995
thread.forceEarlyReturn(env.vm().mirrorOf(43));
2996
msg("Step over instruction to do the forced return");
2997
env.stepOverInstruction(thread);
2998
printStack(thread);
2999
msg("ForceEarlyReturn DONE");
3000
}
3001
3002
@Override
3003
public boolean shouldSkip() {
3004
// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
3005
// And Graal currently doesn't support Force Early Return
3006
return super.shouldSkip() ||
3007
!env.targetVMOptions.EliminateAllocations ||
3008
// With ZGC the OOME is not always thrown as expected
3009
env.targetVMOptions.ZGCIsSelected ||
3010
env.targetVMOptions.DeoptimizeObjectsALot ||
3011
env.targetVMOptions.UseJVMCICompiler;
3012
}
3013
}
3014
3015
class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget extends EATestCaseBaseTarget {
3016
3017
public int checkSum;
3018
3019
public void dontinline_testMethod() {
3020
long a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // scalar replaced
3021
Vector10 v = new Vector10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // scalar replaced
3022
long l = inlinedCallForcedToReturn();
3023
lResult = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]
3024
+ v.i0 + v.i1 + v.i2 + v.i3 + v.i4 + v.i5 + v.i6 + v.i7 + v.i8 + v.i9 + l;
3025
}
3026
3027
public long inlinedCallForcedToReturn() { // forced to return 43
3028
long cs = checkSum;
3029
dontinline_consumeAllMemory();
3030
while (loopCount-- > 0) {
3031
targetIsInLoop = true;
3032
checkSum += checkSum % ++cs;
3033
}
3034
loopCount = 3;
3035
targetIsInLoop = false;
3036
return checkSum;
3037
}
3038
3039
public void dontinline_consumeAllMemory() {
3040
if (warmupDone) {
3041
consumeAllMemory();
3042
}
3043
}
3044
3045
@Override
3046
public long getExpectedLResult() {
3047
long n = 10;
3048
return 2*n*(n+1)/2 + 43;
3049
}
3050
3051
@Override
3052
public void setUp() {
3053
super.setUp();
3054
testMethodDepth = 2;
3055
loopCount = 3;
3056
}
3057
3058
public void warmupDone() {
3059
super.warmupDone();
3060
msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
3061
loopCount = Long.MAX_VALUE; // endless loop
3062
}
3063
3064
@Override
3065
public boolean shouldSkip() {
3066
// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
3067
// And Graal currently doesn't support Force Early Return
3068
return super.shouldSkip() ||
3069
!EliminateAllocations ||
3070
// With ZGC the OOME is not always thrown as expected
3071
ZGCIsSelected ||
3072
DeoptimizeObjectsALot ||
3073
UseJVMCICompiler;
3074
}
3075
}
3076
3077
/////////////////////////////////////////////////////////////////////////////
3078
//
3079
// Get Instances of ReferenceType
3080
//
3081
/////////////////////////////////////////////////////////////////////////////
3082
3083
/**
3084
* Check if instances of a type are found even if they are scalar replaced. To stress the
3085
* implementation a little more, the instances should be retrieved while the target is running.
3086
*/
3087
class EAGetInstancesOfReferenceType extends EATestCaseBaseDebugger {
3088
3089
public void runTestCase() throws Exception {
3090
printStack(env.targetMainThread);
3091
ReferenceType cls = ((ClassObjectReference)getField(testCase, "cls")).reflectedType();
3092
msg("reflected type is " + cls);
3093
msg("resume");
3094
env.vm().resume();
3095
waitUntilTargetHasEnteredEndlessLoop();
3096
// do this while thread is running!
3097
msg("Retrieve instances of " + cls.name());
3098
List<ObjectReference> instances = cls.instances(10);
3099
Asserts.assertEQ(instances.size(), 3, "unexpected number of instances of " + cls.name());
3100
// invariant: main thread is suspended at the end of the test case
3101
msg("suspend");
3102
env.targetMainThread.suspend();
3103
terminateEndlessLoop();
3104
}
3105
}
3106
3107
class EAGetInstancesOfReferenceTypeTarget extends EATestCaseBaseTarget {
3108
3109
public long checkSum;
3110
3111
public static Class<LocalXYVal> cls = LocalXYVal.class;
3112
3113
public static class LocalXYVal {
3114
public int x, y;
3115
3116
public LocalXYVal(int x, int y) {
3117
this.x = x; this.y = y;
3118
}
3119
}
3120
3121
@Override
3122
public void dontinline_testMethod() {
3123
LocalXYVal p1 = new LocalXYVal(4, 2);
3124
LocalXYVal p2 = new LocalXYVal(5, 3);
3125
LocalXYVal p3 = new LocalXYVal(6, 4);
3126
dontinline_endlessLoop();
3127
iResult = p1.x+p1.y + p2.x+p2.y + p3.x+p3.y;
3128
}
3129
3130
@Override
3131
public int getExpectedIResult() {
3132
return 6+8+10;
3133
}
3134
3135
@Override
3136
public void setUp() {
3137
super.setUp();
3138
testMethodDepth = 2;
3139
loopCount = 3;
3140
}
3141
3142
public void warmupDone() {
3143
super.warmupDone();
3144
msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
3145
loopCount = Long.MAX_VALUE; // endless loop
3146
}
3147
}
3148
3149
3150
// End of test case collection
3151
/////////////////////////////////////////////////////////////////////////////
3152
3153
/////////////////////////////////////////////////////////////////////////////
3154
// Helper classes
3155
class XYVal {
3156
3157
public int x, y;
3158
3159
public XYVal(int x, int y) {
3160
this.x = x;
3161
this.y = y;
3162
}
3163
3164
/**
3165
* Note that we don't use a sync block here because javac would generate an synthetic exception
3166
* handler for the synchronized block that catches Throwable E, unlocks and throws E
3167
* again. The throw bytecode causes the BCEscapeAnalyzer to set the escape state to GlobalEscape
3168
* (see comment on exception handlers in BCEscapeAnalyzer::iterate_blocks())
3169
*/
3170
public synchronized void dontinline_sync_method(EATestCaseBaseTarget target) {
3171
target.dontinline_brkpt();
3172
}
3173
3174
/**
3175
* Just like {@link #dontinline_sync_method(EATestCaseBaseTarget)} but without the call to
3176
* {@link EATestCaseBaseTarget#dontinline_brkpt()}.
3177
*/
3178
public synchronized void dontinline_sync_method_no_brkpt(EATestCaseBaseTarget target) {
3179
}
3180
}
3181
3182
class Vector10 {
3183
int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
3184
public Vector10(int j0, int j1, int j2, int j3, int j4, int j5, int j6, int j7, int j8, int j9) {
3185
i0=j0; i1=j1; i2=j2; i3=j3; i4=j4; i5=j5; i6=j6; i7=j7; i8=j8; i9=j9;
3186
}
3187
}
3188
3189
class ILFDO {
3190
3191
public int i;
3192
public int i2;
3193
public long l;
3194
public long l2;
3195
public float f;
3196
public float f2;
3197
public double d;
3198
public double d2;
3199
public Long o;
3200
public Long o2;
3201
3202
public ILFDO(int i,
3203
int i2,
3204
long l,
3205
long l2,
3206
float f,
3207
float f2,
3208
double d,
3209
double d2,
3210
Long o,
3211
Long o2) {
3212
this.i = i;
3213
this.i2 = i2;
3214
this.l = l;
3215
this.l2 = l2;
3216
this.f = f;
3217
this.f2 = f2;
3218
this.d = d;
3219
this.d2 = d2;
3220
this.o = o;
3221
this.o2 = o2;
3222
}
3223
3224
}
3225
3226