# HG changeset patch # User twisti # Date 1374707957 25200 # Node ID 886c2df7a7e4ce4201926ded5643d0e94be7ec1a # Parent 3ad7c15c262396e53185805e9f1f9a0341a8cd7c Stubs need both an outgoing and incoming calling convention. diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java Wed Jul 24 16:19:17 2013 -0700 @@ -30,9 +30,16 @@ public interface ForeignCallLinkage extends InvokeTarget { /** - * Gets the details of where parameters are passed and value(s) are returned. + * Gets the details of where parameters are passed and value(s) are returned from the caller's + * perspective. */ - CallingConvention getCallingConvention(); + CallingConvention getOutgoingCallingConvention(); + + /** + * Gets the details of where parameters are passed and value(s) are returned from the callee's + * perspective. + */ + CallingConvention getIncomingCallingConvention(); /** * Returns the maximum absolute offset of PC relative call to this stub from any position in the diff -r 3ad7c15c2623 -r 886c2df7a7e4 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 Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Jul 24 16:19:17 2013 -0700 @@ -603,7 +603,7 @@ LIRFrameState state = !linkage.canDeoptimize() ? null : stateFor(info.getDeoptimizationState(), info.getDeoptimizationReason()); // move the arguments into the correct location - CallingConvention linkageCc = linkage.getCallingConvention(); + CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); frameMap.callsMethod(linkageCc); assert linkageCc.getArgumentCount() == args.length : "argument count mismatch"; Value[] argLocations = new Value[args.length]; diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Jul 24 16:19:17 2013 -0700 @@ -355,7 +355,7 @@ @Override public void emitUnwind(Value exception) { ForeignCallLinkage linkage = getRuntime().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER); - CallingConvention linkageCc = linkage.getCallingConvention(); + CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); assert linkageCc.getArgumentCount() == 2; RegisterValue exceptionParameter = (RegisterValue) linkageCc.getArgument(0); emitMove(exceptionParameter, exception); @@ -381,7 +381,7 @@ public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) { Variable handler = load(operand(handlerInCallerPc)); ForeignCallLinkage linkage = getRuntime().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER); - CallingConvention linkageCc = linkage.getCallingConvention(); + CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); assert linkageCc.getArgumentCount() == 2; RegisterValue exceptionFixed = (RegisterValue) linkageCc.getArgument(0); RegisterValue exceptionPcFixed = (RegisterValue) linkageCc.getArgument(1); diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Wed Jul 24 16:19:17 2013 -0700 @@ -61,8 +61,8 @@ RegisterValue exception = rax.asValue(Kind.Object); RegisterValue exceptionPc = rdx.asValue(word); CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc); - register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); - register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); + register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, exceptionCc, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); + register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); // The x86 crypto stubs do callee saving registerForeignCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Wed Jul 24 16:19:17 2013 -0700 @@ -51,7 +51,7 @@ leaveFrameAndRestoreRbp(tasm, masm); ForeignCallLinkage linkage = tasm.runtime.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER); - CallingConvention cc = linkage.getCallingConvention(); + CallingConvention cc = linkage.getOutgoingCallingConvention(); assert cc.getArgumentCount() == 2; assert exception.equals(cc.getArgument(0)); diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Jul 24 16:19:17 2013 -0700 @@ -154,7 +154,7 @@ @Override public void emitUnwind(Value exception) { ForeignCallLinkage linkage = getRuntime().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER); - CallingConvention linkageCc = linkage.getCallingConvention(); + CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); assert linkageCc.getArgumentCount() == 2; RegisterValue exceptionParameter = (RegisterValue) linkageCc.getArgument(0); emitMove(exceptionParameter, exception); @@ -182,7 +182,7 @@ public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) { Variable handler = load(operand(handlerInCallerPc)); ForeignCallLinkage linkage = getRuntime().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER); - CallingConvention linkageCc = linkage.getCallingConvention(); + CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); assert linkageCc.getArgumentCount() == 2; RegisterValue exceptionFixed = (RegisterValue) linkageCc.getArgument(0); RegisterValue exceptionPcFixed = (RegisterValue) linkageCc.getArgument(1); diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java Wed Jul 24 16:19:17 2013 -0700 @@ -51,11 +51,14 @@ // The calling convention for the exception handler stub is (only?) defined in // TemplateInterpreterGenerator::generate_throw_exception() // in templateInterpreter_sparc.cpp around line 1925 - RegisterValue exception = o0.asValue(Kind.Object); // XXX should this be i0? - RegisterValue exceptionPc = o1.asValue(word); // XXX should this be i1? - CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc); - register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); - register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); + RegisterValue outgoingException = o0.asValue(Kind.Object); + RegisterValue outgoingExceptionPc = o1.asValue(word); + RegisterValue incomingException = i0.asValue(Kind.Object); + RegisterValue incomingExceptionPc = i1.asValue(word); + CallingConvention outgoingExceptionCc = new CallingConvention(0, ILLEGAL, outgoingException, outgoingExceptionPc); + CallingConvention incomingExceptionCc = new CallingConvention(0, ILLEGAL, incomingException, incomingExceptionPc); + register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); + register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); super.registerReplacements(replacements); } diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java Wed Jul 24 16:19:17 2013 -0700 @@ -52,7 +52,7 @@ leaveFrame(tasm); ForeignCallLinkage linkage = tasm.runtime.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER); - CallingConvention cc = linkage.getCallingConvention(); + CallingConvention cc = linkage.getOutgoingCallingConvention(); assert cc.getArgumentCount() == 2; assert exception.equals(cc.getArgument(0)); diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java Wed Jul 24 16:19:17 2013 -0700 @@ -42,7 +42,7 @@ /** * Constants for specifying whether a foreign call destroys or preserves registers. A foreign - * call will always destroy {@link HotSpotForeignCallLinkage#getCallingConvention() its} + * call will always destroy {@link HotSpotForeignCallLinkage#getOutgoingCallingConvention() its} * {@linkplain ForeignCallLinkage#getTemporaries() temporary} registers. */ public enum RegisterEffect { @@ -81,7 +81,13 @@ /** * The calling convention for this call. */ - private final CallingConvention cc; + private final CallingConvention outgoingCallingConvention; + + /** + * The calling convention for incoming arguments to the stub, iff this call uses a compiled + * {@linkplain Stub stub}. + */ + private final CallingConvention incomingCallingConvention; private final RegisterEffect effect; @@ -106,17 +112,19 @@ * @param address the address of the code to call * @param effect specifies if the call destroys or preserves all registers (apart from * temporaries which are always destroyed) - * @param ccType calling convention type + * @param outgoingCcType outgoing (caller) calling convention type + * @param incomingCcType incoming (callee) calling convention type * @param transition specifies if this is a {@linkplain #canDeoptimize() leaf} call * @param reexecutable specifies if the call can be re-executed without (meaningful) side * effects. Deoptimization will not return to a point before a call that cannot be * re-executed. * @param killedLocations the memory locations killed by the call */ - public static HotSpotForeignCallLinkage create(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type ccType, Transition transition, boolean reexecutable, - LocationIdentity... killedLocations) { - CallingConvention targetCc = createCallingConvention(descriptor, ccType); - return new HotSpotForeignCallLinkage(descriptor, address, effect, transition, targetCc, reexecutable, killedLocations); + public static HotSpotForeignCallLinkage create(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type outgoingCcType, Type incomingCcType, Transition transition, + boolean reexecutable, LocationIdentity... killedLocations) { + CallingConvention outgoingCc = createCallingConvention(descriptor, outgoingCcType); + CallingConvention incomingCc = createCallingConvention(descriptor, incomingCcType); + return new HotSpotForeignCallLinkage(descriptor, address, effect, transition, outgoingCc, incomingCc, reexecutable, killedLocations); } /** @@ -142,13 +150,14 @@ } } - public HotSpotForeignCallLinkage(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Transition transition, CallingConvention cc, boolean reexecutable, - LocationIdentity... killedLocations) { + public HotSpotForeignCallLinkage(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Transition transition, CallingConvention outgoingCallingConvention, + CallingConvention incomingCallingConvention, boolean reexecutable, LocationIdentity... killedLocations) { this.address = address; this.effect = effect; this.transition = transition; this.descriptor = descriptor; - this.cc = cc; + this.outgoingCallingConvention = outgoingCallingConvention; + this.incomingCallingConvention = incomingCallingConvention; this.reexecutable = reexecutable; this.killedLocations = killedLocations; } @@ -156,7 +165,7 @@ @Override public String toString() { StringBuilder sb = new StringBuilder(stub == null ? descriptor.toString() : stub.toString()); - sb.append("@0x").append(Long.toHexString(address)).append(':').append(cc); + sb.append("@0x").append(Long.toHexString(address)).append(':').append(outgoingCallingConvention).append(":").append(incomingCallingConvention); if (temporaries != null && temporaries.length != 0) { sb.append("; temps="); String sep = ""; @@ -176,8 +185,12 @@ return killedLocations; } - public CallingConvention getCallingConvention() { - return cc; + public CallingConvention getOutgoingCallingConvention() { + return outgoingCallingConvention; + } + + public CallingConvention getIncomingCallingConvention() { + return incomingCallingConvention; } public Value[] getTemporaries() { diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Jul 24 16:19:17 2013 -0700 @@ -207,7 +207,7 @@ * @param killedLocations the memory locations killed by the stub call */ protected HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, boolean reexecutable, Transition transition, LocationIdentity... killedLocations) { - return register(HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCallee, transition, reexecutable, killedLocations)); + return register(HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations)); } /** @@ -222,7 +222,7 @@ boolean reexecutable, LocationIdentity... killedLocations) { Class resultType = descriptor.getResultType(); assert transition == LEAF || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor; - return register(HotSpotForeignCallLinkage.create(descriptor, address, effect, ccType, transition, reexecutable, killedLocations)); + return register(HotSpotForeignCallLinkage.create(descriptor, address, effect, ccType, ccType, transition, reexecutable, killedLocations)); } private static void link(Stub stub) { diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Wed Jul 24 16:19:17 2013 -0700 @@ -86,11 +86,11 @@ */ public ForeignCallStub(HotSpotRuntime runtime, Replacements replacements, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable, LocationIdentity... killedLocations) { - super(runtime, replacements, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCallee, transition, reexecutable, killedLocations)); + super(runtime, replacements, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations)); this.prependThread = prependThread; Class[] targetParameterTypes = createTargetParameters(descriptor); ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes); - target = HotSpotForeignCallLinkage.create(targetSig, address, DESTROYS_REGISTERS, NativeCall, transition, reexecutable, killedLocations); + target = HotSpotForeignCallLinkage.create(targetSig, address, DESTROYS_REGISTERS, NativeCall, NativeCall, transition, reexecutable, killedLocations); } /** @@ -220,7 +220,7 @@ @Override protected StructuredGraph getGraph() { Class[] args = linkage.getDescriptor().getArgumentTypes(); - boolean isObjectResult = linkage.getCallingConvention().getReturn().getKind() == Kind.Object; + boolean isObjectResult = linkage.getOutgoingCallingConvention().getReturn().getKind() == Kind.Object; GraphBuilder builder = new GraphBuilder(this); LocalNode[] locals = createLocals(builder, args); diff -r 3ad7c15c2623 -r 886c2df7a7e4 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Wed Jul 24 15:07:17 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Wed Jul 24 16:19:17 2013 -0700 @@ -154,8 +154,9 @@ PhasePlan phasePlan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - CallingConvention cc = linkage.getCallingConvention(); - final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, getInstalledCodeOwner(), runtime, replacements, backend, runtime.getTarget(), null, phasePlan, + // The stub itself needs the incoming calling convention. + CallingConvention incomingCc = linkage.getIncomingCallingConvention(); + final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), runtime, replacements, backend, runtime.getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), runtime.getDefaultSuites(), new CompilationResult()); assert destroyedRegisters != null;