changeset 20092:5ba6a770b0c6

Merge.
author Doug Simon <doug.simon@oracle.com>
date Mon, 30 Mar 2015 17:58:22 +0200
parents 1bc27c390bce (current diff) e4bb07ed276c (diff)
children bba03da2b86b
files
diffstat 5 files changed, 299 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/IncrementDecrementMacroTest.java	Mon Mar 30 17:58:22 2015 +0200
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.asm.amd64.test;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
+import static org.junit.Assume.*;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.asm.test.*;
+
+public class IncrementDecrementMacroTest extends AssemblerTest {
+
+    @Before
+    public void checkAMD64() {
+        assumeTrue("skipping AMD64 specific test", codeCache.getTarget().arch instanceof AMD64);
+    }
+
+    public static class LongField {
+        public long x;
+
+        LongField(long x) {
+            this.x = x;
+        }
+    }
+
+    private static class IncrementCodeGenTest implements CodeGenTest {
+        final int value;
+
+        public IncrementCodeGenTest(int value) {
+            this.value = value;
+        }
+
+        @Override
+        public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
+            AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig);
+            Register ret = registerConfig.getReturnRegister(Kind.Int);
+            try {
+                Field f = LongField.class.getDeclaredField("x");
+                AMD64Address arg = new AMD64Address(asRegister(cc.getArgument(0)), (int) unsafe.objectFieldOffset(f));
+                asm.incrementq(arg, value);
+                asm.movq(ret, arg);
+                asm.ret(0);
+                return asm.close(true);
+            } catch (Exception e) {
+                throw new RuntimeException("exception while trying to generate field access:", e);
+            }
+        }
+    }
+
+    private void assertIncrement(long initValue, int increment) {
+        assertReturn("longFieldStubIncrement", new IncrementCodeGenTest(increment), initValue + increment, new LongField(initValue));
+    }
+
+    private void assertIncrements(int increment) {
+        assertIncrement(0x4242_4242_4242_4242L, increment);
+    }
+
+    @SuppressWarnings("unused")
+    public static long longFieldStubIncrement(LongField arg) {
+        return 0;
+    }
+
+    private static class DecrementCodeGenTest implements CodeGenTest {
+        final int value;
+
+        public DecrementCodeGenTest(int value) {
+            this.value = value;
+        }
+
+        @Override
+        public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
+            AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig);
+            Register ret = registerConfig.getReturnRegister(Kind.Int);
+            try {
+                Field f = LongField.class.getDeclaredField("x");
+                AMD64Address arg = new AMD64Address(asRegister(cc.getArgument(0)), (int) unsafe.objectFieldOffset(f));
+                asm.decrementq(arg, value);
+                asm.movq(ret, arg);
+                asm.ret(0);
+                return asm.close(true);
+            } catch (Exception e) {
+                throw new RuntimeException("exception while trying to generate field access:", e);
+            }
+        }
+    }
+
+    private void assertDecrement(long initValue, int increment) {
+        assertReturn("longFieldStubDecrement", new DecrementCodeGenTest(increment), initValue - increment, new LongField(initValue));
+    }
+
+    private void assertDecrements(int increment) {
+        assertDecrement(0x4242_4242_4242_4242L, increment);
+    }
+
+    @SuppressWarnings("unused")
+    public static long longFieldStubDecrement(LongField arg) {
+        return 0;
+    }
+
+    @Test
+    public void incrementMemTest0() {
+        int increment = 0;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest1() {
+        int increment = 1;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest2() {
+        int increment = 2;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest3() {
+        int increment = Integer.MAX_VALUE;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest4() {
+        int increment = Integer.MIN_VALUE;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest5() {
+        int increment = -1;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest6() {
+        int increment = -2;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest7() {
+        int increment = -0x1000_0000;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void decrementMemTest0() {
+        int decrement = 0;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest1() {
+        int decrement = 1;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest2() {
+        int decrement = 2;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest3() {
+        int decrement = Integer.MAX_VALUE;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest4() {
+        int decrement = Integer.MIN_VALUE;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest5() {
+        int decrement = -1;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest6() {
+        int decrement = -2;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest7() {
+        int decrement = -0x1000_0000;
+        assertDecrements(decrement);
+    }
+
+}
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Mon Mar 30 17:51:05 2015 +0200
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Mon Mar 30 17:58:22 2015 +0200
@@ -27,6 +27,7 @@
 import static com.oracle.graal.asm.NumUtil.*;
 import static com.oracle.graal.asm.amd64.AMD64AsmOptions.*;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.*;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.*;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*;
 
 import com.oracle.graal.amd64.*;
@@ -729,6 +730,7 @@
         public static final AMD64MOp DIV  = new AMD64MOp("DIV",  0xF7, 6);
         public static final AMD64MOp IDIV = new AMD64MOp("IDIV", 0xF7, 7);
         public static final AMD64MOp INC  = new AMD64MOp("INC",  0xFF, 0);
+        public static final AMD64MOp DEC  = new AMD64MOp("DEC",  0xFF, 1);
         // @formatter:on
 
         private final int ext;
@@ -1961,6 +1963,10 @@
         ADD.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32);
     }
 
+    public final void addq(AMD64Address dst, int imm32) {
+        ADD.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32);
+    }
+
     public final void addq(Register dst, Register src) {
         ADD.rmOp.emit(this, QWORD, dst, src);
     }
@@ -2024,6 +2030,10 @@
         emitByte(0xC8 | encode);
     }
 
+    public final void decq(AMD64Address dst) {
+        DEC.emit(this, QWORD, dst);
+    }
+
     public final void incq(Register dst) {
         // Don't use it directly. Use Macroincrementq() instead.
         // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
@@ -2032,6 +2042,10 @@
         emitByte(0xC0 | encode);
     }
 
+    public final void incq(AMD64Address dst) {
+        INC.emit(this, QWORD, dst);
+    }
+
     public final void movq(Register dst, long imm64) {
         int encode = prefixqAndEncode(dst.encoding);
         emitByte(0xB8 | encode);
@@ -2130,6 +2144,10 @@
         SUB.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32);
     }
 
+    public final void subq(AMD64Address dst, int imm32) {
+        SUB.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32);
+    }
+
     public final void subqWide(Register dst, int imm32) {
         // don't use the sign-extending version, forcing a 32-bit immediate
         SUB.getMIOpcode(QWORD, false).emit(this, QWORD, dst, imm32);
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Mon Mar 30 17:51:05 2015 +0200
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Mon Mar 30 17:58:22 2015 +0200
@@ -56,6 +56,25 @@
         }
     }
 
+    public final void decrementq(AMD64Address dst, int value) {
+        if (value == Integer.MIN_VALUE) {
+            subq(dst, value);
+            return;
+        }
+        if (value < 0) {
+            incrementq(dst, -value);
+            return;
+        }
+        if (value == 0) {
+            return;
+        }
+        if (value == 1 && UseIncDec) {
+            decq(dst);
+        } else {
+            subq(dst, value);
+        }
+    }
+
     public void incrementq(Register reg, int value) {
         if (value == Integer.MIN_VALUE) {
             addq(reg, value);
@@ -75,6 +94,25 @@
         }
     }
 
+    public final void incrementq(AMD64Address dst, int value) {
+        if (value == Integer.MIN_VALUE) {
+            addq(dst, value);
+            return;
+        }
+        if (value < 0) {
+            decrementq(dst, -value);
+            return;
+        }
+        if (value == 0) {
+            return;
+        }
+        if (value == 1 && UseIncDec) {
+            incq(dst);
+        } else {
+            addq(dst, value);
+        }
+    }
+
     public final void movptr(Register dst, AMD64Address src) {
         movq(dst, src);
     }
--- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Mon Mar 30 17:51:05 2015 +0200
+++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Mon Mar 30 17:58:22 2015 +0200
@@ -29,6 +29,8 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.runtime.*;
 import com.oracle.graal.test.*;
@@ -54,21 +56,25 @@
 
     protected InstalledCode assembleMethod(Method m, CodeGenTest test) {
         ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(m);
-        RegisterConfig registerConfig = codeCache.getRegisterConfig();
-        CallingConvention cc = CodeUtil.getCallingConvention(codeCache, CallingConvention.Type.JavaCallee, method, false);
+        try (Scope s = Debug.scope("assembleMethod", method, codeCache)) {
+            RegisterConfig registerConfig = codeCache.getRegisterConfig();
+            CallingConvention cc = CodeUtil.getCallingConvention(codeCache, CallingConvention.Type.JavaCallee, method, false);
 
-        CompilationResult compResult = new CompilationResult();
-        byte[] targetCode = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc);
-        compResult.setTargetCode(targetCode, targetCode.length);
+            CompilationResult compResult = new CompilationResult();
+            byte[] targetCode = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc);
+            compResult.setTargetCode(targetCode, targetCode.length);
+
+            InstalledCode code = codeCache.addMethod(method, compResult, null, null);
 
-        InstalledCode code = codeCache.addMethod(method, compResult, null, null);
-
-        DisassemblerProvider dis = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getDisassembler();
-        if (dis != null) {
-            String disasm = dis.disassemble(code);
-            Assert.assertTrue(code.toString(), disasm == null || disasm.length() > 0);
+            DisassemblerProvider dis = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getDisassembler();
+            if (dis != null) {
+                String disasm = dis.disassemble(code);
+                Assert.assertTrue(code.toString(), disasm == null || disasm.length() > 0);
+            }
+            return code;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
         }
-        return code;
     }
 
     protected Object runTest(String methodName, CodeGenTest test, Object... args) {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java	Mon Mar 30 17:51:05 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java	Mon Mar 30 17:58:22 2015 +0200
@@ -24,10 +24,6 @@
 
 import static com.oracle.graal.amd64.AMD64.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.asm.NumUtil.*;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.*;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.*;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*;
 import static com.oracle.graal.compiler.common.GraalInternalError.*;
 
 import com.oracle.graal.api.code.*;
@@ -107,11 +103,7 @@
         // increment counter (in memory)
         if (isConstant(incrementValue)) {
             int increment = asInt(asConstant(incrementValue));
-            if (increment == 1) {
-                INC.emit(masm, QWORD, counterAddr);
-            } else {
-                ADD.getMIOpcode(QWORD, isByte(increment)).emit(masm, QWORD, counterAddr, increment);
-            }
+            masm.incrementq(counterAddr, increment);
         } else {
             masm.addq(counterAddr, asRegister(incrementValue));
         }