# HG changeset patch # User Thomas Wuerthinger # Date 1376122136 -7200 # Node ID 12661a4492266e8855a6fd43294a5fe9666c6e9e # Parent af358daf4f41dcad808967ae2a1f397665011685# Parent 6d28ce8cdeb7ff7597e184db37ee8f8527bd9d10 Merge. diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java --- 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 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; } } diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java --- 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(); } } diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java --- 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; } diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- 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; diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java --- 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())); } } diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- 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 diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java --- 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. + *

+ * 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"); diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java --- 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); diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java --- 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. + *

+ * 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"); diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/Logic0.java --- /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); + } +} diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java --- 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(); + } } } } diff -r af358daf4f41 -r 12661a449226 graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java --- 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); } diff -r af358daf4f41 -r 12661a449226 src/cpu/x86/vm/stubGenerator_x86_64.cpp --- 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:");