changeset 5816:b3d3a2fcba3d

Merge
author Gilles Duboscq <duboscq@ssw.jku.at>
date Wed, 11 Jul 2012 14:41:22 +0200
parents 272f9da7ce78 (current diff) 013081f7771b (diff)
children 74eb5feba8dc
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotProxy.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java
diffstat 32 files changed, 329 insertions(+), 321 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Wed Jul 11 14:41:22 2012 +0200
@@ -264,16 +264,16 @@
                 if (value instanceof String) {
                     String s = (String) value;
                     if (s.length() > 50) {
-                        return "\"" + s.substring(0, 30) + "...\"";
+                        return "String:\"" + s.substring(0, 30) + "...\"";
                     } else {
-                        return " \"" + s + '"';
+                        return "String:\"" + s + '"';
                     }
                 } else if (value instanceof JavaType) {
-                    return "class " + MetaUtil.toJavaName((JavaType) value);
-                } else if (value instanceof Enum || value instanceof FormatWithToString) {
-                    return String.valueOf(value);
+                    return "JavaType:" + MetaUtil.toJavaName((JavaType) value);
+                } else if (value instanceof Enum || value instanceof FormatWithToString || value instanceof Number) {
+                    return MetaUtil.getSimpleName(value.getClass(), true) + ":" + String.valueOf(value);
                 } else if (value instanceof Class< ? >) {
-                    return ((Class< ? >) value).getName() + ".class";
+                    return "Class:" + ((Class< ? >) value).getName();
                 } else if (value.getClass().isArray()) {
                     return formatArray(value);
                 } else {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Wed Jul 11 14:41:22 2012 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler;
 
+import com.oracle.graal.nodes.*;
+
 
 /**
  * This class encapsulates options that control the behavior of the Graal compiler.
@@ -72,6 +74,7 @@
     public static boolean PrintEscapeAnalysis                = ____;
 
     public static double TailDuplicationProbability          = 0.5;
+    public static int    TailDuplicationTrivialSize          = 1;
 
     // absolute probability analysis
     public static boolean ProbabilityAnalysis                = true;
@@ -271,6 +274,11 @@
     public static String HIRLowerNewInstance = "";
     public static String HIRLowerNewArray = "";
 
+    /**
+     * Use XIR to lower {@link Invoke} nodes.
+     */
+    public static boolean XIRLowerInvokes = false;
+
     static {
         // turn detailed assertions on when the general assertions are on (misusing the assert keyword for this)
         assert (DetailedAsserts = true) == true;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Jul 11 14:41:22 2012 +0200
@@ -44,6 +44,8 @@
 import com.oracle.graal.lir.StandardOp.ParametersOp;
 import com.oracle.graal.lir.StandardOp.PhiJumpOp;
 import com.oracle.graal.lir.StandardOp.PhiLabelOp;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.asm.TargetMethodAssembler.CallPositionListener;
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.FrameState.InliningIdentifier;
@@ -55,6 +57,7 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.max.asm.*;
+import com.oracle.max.cri.xir.*;
 import com.oracle.max.cri.xir.XirAssembler.XirConstant;
 import com.oracle.max.cri.xir.XirAssembler.XirInstruction;
 import com.oracle.max.cri.xir.XirAssembler.XirMark;
@@ -62,7 +65,6 @@
 import com.oracle.max.cri.xir.XirAssembler.XirParameter;
 import com.oracle.max.cri.xir.XirAssembler.XirRegister;
 import com.oracle.max.cri.xir.XirAssembler.XirTemp;
-import com.oracle.max.cri.xir.*;
 import com.oracle.max.criutils.*;
 
 /**
@@ -900,15 +902,27 @@
             destinationAddress = emitXir(snippet, x.node(), addrInfo, false);
         }
 
+        final Map<XirMark, Mark> marks = snippet.marks;
+
+        CallPositionListener callPositionListener = new CallPositionListener() {
+            public void beforeCall(TargetMethodAssembler tasm) {
+            }
+            public void atCall(TargetMethodAssembler tasm) {
+                if (marks != null) {
+                    marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
+                }
+            }
+        };
+
         LIRFrameState callInfo = stateFor(x.stateDuring(), null, x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null, x.leafGraphId());
-        emitCall(targetMethod, resultOperand, argList, destinationAddress, callInfo, snippet.marks);
+        emitCall(targetMethod, resultOperand, argList, destinationAddress, callInfo, callPositionListener);
 
         if (isLegal(resultOperand)) {
             setResult(x.node(), emitMove(resultOperand));
         }
     }
 
-    protected abstract void emitCall(Object targetMethod, Value result, List<Value> arguments, Value targetAddress, LIRFrameState info, Map<XirMark, Mark> marks);
+    protected abstract void emitCall(Object targetMethod, Value result, List<Value> arguments, Value targetAddress, LIRFrameState info, CallPositionListener ecl);
 
 
     private static Value toStackKind(Value value) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/TailDuplicationPhase.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/TailDuplicationPhase.java	Wed Jul 11 14:41:22 2012 +0200
@@ -74,6 +74,9 @@
     public static final TailDuplicationDecision DEFAULT_DECISION = new TailDuplicationDecision() {
 
         public boolean doTransform(MergeNode merge, int fixedNodeCount) {
+            if (fixedNodeCount < GraalOptions.TailDuplicationTrivialSize) {
+                return true;
+            }
             HashSet<PhiNode> improvements = new HashSet<>();
             for (PhiNode phi : merge.phis()) {
                 Stamp phiStamp = phi.stamp();
@@ -157,13 +160,13 @@
             if (fixed instanceof EndNode && !(((EndNode) fixed).merge() instanceof LoopBeginNode)) {
                 metricDuplicationEnd.increment();
                 if (decision.doTransform(merge, fixedCount)) {
-                    metricDuplicationEndPerformed.add(fixedCount);
+                    metricDuplicationEndPerformed.increment();
                     new DuplicationOperation(merge, replacements).duplicate();
                 }
             } else if (merge.stateAfter() != null) {
                 metricDuplicationOther.increment();
                 if (decision.doTransform(merge, fixedCount)) {
-                    metricDuplicationOtherPerformed.add(fixedCount);
+                    metricDuplicationOtherPerformed.increment();
                     new DuplicationOperation(merge, replacements).duplicate();
                 }
             }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Jul 11 14:41:22 2012 +0200
@@ -29,13 +29,7 @@
 
 import java.util.*;
 
-import com.oracle.max.asm.*;
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.max.cri.xir.XirAssembler.XirMark;
-import com.oracle.max.cri.xir.*;
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
@@ -44,7 +38,6 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.StandardOp.LabelOp;
-import com.oracle.graal.lir.LIRValueUtil;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.DivOp;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op1Reg;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op1Stack;
@@ -54,7 +47,14 @@
 import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
 import com.oracle.graal.lir.amd64.AMD64Call.IndirectCallOp;
 import com.oracle.graal.lir.amd64.AMD64Compare.CompareOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.*;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatBranchOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.ReturnOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.SequentialSwitchOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.SwitchRangesOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
 import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
 import com.oracle.graal.lir.amd64.AMD64Move.LeaOp;
 import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
@@ -64,10 +64,15 @@
 import com.oracle.graal.lir.amd64.AMD64Move.NullCheckOp;
 import com.oracle.graal.lir.amd64.AMD64Move.SpillMoveOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StoreOp;
+import com.oracle.graal.lir.asm.TargetMethodAssembler.CallPositionListener;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
+import com.oracle.max.cri.xir.*;
 
 /**
  * This class implements the X86-specific portion of the LIR generator.
@@ -542,11 +547,11 @@
     }
 
     @Override
-    protected void emitCall(Object targetMethod, Value result, List<Value> arguments, Value targetAddress, LIRFrameState info, Map<XirMark, Mark> marks) {
+    protected void emitCall(Object targetMethod, Value result, List<Value> arguments, Value targetAddress, LIRFrameState info, CallPositionListener cpl) {
         if (isConstant(targetAddress)) {
-            append(new DirectCallOp(targetMethod, result, arguments.toArray(new Value[arguments.size()]), info, marks));
+            append(new DirectCallOp(targetMethod, result, arguments.toArray(new Value[arguments.size()]), info, cpl));
         } else {
-            append(new IndirectCallOp(targetMethod, result, arguments.toArray(new Value[arguments.size()]), targetAddress, info, marks));
+            append(new IndirectCallOp(targetMethod, result, arguments.toArray(new Value[arguments.size()]), targetAddress, info, cpl));
         }
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java	Wed Jul 11 14:41:22 2012 +0200
@@ -367,7 +367,7 @@
             }
             if (GraalOptions.OptTailDuplication) {
                 /*
-                 * We might want to perform tail duplication at the merge after a type switch, is there are invokes that would
+                 * We might want to perform tail duplication at the merge after a type switch, if there are invokes that would
                  * benefit from the improvement in type information.
                  */
                 FixedNode current = returnMerge;
--- a/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java	Wed Jul 11 14:41:22 2012 +0200
@@ -27,7 +27,6 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.logging.*;
 
 public class ReplacingStreams {
@@ -48,7 +47,6 @@
         invocation = new InvocationSocket(output, input);
 
         addStaticObject(Value.IllegalValue);
-        addStaticObject(HotSpotProxy.DUMMY_CONSTANT_OBJ);
     }
 
     public void setInvocationSocket(InvocationSocket invocation) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotProxy.java	Wed Jul 11 14:36:32 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2011, 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.hotspot;
-
-/**
- * Provides methods to classify the HotSpot-internal identifiers.
- */
-public final class HotSpotProxy {
-
-    private HotSpotProxy() {
-    }
-
-    private enum CompilerObjectType {
-        // this enum needs to have the same values as the one in graal_Compiler.hpp
-        STUB(0x100000000000000L),
-        METHOD(0x200000000000000L),
-        CLASS(0x300000000000000L),
-        SYMBOL(0x400000000000000L),
-        CONSTANT_POOL(0x500000000000000L),
-        CONSTANT(0x600000000000000L),
-        TYPE_MASK(0xf00000000000000L),
-        DUMMY_CONSTANT(0x6ffffffffffffffL);
-
-        public final long bits;
-
-        CompilerObjectType(long bits) {
-            this.bits = bits;
-        }
-    }
-
-    public static final Long DUMMY_CONSTANT_OBJ = CompilerObjectType.DUMMY_CONSTANT.bits;
-
-    private static boolean isType(long id, CompilerObjectType type) {
-        return (id & CompilerObjectType.TYPE_MASK.bits) == type.bits;
-    }
-
-    public static boolean isStub(long id) {
-        return isType(id, CompilerObjectType.STUB);
-    }
-
-    public static boolean isMethod(long id) {
-        return isType(id, CompilerObjectType.METHOD);
-    }
-
-    public static boolean isClass(long id) {
-        return isType(id, CompilerObjectType.CLASS);
-    }
-
-    public static boolean isSymbol(long id) {
-        return isType(id, CompilerObjectType.SYMBOL);
-    }
-
-    public static boolean isConstantPool(long id) {
-        return isType(id, CompilerObjectType.CONSTANT_POOL);
-    }
-
-    public static boolean isConstant(long id) {
-        return isType(id, CompilerObjectType.CONSTANT_POOL);
-    }
-
-    public static String toString(long id) {
-        CompilerObjectType type = null;
-        for (CompilerObjectType t : CompilerObjectType.values()) {
-            if ((id & CompilerObjectType.TYPE_MASK.bits) == t.bits) {
-                type = t;
-            }
-        }
-        long num = id & ~CompilerObjectType.TYPE_MASK.bits;
-        return type + " " + num;
-    }
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/counters/MethodEntryCounters.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/counters/MethodEntryCounters.java	Wed Jul 11 14:41:22 2012 +0200
@@ -80,8 +80,8 @@
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
             int start = masm.codeBuffer.position();
-            int off = Unsafe.getUnsafe().arrayBaseOffset(long[].class);
-            int scale = Unsafe.getUnsafe().arrayIndexScale(long[].class);
+            int off = Unsafe.ARRAY_LONG_BASE_OFFSET;
+            int scale = Unsafe.ARRAY_LONG_INDEX_SCALE;
 
             AMD64Move.move(tasm, masm, counterArr, Constant.forObject(counter.counts));
             AMD64Move.load(tasm, masm, callerPc, new Address(Kind.Long, AMD64.rbp.asValue(Kind.Long), 8), null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java	Wed Jul 11 14:41:22 2012 +0200
@@ -119,7 +119,8 @@
                 asm.pload(target.wordKind, temp, receiver, true);
             }
             asm.mark(MARK_INVOKEINTERFACE);
-            asm.mov(tempO, asm.createConstant(Constant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ)));
+            // Initialize the klassOop slot of an inline cache with null - the C++ Graal code will convert this to Universe::non_oop_word()
+            asm.mov(tempO, asm.createConstant(Constant.NULL_OBJECT));
 
             return asm.finishTemplate(addr, "invokeinterface");
         }
@@ -140,7 +141,8 @@
                 asm.pload(target.wordKind, temp, receiver, true);
             }
             asm.mark(MARK_INVOKEVIRTUAL);
