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