changeset 5798:2585af1e26ac

implemented non-XIR lowering of invokes (todo: inline virtual dispatch and null checking of receivers) removed HotSpotProxy class
author Doug Simon <doug.simon@oracle.com>
date Mon, 09 Jul 2012 22:18:49 +0200
parents b3a87b533c0f
children 99b883463e36 be428fe2d86c
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotProxy.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/code/nmethod.cpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 15 files changed, 213 insertions(+), 171 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Mon Jul 09 22:17:00 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Mon Jul 09 22:18:49 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.
@@ -270,6 +272,11 @@
     public static String HIRLowerNewInstance = "";
     public static String HIRLowerNewArray = "";
 
+    /**
+     * Use XIR to lower {@link Invoke} nodes.
+     */
+    public static boolean XIRLowerInvokes = true;
+
     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	Mon Jul 09 22:17:00 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Mon Jul 09 22:18:49 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/target/amd64/AMD64LIRGenerator.java	Mon Jul 09 22:17:00 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Mon Jul 09 22:18:49 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.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java	Mon Jul 09 22:17:00 2012 +0200
+++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java	Mon Jul 09 22:18:49 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	Mon Jul 09 22:17:00 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/meta/HotSpotXirGenerator.java	Mon Jul 09 22:17:00 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java	Mon Jul 09 22:18:49 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/target/amd64/HotSpotAMD64Backend.java	Mon Jul 09 22:17:00 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java	Mon Jul 09 22:18:49 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	Mon Jul 09 22:17:00 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Mon Jul 09 22:18:49 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/asm/TargetMethodAssembler.java	Mon Jul 09 22:17:00 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Mon Jul 09 22:18:49 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	Mon Jul 09 22:17:00 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Mon Jul 09 22:18:49 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/src/share/vm/classfile/systemDictionary.hpp	Mon Jul 09 22:17:00 2012 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Jul 09 22:18:49 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	Mon Jul 09 22:17:00 2012 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Jul 09 22:18:49 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	Mon Jul 09 22:17:00 2012 +0200
+++ b/src/share/vm/code/nmethod.cpp	Mon Jul 09 22:18:49 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	Mon Jul 09 22:17:00 2012 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Jul 09 22:18:49 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	Mon Jul 09 22:17:00 2012 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Jul 09 22:18:49 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;") \