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 package org.graalvm.compiler.hotspot.test;
24
25 import java.lang.management.ManagementFactory;
26 import java.lang.management.MonitorInfo;
27 import java.lang.management.ThreadInfo;
28 import java.lang.management.ThreadMXBean;
29 import java.util.Collection;
30 import java.util.HashMap;
31 import java.util.HashSet;
32
33 import org.graalvm.compiler.api.directives.GraalDirectives;
34 import org.graalvm.compiler.core.phases.HighTier;
35 import org.graalvm.compiler.debug.DebugContext;
36 import org.graalvm.compiler.debug.GraalError;
37 import org.graalvm.compiler.debug.TTY;
38 import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase;
39 import org.graalvm.compiler.options.OptionKey;
40 import org.graalvm.compiler.options.OptionValues;
41 import org.graalvm.util.EconomicMap;
42 import org.junit.Assert;
43 import org.junit.Test;
44
45 import jdk.vm.ci.meta.ResolvedJavaMethod;
46 import org.junit.Assume;
47
48 /**
49 * Test on-stack-replacement with locks.
50 */
51 public class GraalOSRLockTest extends GraalOSRTestBase {
52
53 private static boolean TestInSeparateThread = false;
54
55 public GraalOSRLockTest() {
56 try {
57 Class.forName("java.lang.management.ManagementFactory");
58 } catch (ClassNotFoundException ex) {
59 Assume.assumeNoException("cannot check for monitors without java.management JDK9 module", ex);
60 }
61 }
62
63 // testing only
64 public static boolean isMonitorLockHeld(Object o) {
65 return isMonitorLockHeldByThread(o, null);
66 }
67
68 public static boolean isMonitorLockHeldByThread(Object o, Thread t) {
69 int oihc = System.identityHashCode(o);
70 ThreadMXBean tmxbean = ManagementFactory.getThreadMXBean();
71 ThreadInfo[] tinfos = tmxbean.dumpAllThreads(true, false);
72
73 for (ThreadInfo ti : tinfos) {
74 if (!(t != null && t.getId() != ti.getThreadId())) {
75 for (MonitorInfo mi : ti.getLockedMonitors()) {
76 if (mi.getIdentityHashCode() == oihc) {
77 return true;
78 }
79 }
80 }
421 }
422 }
423
424 public static ReturnValue testOuterInnerLockCompileRestOfMethod() {
425 ReturnValue ret = ReturnValue.FAILURE;
426 synchronized (lock) {
427 for (int i = 1; i < 10 * limit; i++) {
428 synchronized (lock1) {
429 GraalDirectives.blackhole(i);
430 if (i % 33 == 0) {
431 ret = ReturnValue.SUCCESS;
432 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
433 GraalDirectives.blackhole(ret);
434 System.gc();
435 }
436 }
437 }
438 }
439 GraalDirectives.controlFlowAnchor();
440 if (!GraalDirectives.inCompiledCode()) {
441 throw new Error("Must part of compiled code");
442 }
443 return ret;
444 }
445 }
446
447 public static ReturnValue testOuterInnerLockDepth1CompileRestOfMethod() {
448 // testing the order of the lock releasing
449 ReturnValue ret = ReturnValue.FAILURE;
450 synchronized (lock) {
451 synchronized (lock1) {
452 for (int i = 1; i < limit; i++) {
453 GraalDirectives.blackhole(i);
454 if (i % 1001 == 0) {
455 ret = ReturnValue.SUCCESS;
456 if (GraalDirectives.inCompiledCode() && i + 33 > (limit)) {
457 GraalDirectives.blackhole(ret);
458 System.gc();
459 }
460 }
461 }
462 }
463 GraalDirectives.controlFlowAnchor();
464 if (!GraalDirectives.inCompiledCode()) {
465 throw new Error("Must part of compiled code");
466 } else {
467 // lock 1 must be free
468 if (isMonitorLockHeld(lock1)) {
469 throw new Error("Lock 1 must have been released already");
470 }
471
472 // lock 2 must still be locked and cannot be acquired by another thread
473 if (!isMonitorLockHeldByThread(lock, Thread.currentThread())) {
474 throw new Error("Lock must not have been released already");
475 }
476 }
477 return ret;
478 }
479 }
480
481 public static ReturnValue testOuterInnerLockDepth1DeoptAfter() {
482 // testing the order of the lock releasing
483 ReturnValue ret = ReturnValue.FAILURE;
484 synchronized (lock) {
485 synchronized (lock1) {
502 return ret;
503 }
504
505 public static ReturnValue testOuterInnerLockDepth1RecursiveCompileRestOfMethod1() {
506 // testing the order of the lock releasing
507 ReturnValue ret = ReturnValue.FAILURE;
508 synchronized (lock) {
509 synchronized (lock) {
510 for (int i = 1; i < 10 * limit; i++) {
511 GraalDirectives.blackhole(i);
512 if (i % 33 == 0) {
513 ret = ReturnValue.SUCCESS;
514 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
515 GraalDirectives.blackhole(ret);
516 }
517 }
518 }
519 }
520 GraalDirectives.controlFlowAnchor();
521 if (!GraalDirectives.inCompiledCode()) {
522 throw new Error("Must part of compiled code");
523 }
524 return ret;
525 }
526 }
527
528 public static ReturnValue testOuterInnerLockDepth1RecursiveCompileRestOfMethod2() {
529 // testing the order of the lock releasing
530 final Object l = lock;
531 ReturnValue ret = ReturnValue.FAILURE;
532 synchronized (l) {
533 synchronized (l) {
534 for (int i = 1; i < 10 * limit; i++) {
535 GraalDirectives.blackhole(i);
536 if (i % 33 == 0) {
537 ret = ReturnValue.SUCCESS;
538 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
539 GraalDirectives.blackhole(ret);
540 }
541 }
542 }
543 }
544 GraalDirectives.controlFlowAnchor();
545 if (!GraalDirectives.inCompiledCode()) {
546 throw new Error("Must part of compiled code");
547 }
548 return ret;
549 }
550 }
551
552 public static ReturnValue testRecursiveLockingRoot() {
553 // testing the order of the lock releasing
554 final Object l = lock;
555 ReturnValue ret = ReturnValue.FAILURE;
556 synchronized (l) {
557 synchronized (l) {
558 for (int i = 1; i < limit; i++) {
559 GraalDirectives.blackhole(i);
560 testRecursiveLockingLeaf();
561 if (i % 33 == 0) {
562 ret = ReturnValue.SUCCESS;
563 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
564 GraalDirectives.blackhole(ret);
565 }
566 }
567 }
568 }
569 GraalDirectives.controlFlowAnchor();
570 if (!GraalDirectives.inCompiledCode()) {
571 throw new Error("Must part of compiled code");
572 }
573 return ret;
574 }
575 }
576
577 public static ReturnValue testRecursiveLockingLeaf() {
578 // testing the order of the lock releasing
579 final Object l = lock;
580 ReturnValue ret = ReturnValue.FAILURE;
581 synchronized (l) {
582 synchronized (l) {
583 for (int i = 1; i < limit; i++) {
584 GraalDirectives.blackhole(i);
585 if (i % 33 == 0) {
586 ret = ReturnValue.SUCCESS;
587 }
588 }
589 }
590 return ret;
591 }
629 }
630
631 // test cases for optimizations
632 public static ReturnValue testOuterLockCompileRestOfMethodSubsequentLock() {
633 final Object monitor = lock;
634 ReturnValue ret = ReturnValue.FAILURE;
635 synchronized (monitor) {
636 for (int i = 1; i < 10 * limit; i++) {
637 GraalDirectives.blackhole(i);
638 if (i % 33 == 0) {
639 ret = ReturnValue.SUCCESS;
640 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
641 GraalDirectives.blackhole(ret);
642 }
643 }
644 }
645 }
646 synchronized (monitor) {
647 GraalDirectives.controlFlowAnchor();
648 if (!GraalDirectives.inCompiledCode()) {
649 throw new Error("Must part of compiled code");
650 }
651 }
652 return ret;
653
654 }
655
656 public static ReturnValue testOuterInnerSameLockCompileRestOfMethod() {
657 final Object monitor = lock;
658 ReturnValue ret = ReturnValue.FAILURE;
659 synchronized (monitor) {
660 for (int i = 1; i < 10 * limit; i++) {
661 synchronized (monitor) {
662 GraalDirectives.blackhole(i);
663 if (i % 33 == 0) {
664 ret = ReturnValue.SUCCESS;
665 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
666 GraalDirectives.blackhole(ret);
667 }
668 }
669 }
670 }
671 GraalDirectives.controlFlowAnchor();
672 if (!GraalDirectives.inCompiledCode()) {
673 throw new Error("Must part of compiled code");
674 }
675 return ret;
676 }
677 }
678
679 }
|
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 package org.graalvm.compiler.hotspot.test;
24
25 import java.lang.management.ManagementFactory;
26 import java.lang.management.MonitorInfo;
27 import java.lang.management.RuntimeMXBean;
28 import java.lang.management.ThreadInfo;
29 import java.lang.management.ThreadMXBean;
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.List;
34
35 import org.graalvm.compiler.api.directives.GraalDirectives;
36 import org.graalvm.compiler.core.phases.HighTier;
37 import org.graalvm.compiler.debug.DebugContext;
38 import org.graalvm.compiler.debug.GraalError;
39 import org.graalvm.compiler.debug.TTY;
40 import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase;
41 import org.graalvm.compiler.options.OptionKey;
42 import org.graalvm.compiler.options.OptionValues;
43 import org.graalvm.util.EconomicMap;
44 import org.junit.Assert;
45 import org.junit.Test;
46
47 import jdk.vm.ci.meta.ResolvedJavaMethod;
48 import org.junit.Assume;
49 import org.junit.BeforeClass;
50
51 /**
52 * Test on-stack-replacement with locks.
53 */
54 public class GraalOSRLockTest extends GraalOSRTestBase {
55
56 private static boolean TestInSeparateThread = false;
57 private static final String COMPILE_ONLY_FLAG = "-Xcomp";
58
59 @BeforeClass
60 public static void checkVMArguments() {
61 try {
62 Class.forName("java.lang.management.ManagementFactory");
63 } catch (ClassNotFoundException ex) {
64 Assume.assumeNoException("cannot check for monitors without java.management JDK9 module", ex);
65 }
66 /*
67 * Note: The -Xcomp execution mode of the VM will stop most of the OSR test cases from
68 * working as every method is compiled at level3 (followed by level4 on the second
69 * invocation). The tests in this class are written in a way that they expect a method to be
70 * executed at the invocation BCI with the interpreter and then perform an OSR to an
71 * installed nmethod at a given BCI.
72 *
73 */
74 RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
75 List<String> arguments = runtimeMxBean.getInputArguments();
76 for (String arg : arguments) {
77 Assume.assumeFalse(arg.equals(COMPILE_ONLY_FLAG));
78 }
79 }
80
81 // testing only
82 public static boolean isMonitorLockHeld(Object o) {
83 return isMonitorLockHeldByThread(o, null);
84 }
85
86 public static boolean isMonitorLockHeldByThread(Object o, Thread t) {
87 int oihc = System.identityHashCode(o);
88 ThreadMXBean tmxbean = ManagementFactory.getThreadMXBean();
89 ThreadInfo[] tinfos = tmxbean.dumpAllThreads(true, false);
90
91 for (ThreadInfo ti : tinfos) {
92 if (!(t != null && t.getId() != ti.getThreadId())) {
93 for (MonitorInfo mi : ti.getLockedMonitors()) {
94 if (mi.getIdentityHashCode() == oihc) {
95 return true;
96 }
97 }
98 }
439 }
440 }
441
442 public static ReturnValue testOuterInnerLockCompileRestOfMethod() {
443 ReturnValue ret = ReturnValue.FAILURE;
444 synchronized (lock) {
445 for (int i = 1; i < 10 * limit; i++) {
446 synchronized (lock1) {
447 GraalDirectives.blackhole(i);
448 if (i % 33 == 0) {
449 ret = ReturnValue.SUCCESS;
450 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
451 GraalDirectives.blackhole(ret);
452 System.gc();
453 }
454 }
455 }
456 }
457 GraalDirectives.controlFlowAnchor();
458 if (!GraalDirectives.inCompiledCode()) {
459 throw new Error("Must be part of compiled code");
460 }
461 return ret;
462 }
463 }
464
465 public static ReturnValue testOuterInnerLockDepth1CompileRestOfMethod() {
466 // testing the order of the lock releasing
467 ReturnValue ret = ReturnValue.FAILURE;
468 synchronized (lock) {
469 synchronized (lock1) {
470 for (int i = 1; i < 10 * limit; i++) {
471 GraalDirectives.blackhole(i);
472 if (i % 33 == 0) {
473 ret = ReturnValue.SUCCESS;
474 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
475 GraalDirectives.blackhole(ret);
476 System.gc();
477 }
478 }
479 }
480 }
481 GraalDirectives.controlFlowAnchor();
482 if (!GraalDirectives.inCompiledCode()) {
483 throw new Error("Must be part of compiled code already hereeeeee");
484 } else {
485 // lock 1 must be free
486 if (isMonitorLockHeld(lock1)) {
487 throw new Error("Lock 1 must have been released already");
488 }
489
490 // lock 2 must still be locked and cannot be acquired by another thread
491 if (!isMonitorLockHeldByThread(lock, Thread.currentThread())) {
492 throw new Error("Lock must not have been released already");
493 }
494 }
495 return ret;
496 }
497 }
498
499 public static ReturnValue testOuterInnerLockDepth1DeoptAfter() {
500 // testing the order of the lock releasing
501 ReturnValue ret = ReturnValue.FAILURE;
502 synchronized (lock) {
503 synchronized (lock1) {
520 return ret;
521 }
522
523 public static ReturnValue testOuterInnerLockDepth1RecursiveCompileRestOfMethod1() {
524 // testing the order of the lock releasing
525 ReturnValue ret = ReturnValue.FAILURE;
526 synchronized (lock) {
527 synchronized (lock) {
528 for (int i = 1; i < 10 * limit; i++) {
529 GraalDirectives.blackhole(i);
530 if (i % 33 == 0) {
531 ret = ReturnValue.SUCCESS;
532 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
533 GraalDirectives.blackhole(ret);
534 }
535 }
536 }
537 }
538 GraalDirectives.controlFlowAnchor();
539 if (!GraalDirectives.inCompiledCode()) {
540 throw new Error("Must be part of compiled code");
541 }
542 return ret;
543 }
544 }
545
546 public static ReturnValue testOuterInnerLockDepth1RecursiveCompileRestOfMethod2() {
547 // testing the order of the lock releasing
548 final Object l = lock;
549 ReturnValue ret = ReturnValue.FAILURE;
550 synchronized (l) {
551 synchronized (l) {
552 for (int i = 1; i < 10 * limit; i++) {
553 GraalDirectives.blackhole(i);
554 if (i % 33 == 0) {
555 ret = ReturnValue.SUCCESS;
556 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
557 GraalDirectives.blackhole(ret);
558 }
559 }
560 }
561 }
562 GraalDirectives.controlFlowAnchor();
563 if (!GraalDirectives.inCompiledCode()) {
564 throw new Error("Must be part of compiled code");
565 }
566 return ret;
567 }
568 }
569
570 public static ReturnValue testRecursiveLockingRoot() {
571 // testing the order of the lock releasing
572 final Object l = lock;
573 ReturnValue ret = ReturnValue.FAILURE;
574 synchronized (l) {
575 synchronized (l) {
576 for (int i = 1; i < limit; i++) {
577 GraalDirectives.blackhole(i);
578 testRecursiveLockingLeaf();
579 if (i % 33 == 0) {
580 ret = ReturnValue.SUCCESS;
581 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
582 GraalDirectives.blackhole(ret);
583 }
584 }
585 }
586 }
587 GraalDirectives.controlFlowAnchor();
588 if (!GraalDirectives.inCompiledCode()) {
589 throw new Error("Must be part of compiled code");
590 }
591 return ret;
592 }
593 }
594
595 public static ReturnValue testRecursiveLockingLeaf() {
596 // testing the order of the lock releasing
597 final Object l = lock;
598 ReturnValue ret = ReturnValue.FAILURE;
599 synchronized (l) {
600 synchronized (l) {
601 for (int i = 1; i < limit; i++) {
602 GraalDirectives.blackhole(i);
603 if (i % 33 == 0) {
604 ret = ReturnValue.SUCCESS;
605 }
606 }
607 }
608 return ret;
609 }
647 }
648
649 // test cases for optimizations
650 public static ReturnValue testOuterLockCompileRestOfMethodSubsequentLock() {
651 final Object monitor = lock;
652 ReturnValue ret = ReturnValue.FAILURE;
653 synchronized (monitor) {
654 for (int i = 1; i < 10 * limit; i++) {
655 GraalDirectives.blackhole(i);
656 if (i % 33 == 0) {
657 ret = ReturnValue.SUCCESS;
658 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
659 GraalDirectives.blackhole(ret);
660 }
661 }
662 }
663 }
664 synchronized (monitor) {
665 GraalDirectives.controlFlowAnchor();
666 if (!GraalDirectives.inCompiledCode()) {
667 throw new Error("Must be part of compiled code");
668 }
669 }
670 return ret;
671
672 }
673
674 public static ReturnValue testOuterInnerSameLockCompileRestOfMethod() {
675 final Object monitor = lock;
676 ReturnValue ret = ReturnValue.FAILURE;
677 synchronized (monitor) {
678 for (int i = 1; i < 10 * limit; i++) {
679 synchronized (monitor) {
680 GraalDirectives.blackhole(i);
681 if (i % 33 == 0) {
682 ret = ReturnValue.SUCCESS;
683 if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
684 GraalDirectives.blackhole(ret);
685 }
686 }
687 }
688 }
689 GraalDirectives.controlFlowAnchor();
690 if (!GraalDirectives.inCompiledCode()) {
691 throw new Error("Must be part of compiled code");
692 }
693 return ret;
694 }
695 }
696
697 }
|