-            asm.mov(tempO, asm.createConstant(Constant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ)));
+            // Initialize the klassOop slot of an inline cache with null - the C++ Graal code will convert this to Universe::non_oop_word()
+            asm.mov(tempO, asm.createConstant(Constant.NULL_OBJECT));
 
             return asm.finishTemplate(addr, "invokevirtual");
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java	Wed Jul 11 14:41:22 2012 +0200
@@ -34,35 +34,17 @@
  */
 public final class TLABAllocateNode extends FixedWithNextNode implements Lowerable {
 
-    private final int size;
-    @Input private ValueNode sizeNode;
+    @Input private ValueNode size;
 
-    public TLABAllocateNode(int size, Kind wordKind) {
+    public TLABAllocateNode(ValueNode size, Kind wordKind) {
         super(StampFactory.forWord(wordKind, true));
         this.size = size;
-        this.sizeNode = null;
     }
 
-    public TLABAllocateNode(Kind wordKind, ValueNode size) {
-        super(StampFactory.forWord(wordKind, true));
-        this.size = -1;
-        this.sizeNode = size;
-    }
-
-    public boolean isSizeConstant() {
-        return sizeNode == null;
-    }
-
-    public int constantSize() {
-        assert isSizeConstant();
+    public ValueNode size() {
         return size;
     }
 
-    public ValueNode variableSize() {
-        assert !isSizeConstant();
-        return sizeNode;
-    }
-
     @Override
     public void lower(LoweringTool tool) {
         tool.getRuntime().lower(this, tool);
@@ -71,18 +53,12 @@
     /**
      * @return null if allocation fails
      */
-    @SuppressWarnings("unused")
-    @NodeIntrinsic
-    public static Word allocateConstantSize(@ConstantNodeParameter int size, @ConstantNodeParameter Kind wordKind) {
-        throw new UnsupportedOperationException();
-    }
-
     /**
      * @return null if allocation fails
      */
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static Word allocateVariableSize(@ConstantNodeParameter Kind wordKind, int size) {
+    public static Word allocateVariableSize(int size, @ConstantNodeParameter Kind wordKind) {
         throw new UnsupportedOperationException();
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Wed Jul 11 14:41:22 2012 +0200
@@ -143,7 +143,7 @@
             DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.RuntimeConstraint);
         }
         int size = getArraySize(length, alignment, headerSize, log2ElementSize);
-        Word memory = TLABAllocateNode.allocateVariableSize(wordKind, size);
+        Word memory = TLABAllocateNode.allocateVariableSize(size, wordKind);
         return InitializeArrayNode.initialize(memory, length, size, type);
     }
 
@@ -252,7 +252,8 @@
             if (!useTLAB) {
                 memory = ConstantNode.forConstant(new Constant(target.wordKind, 0L), runtime, graph);
             } else {
-                TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(size, wordKind()));
+                ConstantNode sizeNode = ConstantNode.forInt(size, graph);
+                TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(sizeNode, wordKind()));
                 graph.addBeforeFixed(newInstanceNode, tlabAllocateNode);
                 memory = tlabAllocateNode;
             }
@@ -286,7 +287,7 @@
                 // Calculate aligned size
                 int size = getArraySize(length, alignment, headerSize, log2ElementSize);
                 ConstantNode sizeNode = ConstantNode.forInt(size, graph);
-                tlabAllocateNode = graph.add(new TLABAllocateNode(size, target.wordKind));
+                tlabAllocateNode = graph.add(new TLABAllocateNode(sizeNode, target.wordKind));
                 graph.addBeforeFixed(newArrayNode, tlabAllocateNode);
                 InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(tlabAllocateNode, lengthNode, sizeNode, arrayType));
                 graph.replaceFixedWithFixed(newArrayNode, initializeNode);
