changeset 11282:12661a449226

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 10 Aug 2013 10:08:56 +0200
parents af358daf4f41 (current diff) 6d28ce8cdeb7 (diff)
children 1cd1f8ff70a1
files
diffstat 13 files changed, 198 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java	Sat Aug 10 10:08:56 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.amd64;
 
-import static com.oracle.graal.amd64.AMD64.*;
+import java.util.*;
 
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
@@ -35,6 +35,8 @@
  */
 public class AMD64HotSpotGraalRuntime extends HotSpotGraalRuntime {
 
+    private Value[] nativeABICallerSaveRegisters;
+
     protected AMD64HotSpotGraalRuntime() {
     }
 
@@ -76,7 +78,62 @@
     }
 
     @Override
-    protected Value[] getRuntimeCallVolatileRegisters() {
-        return new Value[]{r10.asValue(), r11.asValue()};
+    protected Value[] getNativeABICallerSaveRegisters() {
+        if (nativeABICallerSaveRegisters == null) {
+            List<Register> callerSave = new ArrayList<>(Arrays.asList(getRuntime().lookupRegisterConfig().getAllocatableRegisters()));
+            if (getConfig().windowsOs) {
+                // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
+                callerSave.remove(AMD64.rdi);
+                callerSave.remove(AMD64.rsi);
+                callerSave.remove(AMD64.rbx);
+                callerSave.remove(AMD64.rbp);
+                callerSave.remove(AMD64.rsp);
+                callerSave.remove(AMD64.r12);
+                callerSave.remove(AMD64.r13);
+                callerSave.remove(AMD64.r14);
+                callerSave.remove(AMD64.r15);
+                callerSave.remove(AMD64.xmm6);
+                callerSave.remove(AMD64.xmm7);
+                callerSave.remove(AMD64.xmm8);
+                callerSave.remove(AMD64.xmm9);
+                callerSave.remove(AMD64.xmm10);
+                callerSave.remove(AMD64.xmm11);
+                callerSave.remove(AMD64.xmm12);
+                callerSave.remove(AMD64.xmm13);
+                callerSave.remove(AMD64.xmm14);
+                callerSave.remove(AMD64.xmm15);
+            } else {
+                /*
+                 * System V Application Binary Interface, AMD64 Architecture Processor Supplement
+                 * 
+                 * Draft Version 0.96
+                 * 
+                 * http://www.uclibc.org/docs/psABI-x86_64.pdf
+                 * 
+                 * 3.2.1
+                 * 
+                 * ...
+                 * 
+                 * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12
+                 * through %r15 "belong" to the calling function and the called function is required
+                 * to preserve their values. In other words, a called function must preserve these
+                 * registers' values for its caller. Remaining registers "belong" to the called
+                 * function. If a calling function wants to preserve such a register value across a
+                 * function call, it must save the value in its local stack frame.
+                 */
+                callerSave.remove(AMD64.rbp);
+                callerSave.remove(AMD64.rbx);
+                callerSave.remove(AMD64.r12);
+                callerSave.remove(AMD64.r13);
+                callerSave.remove(AMD64.r14);
+                callerSave.remove(AMD64.r15);
+            }
+            nativeABICallerSaveRegisters = new Value[callerSave.size()];
+            for (int i = 0; i < callerSave.size(); i++) {
+                nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue();
+            }
+        }
+
+        return nativeABICallerSaveRegisters;
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java	Sat Aug 10 10:08:56 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.sparc.*;
@@ -69,8 +70,7 @@
     }
 
     @Override
-    protected Value[] getRuntimeCallVolatileRegisters() {
-        // TODO: is this correct?
-        return new Value[0];
+    protected Value[] getNativeABICallerSaveRegisters() {
+        throw GraalInternalError.unimplemented();
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Sat Aug 10 10:08:56 2013 +0200
@@ -126,7 +126,7 @@
         CallingConvention incomingCc = incomingCcType == null ? null : createCallingConvention(descriptor, incomingCcType);
         HotSpotForeignCallLinkage linkage = new HotSpotForeignCallLinkage(descriptor, address, effect, transition, outgoingCc, incomingCc, reexecutable, killedLocations);
         if (outgoingCcType == Type.NativeCall) {
-            linkage.temporaries = graalRuntime().getRuntimeCallVolatileRegisters();
+            linkage.temporaries = graalRuntime().getNativeABICallerSaveRegisters();
         }
         return linkage;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Sat Aug 10 10:08:56 2013 +0200
@@ -32,7 +32,6 @@
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.logging.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -255,11 +254,9 @@
     protected abstract HotSpotRuntime createRuntime();
 
     /**
-     * Gets the registers that are treated volatile by foreign calls into the runtime. These
-     * registers must be spilled across all native foreign runtime calls, even for calls that are
-     * declared as {@link RegisterEffect#PRESERVES_REGISTERS register preserving}.
+     * Gets the registers that must be saved across a foreign call into the runtime.
      */
-    protected abstract Value[] getRuntimeCallVolatileRegisters();
+    protected abstract Value[] getNativeABICallerSaveRegisters();
 
     public HotSpotVMConfig getConfig() {
         return config;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java	Sat Aug 10 10:08:56 2013 +0200
@@ -56,6 +56,6 @@
 
     @NodeIntrinsic
     public static Word get() {
-        return Word.box(unsafeReadWord(Thread.currentThread(), eetopOffset()));
+        return Word.unsigned(unsafeReadWord(Thread.currentThread(), eetopOffset()));
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Sat Aug 10 10:08:56 2013 +0200
@@ -490,16 +490,13 @@
     @SuppressWarnings("unused")
     @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
     private static Word loadWordFromObjectIntrinsic(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind) {
-        return Word.box(unsafeReadWord(object, offset + displacement));
+        return Word.unsigned(unsafeReadWord(object, offset + displacement));
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
     static Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word, GuardingNode anchor) {
-        if (wordKind() == Kind.Int) {
-            return Word.box((int) unsafeReadKlassPointer(object));
-        }
-        return Word.box(unsafeReadKlassPointer(object));
+        return Word.unsigned(unsafeReadKlassPointer(object));
     }
 
     @Fold
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Sat Aug 10 10:08:56 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.nodes.PatchReturnAddressNode.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.hotspot.stubs.StubUtil.*;
@@ -99,9 +98,13 @@
             if (currentException != null) {
                 fatal("exception object in thread must be null, not %p", Word.fromObject(currentException).rawValue());
             }
-            Word currentExceptionPc = readExceptionPc(thread());
-            if (currentExceptionPc.notEqual(Word.zero())) {
-                fatal("exception PC in thread must be zero, not %p", currentExceptionPc.rawValue());
+            if (cAssertionsEnabled()) {
+                // This thread-local is only cleared in DEBUG builds of the VM
+                // (see OptoRuntime::generate_exception_blob)
+                Word currentExceptionPc = readExceptionPc(thread());
+                if (currentExceptionPc.notEqual(Word.zero())) {
+                    fatal("exception PC in thread must be zero, not %p", currentExceptionPc.rawValue());
+                }
             }
         }
     }
@@ -117,12 +120,19 @@
         return Boolean.getBoolean("graal.logExceptionHandlerStub");
     }
 
+    /**
+     * Determines if either Java assertions are enabled for {@link ExceptionHandlerStub} or if this
+     * is a HotSpot build where the ASSERT mechanism is enabled.
+     * <p>
+     * This first check relies on the per-class assertion status which is why this method must be in
+     * this class.
+     */
     @Fold
     @SuppressWarnings("all")
     private static boolean assertionsEnabled() {
         boolean enabled = false;
         assert enabled = true;
-        return enabled || graalRuntime().getConfig().cAssertions;
+        return enabled || cAssertionsEnabled();
     }
 
     public static final ForeignCallDescriptor EXCEPTION_HANDLER_FOR_PC = descriptorFor(ExceptionHandlerStub.class, "exceptionHandlerForPc");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Sat Aug 10 10:08:56 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.code.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.nodes.CStringNode.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.word.Word.*;
@@ -80,6 +81,14 @@
         }
     }
 
+    /**
+     * Determines if this is a HotSpot build where the ASSERT mechanism is enabled.
+     */
+    @Fold
+    public static boolean cAssertionsEnabled() {
+        return graalRuntime().getConfig().cAssertions;
+    }
+
     @NodeIntrinsic(StubForeignCallNode.class)
     private static native void vmMessageC(@ConstantNodeParameter ForeignCallDescriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Sat Aug 10 10:08:56 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.nodes.JumpToExceptionHandlerInCallerNode.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*;
@@ -89,12 +88,19 @@
         return Boolean.getBoolean("graal.logUnwindExceptionToCallerStub");
     }
 
+    /**
+     * Determines if either Java assertions are enabled for {@link UnwindExceptionToCallerStub} or
+     * if this is a HotSpot build where the ASSERT mechanism is enabled.
+     * <p>
+     * This first check relies on the per-class assertion status which is why this method must be in
+     * this class.
+     */
     @Fold
     @SuppressWarnings("all")
     private static boolean assertionsEnabled() {
         boolean enabled = false;
         assert enabled = true;
-        return enabled || graalRuntime().getConfig().cAssertions;
+        return enabled || cAssertionsEnabled();
     }
 
     public static final ForeignCallDescriptor EXCEPTION_HANDLER_FOR_RETURN_ADDRESS = descriptorFor(UnwindExceptionToCallerStub.class, "exceptionHandlerForReturnAddress");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/Logic0.java	Sat Aug 10 10:08:56 2013 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011, 2012, 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.jtt.optimize;
+
+import com.oracle.graal.jtt.*;
+import org.junit.*;
+
+/*
+ */
+public class Logic0 extends JTTTest {
+
+    public static int test(int a, int b) {
+        if (((a != 0 ? 1 : 0) & (a != b ? 1 : 0)) != 0) {
+            return 42;
+        }
+        return 11;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest("test", 0, 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest("test", 0, 33);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        runTest("test", 33, 66);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", 33, 67);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        runTest("test", 33, 33);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        runTest("test", 0, 32);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        runTest("test", 32, 66);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        runTest("test", 32, 67);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        runTest("test", 32, 32);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Sat Aug 10 10:08:56 2013 +0200
@@ -28,6 +28,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 /**
  * The {@code ConditionalNode} class represents a comparison that yields one of two values. Note
@@ -65,9 +66,12 @@
         // this optimizes the case where a value that can only be 0 or 1 is materialized to 0 or 1
         if (x().isConstant() && y().isConstant() && condition instanceof IntegerEqualsNode) {
             IntegerEqualsNode equals = (IntegerEqualsNode) condition;
-            if (equals.y().isConstant() && equals.y().asConstant().equals(Constant.INT_0)) {
-                if (x().asConstant().equals(Constant.INT_0) && y().asConstant().equals(Constant.INT_1)) {
-                    return equals.x();
+            if (equals.y().isConstant() && equals.y().asConstant().equals(Constant.INT_0) && equals.x().stamp() instanceof IntegerStamp) {
+                IntegerStamp equalsXStamp = (IntegerStamp) equals.x().stamp();
+                if (equalsXStamp.mask() == 1) {
+                    if (x().asConstant().equals(Constant.INT_0) && y().asConstant().equals(Constant.INT_1)) {
+                        return equals.x();
+                    }
                 }
             }
         }
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Fri Aug 09 14:07:20 2013 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Sat Aug 10 10:08:56 2013 +0200
@@ -73,7 +73,11 @@
     }
      // @formatter:on
 
-    public static Word box(long val) {
+    /*
+     * Outside users should use the different signed() and unsigned() methods to ensure proper
+     * expansion of 32-bit values on 64-bit systems.
+     */
+    private static Word box(long val) {
         return HostedWord.boxLong(val);
     }
 
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri Aug 09 14:07:20 2013 +0200
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Sat Aug 10 10:08:56 2013 +0200
@@ -3647,8 +3647,8 @@
     const Register crc   = c_rarg0;  // crc
     const Register buf   = c_rarg1;  // source java byte array address
     const Register len   = c_rarg2;  // length
-    const Register table = rscratch1;// crc_table address
-    const Register tmp   = rscratch2;
+    const Register table = c_rarg3;  // crc_table address (reuse register)
+    const Register tmp   = r11;
     assert_different_registers(crc, buf, len, table, tmp, rax);
 
     BLOCK_COMMENT("Entry:");