# HG changeset patch # User Doug Simon # Date 1341865129 -7200 # Node ID 2585af1e26ac6f360176f8b2954c29c7f9b13b92 # Parent b3a87b533c0f9fef491792c004b9f6543fb3ea7e implemented non-XIR lowering of invokes (todo: inline virtual dispatch and null checking of receivers) removed HotSpotProxy class diff -r b3a87b533c0f -r 2585af1e26ac graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java --- 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; diff -r b3a87b533c0f -r 2585af1e26ac graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- 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 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 arguments, Value targetAddress, LIRFrameState info, Map marks); + protected abstract void emitCall(Object targetMethod, Value result, List arguments, Value targetAddress, LIRFrameState info, CallPositionListener ecl); private static Value toStackKind(Value value) { diff -r b3a87b533c0f -r 2585af1e26ac graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java --- 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 arguments, Value targetAddress, LIRFrameState info, Map marks) { + protected void emitCall(Object targetMethod, Value result, List 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)); } } diff -r b3a87b533c0f -r 2585af1e26ac graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java --- 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) { diff -r b3a87b533c0f -r 2585af1e26ac graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotProxy.java --- 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; - } - -} diff -r b3a87b533c0f -r 2585af1e26ac graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java --- 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"); } diff -r b3a87b533c0f -r 2585af1e26ac graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java --- 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 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 diff -r b3a87b533c0f -r 2585af1e26ac graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java --- 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 marks; + protected final CallPositionListener callPositionListener; - public DirectCallOp(Object targetMethod, Value result, Value[] parameters, LIRFrameState state, Map 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 marks; + protected final CallPositionListener callPositionListener; - public IndirectCallOp(Object targetMethod, Value result, Value[] parameters, Value targetAddress, LIRFrameState state, Map 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) { diff -r b3a87b533c0f -r 2585af1e26ac graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java --- 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); } diff -r b3a87b533c0f -r 2585af1e26ac graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java --- 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 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); diff -r b3a87b533c0f -r 2585af1e26ac src/share/vm/classfile/systemDictionary.hpp --- 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) \ diff -r b3a87b533c0f -r 2585af1e26ac src/share/vm/classfile/vmSymbols.hpp --- 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") \ diff -r b3a87b533c0f -r 2585af1e26ac src/share/vm/code/nmethod.cpp --- 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]"); diff -r b3a87b533c0f -r 2585af1e26ac src/share/vm/graal/graalCodeInstaller.cpp --- 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; diff -r b3a87b533c0f -r 2585af1e26ac src/share/vm/graal/graalJavaAccess.hpp --- 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;") \