1 /* 2 * Copyright (c) 2013, 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.hotspot.amd64.test; 24 25 import static jdk.vm.ci.amd64.AMD64.rax; 26 27 import java.util.Arrays; 28 29 import org.junit.Assert; 30 import org.junit.Ignore; 31 import org.junit.Test; 32 33 import org.graalvm.compiler.asm.amd64.AMD64Assembler; 34 import org.graalvm.compiler.core.test.GraalCompilerTest; 35 36 import jdk.vm.ci.code.InstalledCode; 37 import jdk.vm.ci.code.Register; 38 import jdk.vm.ci.code.RegisterArray; 39 import jdk.vm.ci.code.TargetDescription; 40 import jdk.vm.ci.hotspot.HotSpotCallingConventionType; 41 import jdk.vm.ci.meta.JavaKind; 42 import jdk.vm.ci.meta.ResolvedJavaMethod; 43 44 /** 45 * Ensures that frame omission works in cases where it is expected to. 46 */ 47 public class AMD64HotSpotFrameOmissionTest extends GraalCompilerTest { 48 49 interface CodeGenerator { 50 51 void generateCode(AMD64Assembler asm); 52 } 53 54 public static void test1snippet() { 55 return; 56 } 57 58 @Ignore 59 @Test 60 public void test1() { 61 testHelper("test1snippet", new CodeGenerator() { 62 63 @Override 64 public void generateCode(AMD64Assembler asm) { 65 asm.nop(5); // padding for mt-safe patching 66 asm.ret(0); 67 } 68 }); 69 } 70 71 public static int test2snippet(int x) { 72 return x + 5; 73 } 74 75 @Ignore 76 @Test 77 public void test2() { 78 testHelper("test2snippet", new CodeGenerator() { 79 80 @Override 81 public void generateCode(AMD64Assembler asm) { 82 Register arg = getArgumentRegister(0, JavaKind.Int); 83 asm.nop(5); // padding for mt-safe patching 84 asm.addl(arg, 5); 85 asm.movl(rax, arg); 86 asm.ret(0); 87 } 88 }); 89 } 90 91 public static long test3snippet(long x) { 92 return 1 + x; 93 } 94 95 @Ignore 96 @Test 97 public void test3() { 98 testHelper("test3snippet", new CodeGenerator() { 99 100 @Override 101 public void generateCode(AMD64Assembler asm) { 102 Register arg = getArgumentRegister(0, JavaKind.Long); 103 asm.nop(5); // padding for mt-safe patching 104 asm.addq(arg, 1); 105 asm.movq(rax, arg); 106 asm.ret(0); 107 } 108 }); 109 } 110 111 private void testHelper(String name, CodeGenerator gen) { 112 ResolvedJavaMethod javaMethod = getResolvedJavaMethod(name); 113 InstalledCode installedCode = getCode(javaMethod); 114 115 TargetDescription target = getCodeCache().getTarget(); 116 AMD64Assembler asm = new AMD64Assembler(target); 117 118 gen.generateCode(asm); 119 byte[] expectedCode = asm.close(true); 120 121 // Only compare up to expectedCode.length bytes to ignore 122 // padding instructions adding during code installation 123 byte[] actualCode = Arrays.copyOf(installedCode.getCode(), expectedCode.length); 124 125 Assert.assertArrayEquals(expectedCode, actualCode); 126 } 127 128 private Register getArgumentRegister(int index, JavaKind kind) { 129 RegisterArray regs = getCodeCache().getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCall, kind); 130 return regs.get(index); 131 } 132 }