# HG changeset patch # User Roland Schatz # Date 1362645805 -3600 # Node ID d413770c6dd089fa196d5e2766581f783209813e # Parent 73536049fa29aca448a29424f7b8f683f099da5c# Parent 1446b04e414841be569139d2292d91c325ee8fa5 Merge. diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Thu Mar 07 09:43:25 2013 +0100 @@ -466,4 +466,10 @@ public void visitSafepointNode(SafepointNode i) { throw new InternalError("NYI"); } + + @Override + public void emitUnwind(Value operand) { + // TODO Auto-generated method stub + + } } diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Thu Mar 07 09:43:25 2013 +0100 @@ -368,4 +368,10 @@ // SPARC: Auto-generated method stub } + + @Override + public void emitUnwind(Value operand) { + // TODO Auto-generated method stub + + } } diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java Wed Mar 06 15:20:21 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2012, 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.amd64; - -import static com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind.*; - -import com.oracle.graal.amd64.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.hotspot.bridge.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; -import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; -import com.oracle.graal.lir.asm.*; -import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; - -/** - * A direct call that complies with the conventions for such calls in HotSpot. In particular, for - * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call. - * This instruction (which moves 0L in RAX) is patched by the C++ Graal code to replace the 0L - * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the - * Klass in an inline cache. - */ -@Opcode("CALL_DIRECT") -final class AMD64DirectCallOp extends DirectCallOp { - - private final InvokeKind invokeKind; - - AMD64DirectCallOp(InvokeTarget target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) { - super(target, result, parameters, temps, state); - this.invokeKind = invokeKind; - assert invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - // The mark for an invocation that uses an inline cache must be placed at the - // instruction - // that loads the Klass from the inline cache so that the C++ code can find it - // and replace the inline 0L value with Universe::non_oop_word() - tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE); - AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.LONG_0); - emitAlignmentForDirectCall(tasm, masm); - AMD64Call.directCall(tasm, masm, callTarget, state); - } -} diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Thu Mar 07 09:43:25 2013 +0100 @@ -50,6 +50,7 @@ import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.phases.*; /** @@ -154,7 +155,15 @@ @Override protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - append(new AMD64DirectCallOp(callTarget.target(), result, parameters, temps, callState, ((HotSpotDirectCallTargetNode) callTarget).invokeKind())); + InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind(); + if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { + append(new AMD64HotspotDirectVirtualCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind)); + } else { + assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special; + HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target(); + Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant(); + append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod)); + } } @Override @@ -165,6 +174,13 @@ emitMove(targetAddress, operand(callTarget.computedAddress())); append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState)); } + + @Override + public void emitUnwind(Value exception) { + RegisterValue exceptionParameter = AMD64.rax.asValue(); + emitMove(exceptionParameter, exception); + append(new AMD64HotSpotUnwindOp(exceptionParameter)); + } } /** @@ -203,7 +219,6 @@ AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; emitStackOverflowCheck(tasm, false); asm.push(rbp); - asm.movq(rbp, rsp); asm.decrementq(rsp, frameSize - 8); // account for the push of RBP above if (GraalOptions.ZapStackOnMethodEntry) { final int intSize = 4; diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Thu Mar 07 09:43:25 2013 +0100 @@ -37,9 +37,8 @@ // @formatter:off public class AMD64HotSpotRegisterConfig implements RegisterConfig { - // be careful - the contents of this array are duplicated in graal_CodeInstaller.cpp private final Register[] allocatable = { - rax, rbx, rcx, rdx, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15*/ + rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15, */ xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 }; diff -r 73536049fa29 -r d413770c6dd0 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 Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Thu Mar 07 09:43:25 2013 +0100 @@ -54,6 +54,10 @@ Kind word = graalRuntime.getTarget().wordKind; // @formatter:off + addRuntimeCall(AMD64HotSpotUnwindOp.UNWIND_EXCEPTION, config.unwindExceptionStub, + /* temps */ null, + /* ret */ ret(Kind.Void), + /* arg0: exception */ javaCallingConvention(Kind.Object)); addRuntimeCall(DEOPTIMIZE, config.deoptimizeStub, /* temps */ null, diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Thu Mar 07 09:43:25 2013 +0100 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012, 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.amd64; + +import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.amd64.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.RuntimeCallTarget.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; + +/** + * Performs an unwind to throw an exception. + */ +@Opcode("CALL_INDIRECT") +final class AMD64HotSpotUnwindOp extends AMD64LIRInstruction { + + public static final Descriptor UNWIND_EXCEPTION = new Descriptor("unwindException", true, void.class, Object.class); + + /** + * Vtable stubs expect the metaspace Method in RBX. + */ + public static final Register METHOD = AMD64.rbx; + + @Use({REG}) protected AllocatableValue exception; + @Temp private RegisterValue framePointer; + + AMD64HotSpotUnwindOp(AllocatableValue exception) { + this.exception = exception; + assert exception == AMD64.rax.asValue(); + framePointer = AMD64.rbp.asValue(); + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + masm.movq(framePointer.getRegister(), rsp); + masm.incrementq(framePointer.getRegister(), tasm.frameMap.frameSize() - 8); + AMD64Call.directCall(tasm, masm, tasm.runtime.lookupRuntimeCall(UNWIND_EXCEPTION), null); + } +} diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java Thu Mar 07 09:43:25 2013 +0100 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012, 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.amd64; + +import com.oracle.graal.amd64.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; + +/** + * A direct call that complies with the conventions for such calls in HotSpot. In particular, for + * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call. + * This instruction (which moves 0L in RAX) is patched by the C++ Graal code to replace the 0L + * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the + * Klass in an inline cache. It puts the called method into rbx before calling. + */ +@Opcode("CALL_DIRECT") +final class AMD64HotspotDirectStaticCallOp extends DirectCallOp { + + private final Constant metaspaceMethod; + private final InvokeKind invokeKind; + + AMD64HotspotDirectStaticCallOp(InvokeTarget target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, Constant metaspaceMethod) { + super(target, result, parameters, temps, state); + assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special; + this.metaspaceMethod = metaspaceMethod; + this.invokeKind = invokeKind; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + // The mark for an invocation that uses an inline cache must be placed at the + // instruction + // that loads the Klass from the inline cache so that the C++ code can find it + // and replace the inline 0L value with Universe::non_oop_word() + AMD64Move.move(tasm, masm, AMD64.rbx.asValue(Kind.Long), metaspaceMethod); + tasm.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL); + AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.LONG_0); + super.emitCode(tasm, masm); + } +} diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java Thu Mar 07 09:43:25 2013 +0100 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012, 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.amd64; + +import static com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind.*; + +import com.oracle.graal.amd64.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; + +/** + * A direct call that complies with the conventions for such calls in HotSpot. In particular, for + * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call. + * This instruction (which moves 0L in RAX) is patched by the C++ Graal code to replace the 0L + * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the + * Klass in an inline cache. + */ +@Opcode("CALL_DIRECT") +final class AMD64HotspotDirectVirtualCallOp extends DirectCallOp { + + private final InvokeKind invokeKind; + + AMD64HotspotDirectVirtualCallOp(InvokeTarget target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) { + super(target, result, parameters, temps, state); + this.invokeKind = invokeKind; + assert invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + // The mark for an invocation that uses an inline cache must be placed at the + // instruction + // that loads the Klass from the inline cache so that the C++ code can find it + // and replace the inline 0L value with Universe::non_oop_word() + tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE); + AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.LONG_0); + super.emitCode(tasm, masm); + } +} diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Thu Mar 07 09:43:25 2013 +0100 @@ -304,7 +304,6 @@ public int typeProfileWidth; // runtime stubs - public long instanceofStub; public long newInstanceStub; public long newArrayStub; public long newMultiArrayStub; diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/Marks.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/Marks.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/Marks.java Thu Mar 07 09:43:25 2013 +0100 @@ -36,9 +36,11 @@ int MARK_DEOPT_HANDLER_ENTRY = 5; int MARK_INVOKEINTERFACE = 6; int MARK_INVOKEVIRTUAL = 7; - int MARK_INLINE_INVOKE = 8; - int MARK_POLL_NEAR = 9; - int MARK_POLL_RETURN_NEAR = 10; - int MARK_POLL_FAR = 11; - int MARK_POLL_RETURN_FAR = 12; + int MARK_INVOKESTATIC = 8; + int MARK_INVOKESPECIAL = 9; + int MARK_INLINE_INVOKE = 10; + int MARK_POLL_NEAR = 11; + int MARK_POLL_RETURN_NEAR = 12; + int MARK_POLL_FAR = 13; + int MARK_POLL_RETURN_FAR = 14; } diff -r 73536049fa29 -r d413770c6dd0 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 Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Mar 07 09:43:25 2013 +0100 @@ -32,7 +32,6 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.snippets.SystemSubstitutions.*; import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; -import static com.oracle.graal.nodes.UnwindNode.*; import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*; import static com.oracle.graal.snippets.Log.*; import static com.oracle.graal.snippets.MathSubstitutionsX86.*; @@ -204,11 +203,6 @@ // @formatter:off - addRuntimeCall(UNWIND_EXCEPTION, config.unwindExceptionStub, - /* temps */ null, - /* ret */ ret(Kind.Void), - /* arg0: exception */ javaCallingConvention(Kind.Object)); - addRuntimeCall(OnStackReplacementPhase.OSR_MIGRATION_END, config.osrMigrationEndStub, /* temps */ null, /* ret */ ret(Kind.Void), @@ -571,13 +565,8 @@ } } } else if (callTarget.invokeKind() == InvokeKind.Special || callTarget.invokeKind() == InvokeKind.Static) { - HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); - ConstantNode metaspaceMethod = ConstantNode.forConstant(hsMethod.getMetaspaceMethodConstant(), this, graph); - ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph), - StampFactory.forKind(wordKind()))); - loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), - CallingConvention.Type.JavaCall)); - graph.addBeforeFixed(invoke.node(), compiledEntry); + loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall, + callTarget.invokeKind())); } if (loweredCallTarget == null) { diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Thu Mar 07 09:43:25 2013 +0100 @@ -159,7 +159,7 @@ @Opcode private final AMD64Arithmetic opcode; @Def({REG, HINT}) protected AllocatableValue result; @Use({REG, STACK}) protected AllocatableValue x; - @Use({CONST}) protected Constant y; + protected Constant y; public BinaryRegConst(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) { this.opcode = opcode; @@ -221,7 +221,7 @@ @Opcode private final AMD64Arithmetic opcode; @Def({REG}) protected AllocatableValue result; @Use({REG, STACK}) protected AllocatableValue x; - @Use({CONST}) protected Constant y; + protected Constant y; public BinaryRegStackConst(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) { this.opcode = opcode; diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Thu Mar 07 09:43:25 2013 +0100 @@ -230,7 +230,7 @@ public static class StoreConstantOp extends MemOp { - @Use({CONST}) protected Constant input; + protected final Constant input; public StoreConstantOp(AMD64Address address, Constant input, LIRFrameState state) { super(address, state); diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Thu Mar 07 09:43:25 2013 +0100 @@ -58,6 +58,7 @@ private static final Class INSTRUCTION_CLASS = LIRInstruction.class; private static final Class VALUE_CLASS = Value.class; + private static final Class CONSTANT_CLASS = Constant.class; private static final Class VALUE_ARRAY_CLASS = Value[].class; private static final Class STATE_CLASS = LIRFrameState.class; @@ -219,7 +220,7 @@ @Override protected void scanField(Field field, Class type, long offset) { - if (VALUE_CLASS.isAssignableFrom(type)) { + if (VALUE_CLASS.isAssignableFrom(type) && type != CONSTANT_CLASS) { assert !Modifier.isFinal(field.getModifiers()) : "Value field must not be declared final because it is modified by register allocator: " + field; OperandModeAnnotation annotation = getOperandModeAnnotation(field); assert annotation != null : "Field must have operand mode annotation: " + field; diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java Thu Mar 07 09:43:25 2013 +0100 @@ -22,8 +22,6 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; @@ -35,8 +33,6 @@ */ public final class UnwindNode extends FixedNode implements LIRLowerable, Node.IterableNodeType { - public static final Descriptor UNWIND_EXCEPTION = new Descriptor("unwindException", true, void.class, Object.class); - @Input private ValueNode exception; public ValueNode exception() { @@ -51,7 +47,6 @@ @Override public void generate(LIRGeneratorTool gen) { - RuntimeCallTarget call = gen.getRuntime().lookupRuntimeCall(UNWIND_EXCEPTION); - gen.emitCall(call, call.getCallingConvention(), false, gen.operand(exception())); + gen.emitUnwind(gen.operand(exception())); } } diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Mar 07 09:43:25 2013 +0100 @@ -132,4 +132,6 @@ public abstract void visitSafepointNode(SafepointNode i); public abstract void visitBreakpointNode(BreakpointNode i); + + public abstract void emitUnwind(Value operand); } diff -r 73536049fa29 -r d413770c6dd0 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Wed Mar 06 15:20:21 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Thu Mar 07 09:43:25 2013 +0100 @@ -164,7 +164,7 @@ public static boolean GenAssertionCode = ____; public static boolean AlignCallsForPatching = true; public static boolean ResolveClassBeforeStaticInvoke = ____; - public static boolean CanOmitFrame = true; + public static boolean CanOmitFrame = false; public static int SafepointPollOffset = 256; public static boolean MemoryAwareScheduling = true; diff -r 73536049fa29 -r d413770c6dd0 mx/commands.py --- a/mx/commands.py Wed Mar 06 15:20:21 2013 +0100 +++ b/mx/commands.py Thu Mar 07 09:43:25 2013 +0100 @@ -373,8 +373,20 @@ else: if not exists(jdk): mx.abort('The ' + build + ' VM has not been created - run \'mx clean; mx build ' + build + '\'') + + _installGraalJarInJdks(mx.distribution('GRAAL')) + return jdk +def _installGraalJarInJdks(graalDist): + graalJar = graalDist.path + jdks = join(_graal_home, 'jdk' + str(mx.java().version)) + if exists(jdks): + for e in os.listdir(jdks): + jreLibDir = join(jdks, e, 'jre', 'lib') + if exists(jreLibDir): + shutil.copyfile(graalJar, join(jreLibDir, 'graal.jar')) + # run a command in the windows SDK Debug Shell def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo={}): newLine = os.linesep @@ -488,25 +500,6 @@ if not 'Xusage.txt' in line: sys.stderr.write(line + os.linesep) - # Check that the declaration of graal_projects in arguments.cpp is up to date - argumentsCpp = join(_graal_home, 'src', 'share', 'vm', 'runtime', 'arguments.cpp') - assert exists(argumentsCpp), 'File does not exist: ' + argumentsCpp - with open(argumentsCpp) as fp: - source = fp.read(); - decl = 'const char* graal_projects[] = {' - start = source.find(decl) - assert start != -1, 'Could not find "' + decl + '" in ' + fp.name - end = source.find('};', start) - assert end != -1, 'Could not find "' + decl + '" ... "};" in ' + fp.name - actual = frozenset(re.findall(r'"([^"]+)"', source[start + len(decl):end])) - expected = frozenset([p.name for p in mx.project('com.oracle.graal.hotspot.' + _arch()).all_deps([], False)]) - missing = expected - actual - extra = actual - expected - if len(missing) != 0: - mx.abort(fp.name + ':' + str(source[:start].count('\n') + 1) + ': add missing project(s) to declaration:\n ' + '\n '.join(missing)) - if len(extra) != 0: - mx.abort(fp.name + ':' + str(source[:start].count('\n') + 1) + ': remove project(s) from declaration:\n ' + '\n '.join(extra)) - # Check if a build really needs to be done timestampFile = join(vmDir, '.build-timestamp') if opts2.force or not exists(timestampFile): @@ -656,6 +649,7 @@ args = ['-javaagent:' + jacocoagent.get_path(True) + '=' + ','.join([k + '=' + v for k, v in agentOptions.items()])] + args if '-d64' not in args: args = ['-d64'] + args + exe = join(jdk, 'bin', mx.exe_suffix('java')) dbg = _native_dbg.split() if _native_dbg is not None else [] return mx.run(dbg + [exe, '-' + vm] + args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout) @@ -1173,3 +1167,5 @@ _jacoco = opts.jacoco global _native_dbg _native_dbg = opts.native_dbg + + mx.distribution('GRAAL').add_update_listener(_installGraalJarInJdks) diff -r 73536049fa29 -r d413770c6dd0 mx/projects --- a/mx/projects Wed Mar 06 15:20:21 2013 +0100 +++ b/mx/projects Thu Mar 07 09:43:25 2013 +0100 @@ -22,6 +22,9 @@ library@DACAPO_SCALA@path=lib/dacapo-scala-0.1.0-20120216.jar library@DACAPO_SCALA@urls=http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20120216.103539-3.jar +distribution@GRAAL@path=graal.jar +distribution@GRAAL@dependencies=com.oracle.graal.hotspot.amd64,com.oracle.graal.hotspot.sparc + # graal.api.runtime project@com.oracle.graal.api.runtime@subDir=graal project@com.oracle.graal.api.runtime@sourceDirs=src diff -r 73536049fa29 -r d413770c6dd0 mxtool/mx.py --- a/mxtool/mx.py Wed Mar 06 15:20:21 2013 +0100 +++ b/mxtool/mx.py Thu Mar 07 09:43:25 2013 +0100 @@ -143,12 +143,36 @@ _projects = dict() _libs = dict() +_dists = dict() _suites = dict() _mainSuite = None _opts = None _java = None """ +A distribution is a jar or zip file containing the output from one or more Java projects. +""" +class Distribution: + def __init__(self, suite, name, path, deps): + self.suite = suite + self.name = name + self.path = path.replace('/', os.sep) + if not isabs(self.path): + self.path = join(suite.dir, self.path) + self.deps = deps + self.update_listeners = set() + + def __str__(self): + return self.name + + def add_update_listener(self, listener): + self.update_listeners.add(listener) + + def notify_updated(self): + for l in self.update_listeners: + l(self) + +""" A dependency is a library or project specified in a suite. """ class Dependency: @@ -416,6 +440,7 @@ self.dir = d self.projects = [] self.libs = [] + self.dists = [] self.includes = [] self.commands = None self.primary = primary @@ -427,6 +452,7 @@ def _load_projects(self, mxDir): libsMap = dict() projsMap = dict() + distsMap = dict() projectsFile = join(mxDir, 'projects') if not exists(projectsFile): return @@ -447,8 +473,10 @@ m = projsMap elif kind == 'library': m = libsMap + elif kind == 'distribution': + m = distsMap else: - abort('Property name does not start with "project@" or "library@": ' + key) + abort('Property name does not start with "project@", "library@" or "distribution@": ' + key) attrs = m.get(name) if attrs is None: @@ -494,6 +522,13 @@ l.__dict__.update(attrs) self.libs.append(l) + for name, attrs in distsMap.iteritems(): + path = attrs.pop('path') + deps = pop_list(attrs, 'dependencies') + d = Distribution(self, name, path, deps) + d.__dict__.update(attrs) + self.dists.append(d) + def _load_commands(self, mxDir): commands = join(mxDir, 'commands.py') if exists(commands): @@ -536,8 +571,6 @@ def _post_init(self, opts): mxDir = join(self.dir, 'mx') self._load_projects(mxDir) - if hasattr(self, 'mx_post_parse_cmd_line'): - self.mx_post_parse_cmd_line(opts) for p in self.projects: existing = _projects.get(p.name) if existing is not None: @@ -549,6 +582,13 @@ if existing is not None: abort('cannot redefine library ' + l.name) _libs[l.name] = l + for d in self.dists: + existing = _dists.get(l.name) + if existing is not None: + abort('cannot redefine distribution ' + d.name) + _dists[d.name] = d + if hasattr(self, 'mx_post_parse_cmd_line'): + self.mx_post_parse_cmd_line(opts) class XMLElement(xml.dom.minidom.Element): def writexml(self, writer, indent="", addindent="", newl=""): @@ -653,6 +693,16 @@ """ return _projects.values() +def distribution(name, fatalIfMissing=True): + """ + Get the distribution for a given name. This will abort if the named distribution does + not exist and 'fatalIfMissing' is true. + """ + d = _dists.get(name) + if d is None and fatalIfMissing: + abort('distribution named ' + name + ' not found') + return d + def project(name, fatalIfMissing=True): """ Get the project for a given name. This will abort if the named project does @@ -1477,6 +1527,9 @@ finally: for n in toBeDeleted: os.remove(n) + + for dist in _dists.values(): + archive(['@' + dist.name]) if suppliedParser: return args @@ -1578,7 +1631,7 @@ projects = set() for p in sorted_deps(): - if _needsEclipseJarBuild(p): + if _isAnnotationProcessorDependency(p): projects.add(p) if len(projects) <= 0: @@ -1586,37 +1639,40 @@ pnames = [p.name for p in projects] build(['--projects', ",".join(pnames)]) - jarprojects(pnames) - -def jarprojects(args): - """create jar files for the output of one or more projects""" - parser = ArgumentParser(prog='mx jar'); - parser.add_argument('-d', '--dest', help='single jar file to create') - parser.add_argument('projects', nargs=REMAINDER, metavar='projects...') + archive(pnames) + +def archive(args): + """create jar files for projects and distributions""" + parser = ArgumentParser(prog='mx archive'); + parser.add_argument('names', nargs=REMAINDER, metavar='[|@]...') args = parser.parse_args(args) - if not args.projects: - args.projects = [p.name for p in projects()] - - if args.dest is not None: - zf = zipfile.ZipFile(args.dest, 'w') - - for pname in args.projects: - p = project(pname, fatalIfMissing=True) - if args.dest is None: + for name in args.names: + if name.startswith('@'): + dname = name[1:] + d = distribution(dname) + zf = zipfile.ZipFile(d.path, 'w') + for p in sorted_deps(d.deps): + outputDir = p.output_dir() + for root, _, files in os.walk(outputDir): + for f in files: + relpath = root[len(outputDir) + 1:] + arcname = join(relpath, f).replace(os.sep, '/') + zf.write(join(root, f), arcname) + zf.close() + d.notify_updated() + + else: + p = project(name) + outputDir = p.output_dir() jar = join(p.dir, p.name + '.jar') zf = zipfile.ZipFile(jar, 'w') - outputDir = p.output_dir() - for root, _, files in os.walk(outputDir): - for f in files: - relpath = root[len(outputDir) + 1:] - arcname = join(relpath, f).replace(os.sep, '/') - zf.write(join(root, f), arcname) - if args.dest is None: + for root, _, files in os.walk(outputDir): + for f in files: + relpath = root[len(outputDir) + 1:] + arcname = join(relpath, f).replace(os.sep, '/') + zf.write(join(root, f), arcname) zf.close() - - if args.dest is not None: - zf.close() def canonicalizeprojects(args): """process all project files to canonicalize the dependencies @@ -1996,6 +2052,12 @@ if buildProcessorJars: processorjars() + projToDist = dict() + for dist in _dists.values(): + distDeps = sorted_deps(dist.deps) + for p in distDeps: + projToDist[p.name] = (dist, [dep.name for dep in distDeps]) + for p in projects(): if p.native: continue @@ -2110,24 +2172,14 @@ out.element('arguments', data='') out.close('buildCommand') - if (_needsEclipseJarBuild(p)): - targetValues = _genEclipseJarBuild(p); - for value in targetValues: - out.open('buildCommand') - out.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder') - out.element('triggers', data='auto,full,incremental,') - out.open('arguments') - out.open('dictionary') - out.element('key', data = 'LaunchConfigHandle') - out.element('value', data = value) - out.close('dictionary') - out.open('dictionary') - out.element('key', data = 'incclean') - out.element('value', data = 'true') - out.close('dictionary') - out.close('arguments') - out.close('buildCommand') - + if _isAnnotationProcessorDependency(p): + _genEclipseBuilder(out, p, 'Jar.launch', 'archive ' + p.name, refresh = False, async = False) + _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh = True, async = True) + + if projToDist.has_key(p.name): + dist, distDeps = projToDist[p.name] + _genEclipseBuilder(out, p, 'Create' + dist.name + 'Dist.launch', 'archive @' + dist.name, refresh=False, async=True) + out.close('buildSpec') out.open('natures') out.element('nature', data='org.eclipse.jdt.core.javanature') @@ -2182,8 +2234,11 @@ make_eclipse_attach('localhost', '8000', deps=projects()) -def _needsEclipseJarBuild(p): - processors = set([]) +def _isAnnotationProcessorDependency(p): + """ + Determines if a given project is part of an annotation processor. + """ + processors = set() for otherProject in projects(): if hasattr(otherProject, 'annotationProcessors') and len(otherProject.annotationProcessors) > 0: @@ -2200,13 +2255,7 @@ return False -def _genEclipseJarBuild(p): - builders = [] - builders.append(_genEclipseLaunch(p, 'Jar.launch', ''.join(['jarprojects ', p.name]), refresh = False, async = False)) - builders.append(_genEclipseLaunch(p, 'Refresh.launch', '', refresh = True, async = True)) - return builders - -def _genEclipseLaunch(p, name, mxCommand, refresh=True, async=False): +def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False): launchOut = XMLDoc(); launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'}) if refresh: @@ -2236,9 +2285,21 @@ os.makedirs(externalToolDir) update_file(join(externalToolDir, name), launchOut.xml(indent='\t', newl='\n')) - return ''.join(["/.externalToolBuilders/", name]) - - + dotProjectDoc.open('buildCommand') + dotProjectDoc.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder') + dotProjectDoc.element('triggers', data='auto,full,incremental,') + dotProjectDoc.open('arguments') + dotProjectDoc.open('dictionary') + dotProjectDoc.element('key', data = 'LaunchConfigHandle') + dotProjectDoc.element('value', data = '/.externalToolBuilders/' + name) + dotProjectDoc.close('dictionary') + dotProjectDoc.open('dictionary') + dotProjectDoc.element('key', data = 'incclean') + dotProjectDoc.element('value', data = 'true') + dotProjectDoc.close('dictionary') + dotProjectDoc.close('arguments') + dotProjectDoc.close('buildCommand') + def netbeansinit(args, suite=None): """(re)generate NetBeans project configurations""" @@ -2496,8 +2557,7 @@ projectConfigFiles = frozenset(['.classpath', 'nbproject']) indicators = projectConfigFiles.intersection(files) if len(indicators) != 0: - response = raw_input(currentDir + ' looks like a removed project -- delete it? [yn]: ') - if 'y' == response: + if not sys.stdout.isatty() or raw_input(currentDir + ' looks like a removed project -- delete it? [yn]: ') == 'y': shutil.rmtree(currentDir) log('Deleted ' + currentDir) @@ -2956,7 +3016,7 @@ 'help': [help_, '[command]'], 'ideclean': [ideclean, ''], 'ideinit': [ideinit, ''], - 'jarprojects': [jarprojects, '[options]'], + 'archive': [archive, '[options]'], 'projectgraph': [projectgraph, ''], 'javap': [javap, ''], 'javadoc': [javadoc, '[options]'], diff -r 73536049fa29 -r d413770c6dd0 src/cpu/x86/vm/graalRuntime_x86.cpp --- a/src/cpu/x86/vm/graalRuntime_x86.cpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/cpu/x86/vm/graalRuntime_x86.cpp Thu Mar 07 09:43:25 2013 +0100 @@ -46,12 +46,6 @@ assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different"); assert(oop_result1 != thread && metadata_result != thread, "registers must be different"); assert(args_size >= 0, "illegal args_size"); - bool align_stack = false; -#ifdef _LP64 - // At a method handle call, the stack may not be properly aligned - // when returning with an exception. - align_stack = (stub_id() == false /*GraalRuntime::handle_exception_from_callee_id*/); -#endif #ifdef _LP64 mov(c_rarg0, thread); @@ -65,20 +59,11 @@ #endif // _LP64 int call_offset; - if (!align_stack) { - set_last_Java_frame(thread, noreg, rbp, NULL); - } else { - address the_pc = pc(); - call_offset = offset(); - set_last_Java_frame(thread, noreg, rbp, the_pc); - andptr(rsp, -(StackAlignmentInBytes)); // Align stack - } + set_last_Java_frame(thread, rsp, noreg, NULL); // do the call call(RuntimeAddress(entry)); - if (!align_stack) { - call_offset = offset(); - } + call_offset = offset(); // verify callee-saved register #ifdef ASSERT guarantee(thread != rax, "change this code"); @@ -93,7 +78,7 @@ } pop(rax); #endif - reset_last_Java_frame(thread, true, align_stack); + reset_last_Java_frame(thread, true, false); // discard thread and arguments NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord)); @@ -356,6 +341,7 @@ map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(rbp_off + num_rt_args), rbp->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi->as_VMReg()); #ifdef _LP64 @@ -373,6 +359,7 @@ map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next()); map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next()); map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rbpH_off + num_rt_args), rbp->as_VMReg()->next()); map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next()); map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next()); @@ -933,69 +920,10 @@ } break; - case slow_subtype_check_id: - { - // Typical calling sequence: - // __ push(klass_RInfo); // object klass or other subclass - // __ push(sup_k_RInfo); // array element klass or other superclass - // __ call(slow_subtype_check); - // Note that the subclass is pushed first, and is therefore deepest. - // Previous versions of this code reversed the names 'sub' and 'super'. - // This was operationally harmless but made the code unreadable. - enum layout { - rax_off, SLOT2(raxH_off) - rcx_off, SLOT2(rcxH_off) - rsi_off, SLOT2(rsiH_off) - rdi_off, SLOT2(rdiH_off) - // saved_rbp_off, SLOT2(saved_rbpH_off) - return_off, SLOT2(returnH_off) - sup_k_off, SLOT2(sup_kH_off) - klass_off, SLOT2(superH_off) - framesize, - result_off = klass_off // deepest argument is also the return value - }; - - __ set_info("slow_subtype_check", dont_gc_arguments); - __ push(rdi); - __ push(rsi); - __ push(rcx); - __ push(rax); - - // This is called by pushing args and not with C abi - __ movptr(rsi, Address(rsp, (klass_off) * VMRegImpl::stack_slot_size)); // subclass - __ movptr(rax, Address(rsp, (sup_k_off) * VMRegImpl::stack_slot_size)); // superclass - - Label miss; - Label success; - __ check_klass_subtype_fast_path(rsi, rax, rcx, &success, &miss, NULL); - - __ check_klass_subtype_slow_path(rsi, rax, rcx, rdi, NULL, &miss); - - // fallthrough on success: - __ bind(success); - __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), 1); // result - __ pop(rax); - __ pop(rcx); - __ pop(rsi); - __ pop(rdi); - __ ret(0); - - __ bind(miss); - __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result - __ pop(rax); - __ pop(rcx); - __ pop(rsi); - __ pop(rdi); - __ ret(0); - } - break; - case unwind_exception_call_id: { // remove the frame from the stack __ movptr(rsp, rbp); __ pop(rbp); - // exception_oop is passed using ordinary java calling conventions - __ movptr(rax, j_rarg0); Label nonNullExceptionOop; __ testptr(rax, rax); diff -r 73536049fa29 -r d413770c6dd0 src/share/vm/classfile/classLoader.cpp --- a/src/share/vm/classfile/classLoader.cpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/share/vm/classfile/classLoader.cpp Thu Mar 07 09:43:25 2013 +0100 @@ -442,20 +442,11 @@ void ClassLoader::setup_bootstrap_search_path() { assert(_first_entry == NULL, "should not setup bootstrap class search path twice"); char* sys_class_path = os::strdup(Arguments::get_sysclasspath()); -#ifdef GRAAL - char* compiler_class_path = os::strdup(Arguments::get_compilerclasspath()); -#endif if (TraceClassLoading && Verbose) { tty->print_cr("[Bootstrap loader class path=%s]", sys_class_path); -#ifdef GRAAL - tty->print_cr("[Compiler loader class path=%s]", compiler_class_path); -#endif } setup_bootstrap_search_path(sys_class_path); -#ifdef GRAAL - setup_bootstrap_search_path(compiler_class_path); -#endif } void ClassLoader::setup_bootstrap_search_path(char* sys_class_path) { diff -r 73536049fa29 -r d413770c6dd0 src/share/vm/code/compiledIC.cpp --- a/src/share/vm/code/compiledIC.cpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/share/vm/code/compiledIC.cpp Thu Mar 07 09:43:25 2013 +0100 @@ -95,7 +95,7 @@ // Don't use ic_destination for this test since that forwards // through ICBuffer instead of returning the actual current state of // the CompiledIC. - if (is_icholder_entry(_ic_call->destination())) { + if (is_icholder_entry(_ic_call->destination()) && !_is_optimized) { // When patching for the ICStub case the cached value isn't // overwritten until the ICStub copied into the CompiledIC during // the next safepoint. Make sure that the CompiledICHolder* is @@ -126,6 +126,13 @@ _ic_call->set_destination_mt_safe(entry_point); } +#ifdef GRAAL + if (_value == NULL) { + // Can happen when Graal converted a virtual call into an invoke special based on static analysis. + return; + } +#endif + if (is_optimized() || is_icstub) { // Optimized call sites don't have a cache value and ICStub call // sites only change the entry point. Changing the value in that @@ -265,12 +272,14 @@ // Check if we are calling into our own codeblob (i.e., to a stub) CodeBlob* cb = CodeCache::find_blob(_ic_call->instruction_address()); address dest = ic_destination(); +#ifndef GRAAL #ifdef ASSERT { CodeBlob* db = CodeCache::find_blob_unsafe(dest); assert(!db->is_adapter_blob(), "must use stub!"); } #endif /* ASSERT */ +#endif is_call_to_interpreted = cb->contains(dest); } return is_call_to_interpreted; @@ -551,7 +560,13 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) { + set_destination_mt_safe(entry); address stub=find_stub(); +#ifdef GRAAL + if (stub == NULL) { + return; + } +#endif assert(stub!=NULL, "stub not found"); if (TraceICs) { @@ -646,7 +661,11 @@ case relocInfo::poll_type: case relocInfo::poll_return_type: // A safepoint can't overlap a call. default: +#ifdef GRAAL + return NULL; +#else ShouldNotReachHere(); +#endif } } } @@ -702,9 +721,11 @@ // Verify stub address stub = find_stub(); +#ifndef GRAAL assert(stub != NULL, "no stub found for static call"); NativeMovConstReg* method_holder = nativeMovConstReg_at(stub); // creation also verifies the object NativeJump* jump = nativeJump_at(method_holder->next_instruction_address()); +#endif // Verify state assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check"); diff -r 73536049fa29 -r d413770c6dd0 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Thu Mar 07 09:43:25 2013 +0100 @@ -699,6 +699,21 @@ _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); break; } + case MARK_INVOKESTATIC: { + assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); + + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_static_call_stub()); + _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand); + break; + } + case MARK_INVOKESPECIAL: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand); + break; + } default: fatal("invalid _next_call_type value"); break; @@ -807,6 +822,8 @@ n_copy->set_data((intptr_t)Universe::non_oop_word()); } case MARK_INLINE_INVOKE: + case MARK_INVOKESTATIC: + case MARK_INVOKESPECIAL: _next_call_type = (MarkId) id; _invoke_mark_pc = instruction; break; diff -r 73536049fa29 -r d413770c6dd0 src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Thu Mar 07 09:43:25 2013 +0100 @@ -38,11 +38,13 @@ MARK_DEOPT_HANDLER_ENTRY = 5, MARK_INVOKEINTERFACE = 6, MARK_INVOKEVIRTUAL = 7, - MARK_INLINE_INVOKE = 8, - MARK_POLL_NEAR = 9, - MARK_POLL_RETURN_NEAR = 10, - MARK_POLL_FAR = 11, - MARK_POLL_RETURN_FAR = 12, + MARK_INVOKESTATIC = 8, + MARK_INVOKESPECIAL = 9, + MARK_INLINE_INVOKE = 10, + MARK_POLL_NEAR = 11, + MARK_POLL_RETURN_NEAR = 12, + MARK_POLL_FAR = 13, + MARK_POLL_RETURN_FAR = 14, MARK_INVOKE_INVALID = -1 }; diff -r 73536049fa29 -r d413770c6dd0 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu Mar 07 09:43:25 2013 +0100 @@ -702,7 +702,6 @@ set_int("layoutHelperHeaderSizeMask", Klass::_lh_header_size_mask); set_int("layoutHelperOffset", in_bytes(Klass::layout_helper_offset())); - set_stub("instanceofStub", GraalRuntime::entry_for(GraalRuntime::slow_subtype_check_id)); set_stub("newInstanceStub", GraalRuntime::entry_for(GraalRuntime::new_instance_id)); set_stub("newArrayStub", GraalRuntime::entry_for(GraalRuntime::new_array_id)); set_stub("newMultiArrayStub", GraalRuntime::entry_for(GraalRuntime::new_multi_array_id)); diff -r 73536049fa29 -r d413770c6dd0 src/share/vm/graal/graalGlobals.hpp --- a/src/share/vm/graal/graalGlobals.hpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/share/vm/graal/graalGlobals.hpp Thu Mar 07 09:43:25 2013 +0100 @@ -52,9 +52,6 @@ product(bool, BootstrapGraal, GRAALVM_ONLY(true) NOT_GRAALVM(false), \ "Bootstrap Graal before running Java main method") \ \ - product(ccstr, GraalClassPath, NULL, \ - "Use this path, zip, or jar, to locate Graal-specific classes") \ - \ product(intx, TraceGraal, 0, \ "Trace level for Graal") \ \ diff -r 73536049fa29 -r d413770c6dd0 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/share/vm/graal/graalRuntime.cpp Thu Mar 07 09:43:25 2013 +0100 @@ -127,7 +127,6 @@ // Make sure that stubs that need oopmaps have them switch (id) { // These stubs don't need to have an oopmap - case slow_subtype_check_id: #if defined(SPARC) || defined(PPC) case handle_exception_nofpu_id: // Unused on sparc #endif diff -r 73536049fa29 -r d413770c6dd0 src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/share/vm/graal/graalRuntime.hpp Thu Mar 07 09:43:25 2013 +0100 @@ -86,7 +86,6 @@ stub(new_array) \ stub(new_multi_array) \ stub(handle_exception_nofpu) /* optimized version that does not preserve fpu registers */ \ - stub(slow_subtype_check) \ stub(unwind_exception_call) \ stub(OSR_migration_end) \ stub(arithmetic_frem) \ diff -r 73536049fa29 -r d413770c6dd0 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/share/vm/runtime/arguments.cpp Thu Mar 07 09:43:25 2013 +0100 @@ -105,9 +105,6 @@ SystemProperty *Arguments::_java_home = NULL; SystemProperty *Arguments::_java_class_path = NULL; SystemProperty *Arguments::_sun_boot_class_path = NULL; -#ifdef GRAAL -SystemProperty *Arguments::_compiler_class_path = NULL; -#endif char* Arguments::_meta_index_path = NULL; char* Arguments::_meta_index_dir = NULL; @@ -169,9 +166,6 @@ _java_library_path = new SystemProperty("java.library.path", NULL, true); _java_home = new SystemProperty("java.home", NULL, true); _sun_boot_class_path = new SystemProperty("sun.boot.class.path", NULL, true); -#ifdef GRAAL - _compiler_class_path = new SystemProperty("compiler.class.path", NULL, true); -#endif _java_class_path = new SystemProperty("java.class.path", "", true); @@ -183,9 +177,6 @@ PropertyList_add(&_system_properties, _java_home); PropertyList_add(&_system_properties, _java_class_path); PropertyList_add(&_system_properties, _sun_boot_class_path); -#ifdef GRAAL - PropertyList_add(&_system_properties, _compiler_class_path); -#endif // Set OS specific system properties values os::init_system_properties_values(); @@ -2189,59 +2180,6 @@ } // Parse JavaVMInitArgs structure -#ifdef GRAAL -static void prepend_to_graal_classpath(SysClassPath &cp, const char* path) { - cp.add_prefix(path); -} - -static void prepend_to_graal_classpath(SysClassPath &cp, const char* graal_dir, const char* project) { - const int BUFFER_SIZE = 1024; - char path[BUFFER_SIZE]; - - const char fileSep = *os::file_separator(); - sprintf(path, "%s%c%s%cbin", graal_dir, fileSep, project, fileSep); - - DIR* dir = os::opendir(path); - if (dir == NULL) { - jio_fprintf(defaultStream::output_stream(), "Error while starting Graal VM: The Graal class directory %s could not be opened.\n", path); - vm_exit(1); - } - os::closedir(dir); - prepend_to_graal_classpath(cp, path); -} - -// Walk up the directory hierarchy starting from JAVA_HOME looking -// for a directory named "graal". If found, then the full path to -// this directory is returned in graal_dir. -static bool find_graal_dir(char* graal_dir) { - strcpy(graal_dir, Arguments::get_java_home()); - char* end = graal_dir + strlen(graal_dir); - const char fileSep = *os::file_separator(); - while (end != graal_dir) { - if (fileSep == '/') - strcat(graal_dir, "/graal"); - else { - assert(fileSep == '\\', "unexpected separator char"); - strcat(graal_dir, "\\graal"); - } - DIR* dir = os::opendir(graal_dir); - if (dir != NULL) { - os::closedir(dir); - return true; - } - *end = 0; - while (end != graal_dir) { - if (*end == fileSep) { - *end = 0; - break; - } - end--; - } - } - return false; -} -#endif - jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) { // For components of the system classpath. SysClassPath scp(Arguments::get_sysclasspath()); @@ -2268,72 +2206,6 @@ return result; } -#ifdef GRAAL - if (PrintVMOptions) { - tty->print_cr("Running Graal VM... "); - } - - SysClassPath scp_compiler(""); - - if (GraalClassPath != NULL) { - prepend_to_graal_classpath(scp_compiler, GraalClassPath); - } else { - const int BUFFER_SIZE = 1024; - char graal_dir[BUFFER_SIZE]; - if (!os::getenv("GRAAL", graal_dir, sizeof(graal_dir))) { - if (find_graal_dir(graal_dir) == false) { - jio_fprintf(defaultStream::output_stream(), "Error while starting Graal VM: The GRAAL environment variable needs to point to the directory containing the Graal projects.\n"); - vm_exit(0); - } - } - if (PrintVMOptions) tty->print_cr("GRAAL=%s", graal_dir); - - // this declaration is checked for correctness by 'mx build' - only - // modify its entries, not its name or shape - const char* graal_projects[] = { - #ifdef AMD64 - "com.oracle.graal.amd64", - "com.oracle.graal.asm.amd64", - "com.oracle.graal.lir.amd64", - "com.oracle.graal.compiler.amd64", - "com.oracle.graal.hotspot.amd64", - #endif - "com.oracle.graal.api.runtime", - "com.oracle.graal.api.meta", - "com.oracle.graal.api.code", - "com.oracle.graal.hotspot", - "com.oracle.graal.asm", - "com.oracle.graal.alloc", - "com.oracle.graal.word", - "com.oracle.graal.snippets", - "com.oracle.graal.compiler", - "com.oracle.graal.loop", - "com.oracle.graal.phases", - "com.oracle.graal.phases.common", - "com.oracle.graal.virtual", - "com.oracle.graal.nodes", - "com.oracle.graal.printer", - "com.oracle.graal.debug", - "com.oracle.graal.graph", - "com.oracle.graal.lir", - "com.oracle.graal.bytecode", - "com.oracle.graal.java" - }; - - const int len = sizeof(graal_projects) / sizeof(char*); - for (int i = 0; i < len; i++) { - if (PrintVMOptions) { - tty->print_cr("Adding project directory %s to bootclasspath", graal_projects[i]); - } - prepend_to_graal_classpath(scp_compiler, graal_dir, graal_projects[i]); - } - } - - scp_compiler.expand_endorsed(); - Arguments::set_compilerclasspath(scp_compiler.combined_path()); - -#endif - if (AggressiveOpts) { // Insert alt-rt.jar between user-specified bootclasspath // prefix and the default bootclasspath. os::set_boot_path() @@ -2349,6 +2221,20 @@ FREE_C_HEAP_ARRAY(char, altclasses_path, mtInternal); } +#ifdef GRAAL + { + // Append graal.jar to bootclasspath if enabled + const char* jar_file = "graal.jar"; + const size_t path_len = strlen(get_meta_index_dir()) + 1 + strlen(jar_file); + char* path = NEW_C_HEAP_ARRAY(char, path_len, mtInternal); + strcpy(path, get_meta_index_dir()); + strcat(path, jar_file); + scp.add_suffix(path); + scp_assembly_required = true; + FREE_C_HEAP_ARRAY(char, path, mtInternal); + } +#endif + // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM) result = parse_java_options_environment_variable(&scp, &scp_assembly_required); if (result != JNI_OK) { diff -r 73536049fa29 -r d413770c6dd0 src/share/vm/runtime/arguments.hpp --- a/src/share/vm/runtime/arguments.hpp Wed Mar 06 15:20:21 2013 +0100 +++ b/src/share/vm/runtime/arguments.hpp Thu Mar 07 09:43:25 2013 +0100 @@ -247,9 +247,6 @@ static SystemProperty *_java_home; static SystemProperty *_java_class_path; static SystemProperty *_sun_boot_class_path; -#ifdef GRAAL - static SystemProperty *_compiler_class_path; -#endif // Meta-index for knowing what packages are in the boot class path static char* _meta_index_path; @@ -537,9 +534,6 @@ static void set_ext_dirs(char *value) { _java_ext_dirs->set_value(value); } static void set_endorsed_dirs(char *value) { _java_endorsed_dirs->set_value(value); } static void set_sysclasspath(char *value) { _sun_boot_class_path->set_value(value); } -#ifdef GRAAL - static void set_compilerclasspath(char *value) { _compiler_class_path->set_value(value); } -#endif static void append_sysclasspath(const char *value) { _sun_boot_class_path->append_value(value); } static void set_meta_index_path(char* meta_index_path, char* meta_index_dir) { _meta_index_path = meta_index_path; @@ -550,9 +544,6 @@ static char *get_dll_dir() { return _sun_boot_library_path->value(); } static char *get_endorsed_dir() { return _java_endorsed_dirs->value(); } static char *get_sysclasspath() { return _sun_boot_class_path->value(); } -#ifdef GRAAL - static char *get_compilerclasspath() { return _compiler_class_path->value(); } -#endif static char* get_meta_index_path() { return _meta_index_path; } static char* get_meta_index_dir() { return _meta_index_dir; }