@@ -307,12 +308,7 @@
         @SuppressWarnings("unused")
         public void lower(TLABAllocateNode tlabAllocateNode, LoweringTool tool) {
             StructuredGraph graph = (StructuredGraph) tlabAllocateNode.graph();
-            ValueNode size;
-            if (tlabAllocateNode.isSizeConstant()) {
-                size = ConstantNode.forInt(tlabAllocateNode.constantSize(), graph);
-            } else {
-                size = tlabAllocateNode.variableSize();
-            }
+            ValueNode size = tlabAllocateNode.size();
             Key key = new Key(allocate);
             Arguments arguments = arguments("size", size);
             SnippetTemplate template = cache.get(key);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java	Wed Jul 11 14:41:22 2012 +0200
@@ -25,11 +25,14 @@
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.hotspot.meta.HotSpotXirGenerator.*;
+import static com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind.*;
 import static com.oracle.max.asm.target.amd64.AMD64.*;
 
 import java.lang.reflect.*;
+import java.util.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.Mark;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.gen.*;
@@ -42,11 +45,13 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.asm.TargetMethodAssembler.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.cri.xir.*;
 
 public class HotSpotAMD64Backend extends Backend {
@@ -57,32 +62,7 @@
 
     @Override
     public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir, XirGenerator xir, Assumptions assumptions) {
-        return new AMD64LIRGenerator(graph, runtime, target, frameMap, method, lir, xir, assumptions) {
-
-            @Override
-            public void visitSafepointNode(SafepointNode i) {
-                LIRFrameState info = state();
-                append(new AMD64SafepointOp(info, ((HotSpotRuntime) runtime).config));
-            }
-
-            @Override
-            public void visitExceptionObject(ExceptionObjectNode x) {
-                HotSpotVMConfig config = ((HotSpotRuntime) runtime).config;
-                RegisterValue thread = r15.asValue();
-                Address exceptionAddress = new Address(Kind.Object, thread, config.threadExceptionOopOffset);
-                Address pcAddress = new Address(Kind.Long, thread, config.threadExceptionPcOffset);
-                Value exception = emitLoad(exceptionAddress, false);
-                emitStore(exceptionAddress, Constant.NULL_OBJECT, false);
-                emitStore(pcAddress, Constant.LONG_0, false);
-                setResult(x, exception);
-            }
-
-            @Override
-            protected void emitPrologue() {
-                super.emitPrologue();
-                MethodEntryCounters.emitCounter(this, method);
-            }
-        };
+        return new HotSpotAMD64LIRGenerator(graph, runtime, target, frameMap, method, lir, xir, assumptions);
     }
 
     @Override
@@ -90,6 +70,103 @@
         return new AMD64XirAssembler(target);
     }
 
