changeset 21142:0b221b4ad707

Merge
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 28 Apr 2015 12:58:40 -0700
parents 2b1228d97525 (current diff) 7a62f41ed610 (diff)
children e13c65f874e5 33ff6b03fad1
files graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagged.java
diffstat 31 files changed, 478 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Apr 28 12:58:40 2015 -0700
@@ -90,6 +90,10 @@
     @Override
     public boolean canInlineConstant(JavaConstant c) {
         switch (c.getKind()) {
+            case Boolean:
+            case Byte:
+            case Char:
+            case Short:
             case Int:
                 return SPARCAssembler.isSimm13(c.asInt()) && !getCodeCache().needsDataPatch(c);
             case Long:
@@ -217,7 +221,7 @@
     @Override
     public void emitCompareBranch(PlatformKind cmpKind, Value x, Value y, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
                     double trueDestinationProbability) {
-        Variable left;
+        Value left;
         Value right;
         Condition actualCondition;
         if (isConstant(x)) {
@@ -230,8 +234,20 @@
             actualCondition = cond;
         }
         SPARCCompare opcode;
-        Kind kind = left.getKind().getStackKind();
-        switch (kind) {
+        Kind actualCmpKind = (Kind) cmpKind;
+        switch (actualCmpKind) {
+            case Byte:
+                left = emitSignExtend(left, 8, 32);
+                right = emitSignExtend(right, 8, 32);
+                actualCmpKind = Kind.Int;
+                opcode = ICMP;
+                break;
+            case Short:
+                left = emitSignExtend(left, 16, 32);
+                right = emitSignExtend(right, 16, 32);
+                actualCmpKind = Kind.Int;
+                opcode = ICMP;
+                break;
             case Object:
                 opcode = ACMP;
                 break;
@@ -239,9 +255,6 @@
                 opcode = LCMP;
                 break;
             case Int:
-            case Short:
-            case Char:
-            case Byte:
                 opcode = ICMP;
                 break;
             case Float:
@@ -251,9 +264,9 @@
                 opcode = DCMP;
                 break;
             default:
-                throw GraalInternalError.shouldNotReachHere(kind.toString());
+                throw GraalInternalError.shouldNotReachHere(actualCmpKind.toString());
         }
-        append(new SPARCControlFlow.CompareBranchOp(opcode, left, right, actualCondition, trueDestination, falseDestination, kind, unorderedIsTrue, trueDestinationProbability));
+        append(new SPARCControlFlow.CompareBranchOp(opcode, left, right, actualCondition, trueDestination, falseDestination, actualCmpKind, unorderedIsTrue, trueDestinationProbability));
     }
 
     @Override
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java	Tue Apr 28 12:58:40 2015 -0700
@@ -34,6 +34,7 @@
         private final InvocationPlugins invocationPlugins;
         private LoadFieldPlugin loadFieldPlugin;
         private LoadIndexedPlugin loadIndexedPlugin;
+        private TypeCheckPlugin typeCheckPlugin;
         private ParameterPlugin parameterPlugin;
         private InlineInvokePlugin inlineInvokePlugin;
         private GenericInvocationPlugin genericInvocationPlugin;
@@ -49,6 +50,7 @@
             this.parameterPlugin = copyFrom.parameterPlugin;
             this.loadFieldPlugin = copyFrom.loadFieldPlugin;
             this.loadIndexedPlugin = copyFrom.loadIndexedPlugin;
+            this.typeCheckPlugin = copyFrom.typeCheckPlugin;
             this.inlineInvokePlugin = copyFrom.inlineInvokePlugin;
             this.loopExplosionPlugin = copyFrom.loopExplosionPlugin;
             this.genericInvocationPlugin = copyFrom.genericInvocationPlugin;
@@ -92,6 +94,14 @@
             this.loadIndexedPlugin = plugin;
         }
 
+        public TypeCheckPlugin getTypeCheckPlugin() {
+            return typeCheckPlugin;
+        }
+
+        public void setTypeCheckPlugin(TypeCheckPlugin typeCheckPlugin) {
+            this.typeCheckPlugin = typeCheckPlugin;
+        }
+
         public ParameterPlugin getParameterPlugin() {
             return parameterPlugin;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/TypeCheckPlugin.java	Tue Apr 28 12:58:40 2015 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 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.graphbuilderconf;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+
+public interface TypeCheckPlugin extends GraphBuilderPlugin {
+    /**
+     * Intercept the parsing of a CHECKCAST bytecode. If the method returns true, it must push
+     * {@link GraphBuilderContext#push push} an object value as the result of the cast.
+     *
+     * @param b The context.
+     * @param object The object to be type checked.
+     * @param type The type that the object is checked against.
+     * @param profile The profiling information for the type check, or null if no profiling
+     *            information is available.
+     * @return True if the plugin handled the cast, false if the bytecode parser should handle the
+     *         cast.
+     */
+    default boolean checkCast(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
+        return false;
+    }
+
+    /**
+     * Intercept the parsing of a INSTANCEOF bytecode. If the method returns true, it must push
+     * {@link GraphBuilderContext#push push} an integer value with the result of the instanceof.
+     *
+     * @param b The context.
+     * @param object The object to be type checked.
+     * @param type The type that the object is checked against.
+     * @param profile The profiling information for the type check, or null if no profiling
+     *            information is available.
+     * @return True if the plugin handled the instanceof, false if the bytecode parser should handle
+     *         the instanceof.
+     */
+    default boolean instanceOf(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
+        return false;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java	Tue Apr 28 12:58:40 2015 -0700
@@ -111,6 +111,11 @@
                     public void write(int b) throws IOException {
                         write(new byte[]{(byte) b}, 0, 1);
                     }
+
+                    @Override
+                    public void flush() throws IOException {
+                        compilerToVM.flushDebugOutput();
+                    }
                 };
                 ps = new PrintStream(ttyOut);
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Apr 28 12:58:40 2015 -0700
@@ -387,4 +387,6 @@
     boolean shouldDebugNonSafepoints();
 
     void writeDebugOutput(byte[] bytes, int offset, int length);
+
+    void flushDebugOutput();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Apr 28 12:58:40 2015 -0700
@@ -206,4 +206,6 @@
     public native boolean shouldDebugNonSafepoints();
 
     public native void writeDebugOutput(byte[] bytes, int offset, int length);
+
+    public native void flushDebugOutput();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Tue Apr 28 12:58:40 2015 -0700
@@ -74,6 +74,7 @@
         plugins.setParameterPlugin(new HotSpotParameterPlugin(wordTypes));
         plugins.setLoadFieldPlugin(new HotSpotLoadFieldPlugin(metaAccess, constantReflection));
         plugins.setLoadIndexedPlugin(new HotSpotLoadIndexedPlugin(wordTypes));
+        plugins.setTypeCheckPlugin(wordOperationPlugin);
         plugins.setInlineInvokePlugin(new DefaultInlineInvokePlugin(replacements));
         plugins.setGenericInvocationPlugin(new DefaultGenericInvocationPlugin(metaAccess, nodeIntrinsification, wordOperationPlugin));
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java	Tue Apr 28 12:58:40 2015 -0700
@@ -22,14 +22,13 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 
 @NodeInfo
-public class G1PostWriteBarrier extends WriteBarrier implements MemoryCheckpoint.Single {
+public class G1PostWriteBarrier extends WriteBarrier {
 
     public static final NodeClass<G1PostWriteBarrier> TYPE = NodeClass.create(G1PostWriteBarrier.class);
     protected final boolean alwaysNull;
@@ -46,8 +45,4 @@
     public boolean alwaysNull() {
         return alwaysNull;
     }
-
-    public LocationIdentity getLocationIdentity() {
-        return LocationIdentity.any();
-    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Tue Apr 28 12:58:40 2015 -0700
@@ -212,13 +212,13 @@
 
             // If the written value is not null continue with the barrier addition.
             if (probability(FREQUENT_PROBABILITY, writtenValue.notEqual(0))) {
-                byte cardByte = cardAddress.readByte(0);
+                byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION);
                 g1EffectiveAfterNullPostWriteBarrierCounter.inc();
 
                 // If the card is already dirty, (hence already enqueued) skip the insertion.
                 if (probability(NOT_FREQUENT_PROBABILITY, cardByte != g1YoungCardValue())) {
-                    MembarNode.memoryBarrier(STORE_LOAD);
-                    byte cardByteReload = cardAddress.readByte(0);
+                    MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION);
+                    byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION);
                     if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue())) {
                         log(trace, "[%d] G1-Post Thread: %p Card: %p \n", gcCycle, thread.rawValue(), Word.unsigned(cardByte).rawValue());
                         cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION);
@@ -298,11 +298,11 @@
 
         while (count-- > 0) {
             Word cardAddress = Word.unsigned((start + cardStart) + count);
-            byte cardByte = cardAddress.readByte(0);
+            byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION);
             // If the card is already dirty, (hence already enqueued) skip the insertion.
             if (probability(NOT_FREQUENT_PROBABILITY, cardByte != g1YoungCardValue())) {
-                MembarNode.memoryBarrier(STORE_LOAD);
-                byte cardByteReload = cardAddress.readByte(0);
+                MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION);
+                byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION);
                 if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue())) {
                     cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION);
                     // If the thread local card queue is full, issue a native call which will
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Tue Apr 28 12:58:40 2015 -0700
@@ -604,9 +604,13 @@
         JavaType type = lookupType(cpi, CHECKCAST);
         ValueNode object = frameState.apop();
         if (type instanceof ResolvedJavaType) {
-            JavaTypeProfile profileForTypeCheck = getProfileForTypeCheck((ResolvedJavaType) type);
-            ValueNode checkCastNode = append(createCheckCast((ResolvedJavaType) type, object, profileForTypeCheck, false));
-            frameState.apush(checkCastNode);
+            ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+            JavaTypeProfile profile = getProfileForTypeCheck(resolvedType);
+            TypeCheckPlugin typeCheckPlugin = this.graphBuilderConfig.getPlugins().getTypeCheckPlugin();
+            if (typeCheckPlugin == null || !typeCheckPlugin.checkCast((GraphBuilderContext) this, object, resolvedType, profile)) {
+                ValueNode checkCastNode = append(createCheckCast(resolvedType, object, profile, false));
+                frameState.apush(checkCastNode);
+            }
         } else {
             handleUnresolvedCheckCast(type, object);
         }
@@ -622,8 +626,12 @@
         ValueNode object = frameState.apop();
         if (type instanceof ResolvedJavaType) {
             ResolvedJavaType resolvedType = (ResolvedJavaType) type;
-            ValueNode instanceOfNode = createInstanceOf((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType));
-            frameState.ipush(append(genConditional(genUnique(instanceOfNode))));
+            JavaTypeProfile profile = getProfileForTypeCheck(resolvedType);
+            TypeCheckPlugin typeCheckPlugin = this.graphBuilderConfig.getPlugins().getTypeCheckPlugin();
+            if (typeCheckPlugin == null || !typeCheckPlugin.instanceOf((GraphBuilderContext) this, object, resolvedType, profile)) {
+                ValueNode instanceOfNode = createInstanceOf(resolvedType, object, profile);
+                frameState.ipush(append(genConditional(genUnique(instanceOfNode))));
+            }
         } else {
             handleUnresolvedInstanceOf(type, object);
         }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_ifeq.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_ifeq.java	Tue Apr 28 12:58:40 2015 -0700
@@ -55,4 +55,101 @@
         runTest("test", 1);
     }
 
