src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphUtilOriginalValueTests.java
changeset 58533 46b0b7fe255c
equal deleted inserted replaced
58532:b4f2e13d20ea 58533:46b0b7fe255c
       
     1 /*
       
     2  * Copyright (c) 2019, Oracle and/or its affiliates. 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 package org.graalvm.compiler.core.test;
       
    26 
       
    27 import java.lang.invoke.ConstantCallSite;
       
    28 import java.lang.invoke.MethodHandle;
       
    29 import java.lang.invoke.MethodHandles;
       
    30 
       
    31 import org.graalvm.compiler.nodes.util.GraphUtil;
       
    32 import org.junit.Assert;
       
    33 import org.junit.Test;
       
    34 import org.objectweb.asm.ClassWriter;
       
    35 import org.objectweb.asm.Label;
       
    36 import org.objectweb.asm.MethodVisitor;
       
    37 
       
    38 import jdk.vm.ci.code.BailoutException;
       
    39 import jdk.vm.ci.meta.ResolvedJavaMethod;
       
    40 
       
    41 /**
       
    42  * Unit tests derived from https://github.com/oracle/graal/pull/1690.
       
    43  */
       
    44 public class GraphUtilOriginalValueTests extends CustomizedBytecodePatternTest {
       
    45 
       
    46     static class LinkedNode {
       
    47         LinkedNode next;
       
    48     }
       
    49 
       
    50     static class A extends LinkedNode {
       
    51     }
       
    52 
       
    53     static class B extends LinkedNode {
       
    54     }
       
    55 
       
    56     static class C extends LinkedNode {
       
    57     }
       
    58 
       
    59     public static Class<?> getLastClass(A a) {
       
    60         LinkedNode current = a;
       
    61         Class<?> currentKlass = null;
       
    62         while (current != null) {
       
    63             // This must not be folded to A.class
       
    64             currentKlass = current.getClass();
       
    65 
       
    66             current = current.next;
       
    67         }
       
    68         return currentKlass;
       
    69     }
       
    70 
       
    71     @Test
       
    72     public void testGetClass() {
       
    73         A a = new A();
       
    74         a.next = new B();
       
    75 
       
    76         test("getLastClass", a);
       
    77     }
       
    78 
       
    79     static final ConstantCallSite cs1 = init(A.class);
       
    80     static final ConstantCallSite cs2 = init(B.class);
       
    81     static final ConstantCallSite cs3 = init(C.class);
       
    82 
       
    83     static ConstantCallSite init(Class<?> c) {
       
    84         try {
       
    85             return new ConstantCallSite(MethodHandles.lookup().unreflectConstructor(c.getDeclaredConstructor()));
       
    86         } catch (Exception e) {
       
    87             throw new InternalError(e);
       
    88         }
       
    89     }
       
    90 
       
    91     public static boolean findTarget(MethodHandle key) {
       
    92         ConstantCallSite cs = cs1;
       
    93         while (cs != null) {
       
    94             if (cs.getTarget() == key) {
       
    95                 return true;
       
    96             }
       
    97             if (cs == cs1) {
       
    98                 cs = cs2;
       
    99             } else if (cs == cs2) {
       
   100                 cs = cs3;
       
   101             } else {
       
   102                 cs = null;
       
   103             }
       
   104         }
       
   105         return false;
       
   106     }
       
   107 
       
   108     @Test
       
   109     public void testGetTarget() {
       
   110         cs1.getTarget();
       
   111         cs2.getTarget();
       
   112         test("findTarget", cs3.getTarget());
       
   113     }
       
   114 
       
   115     @Override
       
   116     protected byte[] generateClass(String internalClassName) {
       
   117         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
       
   118         cw.visit(52, ACC_SUPER | ACC_PUBLIC, internalClassName, null, "java/lang/Object", null);
       
   119 
       
   120         String getDescriptor = "(Ljava/lang/Object;)V";
       
   121         MethodVisitor m = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "unbalancedMonitors", getDescriptor, null, null);
       
   122         Label loopHead = new Label();
       
   123         Label end = new Label();
       
   124         m.visitCode();
       
   125 
       
   126         // @formatter:off
       
   127         /*
       
   128          * void unbalancedMonitors(Object o) {
       
   129          *     monitorenter(o);
       
   130          *     while (o.toString() != o) {
       
   131          *         monitorexit(o);
       
   132          *         o = o.toString();
       
   133          *     }
       
   134          * }
       
   135          */
       
   136         // @formatter:on
       
   137 
       
   138         m.visitVarInsn(ALOAD, 0);
       
   139         m.visitInsn(MONITORENTER);
       
   140         m.visitLabel(loopHead);
       
   141         m.visitVarInsn(ALOAD, 0);
       
   142         m.visitInsn(MONITOREXIT);
       
   143         m.visitVarInsn(ALOAD, 0);
       
   144         m.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false);
       
   145         m.visitVarInsn(ALOAD, 0);
       
   146         m.visitJumpInsn(IF_ACMPEQ, end);
       
   147         m.visitVarInsn(ALOAD, 0);
       
   148         m.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false);
       
   149         m.visitVarInsn(ASTORE, 0);
       
   150         m.visitJumpInsn(GOTO, loopHead);
       
   151         m.visitLabel(end);
       
   152         m.visitInsn(RETURN);
       
   153         m.visitMaxs(2, 2);
       
   154         m.visitEnd();
       
   155 
       
   156         cw.visitEnd();
       
   157         return cw.toByteArray();
       
   158     }
       
   159 
       
   160     /**
       
   161      * Tests that the use of {@link GraphUtil#originalValue} in parsing MONITOREXIT correctly
       
   162      * detects unbalanced monitors.
       
   163      */
       
   164     @Test
       
   165     public void testUnbalancedMonitors() throws ClassNotFoundException {
       
   166         Class<?> testClass = getClass("UnbalancedMonitors");
       
   167         ResolvedJavaMethod t1 = getResolvedJavaMethod(testClass, "unbalancedMonitors");
       
   168         try {
       
   169             parseForCompile(t1);
       
   170             Assert.fail("expected a " + BailoutException.class.getName());
       
   171         } catch (BailoutException e) {
       
   172             String msg = e.getMessage();
       
   173             Assert.assertTrue(msg, msg.contains("unbalanced monitors"));
       
   174         }
       
   175     }
       
   176 }