+    static final class HotSpotAMD64LIRGenerator extends AMD64LIRGenerator {
+
+        private HotSpotAMD64LIRGenerator(Graph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir, XirGenerator xir,
+                        Assumptions assumptions) {
+            super(graph, runtime, target, frameMap, method, lir, xir, assumptions);
+        }
+
+        @Override
+        public void visitSafepointNode(SafepointNode i) {
+            LIRFrameState info = state();
+            append(new AMD64SafepointOp(info, ((HotSpotRuntime) runtime).config));
+        }
+
+        @Override
+        public void visitExceptionObject(ExceptionObjectNode x) {
+            HotSpotVMConfig config = ((HotSpotRuntime) runtime).config;
+            RegisterValue thread = r15.asValue();
+            Address exceptionAddress = new Address(Kind.Object, thread, config.threadExceptionOopOffset);
+            Address pcAddress = new Address(Kind.Long, thread, config.threadExceptionPcOffset);
+            Value exception = emitLoad(exceptionAddress, false);
+            emitStore(exceptionAddress, Constant.NULL_OBJECT, false);
+            emitStore(pcAddress, Constant.LONG_0, false);
+            setResult(x, exception);
+        }
+
+        @Override
+        protected void emitPrologue() {
+            super.emitPrologue();
+            MethodEntryCounters.emitCounter(this, method);
+        }
+
+        @Override
+        public void emitInvoke(Invoke x) {
+            if (GraalOptions.XIRLowerInvokes) {
+                super.emitInvoke(x);
+                return;
+            }
+            final MethodCallTargetNode callTarget = x.callTarget();
+            final InvokeKind invokeKind = callTarget.invokeKind();
+            Kind[] signature = MetaUtil.signatureToKinds(callTarget.targetMethod().signature(), callTarget.isStatic() ? null : callTarget.targetMethod().holder().kind());
+            CallingConvention cc = frameMap.registerConfig.getCallingConvention(JavaCall, signature, target(), false);
+            frameMap.callsMethod(cc, JavaCall);
+            List<Value> argList = visitInvokeArguments(cc, callTarget.arguments());
+
+            Value address = callTarget.address() == null ? Constant.forLong(0L) : operand(callTarget.address());
+
+            final Mark[] callsiteForStaticCallStub = {null};
+
+            if (invokeKind == Static || invokeKind == Special) {
+                lir.stubs.add(new AMD64Code() {
+                    public String description() {
+                        return "static call stub for Invoke" + invokeKind;
+                    }
+                    @Override
+                    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+                        assert callsiteForStaticCallStub[0] != null;
+                        tasm.recordMark(MARK_STATIC_CALL_STUB, callsiteForStaticCallStub);
+                        masm.movq(AMD64.rbx, 0L);
+                        Label dummy = new Label();
+                        masm.jmp(dummy);
+                        masm.bind(dummy);
+                    }
+                });
+            }
+
+            CallPositionListener cpl = new CallPositionListener() {
+                @Override
+                public void beforeCall(TargetMethodAssembler tasm) {
+                    if (invokeKind == Static || invokeKind == Special) {
+                        tasm.recordMark(invokeKind == Static ? MARK_INVOKESTATIC : MARK_INVOKESPECIAL);
+                    } else {
+                        // The mark for an invocation that uses an inline cache must be placed at the instruction
+                        // that loads the klassOop from the inline cache so that the C++ code can find it
+                        // and replace the inline null value with Universe::non_oop_word()
+                        assert invokeKind == Virtual || invokeKind == Interface;
+                        tasm.recordMark(invokeKind == Virtual ? MARK_INVOKEVIRTUAL : MARK_INVOKEINTERFACE);
+                        AMD64MacroAssembler masm = (AMD64MacroAssembler) tasm.asm;
+                        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Object), Constant.NULL_OBJECT);
+                    }
+                }
+                public void atCall(TargetMethodAssembler tasm) {
+                    if (invokeKind == Static || invokeKind == Special) {
+                        callsiteForStaticCallStub[0] = tasm.recordMark(null);
+                    }
+                }
+            };
+
+            LIRFrameState callState = stateFor(x.stateDuring(), null, x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null, x.leafGraphId());
+            Value result = resultOperandFor(x.node().kind());
+            emitCall(callTarget.targetMethod(), result, argList, address, callState, cpl);
+
+            if (isLegal(result)) {
+                setResult(x.node(), emitMove(result));
+            }
+        }
+    }
+
     class HotSpotFrameContext implements FrameContext {
 
         @Override
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Wed Jul 11 14:41:22 2012 +0200
@@ -25,16 +25,13 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
-import java.util.*;
-
-import com.oracle.graal.api.code.CompilationResult.Mark;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.asm.TargetMethodAssembler.CallPositionListener;
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.xir.XirAssembler.XirMark;
 
 public class AMD64Call {
 
@@ -45,22 +42,19 @@
         @State protected LIRFrameState state;
 
         protected final Object targetMethod;
-        protected final Map<XirMark, Mark> marks;
+        protected final CallPositionListener callPositionListener;
 
-        public DirectCallOp(Object targetMethod, Value result, Value[] parameters, LIRFrameState state, Map<XirMark, Mark> marks) {
+        public DirectCallOp(Object targetMethod, Value result, Value[] parameters, LIRFrameState state, CallPositionListener callPositionListener) {
             this.targetMethod = targetMethod;
             this.result = result;
             this.parameters = parameters;
             this.state = state;
-            this.marks = marks;
+            this.callPositionListener = callPositionListener;
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            callAlignment(tasm, masm);
-            if (marks != null) {
-                marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
-            }
+            callAlignment(tasm, masm, callPositionListener);
             directCall(tasm, masm, targetMethod, state);
         }
     }
@@ -73,35 +67,41 @@
         @State protected LIRFrameState state;
 
         private final Object targetMethod;
-        private final Map<XirMark, Mark> marks;
+        protected final CallPositionListener callPositionListener;
 
-        public IndirectCallOp(Object targetMethod, Value result, Value[] parameters, Value targetAddress, LIRFrameState state, Map<XirMark, Mark> marks) {
+        public IndirectCallOp(Object targetMethod, Value result, Value[] parameters, Value targetAddress, LIRFrameState state, CallPositionListener callPositionListener) {
             this.targetMethod = targetMethod;
             this.result = result;
             this.parameters = parameters;
             this.targetAddress = targetAddress;
             this.state = state;
-            this.marks = marks;
+            this.callPositionListener = callPositionListener;
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            callAlignment(tasm, masm);
-            if (marks != null) {
-                marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
-            }
+            callAlignment(tasm, masm, callPositionListener);
             indirectCall(tasm, masm, asRegister(targetAddress), targetMethod, state);
         }
     }
 
+    public static void callAlignment(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CallPositionListener callPositionListener) {
+        if (callPositionListener != null) {
+            callPositionListener.beforeCall(tasm);
+        }
 
-    public static void callAlignment(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
         // make sure that the displacement word of the call ends up word aligned
         int offset = masm.codeBuffer.position();
         offset += tasm.target.arch.machineCodeCallDisplacementOffset;
         while (offset++ % tasm.target.wordSize != 0) {
             masm.nop();
         }
+
+        if (callPositionListener != null) {
+            int pos = masm.codeBuffer.position();
+            callPositionListener.atCall(tasm);
+            assert pos == masm.codeBuffer.position() : "call position listener inserted code before an aligned call";
+        }
     }
 
     public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target, LIRFrameState info) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Jul 11 14:41:22 2012 +0200
@@ -197,74 +197,4 @@
     public boolean hasArgInCallerFrame() {
         return hasArgInCallerFrame;
     }
-
-/*
-    private int lastDecodeStart;
-
-    private void printAssembly(TargetMethodAssembler tasm) {
-        byte[] currentBytes = tasm.asm.codeBuffer.copyData(lastDecodeStart, tasm.asm.codeBuffer.position());
-        if (currentBytes.length > 0) {
-            String disasm = tasm.runtime.disassemble(currentBytes, lastDecodeStart);
-            if (disasm.length() != 0) {
-                TTY.println(disasm);
-            } else {
-                TTY.println("Code [+%d]: %d bytes", lastDecodeStart, currentBytes.length);
-                Util.printBytes(lastDecodeStart, currentBytes, GraalOptions.PrintAssemblyBytesPerLine);
-            }
-        }
-        lastDecodeStart = tasm.asm.codeBuffer.position();
-    }
-
-
-    public static void printBlock(Block x) {
-        // print block id
-        TTY.print("B%d ", x.getId());
-
-        // print flags
-        if (x.isLoopHeader()) {
-            TTY.print("lh ");
-        }
-        if (x.isLoopEnd()) {
-            TTY.print("le ");
-        }
-
-        // print block bci range
-        TTY.print("[%d, %d] ", -1, -1);
-
-        // print predecessors and successors
-        if (x.numberOfPreds() > 0) {
-            TTY.print("preds: ");
-            for (int i = 0; i < x.numberOfPreds(); i++) {
-                TTY.print("B%d ", x.predAt(i).getId());
-            }
-        }
-
-        if (x.numberOfSux() > 0) {
-            TTY.print("sux: ");
-            for (int i = 0; i < x.numberOfSux(); i++) {
-                TTY.print("B%d ", x.suxAt(i).getId());
-            }
-        }
-
-        TTY.println();
-    }
-
-    public static void printLIR(List<Block> blocks) {
-        if (TTY.isSuppressed()) {
-            return;
-        }
-        TTY.println("LIR:");
-        int i;
-        for (i = 0; i < blocks.size(); i++) {
-            Block bb = blocks.get(i);
-            printBlock(bb);
-            TTY.println("__id_Instruction___________________________________________");
-            for (LIRInstruction op : bb.lir) {
-                TTY.println(op.toStringWithIdPrefix());
-                TTY.println();
-            }
-            TTY.println();
-        }
-    }
-*/
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Wed Jul 11 14:41:22 2012 +0200
@@ -276,7 +276,7 @@
                     long offset = calc.getOffset(field);
 
                     if (VALUE_CLASS.isAssignableFrom(type)) {
-                        assert Modifier.isProtected(field.getModifiers()) && !Modifier.isFinal(field.getModifiers()) : "Value field must not be declared final or private because it is modified by register allocator: " + field;
+                        assert Modifier.isProtected(field.getModifiers()) && !Modifier.isFinal(field.getModifiers()) : "Value field must not be declared final or [package] private because it is modified by register allocator: " + field;
                         OperandModeAnnotation annotation = getOperandModeAnnotation(field);
                         assert annotation != null : "Field must have operand mode annotation: " + field;
                         annotation.scalarOffsets.add(offset);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Wed Jul 11 14:41:22 2012 +0200
@@ -59,7 +59,11 @@
     }
 
     public static boolean verify(final LIRInstruction op) {
-        ValueProcedure allowedProc = new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return allowed(op, value, mode, flags); } };
+        ValueProcedure allowedProc = new ValueProcedure() {
+            @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
+                return allowed(op, value, mode, flags);
+            }
+        };
 
         op.forEachInput(allowedProc);
         op.forEachAlive(allowedProc);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Wed Jul 11 14:41:22 2012 +0200
