1 /* 2 * Copyright (c) 2015, 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 package org.graalvm.compiler.jtt.backend; 24 25 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; 26 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER; 27 import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD; 28 import static jdk.internal.org.objectweb.asm.Opcodes.IFNE; 29 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL; 30 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC; 31 import static jdk.internal.org.objectweb.asm.Opcodes.LADD; 32 import static jdk.internal.org.objectweb.asm.Opcodes.LCMP; 33 import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_0; 34 import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD; 35 import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN; 36 import static jdk.internal.org.objectweb.asm.Opcodes.RETURN; 37 38 import org.junit.BeforeClass; 39 import org.junit.Test; 40 41 import org.graalvm.compiler.api.directives.GraalDirectives; 42 import org.graalvm.compiler.core.common.GraalOptions; 43 import org.graalvm.compiler.jtt.JTTTest; 44 import org.graalvm.compiler.options.OptionValue; 45 import org.graalvm.compiler.options.OptionValue.OverrideScope; 46 import org.graalvm.compiler.test.ExportingClassLoader; 47 48 import jdk.internal.org.objectweb.asm.ClassWriter; 49 import jdk.internal.org.objectweb.asm.Label; 50 import jdk.internal.org.objectweb.asm.MethodVisitor; 51 import jdk.internal.org.objectweb.asm.Opcodes; 52 import jdk.internal.org.objectweb.asm.Type; 53 54 public class LargeConstantSectionTest extends JTTTest { 55 private static final String NAME = "LargeConstantSection"; 56 private static final long LARGE_CONSTANT = 0xF0F0F0F0F0L; 57 private static LargeConstantClassLoader LOADER; 58 59 @BeforeClass 60 public static void before() { 61 LOADER = new LargeConstantClassLoader(LargeConstantSectionTest.class.getClassLoader()); 62 } 63 64 public abstract static class LargeConstantAbstract { 65 public abstract long run(long i); 66 } 67 68 public static long test(LargeConstantAbstract a, long i) throws Exception { 69 return a.run(GraalDirectives.opaque(i)); 70 } 71 72 public static class LargeConstantClassLoader extends ExportingClassLoader { 73 public LargeConstantClassLoader(ClassLoader parent) { 74 super(parent); 75 } 76 77 @Override 78 protected Class<?> findClass(String name) throws ClassNotFoundException { 79 if (name.equals(NAME)) { 80 String graalDirectivesClassName = GraalDirectives.class.getName().replace('.', '/'); 81 int numberIfBlocks = 1100; // Each if block contains three constants 82 ClassWriter cw = new ClassWriter(0); 83 MethodVisitor mv; 84 String abstractClassName = Type.getInternalName(LargeConstantAbstract.class); 85 cw.visit(52, ACC_PUBLIC + ACC_SUPER, NAME, null, abstractClassName, null); 86 87 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 88 mv.visitCode(); 89 Label l0 = new Label(); 90 mv.visitLabel(l0); 91 mv.visitVarInsn(ALOAD, 0); 92 mv.visitMethodInsn(INVOKESPECIAL, abstractClassName, "<init>", "()V", false); 93 mv.visitInsn(RETURN); 94 Label l1 = new Label(); 95 mv.visitLabel(l1); 96 mv.visitMaxs(1, 1); 97 mv.visitEnd(); 98 99 mv = cw.visitMethod(ACC_PUBLIC, "run", "(J)J", null, null); 100 mv.visitCode(); 101 Label nextIf = new Label(); 102 for (int i = 0; i < numberIfBlocks; i++) { 103 mv.visitLabel(nextIf); 104 mv.visitFrame(Opcodes.F_NEW, 2, new Object[]{abstractClassName, Opcodes.LONG}, 0, new Object[]{}); 105 mv.visitVarInsn(LLOAD, 1); 106 mv.visitLdcInsn(new Long(LARGE_CONSTANT + i)); 107 mv.visitInsn(LCMP); 108 nextIf = new Label(); 109 mv.visitJumpInsn(IFNE, nextIf); 110 mv.visitLdcInsn(new Long(LARGE_CONSTANT + i + numberIfBlocks)); 111 mv.visitMethodInsn(INVOKESTATIC, graalDirectivesClassName, "opaque", "(J)J", false); 112 mv.visitLdcInsn(new Long(LARGE_CONSTANT + i + numberIfBlocks * 2)); 113 mv.visitMethodInsn(INVOKESTATIC, graalDirectivesClassName, "opaque", "(J)J", false); 114 mv.visitInsn(LADD); 115 mv.visitInsn(LRETURN); 116 } 117 mv.visitLabel(nextIf); 118 mv.visitFrame(Opcodes.F_NEW, 2, new Object[]{abstractClassName, Opcodes.LONG}, 0, new Object[]{}); 119 mv.visitInsn(LCONST_0); 120 mv.visitInsn(LRETURN); 121 Label l9 = new Label(); 122 mv.visitLabel(l9); 123 mv.visitMaxs(4, 6); 124 mv.visitEnd(); 125 126 cw.visitEnd(); 127 128 byte[] bytes = cw.toByteArray(); 129 return defineClass(name, bytes, 0, bytes.length); 130 } else { 131 return super.findClass(name); 132 } 133 } 134 } 135 136 @Test 137 @SuppressWarnings("try") 138 public void run0() throws Exception { 139 try (OverrideScope os = OptionValue.override(GraalOptions.InlineEverything, true)) { 140 runTest("test", LOADER.findClass(NAME).newInstance(), 0L); 141 } 142 } 143 }