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