@@ -36,6 +36,25 @@
 
 public class TargetMethodAssembler {
 
+    /**
+     * A client interested in knowing the position(s) associated with a call instruction.
+     */
+    public interface CallPositionListener {
+        /**
+         * Notifies this listener that the code buffer is at the position before any alignment
+         * instructions are emitted for a call. This listener can safely emit instructions into
+         * the code buffer as the alignment has not yet been computed.
+         */
+        void beforeCall(TargetMethodAssembler tasm);
+
+        /**
+         * Notifies this listener that the code buffer is at the position after alignment
+         * instruction have been emitted but before the call instruction has been emitted.
+         * This listener must not emit instructions at this position.
+         */
+        void atCall(TargetMethodAssembler tasm);
+    }
+
     private static class ExceptionInfo {
         public final int codeOffset;
         public final LabelRef exceptionEdge;
@@ -82,11 +101,13 @@
         targetMethod.setFrameSize(frameSize);
     }
 
+    private static final CompilationResult.Mark[] NO_REFS = {};
+
     public CompilationResult.Mark recordMark(Object id) {
-        return targetMethod.recordMark(asm.codeBuffer.position(), id, null);
+        return targetMethod.recordMark(asm.codeBuffer.position(), id, NO_REFS);
     }
 
-    public CompilationResult.Mark recordMark(Object id, CompilationResult.Mark[] references) {
+    public CompilationResult.Mark recordMark(Object id, CompilationResult.Mark... references) {
         return targetMethod.recordMark(asm.codeBuffer.position(), id, references);
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Wed Jul 11 14:41:22 2012 +0200
@@ -31,6 +31,16 @@
 
     @Input protected final NodeInputList<ValueNode> arguments;
 
+    @Input protected ValueNode address;
+
+    public ValueNode address() {
+        return address;
+    }
+
+    public void setAddress(ValueNode address) {
+        this.address = address;
+    }
+
     public CallTargetNode(ValueNode[] arguments) {
         super(StampFactory.extension());
         this.arguments = new NodeInputList<>(this, arguments);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Wed Jul 11 14:41:22 2012 +0200
@@ -24,8 +24,9 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
 
-public interface Invoke extends StateSplit {
+public interface Invoke extends StateSplit, Lowerable {
 
     FixedNode next();
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Wed Jul 11 14:41:22 2012 +0200
@@ -96,6 +96,15 @@
     }
 
     @Override
+    public void lower(LoweringTool tool) {
+        NodeInputList<ValueNode> parameters = callTarget.arguments();
+        ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0);
+        if (!callTarget.isStatic() && firstParam.kind() == Kind.Object && !firstParam.objectStamp().nonNull()) {
+            dependencies().add(tool.createNullCheckGuard(firstParam, leafGraphId));
+        }
+    }
+
+    @Override
     public void generate(LIRGeneratorTool gen) {
         gen.emitInvoke(this);
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Wed Jul 11 14:41:22 2012 +0200
@@ -127,6 +127,15 @@
     }
 
     @Override
+    public void lower(LoweringTool tool) {
+        NodeInputList<ValueNode> parameters = callTarget.arguments();
+        ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0);
+        if (!callTarget.isStatic() && firstParam.kind() == Kind.Object && !firstParam.objectStamp().nonNull()) {
+            dependencies().add(tool.createNullCheckGuard(firstParam, leafGraphId));
+        }
+    }
+
+    @Override
     public void generate(LIRGeneratorTool gen) {
         gen.emitInvoke(this);
     }
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/InvokeTest.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/InvokeTest.java	Wed Jul 11 14:41:22 2012 +0200
@@ -44,8 +44,9 @@
     }
 
     public static class A implements I {
+        final String name = "A";
         public String virtualMethod(String s) {
-            return s;
+            return name + s;
         }
     }
 
@@ -60,7 +61,15 @@
         test("invokespecialConstructor", "a string");
         test("invokespecial", this, "a string");
         test("invokevirtual", new A(), "a string");
+        test("invokevirtual2", new A(), "a string");
         test("invokeinterface", new A(), "a string");
+        Object[] args = {null};
+        test("invokestatic", args);
+        test("invokespecialConstructor", args);
+        test("invokespecial", null, null);
+        test("invokevirtual", null, null);
+        test("invokevirtual2", null, null);
+        test("invokeinterface", null, null);
     }
 
     public static String invokestatic(String s) {
@@ -83,6 +92,11 @@
         return a.virtualMethod(s);
     }
 
+    public static String invokevirtual2(A a, String s) {
+        a.virtualMethod(s);
+        return a.virtualMethod(s);
+    }
+
     public static String invokeinterface(I i, String s) {
         return i.virtualMethod(s);
     }
--- a/src/share/vm/classfile/systemDictionary.hpp	Wed Jul 11 14:36:32 2012 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Jul 11 14:41:22 2012 +0200
@@ -191,7 +191,6 @@
   template(GraalBitMap_klass,                     java_util_BitSet,                                             Opt) \
   /* graal.hotspot */                                                                                                 \
   template(HotSpotKlassOop_klass,                 com_oracle_graal_hotspot_HotSpotKlassOop,                     Opt) \
-  template(HotSpotProxy_klass,                    com_oracle_graal_hotspot_HotSpotProxy,                        Opt) \
   template(HotSpotCompilationResult_klass,        com_oracle_graal_hotspot_HotSpotCompilationResult,            Opt) \
   template(HotSpotCodeInfo_klass,                 com_oracle_graal_hotspot_meta_HotSpotCodeInfo,                Opt) \
   template(HotSpotCompiledMethod_klass,           com_oracle_graal_hotspot_meta_HotSpotCompiledMethod,          Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Wed Jul 11 14:36:32 2012 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Jul 11 14:41:22 2012 +0200
@@ -274,7 +274,6 @@
   template(com_oracle_graal_hotspot_HotSpotGraalRuntime,             "com/oracle/graal/hotspot/HotSpotGraalRuntime")                  \
   template(com_oracle_graal_hotspot_HotSpotKlassOop,                 "com/oracle/graal/hotspot/HotSpotKlassOop")                      \
   template(com_oracle_graal_hotspot_HotSpotOptions,                  "com/oracle/graal/hotspot/HotSpotOptions")                       \
-  template(com_oracle_graal_hotspot_HotSpotProxy,                    "com/oracle/graal/hotspot/HotSpotProxy")                         \
   template(com_oracle_graal_hotspot_HotSpotCompilationResult,        "com/oracle/graal/hotspot/HotSpotCompilationResult")             \
   template(com_oracle_graal_hotspot_bridge_VMToCompiler,             "com/oracle/graal/hotspot/bridge/VMToCompiler")                  \
   template(com_oracle_graal_hotspot_meta_HotSpotCodeInfo,            "com/oracle/graal/hotspot/meta/HotSpotCodeInfo")                 \
--- a/src/share/vm/code/nmethod.cpp	Wed Jul 11 14:36:32 2012 +0200
+++ b/src/share/vm/code/nmethod.cpp	Wed Jul 11 14:41:22 2012 +0200
@@ -2599,9 +2599,9 @@
 void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) {
   if (block_begin == entry_point())             stream->print_cr("[Entry Point]");
   if (block_begin == verified_entry_point())    stream->print_cr("[Verified Entry Point]");
-  if (block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
+  if (GRAAL_ONLY(_exception_offset >= 0 &&) block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
   if (block_begin == stub_begin())              stream->print_cr("[Stub Code]");
-  if (block_begin == deopt_handler_begin())     stream->print_cr("[Deopt Handler Code]");
+  if (GRAAL_ONLY(_deoptimize_offset >= 0 &&) block_begin == deopt_handler_begin())     stream->print_cr("[Deopt Handler Code]");
 
   if (has_method_handle_invokes())
     if (block_begin == deopt_mh_handler_begin())  stream->print_cr("[Deopt MH Handler Code]");
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jul 11 14:36:32 2012 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jul 11 14:41:22 2012 +0200
@@ -787,9 +787,6 @@
         TRACE_graal_3("relocating (HotSpotJavaType) at %016x/%016x", instruction, operand);
       } else {
         jobject value = JNIHandles::make_local(obj());
-        if (obj() == HotSpotProxy::DUMMY_CONSTANT_OBJ()) {
-          value = (jobject) Universe::non_oop_word();
-        }
         *((jobject*) operand) = value;
         _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
         TRACE_graal_3("relocating (oop constant) at %016x/%016x", instruction, operand);
@@ -836,11 +833,19 @@
         _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
         break;
       }
+      case MARK_INVOKEVIRTUAL:
+      case MARK_INVOKEINTERFACE: {
+        // Convert the initial value of the klassOop slot in an inline cache
+        // from NULL to Universe::non_oop_word().
+        NativeMovConstReg* n_copy = nativeMovConstReg_at(instruction);
+        assert(n_copy->data() == 0, "inline cache klassOop initial value should be NULL");
+        n_copy->set_data((intptr_t)Universe::non_oop_word());
+        // Add relocation record for the klassOop embedded in the inline cache
+        _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
+      }
       case MARK_INVOKE_INVALID:
-      case MARK_INVOKEINTERFACE:
+      case MARK_INVOKESPECIAL:
       case MARK_INVOKESTATIC:
-      case MARK_INVOKESPECIAL:
-      case MARK_INVOKEVIRTUAL:
         _next_call_type = (MarkId) id;
         _invoke_mark_pc = instruction;
         break;
--- a/src/share/vm/graal/graalJavaAccess.hpp	Wed Jul 11 14:36:32 2012 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Wed Jul 11 14:41:22 2012 +0200
@@ -95,9 +95,6 @@
     long_field(HotSpotCodeInfo, start)                                                  \
     oop_field(HotSpotCodeInfo, code, "[B")                                              \
   end_class                                                                             \
-  start_class(HotSpotProxy)                                                             \
-    static_oop_field(HotSpotProxy, DUMMY_CONSTANT_OBJ, "Ljava/lang/Long;")              \
-  end_class                                                                             \
   start_class(HotSpotCompilationResult)                                                      \
     oop_field(HotSpotCompilationResult, comp, "Lcom/oracle/graal/api/code/CompilationResult;") \
     oop_field(HotSpotCompilationResult, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;") \
--- a/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Wed Jul 11 14:41:22 2012 +0200
@@ -49,7 +49,7 @@
     public BytecodeNode(InputBytecode bytecode, InputGraph graph, String bciValue) {
 
         super(Children.LEAF);
-        this.setDisplayName(bytecode.getBci() + " " + bytecode.getName());
+        String displayName = bytecode.getBci() + " " + bytecode.getName() + " " + bytecode.getOperands();
 
         bciValue = bytecode.getBci() + " " + bciValue;
         bciValue = bciValue.trim();
@@ -62,8 +62,14 @@
             for (InputNode n : nodeList) {
                 nodes.add(n);
             }
-            this.setDisplayName(this.getDisplayName() + " (" + nodes.size() + " nodes)");
+            displayName += " (" + nodes.size() + " nodes)";
         }
+        
+        if (bytecode.getComment() != null) {
+            displayName += " // " + bytecode.getComment();
+        }
+        
+        this.setDisplayName(displayName);
     }
 
     @Override
--- a/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Wed Jul 11 14:41:22 2012 +0200
@@ -91,7 +91,7 @@
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
-     * To obtain the singleton instance, use {@link findInstance}.
+     * To obtain the singleton instance, use {@link #findInstance}.
      */
     public static synchronized BytecodeViewTopComponent getDefault() {
         if (instance == null) {
--- a/visualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java	Wed Jul 11 14:41:22 2012 +0200
@@ -31,11 +31,15 @@
 
     private int bci;
     private String name;
+    private String operands;
+    private String comment;
     private InputMethod inlined;
 
-    public InputBytecode(int bci, String name) {
+    public InputBytecode(int bci, String name, String operands, String comment) {
         this.bci = bci;
         this.name = name;
+        this.operands = operands;
+        this.comment = comment;
     }
 
     public InputMethod getInlined() {
@@ -53,4 +57,12 @@
     public String getName() {
         return name;
     }
+
+    public String getOperands() {
+        return operands;
+    }
+
+    public String getComment() {
+        return comment;
+    }
 }
--- a/visualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Wed Jul 11 14:36:32 2012 +0200
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Wed Jul 11 14:41:22 2012 +0200
@@ -26,6 +26,8 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  *
@@ -109,35 +111,38 @@
     }
 
     public void setBytecodes(String text) {
-
+        Pattern instruction = Pattern.compile("\\s*(\\d+)\\s*:?\\s*(\\w+)\\s*(.*)(?://(.*))?");
         String[] strings = text.split("\n");
-        int oldNumber = -1;
+        int oldBci = -1;
         for (String s : strings) {
-
-            if (s.length() > 0 && Character.isDigit(s.charAt(0))) {
-                s = s.trim();
-                int spaceIndex = s.indexOf(' ');
-                String numberString = s.substring(0, spaceIndex);
-                String tmpName = s.substring(spaceIndex + 1, s.length());
+            s = s.trim();
+            if (s.length() != 0) {
+                final Matcher matcher = instruction.matcher(s);
+                if (matcher.matches()) {
+                    String bciString = matcher.group(1);
+                    String opcode = matcher.group(2);
+                    String operands = matcher.group(3).trim();
+                    String comment = matcher.group(4);
+                    if (comment != null) {
+                        comment = comment.trim();
+                    }
 
-                int number = -1;
-                try {
-                    number = Integer.parseInt(numberString);
-                } catch (NumberFormatException e) {
-                    // nothing to do...
-                }
+                    int bci = Integer.parseInt(bciString);
+
+                    // assert correct order of bytecodes
+                    assert bci > oldBci;
+
+                    InputBytecode bc = new InputBytecode(bci, opcode, operands, comment);
+                    bytecodes.add(bc);
 
-                // assert correct order of bytecodes
-                assert number > oldNumber;
-
-                InputBytecode bc = new InputBytecode(number, tmpName);
-                bytecodes.add(bc);
-
-                for (InputMethod m : inlined) {
-                    if (m.getBci() == number) {
-                        bc.setInlined(m);
-                        break;
+                    for (InputMethod m : inlined) {
+                        if (m.getBci() == bci) {
+                            bc.setInlined(m);
+                            break;
+                        }
                     }
+                } else {
+                    System.out.println("no match: " + s);
                 }
             }
         }