+    @Test
+    public void run3() {
+        runTest("testb", 0xff);
+    }
+
+    /**
+     * Tests if the if does work properly on byte stamp.
+     */
+    public static int testb(int b) {
+        byte x = (byte) b;
+        int y = x & 0xff;
+        if (y == 0xff) {
+            // Just do anything else to force jump instead of conditional move
+            y = (int) (System.currentTimeMillis() >> 32);
+        }
+        return y;
+    }
+
+    @Test
+    public void run4() {
+        runTest("tests", 0xffff);
+    }
+
+    /**
+     * Tests if the if does work properly on short stamp.
+     */
+    public static int tests(int b) {
+        short x = (short) b;
+        int y = x & 0xffff;
+        if (y == 0xffff) {
+            // Just do anything else to force jump instead of conditional move
+            y = (int) (System.currentTimeMillis() >> 32);
+        }
+        return y;
+    }
+
+    @Test
+    public void run5() {
+        runTest("testc", 0xffff);
+    }
+
+    /**
+     * Tests if the if does work properly on char stamp (boils down to short, just to cover all the
+     * java types).
+     */
+    public static int testc(int b) {
+        char x = (char) b;
+        int y = x & 0xffff;
+        if (y == 0xffff) {
+            // Just do anything else to force jump instead of conditional move
+            y = (int) (System.currentTimeMillis() >> 32);
+        }
+        return y;
+    }
+
+    // the same with conditional move
+    @Test
+    public void run6() {
+        runTest("testCondb", 0xff);
+    }
+
+    /**
+     * Tests if the if does work properly on byte stamp.
+     */
+    public static boolean testCondb(int b) {
+        byte x = (byte) b;
+        int y = x & 0xff;
+        return y == 0xff;
+    }
+
+    @Test
+    public void run7() {
+        runTest("testConds", 0xffff);
+    }
+
+    /**
+     * Tests if the if does work properly on short stamp.
+     */
+    public static boolean testConds(int b) {
+        short x = (short) b;
+        int y = x & 0xffff;
+        return y == 0xffff;
+    }
+
+    @Test
+    public void run8() {
+        runTest("testCondc", 0xffff);
+    }
+
+    /**
+     * Tests if the if does work properly on char type.
+     */
+    public static boolean testCondc(int b) {
+        char x = (char) b;
+        int y = x & 0xffff;
+        return y == 0xffff;
+    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Tue Apr 28 12:58:40 2015 -0700
@@ -33,6 +33,7 @@
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.sparc.SPARCControlFlow.CompareBranchOp;
 
 public enum SPARCCompare {
     ICMP,
@@ -63,11 +64,11 @@
         @Override
         public void verify() {
             super.verify();
+            assert CompareBranchOp.SUPPORTED_KINDS.contains(x.getKind()) : x.getKind();
+            assert x.getKind().equals(y.getKind()) : x + " " + y;
             // @formatter:off
-            assert  (name().startsWith("I") &&
-                            (!(x.getKind() == Kind.Int) || y.getKind().getStackKind() == Kind.Int) &&
-                            (!(x.getKind() == Kind.Short) || y.getKind().getStackKind() == Kind.Int) &&
-                            (!(x.getKind() == Kind.Byte) || y.getKind().getStackKind() == Kind.Int)) ||
+            assert
+                    (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) ||
                     (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) ||
                     (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) ||
                     (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) ||
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Apr 28 12:58:40 2015 -0700
@@ -31,6 +31,8 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
@@ -75,6 +77,7 @@
 
     public static final class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, SPARCDelayedControlTransfer {
         public static final LIRInstructionClass<CompareBranchOp> TYPE = LIRInstructionClass.create(CompareBranchOp.class);
+        static final EnumSet<Kind> SUPPORTED_KINDS = EnumSet.of(Kind.Long, Kind.Int, Kind.Object, Kind.Float, Kind.Double);
 
         private final SPARCCompare opcode;
         @Use({REG}) protected Value x;
@@ -231,9 +234,6 @@
 
         private static void emitCBCond(SPARCMacroAssembler masm, Value actualX, Value actualY, Label actualTrueTarget, ConditionFlag conditionFlag) {
             switch ((Kind) actualX.getLIRKind().getPlatformKind()) {
-                case Byte:
-                case Char:
-                case Short:
                 case Int:
                     if (isConstant(actualY)) {
                         int constantY = asConstant(actualY).asInt();
@@ -269,9 +269,6 @@
                 return false;
             }
             switch ((Kind) x.getPlatformKind()) {
-                case Byte:
-                case Char:
-                case Short:
                 case Int:
                 case Long:
                 case Object:
@@ -319,6 +316,13 @@
             emitted = false;
             delaySlotPosition = -1;
         }
+
+        @Override
+        public void verify() {
+            super.verify();
+            assert SUPPORTED_KINDS.contains(kind) : kind;
+            assert x.getKind().equals(kind) && y.getKind().equals(kind) : x + " " + y;
+        }
     }
 
     public static final class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp {
@@ -342,6 +346,11 @@
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             emitBranch(crb, masm, kind, conditionFlag, trueDestination, falseDestination, true, trueDestinationProbability);
         }
+
+        @Override
+        public void verify() {
+            assert CompareBranchOp.SUPPORTED_KINDS.contains(kind);
+        }
     }
 
     private static boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind kind, ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination,
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Tue Apr 28 12:58:40 2015 -0700
@@ -37,15 +37,21 @@
 
     public static final NodeClass<MembarNode> TYPE = NodeClass.create(MembarNode.class);
     protected final int barriers;
+    protected final LocationIdentity location;
 
     public MembarNode(int barriers) {
+        this(barriers, LocationIdentity.any());
+    }
+
+    public MembarNode(int barriers, LocationIdentity location) {
         super(TYPE, StampFactory.forVoid());
         this.barriers = barriers;
+        this.location = location;
     }
 
     @Override
     public LocationIdentity getLocationIdentity() {
-        return LocationIdentity.any();
+        return location;
     }
 
     @Override
@@ -55,4 +61,7 @@
 
     @NodeIntrinsic
     public static native void memoryBarrier(@ConstantNodeParameter int barriers);
+
+    @NodeIntrinsic
+    public static native void memoryBarrier(@ConstantNodeParameter int barriers, @ConstantNodeParameter LocationIdentity location);
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Tue Apr 28 12:58:40 2015 -0700
@@ -427,7 +427,7 @@
     }
 
     public static BytecodePosition processSimpleInfopoint(Invoke invoke, SimpleInfopointNode infopointNode, BytecodePosition incomingPos) {
-        BytecodePosition pos = incomingPos != null ? incomingPos : new BytecodePosition(toBytecodePosition(invoke.stateAfter()), invoke.asNode().graph().method(), invoke.bci());
+        BytecodePosition pos = incomingPos != null ? incomingPos : new BytecodePosition(toBytecodePosition(invoke.stateAfter()).getCaller(), invoke.asNode().graph().method(), invoke.bci());
         infopointNode.addCaller(pos);
         return pos;
     }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Tue Apr 28 12:58:40 2015 -0700
@@ -110,6 +110,20 @@
         }
     }
 
+    @Test
+    public void testCast() {
+        test("cast", 1234L);
+    }
+
+    @Snippet
+    public static long cast(long input) {
+        WordBase base = Word.signed(input);
+        Unsigned unsigned = (Unsigned) base;
+        Pointer pointer = (Pointer) unsigned;
+        Word word = (Word) pointer;
+        return word.rawValue();
+    }
+
     @Snippet
     public static long unsignedLong(long word) {
         return Word.unsigned(word).rawValue();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Apr 28 12:58:40 2015 -0700
@@ -52,6 +52,8 @@
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.options.*;
+import com.oracle.graal.options.OptionValue.OverrideScope;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
@@ -446,7 +448,9 @@
      * @param frameStateProcessing controls how {@link FrameState FrameStates} should be handled.
      */
     public StructuredGraph makeGraph(ResolvedJavaMethod method, Object[] args, ResolvedJavaMethod original, FrameStateProcessing frameStateProcessing) {
-        return createGraphMaker(method, original, frameStateProcessing).makeGraph(args);
+        try (OverrideScope s = OptionValue.override(DeoptALot, false)) {
+            return createGraphMaker(method, original, frameStateProcessing).makeGraph(args);
+        }
     }
 
     /**
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java	Tue Apr 28 12:58:40 2015 -0700
@@ -43,9 +43,10 @@
 import com.oracle.graal.word.nodes.*;
 
 /**
- * A {@link GenericInvocationPlugin} for calls to {@linkplain Operation word operations}.
+ * A {@link GenericInvocationPlugin} for calls to {@linkplain Operation word operations}, and a
+ * {@link TypeCheckPlugin} to handle casts between word types.
  */
-public class WordOperationPlugin implements GenericInvocationPlugin {
+public class WordOperationPlugin implements GenericInvocationPlugin, TypeCheckPlugin {
     protected final WordTypes wordTypes;
     protected final Kind wordKind;
     protected final SnippetReflectionProvider snippetReflection;
@@ -71,6 +72,32 @@
         return true;
     }
 
+    @Override
+    public boolean checkCast(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
+        if (!wordTypes.isWord(type)) {
+            if (object.getKind() != Kind.Object) {
+                throw b.bailout("Cannot cast a word value to a non-word type: " + type.toJavaName(true));
+            }
+            return false;
+        }
+
+        if (object.getKind() != wordTypes.getWordKind()) {
+            throw b.bailout("Cannot cast a non-word value to a word type: " + type.toJavaName(true));
+        }
+        b.push(Kind.Object, object);
+        return true;
+    }
+
+    @Override
+    public boolean instanceOf(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
+        if (wordTypes.isWord(type)) {
+            throw b.bailout("Cannot use instanceof for word a type: " + type.toJavaName(true));
+        } else if (object.getKind() != Kind.Object) {
+            throw b.bailout("Cannot use instanceof on a word value: " + type.toJavaName(true));
+        }
+        return false;
+    }
+
     protected void processWordOperation(GraphBuilderContext b, ValueNode[] args, ResolvedJavaMethod wordMethod) throws GraalInternalError {
         Operation operation = wordMethod.getAnnotation(Word.Operation.class);
         Kind returnKind = wordMethod.getSignature().getReturnKind();
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Tue Apr 28 12:58:40 2015 -0700
@@ -89,8 +89,11 @@
                 ReadCacheEntry identifier = new ReadCacheEntry(object, read.location());
                 ValueNode cachedValue = state.getCacheEntry(identifier);
                 if (cachedValue != null && read.stamp().isCompatible(cachedValue.stamp())) {
+                    // Anchor guard if it is not fixed and different from cachedValue's guard
                     if (read.getGuard() != null && !(read.getGuard() instanceof FixedNode)) {
-                        effects.addFixedNodeBefore(new ValueAnchorNode((ValueNode) read.getGuard()), read);
+                        if (!(cachedValue instanceof GuardedNode) || ((GuardedNode) cachedValue).getGuard() != read.getGuard()) {
+                            effects.addFixedNodeBefore(new ValueAnchorNode((ValueNode) read.getGuard()), read);
+                        }
                     }
                     effects.replaceAtUsages(read, cachedValue);
                     addScalarAlias(read, cachedValue);
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java	Tue Apr 28 12:58:40 2015 -0700
@@ -39,7 +39,8 @@
 /**
  * A <em>binding</em> between:
  * <ol>
- * <li>A program location in an executing Truffle AST (defined by a {@link SourceSection}), and</li>
+ * <li>A program location in an executing Truffle AST (corresponding to a {@link SourceSection}),
+ * and</li>
  * <li>A dynamically managed collection of "attached" {@linkplain Instrument Instruments} that
  * receive event notifications on behalf of external clients.</li>
  * </ol>
@@ -97,7 +98,7 @@
  * @see ProbeListener
  * @see SyntaxTag
  */
-public final class Probe implements SyntaxTagged {
+public final class Probe {
 
     private static final List<ASTProber> astProbers = new ArrayList<>();
 
@@ -108,7 +109,17 @@
      */
     private static final List<WeakReference<Probe>> probes = new ArrayList<>();
 
-    @CompilationFinal private static SyntaxTagTrap tagTrap = null;
+    /**
+     * A global trap that triggers notification just before executing any Node that is Probed with a
+     * matching tag.
+     */
+    @CompilationFinal private static SyntaxTagTrap beforeTagTrap = null;
+
+    /**
+     * A global trap that triggers notification just after executing any Node that is Probed with a
+     * matching tag.
+     */
+    @CompilationFinal private static SyntaxTagTrap afterTagTrap = null;
 
     private static final class FindSourceVisitor implements NodeVisitor {
 
@@ -198,24 +209,50 @@
         return taggedProbes;
     }
 
-    // TODO (mlvdv) can this be generalized to permit multiple traps without a performance hit?
+    // TODO (mlvdv) generalize to permit multiple "before traps" without a performance hit?
     /**
-     * Sets the current "tag trap"; there can be no more than one set at a time.
+     * Sets the current "<em>before</em> tag trap"; there can be no more than one in effect.
      * <ul>
-     * <li>A non-null trap sets a callback to be triggered whenever execution reaches a
-     * {@link Probe} (either existing or subsequently created) with the specified tag.</li>
-     * <li>Setting the trap to null clears the existing trap.</li>
-     * <li>Setting a non-null trap when one is already set will clear the previously set trap.</li>
+     * <li>The before-trap triggers a callback just <strong><em>before</em></strong> execution
+     * reaches <strong><em>any</em></strong> {@link Probe} (either existing or subsequently created)
+     * with the specified {@link SyntaxTag}.</li>
+     * <li>Setting the before-trap to {@code null} clears an existing before-trap.</li>
+     * <li>Setting a non{@code -null} before-trap when one is already set clears the previously set
+     * before-trap.</li>
      * </ul>
      *
-     * @param newTagTrap The {@link SyntaxTagTrap} to set.
+     * @param newBeforeTagTrap The new "before" {@link SyntaxTagTrap} to set.
      */
-    public static void setTagTrap(SyntaxTagTrap newTagTrap) {
-        tagTrap = newTagTrap;
+    public static void setBeforeTagTrap(SyntaxTagTrap newBeforeTagTrap) {
+        beforeTagTrap = newBeforeTagTrap;
         for (WeakReference<Probe> ref : probes) {
             final Probe probe = ref.get();
             if (probe != null) {
-                probe.notifyTrapSet();
+                probe.notifyTrapsChanged();
+            }
+        }
+    }
+
+    // TODO (mlvdv) generalize to permit multiple "after traps" without a performance hit?
+    /**
+     * Sets the current "<em>after</em> tag trap"; there can be no more than one in effect.
+     * <ul>
+     * <li>The after-trap triggers a callback just <strong><em>after</em></strong> execution leaves
+     * <strong><em>any</em></strong> {@link Probe} (either existing or subsequently created) with
+     * the specified {@link SyntaxTag}.</li>
+     * <li>Setting the after-trap to {@code null} clears an existing after-trap.</li>
+     * <li>Setting a non{@code -null} after-trap when one is already set clears the previously set
+     * after-trap.</li>
+     * </ul>
+     *
+     * @param newAfterTagTrap The new "after" {@link SyntaxTagTrap} to set.
+     */
+    public static void setAfterTagTrap(SyntaxTagTrap newAfterTagTrap) {
+        afterTagTrap = newAfterTagTrap;
+        for (WeakReference<Probe> ref : probes) {
+            final Probe probe = ref.get();
+            if (probe != null) {
+                probe.notifyTrapsChanged();
             }
         }
     }
@@ -236,8 +273,11 @@
      */
     @CompilationFinal private Assumption probeStateUnchangedAssumption = probeStateUnchangedCyclic.getAssumption();
 
-    // Must invalidate whenever this changes.
-    @CompilationFinal private boolean isTrapActive = false;
+    // Must invalidate whenever changed
+    @CompilationFinal private boolean isBeforeTrapActive = false;
+
+    // Must invalidate whenever changed
+    @CompilationFinal private boolean isAfterTrapActive = false;
 
     /**
      * Intended for use only by {@link ProbeNode}.
@@ -251,11 +291,18 @@
         }
     }
 
+    /**
+     * Is this node tagged as belonging to a particular human-sensible category of language
+     * constructs?
+     */
     public boolean isTaggedAs(SyntaxTag tag) {
         assert tag != null;
         return tags.contains(tag);
     }
 
+    /**
+     * In which user-sensible categories has this node been tagged (<em>empty set</em> if none).
+     */
     public Collection<SyntaxTag> getSyntaxTags() {
         return Collections.unmodifiableCollection(tags);
     }
@@ -271,8 +318,18 @@
             for (ProbeListener listener : probeListeners) {
                 listener.probeTaggedAs(this, tag, tagValue);
             }
-            if (tagTrap != null && tag == tagTrap.getTag()) {
-                this.isTrapActive = true;
+
+            // Update the status of this Probe with respect to global tag traps
+            boolean tagTrapsChanged = false;
+            if (beforeTagTrap != null && tag == beforeTagTrap.getTag()) {
+                this.isBeforeTrapActive = true;
+                tagTrapsChanged = true;
+            }
+            if (afterTagTrap != null && tag == afterTagTrap.getTag()) {
+                this.isAfterTrapActive = true;
+                tagTrapsChanged = true;
+            }
+            if (tagTrapsChanged) {
                 invalidateProbeUnchanged();
             }
         }
@@ -341,11 +398,25 @@
     }
 
     /**
-     * Gets the currently active {@linkplain SyntaxTagTrap tagTrap}; {@code null} if not set.
+     * Gets the currently active <strong><em>before</em></strong> {@linkplain SyntaxTagTrap Tag
+     * Trap} at this Probe. Non{@code -null} if the global
+     * {@linkplain Probe#setBeforeTagTrap(SyntaxTagTrap) Before Tag Trap} is set and if this Probe
+     * holds the {@link SyntaxTag} specified in the trap.
      */
-    SyntaxTagTrap getTrap() {
+    SyntaxTagTrap getBeforeTrap() {
         checkProbeUnchanged();
-        return isTrapActive ? tagTrap : null;
+        return isBeforeTrapActive ? beforeTagTrap : null;
+    }
+
+    /**
+     * Gets the currently active <strong><em>after</em></strong> {@linkplain SyntaxTagTrap Tag Trap}
+     * at this Probe. Non{@code -null} if the global
+     * {@linkplain Probe#setAfterTagTrap(SyntaxTagTrap) After Tag Trap} is set and if this Probe
+     * holds the {@link SyntaxTag} specified in the trap.
+     */
+    SyntaxTagTrap getAfterTrap() {
+        checkProbeUnchanged();
+        return isAfterTrapActive ? afterTagTrap : null;
     }
 
     /**
@@ -366,8 +437,9 @@
         probeStateUnchangedCyclic.invalidate();
     }
 
-    private void notifyTrapSet() {
-        this.isTrapActive = tagTrap != null && this.isTaggedAs(tagTrap.getTag());
+    private void notifyTrapsChanged() {
+        this.isBeforeTrapActive = beforeTagTrap != null && this.isTaggedAs(beforeTagTrap.getTag());
+        this.isAfterTrapActive = afterTagTrap != null && this.isTaggedAs(afterTagTrap.getTag());
         invalidateProbeUnchanged();
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java	Tue Apr 28 12:58:40 2015 -0700
@@ -153,9 +153,9 @@
 
     public void enter(Node node, VirtualFrame vFrame) {
         this.probe.checkProbeUnchanged();
-        final SyntaxTagTrap trap = probe.getTrap();
-        if (trap != null) {
-            trap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        final SyntaxTagTrap beforeTagTrap = probe.getBeforeTrap();
+        if (beforeTagTrap != null) {
+            beforeTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
         }
         if (firstInstrumentNode != null) {
             firstInstrumentNode.enter(node, vFrame);
@@ -167,6 +167,10 @@
         if (firstInstrumentNode != null) {
             firstInstrumentNode.returnVoid(node, vFrame);
         }
+        final SyntaxTagTrap afterTagTrap = probe.getAfterTrap();
+        if (afterTagTrap != null) {
+            afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        }
     }
 
     public void returnValue(Node node, VirtualFrame vFrame, Object result) {
@@ -174,6 +178,10 @@
         if (firstInstrumentNode != null) {
             firstInstrumentNode.returnValue(node, vFrame, result);
         }
+        final SyntaxTagTrap afterTagTrap = probe.getAfterTrap();
+        if (afterTagTrap != null) {
+            afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        }
     }
 
     public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) {
@@ -181,6 +189,10 @@
         if (firstInstrumentNode != null) {
             firstInstrumentNode.returnExceptional(node, vFrame, exception);
         }
+        final SyntaxTagTrap afterTagTrap = probe.getAfterTrap();
+        if (afterTagTrap != null) {
+            afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        }
     }
 
     public String instrumentationInfo() {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java	Tue Apr 28 12:58:40 2015 -0700
@@ -45,7 +45,7 @@
     }
 
     /**
-     * Callback that will be received whenever execution enters a node with the specified tag.
+     * Notifies that execution is halted at a node with the specified tag.
      */
     public abstract void tagTrappedAt(Node node, MaterializedFrame frame);
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagged.java	Tue Apr 28 10:14:40 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.truffle.api.instrument;
-
-import java.util.*;
-
-/**
- * Information about a guest language program element in a Truffle AST that can be marked as
- * belonging to 0 or more {@linkplain SyntaxTag tags}.
- */
-public interface SyntaxTagged {
-
-    /**
-     * Is this node tagged as belonging to a particular human-sensible category of language
-     * constructs?
-     */
-    boolean isTaggedAs(SyntaxTag tag);
-
-    /**
-     * In which user-sensible categories has this node been tagged (<em>empty set</em> if none).
-     */
-    Collection<SyntaxTag> getSyntaxTags();
-
-}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Tue Apr 28 12:58:40 2015 -0700
@@ -118,18 +118,20 @@
     }
 
     /**
-     * Retrieves the guest language source code section that is currently assigned to this node.
+     * Retrieves the segment of guest language source code that is represented by this Node.
      *
-     * @return the assigned source code section
+     * @return the source code represented by this Node
      */
     public final SourceSection getSourceSection() {
         return sourceSection;
     }
 
     /**
-     * Retrieves the guest language source code section that is currently assigned to this node.
+     * Retrieves the segment of guest language source code that is represented by this Node, if
+     * present; otherwise retrieves the segment represented by the nearest AST ancestor that has
+     * this information.
      *
-     * @return the assigned source code section
+     * @return an approximation of the source code represented by this Node
      */
     @ExplodeLoop
     public final SourceSection getEncapsulatingSourceSection() {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java	Tue Apr 28 10:14:40 2015 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java	Tue Apr 28 12:58:40 2015 -0700
@@ -41,10 +41,16 @@
         super(src);
     }
 
-    @Specialization
-    protected long div(long left, long right) {
-        /* No overflow is possible on a division. */
-        return left / right;
+    @Specialization(rewriteOn = ArithmeticException.class)
+    protected long div(long left, long right) throws ArithmeticException {
+        long result = left / right;
+        /*
+         * The division overflows if left is Long.MIN_VALUE and right is -1.
+         */
+        if ((left & right & result) < 0) {
+            throw new ArithmeticException("long overflow");
+        }
+        return result;
     }
 
     @Specialization
--- a/mx/mx_graal.py	Tue Apr 28 10:14:40 2015 -0700
+++ b/mx/mx_graal.py	Tue Apr 28 12:58:40 2015 -0700
@@ -601,6 +601,8 @@
 
 def _classifyGraalServices(classNames, graalJars):
     classification = {}
+    if not classNames:
+        return classification
     for className in classNames:
         classification[className] = None
     javap = mx.java().javap
@@ -680,14 +682,17 @@
                     assert serviceName and member == 'META-INF/services/' + serviceName
                     with zf.open(member) as serviceFile:
                         serviceImpls = servicesMap.setdefault(serviceName, [])
-                        serviceImpls.extend(serviceFile.readlines())
+                        for line in serviceFile.readlines():
+                            line = line.strip()
+                            if line:
+                                serviceImpls.append(line)
     graalServices = _filterGraalService(servicesMap.keys(), graalJars)
     for serviceName in graalServices:
         serviceImpls = servicesMap[serviceName]
         fd, tmp = tempfile.mkstemp(prefix=serviceName)
         f = os.fdopen(fd, 'w+')
         for serviceImpl in serviceImpls:
-            f.write(serviceImpl.rstrip() + os.linesep)
+            f.write(serviceImpl + os.linesep)
         target = join(destination, serviceName)
         f.close()
         shutil.move(tmp, target)
--- a/src/cpu/sparc/vm/graalGlobals_sparc.hpp	Tue Apr 28 10:14:40 2015 -0700
+++ b/src/cpu/sparc/vm/graalGlobals_sparc.hpp	Tue Apr 28 12:58:40 2015 -0700
@@ -60,4 +60,6 @@
 define_pd_global(intx, MethodProfileWidth,           0);
 #endif // COMPILERGRAAL
 
+define_pd_global(intx, MaxVectorSize,                8);
+
 #endif // CPU_SPARC_VM_GRAALGLOBALS_SPARC_HPP
--- a/src/cpu/x86/vm/graalGlobals_x86.hpp	Tue Apr 28 10:14:40 2015 -0700
+++ b/src/cpu/x86/vm/graalGlobals_x86.hpp	Tue Apr 28 12:58:40 2015 -0700
@@ -60,4 +60,6 @@
 define_pd_global(intx, MethodProfileWidth,           0);
 #endif // COMPILERGRAAL
 
+define_pd_global(intx, MaxVectorSize,                32);
+
 #endif // CPU_X86_VM_GRAALGLOBALS_X86_HPP
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Tue Apr 28 10:14:40 2015 -0700
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Apr 28 12:58:40 2015 -0700
@@ -1019,6 +1019,10 @@
   }
 C2V_END
 
+C2V_VMENTRY(void, flushDebugOutput, (JNIEnv*, jobject))
+  tty->flush();
+C2V_END
+
 
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
@@ -1099,6 +1103,7 @@
   {CC"materializeVirtualObjects",                    CC"("HS_STACK_FRAME_REF"Z)V",                                             FN_PTR(materializeVirtualObjects)},
   {CC"shouldDebugNonSafepoints",                     CC"()Z",                                                                  FN_PTR(shouldDebugNonSafepoints)},
   {CC"writeDebugOutput",                             CC"([BII)V",                                                              FN_PTR(writeDebugOutput)},
+  {CC"flushDebugOutput",                             CC"()V",                                                                  FN_PTR(flushDebugOutput)},
 };
 
 int CompilerToVM_methods_count() {
--- a/src/share/vm/graal/graalGlobals.hpp	Tue Apr 28 10:14:40 2015 -0700
+++ b/src/share/vm/graal/graalGlobals.hpp	Tue Apr 28 12:58:40 2015 -0700
@@ -67,7 +67,7 @@
   GRAAL_ONLY(product(bool, CodeInstallSafepointChecks, true,                \
           "Perform explicit safepoint checks while installing code"))       \
                                                                             \
-  NOT_COMPILER2(product(intx, MaxVectorSize, 32,                            \
+  NOT_COMPILER2(product_pd(intx, MaxVectorSize,                                \
           "Max vector size in bytes, "                                      \
           "actual size could be less depending on elements type"))          \
                                                                             \
--- a/src/share/vm/graal/graalRuntime.cpp	Tue Apr 28 10:14:40 2015 -0700
+++ b/src/share/vm/graal/graalRuntime.cpp	Tue Apr 28 12:58:40 2015 -0700
@@ -1099,19 +1099,43 @@
         GrowableArray<char*>* implNames = new GrowableArray<char*>();
         char* line = buffer;
         while (line - buffer < num_read) {
-          char* nl = strchr(line, '\n');
-          if (nl != NULL) {
-            *nl = '\0';
+          // find line end (\r, \n or \r\n)
+          char* nextline = NULL;
+          char* cr = strchr(line, '\r');
+          char* lf = strchr(line, '\n');
+          if (cr != NULL && lf != NULL) {
+            char* min = MIN2(cr, lf);
+            *min = '\0';
+            if (lf == cr + 1) {
+              nextline = lf + 1;
+            } else {
+              nextline = min + 1;
+            }
+          } else if (cr != NULL) {
+            *cr = '\0';
+            nextline = cr + 1;
+          } else if (lf != NULL) {
+            *lf = '\0';
+            nextline = lf + 1;
           }
-          // Turn all '.'s into '/'s
-          for (size_t index = 0; line[index] != '\0'; index++) {
-            if (line[index] == '.') {
-              line[index] = '/';
+          // trim left
+          while (*line == ' ' || *line == '\t') line++;
+          char* end = line + strlen(line);
+          // trim right
+          while (end > line && (*(end -1) == ' ' || *(end -1) == '\t')) end--;
+          *end = '\0';
+          // skip comments and empty lines
+          if (*line != '#' && strlen(line) > 0) {
+            // Turn all '.'s into '/'s
+            for (size_t index = 0; line[index] != '\0'; index++) {
+              if (line[index] == '.') {
+                line[index] = '/';
+              }
             }
+            implNames->append(line);
           }
-          implNames->append(line);
-          if (nl != NULL) {
-            line = nl + 1;
+          if (nextline != NULL) {
+            line = nextline;
           } else {
             // File without newline at the end
             break;