001/*
002 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.replacements.test;
024
025import java.util.*;
026
027import jdk.internal.jvmci.meta.*;
028
029import org.junit.*;
030
031import com.oracle.graal.compiler.test.*;
032import com.oracle.graal.phases.common.*;
033
034/**
035 * Tests that deoptimization upon exception handling works.
036 */
037public class DeoptimizeOnExceptionTest extends GraalCompilerTest {
038
039    public DeoptimizeOnExceptionTest() {
040        getSuites().getHighTier().findPhase(AbstractInliningPhase.class).remove();
041    }
042
043    private static void raiseException(String m1, String m2, String m3, String m4, String m5) {
044        throw new RuntimeException(m1 + m2 + m3 + m4 + m5);
045    }
046
047    @Test
048    public void test1() {
049        test("test1Snippet", "m1", "m2", "m3", "m4", "m5");
050    }
051
052    // no local exception handler - will deopt
053    public static String test1Snippet(String m1, String m2, String m3, String m4, String m5) {
054        if (m1 != null) {
055            raiseException(m1, m2, m3, m4, m5);
056        }
057        return m1 + m2 + m3 + m4 + m5;
058    }
059
060    @Test
061    public void test2() {
062        test("test2Snippet");
063    }
064
065    public String test2Snippet() throws Exception {
066        try {
067            ClassLoader testCl = new MyClassLoader();
068            @SuppressWarnings("unchecked")
069            Class<Runnable> c = (Class<Runnable>) testCl.loadClass(name);
070            Runnable r = c.newInstance();
071            ct = Long.MAX_VALUE;
072            // warmup
073            for (int i = 0; i < 100; i++) {
074                r.run();
075            }
076            // compile
077            ResolvedJavaMethod method = getResolvedJavaMethod(c, "run");
078            getCode(method);
079            ct = 0;
080            r.run();
081        } catch (Throwable e) {
082            e.printStackTrace(System.out);
083            Assert.fail();
084        }
085        return "SUCCESS";
086    }
087
088    public static class MyClassLoader extends ClassLoader {
089        @Override
090        protected Class<?> findClass(String className) throws ClassNotFoundException {
091            return defineClass(name.replace('/', '.'), clazz, 0, clazz.length);
092        }
093    }
094
095    public static void methodB() {
096        Random r = new Random(System.currentTimeMillis());
097        while (r.nextFloat() > .03f) {
098            // Empty
099        }
100
101        return;
102    }
103
104    public static void methodA() {
105        Random r = new Random(System.currentTimeMillis());
106        while (r.nextDouble() > .05) {
107            // Empty
108        }
109        return;
110    }
111
112    private static Object m = new Object();
113    static long ct = Long.MAX_VALUE;
114
115    public static Object getM() {
116        if (ct-- > 0) {
117            return m;
118        } else {
119            return null;
120        }
121    }
122
123    private static String name = "t/TestJSR";
124    //@formatter:off
125    /*
126        // Code generated the class below using asm.
127        String clazzName = "com.oracle.graal.replacements.test.DeoptimizeOnExceptionTest".replace('.', '/');
128        final ClassWriter w = new ClassWriter(0);
129        w.visit(V1_5, ACC_PUBLIC,
130                "t/TestJSR", null, "java/lang/Object",
131                new String[] { "java/lang/Runnable" });
132        MethodVisitor mv = w.visitMethod(ACC_PUBLIC, "<init>", "()V", null, new String[] { });
133        mv.visitCode();
134        mv.visitVarInsn(ALOAD, 0);
135        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
136        mv.visitInsn(RETURN);
137        mv.visitMaxs(10, 10);
138        mv.visitEnd();
139
140        mv = w.visitMethod(ACC_PUBLIC, "run", "()V", null, null);
141        mv.visitCode();
142        mv.visitMethodInsn(INVOKESTATIC, clazzName, "getM", "()Ljava/lang/Object;", false);
143        Label l1 = new Label();
144        mv.visitJumpInsn(JSR, l1);
145        mv.visitInsn(RETURN);
146
147        mv.visitLabel(l1);
148        mv.visitVarInsn(ASTORE, 1);
149
150        Label lElse = new Label();
151        Label lEnd = new Label();
152        mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false);
153        mv.visitInsn(POP2);
154        mv.visitMethodInsn(INVOKESTATIC, clazzName, "getM", "()Ljava/lang/Object;", false);
155        mv.visitInsn(DUP);
156        mv.visitJumpInsn(IFNULL, lElse);
157        mv.visitMethodInsn(INVOKESTATIC, clazzName, "methodA", "()V", false);
158        mv.visitJumpInsn(GOTO, lEnd);
159        mv.visitLabel(lElse);
160        mv.visitMethodInsn(INVOKESTATIC, clazzName, "methodB", "()V", false);
161        mv.visitLabel(lEnd);
162
163        mv.visitVarInsn(RET, 1);
164        mv.visitMaxs(10, 10);
165        mv.visitEnd();
166     */
167    //@formatter:on
168    private static byte[] clazz = new byte[]{-54, -2, -70, -66, 0, 0, 0, 49, 0, 25, 1, 0, 9, 116, 47, 84, 101, 115, 116, 74, 83, 82, 7, 0, 1, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47,
169                    79, 98, 106, 101, 99, 116, 7, 0, 3, 1, 0, 18, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 82, 117, 110, 110, 97, 98, 108, 101, 7, 0, 5, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0,
170                    3, 40, 41, 86, 12, 0, 7, 0, 8, 10, 0, 4, 0, 9, 1, 0, 3, 114, 117, 110, 1, 0, 60, 99, 111, 109, 47, 111, 114, 97, 99, 108, 101, 47, 103, 114, 97, 97, 108, 47, 114, 101, 112, 108,
171                    97, 99, 101, 109, 101, 110, 116, 115, 47, 116, 101, 115, 116, 47, 68, 101, 111, 112, 116, 105, 109, 105, 122, 101, 79, 110, 69, 120, 99, 101, 112, 116, 105, 111, 110, 84, 101,
172                    115, 116, 7, 0, 12, 1, 0, 4, 103, 101, 116, 77, 1, 0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 12, 0, 14, 0, 15, 10, 0, 13, 0,
173                    16, 1, 0, 7, 109, 101, 116, 104, 111, 100, 65, 12, 0, 18, 0, 8, 10, 0, 13, 0, 19, 1, 0, 7, 109, 101, 116, 104, 111, 100, 66, 12, 0, 21, 0, 8, 10, 0, 13, 0, 22, 1, 0, 4, 67, 111,
174                    100, 101, 0, 1, 0, 2, 0, 4, 0, 1, 0, 6, 0, 0, 0, 2, 0, 1, 0, 7, 0, 8, 0, 1, 0, 24, 0, 0, 0, 17, 0, 10, 0, 10, 0, 0, 0, 5, 42, -73, 0, 10, -79, 0, 0, 0, 0, 0, 1, 0, 11, 0, 8, 0, 1,
175                    0, 24, 0, 0, 0, 38, 0, 10, 0, 10, 0, 0, 0, 26, -72, 0, 17, -88, 0, 4, -79, 76, -72, 0, 17, 89, -58, 0, 9, -72, 0, 20, -89, 0, 6, -72, 0, 23, -87, 1, 0, 0, 0, 0, 0, 0};
176
177}