< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java

Print this page




   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 }
< prev index next >