Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/serviceability/jvmti/Heap/IterateHeapWithEscapeAnalysisEnabled.java
41153 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
* @test
26
* @bug 8230956
27
* @summary JVMTI agents can obtain references to not escaping objects using JVMTI Heap functions.
28
* Therefore optimizations based on escape analysis have to be reverted,
29
* i.e. scalar replaced objects need to be reallocated on the heap and objects with eliminated locking
30
* need to be relocked.
31
* @requires ((vm.compMode == "Xmixed") & vm.compiler2.enabled & vm.jvmti)
32
* @library /test/lib /test/hotspot/jtreg
33
* @build sun.hotspot.WhiteBox
34
* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox
35
* @compile IterateHeapWithEscapeAnalysisEnabled.java
36
*
37
* @comment BLOCK BEGIN EXCLUSIVE TESTCASES {
38
*
39
* The following test cases are executed in fresh VMs because they require that the
40
* capability can_tag_objects is not taken until dontinline_testMethod is jit compiled and
41
* an activation of the compiled version is on stack of the target thread.
42
*
43
* Without JDK-8227745 these test cases require that escape analysis is disabled at
44
* start-up because can_tag_objects can be taken lazily, potentially after loading an
45
* agent dynamically by means of the attach API. Disabling escape analysis and invalidating
46
* compiled methods does not help then because there may be compiled frames with ea-based
47
* optimizations on stack. Just like in this collection of test cases.
48
*
49
* @run main/othervm/native
50
* -agentlib:IterateHeapWithEscapeAnalysisEnabled
51
* -XX:+UnlockDiagnosticVMOptions
52
* -Xms256m -Xmx256m
53
* -XX:+PrintCompilation -XX:+PrintInlining
54
* -XX:+WhiteBoxAPI -Xbootclasspath/a:.
55
* -Xbatch
56
* -XX:CompileCommand=dontinline,*::dontinline_*
57
* -XX:+DoEscapeAnalysis
58
* IterateHeapWithEscapeAnalysisEnabled IterateOverReachableObjects
59
* @run main/othervm/native
60
* -agentlib:IterateHeapWithEscapeAnalysisEnabled
61
* -XX:+UnlockDiagnosticVMOptions
62
* -Xms256m -Xmx256m
63
* -XX:+PrintCompilation -XX:+PrintInlining
64
* -XX:+WhiteBoxAPI -Xbootclasspath/a:.
65
* -Xbatch
66
* -XX:CompileCommand=dontinline,*::dontinline_*
67
* -XX:+DoEscapeAnalysis
68
* IterateHeapWithEscapeAnalysisEnabled IterateOverHeap
69
* @run main/othervm/native
70
* -agentlib:IterateHeapWithEscapeAnalysisEnabled
71
* -XX:+UnlockDiagnosticVMOptions
72
* -Xms256m -Xmx256m
73
* -XX:+PrintCompilation -XX:+PrintInlining
74
* -XX:+WhiteBoxAPI -Xbootclasspath/a:.
75
* -Xbatch
76
* -XX:CompileCommand=dontinline,*::dontinline_*
77
* -XX:+DoEscapeAnalysis
78
* IterateHeapWithEscapeAnalysisEnabled IterateOverInstancesOfClass
79
* @run main/othervm/native
80
* -agentlib:IterateHeapWithEscapeAnalysisEnabled
81
* -XX:+UnlockDiagnosticVMOptions
82
* -Xms256m -Xmx256m
83
* -XX:+PrintCompilation -XX:+PrintInlining
84
* -XX:+WhiteBoxAPI -Xbootclasspath/a:.
85
* -Xbatch
86
* -XX:CompileCommand=dontinline,*::dontinline_*
87
* -XX:+DoEscapeAnalysis
88
* IterateHeapWithEscapeAnalysisEnabled FollowReferences
89
* @run main/othervm/native
90
* -agentlib:IterateHeapWithEscapeAnalysisEnabled
91
* -XX:+UnlockDiagnosticVMOptions
92
* -Xms256m -Xmx256m
93
* -XX:+PrintCompilation -XX:+PrintInlining
94
* -XX:+WhiteBoxAPI -Xbootclasspath/a:.
95
* -Xbatch
96
* -XX:CompileCommand=dontinline,*::dontinline_*
97
* -XX:+DoEscapeAnalysis
98
* IterateHeapWithEscapeAnalysisEnabled IterateThroughHeap
99
*
100
* @comment } BLOCK END EXCLUSIVE TESTCASES
101
*
102
* @comment BLOCK BEGIN NON EXCLUSIVE TESTCASES {
103
*
104
* @run main/othervm/native
105
* -agentlib:IterateHeapWithEscapeAnalysisEnabled
106
* -XX:+UnlockDiagnosticVMOptions
107
* -Xms256m -Xmx256m
108
* -XX:CompileCommand=dontinline,*::dontinline_*
109
* -XX:+PrintCompilation
110
* -XX:+PrintInlining
111
* -XX:+WhiteBoxAPI -Xbootclasspath/a:.
112
* -Xbatch
113
* -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
114
* IterateHeapWithEscapeAnalysisEnabled
115
* @run main/othervm/native
116
* -agentlib:IterateHeapWithEscapeAnalysisEnabled
117
* -XX:+UnlockDiagnosticVMOptions
118
* -Xms256m -Xmx256m
119
* -XX:CompileCommand=dontinline,*::dontinline_*
120
* -XX:+PrintCompilation
121
* -XX:+PrintInlining
122
* -XX:+WhiteBoxAPI -Xbootclasspath/a:.
123
* -Xbatch
124
* -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
125
* IterateHeapWithEscapeAnalysisEnabled
126
* @run main/othervm/native
127
* -agentlib:IterateHeapWithEscapeAnalysisEnabled
128
* -XX:+UnlockDiagnosticVMOptions
129
* -Xms256m -Xmx256m
130
* -XX:CompileCommand=dontinline,*::dontinline_*
131
* -XX:+PrintCompilation
132
* -XX:+PrintInlining
133
* -XX:+WhiteBoxAPI -Xbootclasspath/a:.
134
* -Xbatch
135
* -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
136
* IterateHeapWithEscapeAnalysisEnabled
137
*
138
* @comment } BLOCK END NON EXCLUSIVE TESTCASES
139
*/
140
141
import compiler.whitebox.CompilerWhiteBoxTest;
142
import jdk.test.lib.Asserts;
143
import sun.hotspot.WhiteBox;
144
145
public class IterateHeapWithEscapeAnalysisEnabled {
146
147
public static final WhiteBox WB = WhiteBox.getWhiteBox();
148
149
public static final int COMPILE_THRESHOLD = CompilerWhiteBoxTest.THRESHOLD;
150
151
public static native int jvmtiTagClass(Class<?> cls, long tag);
152
153
// Methods to tag or count instances of a given class available in JVMTI
154
public static enum TaggingAndCountingMethods {
155
IterateOverReachableObjects,
156
IterateOverHeap,
157
IterateOverInstancesOfClass,
158
FollowReferences,
159
IterateThroughHeap
160
}
161
162
public static native int acquireCanTagObjectsCapability();
163
public static native int registerMethod(TaggingAndCountingMethods m, String name);
164
public static native void agentTearDown();
165
166
/**
167
* Count and tag instances of a given class.
168
* @param cls Used by the method {@link TaggingAndCountingMethods#IterateOverInstancesOfClass} as class to count and tag instances of.
169
* Ignored by other counting methods.
170
* @param clsTag Tag of the class to count and tag instances of. Used by all methods except
171
* {@link TaggingAndCountingMethods#IterateOverInstancesOfClass}
172
* @param instanceTag The tag to be set for selected instances.
173
* @param method JVMTI counting and tagging method to be used.
174
* @return The number of instances or -1 if the call fails.
175
*/
176
public static native int countAndTagInstancesOfClass(Class<?> cls, long clsTag, long instanceTag, TaggingAndCountingMethods method);
177
178
/**
179
* Get all objects tagged with the given tag.
180
* @param tag The tag used to select objects.
181
* @param result Selected objects are copied into this array.
182
* @return -1 to indicated failure and 0 for success.
183
*/
184
public static native int getObjectsWithTag(long tag, Object[] result);
185
186
public static void main(String[] args) throws Exception {
187
try {
188
new IterateHeapWithEscapeAnalysisEnabled().runTestCases(args);
189
} finally {
190
agentTearDown();
191
}
192
}
193
194
public void runTestCases(String[] args) throws Exception {
195
// register various instance tagging and counting methods with agent
196
for (TaggingAndCountingMethods m : TaggingAndCountingMethods.values()) {
197
msg("register instance count method " + m.name());
198
int rc = registerMethod(m, m.name());
199
Asserts.assertGreaterThanOrEqual(rc, 0, "method " + m.name() + " is unknown to agent");
200
}
201
202
if (args.length > 0) {
203
// EXCLUSIVE TEST CASES
204
// cant_tag_objects is acquired after warmup. Use given tagging/counting method.
205
new TestCase01(true, 100, TaggingAndCountingMethods.valueOf(args[0])).run();
206
} else {
207
// NON-EXCLUSIVE TEST CASES
208
// cant_tag_objects is acquired before test cases are run but still during live phase.
209
msgHL("Acquire capability can_tag_objects before first test case.");
210
int err = acquireCanTagObjectsCapability();
211
Asserts.assertEQ(0, err, "acquireCanTagObjectsCapability FAILED");
212
213
// run test cases
214
for (TaggingAndCountingMethods m : TaggingAndCountingMethods.values()) {
215
new TestCase01(false, 200, m).run();
216
}
217
new TestCase02a(200).run();
218
new TestCase02b(300).run();
219
}
220
}
221
222
static class ABBox {
223
public int aVal;
224
public int bVal;
225
public TestCaseBase testCase;
226
227
public ABBox() { /* empty */ }
228
229
public ABBox(TestCaseBase testCase) {
230
this.testCase = testCase;
231
}
232
233
/**
234
* Increment {@link #aVal} and {@link #bVal} under lock. The method is supposed to
235
* be inlined into the test method and locking is supposed to be eliminated. After
236
* this object escaped to the JVMTI agent, the code with eliminated locking must
237
* not be used anymore.
238
*/
239
public synchronized void synchronizedSlowInc() {
240
aVal++;
241
testCase.waitingForCheck = true;
242
dontinline_waitForCheck(testCase);
243
testCase.waitingForCheck = false;
244
bVal++;
245
}
246
247
public static void dontinline_waitForCheck(TestCaseBase testCase) {
248
if (testCase.warmUpDone) {
249
while(!testCase.checkingNow) {
250
try {
251
Thread.sleep(50);
252
} catch (InterruptedException e) { /*ign*/ }
253
}
254
}
255
}
256
257
/**
258
* This method and incrementing {@link #aVal} and {@link #bVal} are synchronized.
259
* So {@link #aVal} and {@link #bVal} should always be equal. Unless the optimized version
260
* of {@link #synchronizedSlowInc()} without locking is still used after this object
261
* escaped to the JVMTI agent.
262
* @return
263
*/
264
public synchronized boolean check() {
265
return aVal == bVal;
266
}
267
}
268
269
public static abstract class TestCaseBase implements Runnable {
270
public final long classTag;
271
public long instanceTag;
272
273
public final Class<?> taggedClass;
274
275
public long checkSum;
276
public long loopCount;
277
public volatile boolean doLoop;
278
public volatile boolean targetIsInLoop;
279
280
public volatile boolean waitingForCheck;
281
public volatile boolean checkingNow;
282
283
public boolean warmUpDone;
284
285
public TestCaseBase(long classTag, Class<?> taggedClass) {
286
this.classTag = classTag;
287
this.taggedClass = taggedClass;
288
}
289
290
public void setUp() {
291
// Tag the class of instances to be scalar replaced
292
msg("tagging " + taggedClass.getName() + " with tag " + classTag);
293
int err = jvmtiTagClass(taggedClass, classTag);
294
Asserts.assertEQ(0, err, "jvmtiTagClass FAILED");
295
}
296
297
// to be overridden by test cases
298
abstract public void dontinline_testMethod();
299
300
public void warmUp() {
301
msg("WarmUp: START");
302
int callCount = COMPILE_THRESHOLD + 1000;
303
doLoop = true;
304
while (callCount-- > 0) {
305
dontinline_testMethod();
306
}
307
warmUpDone = true;
308
msg("WarmUp: DONE");
309
}
310
311
public Object dontinline_endlessLoop(Object argEscape) {
312
long cs = checkSum;
313
while (loopCount-- > 0 && doLoop) {
314
targetIsInLoop = true;
315
checkSum += checkSum % ++cs;
316
}
317
loopCount = 3;
318
targetIsInLoop = false;
319
return argEscape;
320
}
321
322
public void waitUntilTargetThreadHasEnteredEndlessLoop() {
323
while(!targetIsInLoop) {
324
msg("Target has not yet entered the loop. Sleep 100ms.");
325
try { Thread.sleep(100); } catch (InterruptedException e) { /*ignore */ }
326
}
327
msg("Target has entered the loop.");
328
}
329
330
public void terminateEndlessLoop() throws Exception {
331
msg("Terminate endless loop");
332
doLoop = false;
333
}
334
}
335
336
/**
337
* Use JVMTI heap functions associated with the elements of {@link TaggingAndCountingMethods} to
338
* get a reference to an object allocated in {@link TestCase01#dontinline_testMethod()}. The
339
* allocation can be eliminated / scalar replaced. The test case can be run in two modes: (1)
340
* the capability can_tag_objects which is required to use the JVMTI heap functions is taken
341
* before the test case (2) the capability is taken after {@link TestCase01#dontinline_testMethod()}
342
* is compiled and the target thread has an activation of it on stack.
343
*/
344
public static class TestCase01 extends TestCaseBase {
345
346
public volatile int testMethod_result;
347
public boolean acquireCanTagObjectsCapabilityAfterWarmup;
348
public TaggingAndCountingMethods taggingMethod;
349
350
public TestCase01(boolean acquireCanTagObjectsCapabilityAfterWarmup, long classTag, TaggingAndCountingMethods taggingMethod) {
351
super(classTag, ABBox.class);
352
instanceTag = classTag + 1;
353
this.acquireCanTagObjectsCapabilityAfterWarmup = acquireCanTagObjectsCapabilityAfterWarmup;
354
this.taggingMethod = taggingMethod;
355
}
356
357
@Override
358
public void setUp() {
359
if (!acquireCanTagObjectsCapabilityAfterWarmup) {
360
super.setUp();
361
}
362
}
363
364
public void setUpAfterWarmUp() {
365
if (acquireCanTagObjectsCapabilityAfterWarmup) {
366
msg("Acquire capability can_tag_objects " + (warmUpDone ? "after" : "before") + " warmup.");
367
int err = acquireCanTagObjectsCapability();
368
Asserts.assertEQ(0, err, "acquireCanTagObjectsCapability FAILED");
369
super.setUp();
370
}
371
}
372
373
public void run() {
374
try {
375
msgHL(getClass().getName() + ": test if object that may be scalar replaced is found using " + taggingMethod);
376
msg("The capability can_tag_object is acquired " + (acquireCanTagObjectsCapabilityAfterWarmup ? "AFTER" : "BEFORE")
377
+ " warmup.");
378
setUp();
379
warmUp();
380
WB.deflateIdleMonitors();
381
WB.fullGC(); // get rid of dead instances from previous test cases
382
runTest(taggingMethod);
383
} catch (Exception e) {
384
Asserts.fail("Unexpected Exception", e);
385
}
386
}
387
388
public void runTest(TaggingAndCountingMethods m) throws Exception {
389
loopCount = 1L << 62; // endless loop
390
doLoop = true;
391
testMethod_result = 0;
392
Thread t1 = new Thread(() -> dontinline_testMethod(), "Target Thread (" + getClass().getName() + ")");
393
try {
394
t1.start();
395
try {
396
waitUntilTargetThreadHasEnteredEndlessLoop();
397
setUpAfterWarmUp();
398
msg("count and tag instances of " + taggedClass.getName() + " with tag " + instanceTag + " using JVMTI " + m.name());
399
int count = countAndTagInstancesOfClass(taggedClass, classTag, instanceTag, m);
400
msg("Done. Count is " + count);
401
Asserts.assertGreaterThanOrEqual(count, 0, "countAndTagInstancesOfClass FAILED");
402
Asserts.assertEQ(count, 1, "unexpected number of instances");
403
404
ABBox[] result = new ABBox[1];
405
msg("get instances tagged with " + instanceTag + ". The instances escape thereby.");
406
int err = getObjectsWithTag(instanceTag, result);
407
msg("Done.");
408
Asserts.assertEQ(0, err, "getObjectsWithTag FAILED");
409
410
msg("change the now escaped instance' bVal");
411
ABBox abBox = result[0];
412
abBox.bVal = 3;
413
terminateEndlessLoop();
414
415
msg("wait until target thread has set testMethod_result");
416
while (testMethod_result == 0) {
417
Thread.sleep(50);
418
}
419
msg("check if the modification of bVal is reflected in testMethod_result.");
420
Asserts.assertEQ(7, testMethod_result, " testMethod_result has wrong value");
421
msg("ok.");
422
} finally {
423
terminateEndlessLoop();
424
}
425
} finally {
426
t1.join();
427
}
428
}
429
430
@Override
431
public void dontinline_testMethod() {
432
ABBox ab = new ABBox(); // can be scalar replaced
433
ab.aVal = 4;
434
ab.bVal = 2;
435
dontinline_endlessLoop(null); // JVMTI agent acquires reference to ab and changes bVal
436
testMethod_result = ab.aVal + ab.bVal;
437
}
438
}
439
440
/**
441
* {@link #dontinline_testMethod()} creates an ArgEscape instance of {@link TestCaseBase#taggedClass} on stack.
442
* The jvmti agent tags all instances of this class using one of the {@link TaggingAndCountingMethods}. Then it gets the tagged
443
* instances using <code>GetObjectsWithTags()</code>. This is where the ArgEscape globally escapes.
444
* It happens at a location without eliminated locking but there is
445
* eliminated locking following, so the compiled frame must be deoptimized. This is checked by letting the agent call the
446
* synchronized method {@link ABBox#check()} on the escaped instance.
447
*/
448
public static class TestCase02a extends TestCaseBase {
449
450
public long instanceTag;
451
452
public TestCase02a(long classTag) {
453
super(classTag, ABBox.class);
454
instanceTag = classTag + 1;
455
}
456
457
public void run() {
458
try {
459
msgHL(getClass().getName() + ": test if owning frame is deoptimized if ArgEscape escapes globally");
460
setUp();
461
warmUp();
462
for (TaggingAndCountingMethods m : TaggingAndCountingMethods.values()) {
463
msgHL(getClass().getName() + ": Tag and Get of ArgEscapes using " + m.name());
464
waitingForCheck = false;
465
checkingNow = false;
466
WB.deflateIdleMonitors();
467
WB.fullGC(); // get rid of dead instances from previous test cases
468
runTest(m);
469
}
470
} catch (Exception e) {
471
Asserts.fail("Unexpected Exception", e);
472
}
473
}
474
475
public void runTest(TaggingAndCountingMethods m) throws Exception {
476
loopCount = 1L << 62; // endless loop
477
doLoop = true;
478
Thread t1 = new Thread(() -> dontinline_testMethod(), "Target Thread (" + getClass().getName() + ")");
479
try {
480
t1.start();
481
try {
482
waitUntilTargetThreadHasEnteredEndlessLoop();
483
msg("count and tag instances of " + taggedClass.getName() + " with tag " + instanceTag + " using JVMTI " + m.name());
484
int count = countAndTagInstancesOfClass(taggedClass, classTag, instanceTag, m);
485
msg("Done. Count is " + count);
486
Asserts.assertGreaterThanOrEqual(count, 0, "countAndTagInstancesOfClass FAILED");
487
Asserts.assertEQ(count, 1, "unexpected number of instances");
488
} finally {
489
terminateEndlessLoop();
490
}
491
492
ABBox[] result = new ABBox[1];
493
msg("get instances tagged with " + instanceTag);
494
int err = getObjectsWithTag(instanceTag, result);
495
msg("Done.");
496
Asserts.assertEQ(0, err, "getObjectsWithTag FAILED");
497
498
ABBox abBoxArgEscape = result[0];
499
while (!waitingForCheck) {
500
Thread.yield();
501
}
502
msg("Check abBoxArgEscape's state is consistent");
503
checkingNow = true;
504
Asserts.assertTrue(abBoxArgEscape.check(), "Detected inconsistent state. abBoxArgEscape.aVal != abBoxArgEscape.bVal");
505
msg("Ok.");
506
} finally {
507
checkingNow = true;
508
t1.join();
509
}
510
}
511
512
@Override
513
public void dontinline_testMethod() {
514
ABBox ab = new ABBox(this);
515
dontinline_endlessLoop(ab);
516
ab.synchronizedSlowInc();
517
}
518
}
519
520
/**
521
* Like {@link TestCase02a}, with the exception that at the location in {@link #dontinline_testMethod()} where the
522
* ArgEscape escapes it is not referenced by a local variable.
523
*/
524
public static class TestCase02b extends TestCaseBase {
525
526
public long instanceTag;
527
528
public TestCase02b(long classTag) {
529
super(classTag, ABBox.class);
530
instanceTag = classTag + 1;
531
}
532
533
public void run() {
534
try {
535
msgHL(getClass().getName() + ": test if owning frame is deoptimized if ArgEscape escapes globally");
536
setUp();
537
warmUp();
538
for (TaggingAndCountingMethods m : TaggingAndCountingMethods.values()) {
539
msgHL(getClass().getName() + ": Tag and Get of ArgEscapes using " + m.name());
540
waitingForCheck = false;
541
checkingNow = false;
542
WB.deflateIdleMonitors();
543
WB.fullGC(); // get rid of dead instances from previous test cases
544
runTest(m);
545
}
546
} catch (Exception e) {
547
Asserts.fail("Unexpected Exception", e);
548
}
549
}
550
551
public void runTest(TaggingAndCountingMethods m) throws Exception {
552
loopCount = 1L << 62; // endless loop
553
doLoop = true;
554
Thread t1 = new Thread(() -> dontinline_testMethod(), "Target Thread (" + getClass().getName() + ")");
555
try {
556
t1.start();
557
try {
558
waitUntilTargetThreadHasEnteredEndlessLoop();
559
msg("count and tag instances of " + taggedClass.getName() + " with tag " + instanceTag + " using JVMTI " + m.name());
560
int count = countAndTagInstancesOfClass(taggedClass, classTag, instanceTag, m);
561
msg("Done. Count is " + count);
562
Asserts.assertGreaterThanOrEqual(count, 0, "countAndTagInstancesOfClass FAILED");
563
Asserts.assertEQ(count, 1, "unexpected number of instances");
564
} finally {
565
terminateEndlessLoop();
566
}
567
568
ABBox[] result = new ABBox[1];
569
msg("get instances tagged with " + instanceTag);
570
int err = getObjectsWithTag(instanceTag, result);
571
msg("Done.");
572
Asserts.assertEQ(0, err, "getObjectsWithTag FAILED");
573
574
ABBox abBoxArgEscape = result[0];
575
while (!waitingForCheck) {
576
Thread.yield();
577
}
578
msg("Check abBoxArgEscape's state is consistent");
579
checkingNow = true;
580
Asserts.assertTrue(abBoxArgEscape.check(), "Detected inconsistent state. abBoxArgEscape.aVal != abBoxArgEscape.bVal");
581
msg("Ok.");
582
} finally {
583
checkingNow = true;
584
t1.join();
585
}
586
}
587
588
@Override
589
public void dontinline_testMethod() {
590
// The new instance is an ArgEscape instance and escapes to the JVMTI agent
591
// while the target thread is in the call to dontinline_endlessLoop(). At this
592
// location there is no local variable that references the ArgEscape.
593
((ABBox) dontinline_endlessLoop(new ABBox(this))).synchronizedSlowInc();;
594
}
595
}
596
597
public static void msg(String m) {
598
System.out.println();
599
System.out.println("### " + m);
600
System.out.println();
601
}
602
603
public static void msgHL(String m) {
604
System.out.println(); System.out.println(); System.out.println();
605
System.out.println("#####################################################");
606
System.out.println("### " + m);
607
System.out.println("###");
608
System.out.println();
609
}
610
}
611
612