# HG changeset patch # User Christian Haeubl # Date 1368601423 -7200 # Node ID 521c4f7aac664b71a746ced84d978df0311cae4d # Parent 4420f32a6d5c7c1809570a6c3510e018b8d44e0f# Parent 5797e00287969538611a1ea94a987d6e6330c5c0 Merge. diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CallingConvention.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CallingConvention.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CallingConvention.java Wed May 15 09:03:43 2013 +0200 @@ -48,12 +48,6 @@ JavaCallee(false), /** - * A request for the outgoing argument locations at a call site to the runtime (which may be - * Java or native code). - */ - RuntimeCall(true), - - /** * A request for the outgoing argument locations at a call site to external native code that * complies with the platform ABI. */ @@ -152,6 +146,16 @@ } /** + * Gets the locations required for the arguments. + */ + public AllocatableValue[] getArguments() { + if (argumentLocations.length == 0) { + return argumentLocations; + } + return argumentLocations.clone(); + } + + /** * Gets the locations used (and killed) by the call apart from the * {@linkplain #getArgument(int) arguments}. */ diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/AbstractSPARCAssembler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/AbstractSPARCAssembler.java Wed May 15 09:03:43 2013 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2009, 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.asm.sparc; + +import com.oracle.graal.api.code.AbstractAddress; +import com.oracle.graal.api.code.Register; +import com.oracle.graal.api.code.TargetDescription; +import com.oracle.graal.asm.AbstractAssembler; +import com.oracle.graal.asm.Label; + +public abstract class AbstractSPARCAssembler extends AbstractAssembler { + + public AbstractSPARCAssembler(TargetDescription target) { + super(target); + } + + @Override + public void align(int modulus) { + // SPARC: Implement alignment. + } + + @Override + public void jmp(Label l) { + // SPARC: Implement jump. + } + + @Override + protected void patchJumpTarget(int branch, int jumpTarget) { + // SPARC: Implement patching of jump target. + } + + @Override + public AbstractAddress makeAddress(Register base, int displacement) { + // SPARC: Implement address calculation. + return null; + } + + @Override + public AbstractAddress getPlaceholder() { + // SPARC: Implement address patching. + return null; + } +} diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Wed May 15 09:03:43 2013 +0200 @@ -23,13 +23,96 @@ package com.oracle.graal.asm.sparc; import com.oracle.graal.api.code.*; -import com.oracle.graal.asm.*; import com.oracle.graal.sparc.*; /** * This class implements an assembler that can encode most SPARC instructions. */ -public class SPARCAssembler extends AbstractAssembler { +public class SPARCAssembler extends AbstractSPARCAssembler { + + public static final int ImmedTrue = 0x00002000; + + public enum Ops { + CallOp(0x40000000), + BranchOp(0x00000000), + ArithOp(0x80000000), + LdstOp(0xC0000000); + + private final int value; + + private Ops(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + public enum Op3s { + Add((0x00 << 19) & 0x01F80000, "add"), + And((0x01 << 19) & 0x01F80000, "and"), + Or((0x02 << 19) & 0x01F80000, "or"), + Xor((0x03 << 19) & 0x01F80000, "xor"), + Sub((0x04 << 19) & 0x01F80000, "sub"), + Andn((0x05 << 19) & 0x01F80000, "andn"), + Orn((0x06 << 19) & 0x01F80000, "orn"), + Xnor((0x07 << 19) & 0x01F80000, "xnor"), + Addc((0x08 << 19) & 0x01F80000, "addc"), + Mulx((0x09 << 19) & 0x01F80000, "mulx"), + Umul((0x0A << 19) & 0x01F80000, "umul"), + Smul((0x0B << 19) & 0x01F80000, "smul"), + Subc((0x0C << 19) & 0x01F80000, "subc"), + Udivx((0x0D << 19) & 0x01F80000, "udivx"), + Udiv((0x0E << 19) & 0x01F80000, "udiv"), + Sdiv((0x0F << 19) & 0x01F80000, "sdiv"), + + Addcc((0x10 << 19) & 0x01F80000, "addcc"), + Andcc((0x11 << 19) & 0x01F80000, "andcc"), + Orcc((0x12 << 19) & 0x01F80000, "orcc"), + Xorcc((0x13 << 19) & 0x01F80000, "xorcc"), + Subcc((0x14 << 19) & 0x01F80000, "subcc"), + Andncc((0x15 << 19) & 0x01F80000, "andncc"), + Orncc((0x16 << 19) & 0x01F80000, "orncc"), + Xnorcc((0x17 << 19) & 0x01F80000, "xnorcc"), + Addccc((0x18 << 19) & 0x01F80000, "addccc"), + Mulxcc((0x19 << 19) & 0x01F80000, "mulxcc"), + Umulcc((0x1A << 19) & 0x01F80000, "umulcc"), + Smulcc((0x1B << 19) & 0x01F80000, "smulcc"), + Subccc((0x1C << 19) & 0x01F80000, "subccc"), + Udivcc((0x1E << 19) & 0x01F80000, "udivcc"), + Sdivcc((0x1F << 19) & 0x01F80000, "sdivcc"), + + Taddcc((0x20 << 19) & 0x01F80000, "taddcc"), + Tsubcc((0x21 << 19) & 0x01F80000, "tsubcc"), + Taddcctv((0x22 << 19) & 0x01F80000, "taddcctv"), + Tsubcctv((0x23 << 19) & 0x01F80000, "tsubcctv"), + Mulscc((0x23 << 19) & 0x01F80000, "mulscc"), + Sll((0x25 << 19) & 0x01F80000, "sll"), + Sllx((0x25 << 19) & 0x01F80000, "sllx"), + Srl((0x26 << 19) & 0x01F80000, "srl"), + Srlx((0x26 << 19) & 0x01F80000, "srlx"), + Sra((0x27 << 19) & 0x01F80000, "srax"), + Srax((0x27 << 19) & 0x01F80000, "srax"), + Rdreg((0x27 << 19) & 0x01F80000, "rdreg"), + Membar((0x27 << 19) & 0x01F80000, "membar"); + + private final int value; + private final String operator; + + private Op3s(int value, String op) { + this.value = value; + this.operator = op; + } + + public int getValue() { + return value; + } + + public String getOperator() { + return operator; + } + } @SuppressWarnings("unused") public SPARCAssembler(TargetDescription target) { @@ -38,30 +121,391 @@ SPARC sparc; } - @Override - public void align(int modulus) { - // SPARC: Implement alignment. + public static final int rs1(int val) { + return val; + } + + public static final int rs2(int val) { + return val; + } + + public static final int rd(int val) { + return val; + } + + public static final int sx1 = 0x00001000; + + public static final int simm(int x, int nbits) { + // assert_signed_range(x, nbits); + return x & ((1 << nbits) - 1); + } + + public final void add(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Add.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void add(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Add.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void addcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Addcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void addcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Addcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void addc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Addc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void addc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Addc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void addccc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Addccc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void addccc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Addccc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void and(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.And.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void and(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.And.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void andcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Andcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void andcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Andcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void andn(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Andn.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void andn(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Andn.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void andncc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Andncc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void andncc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Andncc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void mulscc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Mulscc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void mulscc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Mulscc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); } - @Override - public void jmp(Label l) { - // SPARC: Implement jump. + public final void mulx(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Mulx.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void mulx(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Mulx.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void or(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Or.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void or(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Or.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void orcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Orcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void orcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Orcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void orn(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Orn.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void orn(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Orn.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void orncc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Orncc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void orncc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Orncc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void rdy(Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding())); + } + + // A.44 Read State Register + + public final void rdccr(Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding()) | 0x00008000); + } + + public final void rdasi(Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding()) | 0x0000C000); + } + + public final void rdtick(Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding()) | 0x00010000); + } + + public final void rdpc(Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding()) | 0x00014000); + } + + public final void rdfprs(Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding()) | 0x00018000); + } + + @Deprecated + public final void sdiv(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Sdiv.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + @Deprecated + public final void sdiv(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Sdiv.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + @Deprecated + public final void sdivcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Sdivcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + @Deprecated + public final void sdivcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Sdivcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void sll(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Sll.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void sll(Register src1, int imm5a, Register dst) { + assert imm5a < 0x40; + emitInt(Ops.ArithOp.getValue() | Op3s.Sll.getValue() | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); + } + + public final void sllx(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Sllx.getValue() | sx1 | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); } - @Override - protected void patchJumpTarget(int branch, int jumpTarget) { - // SPARC: Implement patching of jump target. + public final void sllx(Register src1, int imm5a, Register dst) { + assert imm5a < 0x40; + emitInt(Ops.ArithOp.getValue() | Op3s.Sllx.getValue() | sx1 | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); + } + + public final void smul(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Smul.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void smul(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Smul.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void smulcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Smulcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void smulcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Smulcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void sra(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Sra.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void sra(Register src1, int imm5a, Register dst) { + assert imm5a < 0x40; + emitInt(Ops.ArithOp.getValue() | Op3s.Sra.getValue() | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); + } + + public final void srax(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Srax.getValue() | sx1 | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void srax(Register src1, int imm5a, Register dst) { + assert imm5a < 0x40; + emitInt(Ops.ArithOp.getValue() | Op3s.Srax.getValue() | sx1 | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); + } + + public final void srl(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Srl.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void srl(Register src1, int imm5a, Register dst) { + assert imm5a < 0x40; + emitInt(Ops.ArithOp.getValue() | Op3s.Srl.getValue() | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); + } + + public final void srlx(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Srlx.getValue() | sx1 | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void srlx(Register src1, int imm5a, Register dst) { + assert imm5a < 0x40; + emitInt(Ops.ArithOp.getValue() | Op3s.Srlx.getValue() | sx1 | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); + } + + public final void sub(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Sub.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void sub(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Sub.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void subcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Subcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void subcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Subcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void subc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Subc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void subc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Subc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void subccc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Subccc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void subccc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Subccc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void taddcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Taddcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void taddcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Taddcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); } - @Override - public AbstractAddress makeAddress(Register base, int displacement) { - // SPARC: Implement address calculation. - return null; + public final void taddcctv(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Taddcctv.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void taddcctv(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Taddcctv.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void tsubcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Tsubcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void tsubcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Tsubcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void tsubcctv(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Tsubcctv.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void tsubcctv(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Tsubcctv.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + @Deprecated + public final void udiv(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Udiv.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + @Deprecated + public final void udiv(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Udiv.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + @Deprecated + public final void udivcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Udivcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + @Deprecated + public final void udivcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Udivcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void udivx(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Udivx.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); } - @Override - public AbstractAddress getPlaceholder() { - // SPARC: Implement address patching. - return null; + public final void udivx(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Udivx.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void umul(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Umul.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void umul(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Umul.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void umulcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Umulcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void umulcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Umulcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void xor(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Xor.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void xor(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Xor.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); } + + public final void xorcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Xorcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void xorcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Xorcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void xnor(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Xnor.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void xnor(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Xnor.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + + public final void xnorcc(Register src1, Register src2, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Xnorcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + } + + public final void xnorcc(Register src1, int simm13, Register dst) { + emitInt(Ops.ArithOp.getValue() | Op3s.Xnorcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + } + } diff -r 4420f32a6d5c -r 521c4f7aac66 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 May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed May 15 09:03:43 2013 +0200 @@ -211,12 +211,12 @@ @Override public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention callCc, DeoptimizingNode info, Value... args) { Stub stub = getStub(); - boolean isCRuntimeCall = ((HotSpotRuntimeCallTarget) callTarget).isCRuntimeCall(); - assert !isCRuntimeCall || stub != null : "direct call to C runtime can only be made from compiled stubs, not from " + graph; + boolean destroysRegisters = ((HotSpotRuntimeCallTarget) callTarget).destroysRegisters(); + assert !destroysRegisters || stub != null : "foreign call that destroys registers can only be made from compiled stub, not from " + graph; AMD64SaveRegistersOp save = null; StackSlot[] savedRegisterLocations = null; - if (isCRuntimeCall) { + if (destroysRegisters) { if (stub.preservesRegisters()) { Register[] savedRegisters = frameMap.registerConfig.getAllocatableRegisters(); savedRegisterLocations = new StackSlot[savedRegisters.length]; @@ -233,7 +233,7 @@ Variable result = super.emitCall(callTarget, callCc, info, args); - if (isCRuntimeCall) { + if (destroysRegisters) { append(new AMD64HotSpotCRuntimeCallEpilogueOp()); if (stub.preservesRegisters()) { assert !calleeSaveInfo.containsKey(currentRuntimeCallInfo); diff -r 4420f32a6d5c -r 521c4f7aac66 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 May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Wed May 15 09:03:43 2013 +0200 @@ -106,7 +106,7 @@ return allocatable; } - public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, boolean globalStubConfig) { + public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, boolean isNative) { this.architecture = architecture; if (config.windowsOs) { @@ -117,7 +117,7 @@ nativeGeneralParameterRegisters = new Register[] {rdi, rsi, rdx, rcx, r8, r9}; } - if (globalStubConfig) { + if (isNative) { Register[] regs = { rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15, @@ -147,6 +147,7 @@ if (type == Type.NativeCall) { return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly); } + // On x64, parameter locations are the same whether viewed from the caller or callee perspective return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly); } diff -r 4420f32a6d5c -r 521c4f7aac66 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 May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Wed May 15 09:03:43 2013 +0200 @@ -23,7 +23,10 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotRuntimeCallTarget.*; +import static com.oracle.graal.hotspot.HotSpotRuntimeCallTarget.RegisterEffect.*; import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.DecryptBlockStubCall.*; import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.EncryptBlockStubCall.*; import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*; @@ -43,61 +46,29 @@ public AMD64HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) { super(config, graalRuntime); - Kind word = graalRuntime.getTarget().wordKind; - - // @formatter:off - - // The calling convention for the exception handler stub is (only?) defined in - // TemplateInterpreterGenerator::generate_throw_exception() - // in templateInterpreter_x86_64.cpp around line 1923 - addStubCall(EXCEPTION_HANDLER, - /* ret */ ret(Kind.Void), - /* arg0: exception */ rax.asValue(Kind.Object), - /* arg1: exceptionPc */ rdx.asValue(word)); - - addJump(EXCEPTION_HANDLER_IN_CALLER, - /* arg0: exception */ rax.asValue(Kind.Object), - /* arg1: exceptionPc */ rdx.asValue(word)); - - addRuntimeCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, - /* temps */ null, - /* ret */ ret(Kind.Void), - /* arg0: in */ nativeCallingConvention(word, - /* arg1: out */ word, - /* arg2: key */ word)); - - addRuntimeCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, - /* temps */ null, - /* ret */ ret(Kind.Void), - /* arg0: in */ nativeCallingConvention(word, - /* arg1: out */ word, - /* arg2: key */ word)); - - addRuntimeCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, - /* temps */ null, - /* ret */ ret(Kind.Void), - /* arg0: in */ nativeCallingConvention(word, - /* arg1: out */ word, - /* arg2: key */ word, - /* arg3: r */ word, - /* arg4: inLength */ Kind.Int)); - - addRuntimeCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, - /* temps */ null, - /* ret */ ret(Kind.Void), - /* arg0: in */ nativeCallingConvention(word, - /* arg1: out */ word, - /* arg2: key */ word, - /* arg3: r */ word, - /* arg4: inLength */ Kind.Int)); - // @formatter:on - } private AMD64ConvertSnippets.Templates convertSnippets; @Override public void registerReplacements(Replacements replacements) { + Kind word = graalRuntime.getTarget().wordKind; + + // The calling convention for the exception handler stub is (only?) defined in + // TemplateInterpreterGenerator::generate_throw_exception() + // in templateInterpreter_x86_64.cpp around line 1923 + RegisterValue exception = rax.asValue(Kind.Object); + RegisterValue exceptionPc = rdx.asValue(word); + CallingConvention exceptionCc = new CallingConvention(0, Value.ILLEGAL, exception, exceptionPc); + register(new HotSpotRuntimeCallTarget(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, exceptionCc, graalRuntime.getCompilerToVM())); + register(new HotSpotRuntimeCallTarget(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, exceptionCc, graalRuntime.getCompilerToVM())); + + // The crypto stubs do callee saving + registerLeafCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS); + registerLeafCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS); + registerLeafCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS); + registerLeafCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS); + convertSnippets = new AMD64ConvertSnippets.Templates(this, replacements, graalRuntime.getTarget()); super.registerReplacements(replacements); } @@ -122,7 +93,7 @@ } @Override - protected RegisterConfig createRegisterConfig(boolean globalStubConfig) { - return new AMD64HotSpotRegisterConfig(graalRuntime.getTarget().arch, config, globalStubConfig); + protected RegisterConfig createRegisterConfig(boolean isNative) { + return new AMD64HotSpotRegisterConfig(graalRuntime.getTarget().arch, config, isNative); } } diff -r 4420f32a6d5c -r 521c4f7aac66 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 May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java Wed May 15 09:03:43 2013 +0200 @@ -46,7 +46,7 @@ } @Override - protected RegisterConfig createRegisterConfig(boolean globalStubConfig) { + protected RegisterConfig createRegisterConfig(boolean isNative) { // SPARC: Create register configuration. return null; } diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Wed May 15 09:03:43 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.DataPatch; @@ -61,7 +59,7 @@ Call call = (Call) infopoint; assert call.target instanceof HotSpotRuntimeCallTarget : this + " cannot have non runtime call: " + call.target; HotSpotRuntimeCallTarget callTarget = (HotSpotRuntimeCallTarget) call.target; - assert callTarget.getAddress() == graalRuntime().getConfig().uncommonTrapStub || callTarget.isCRuntimeCall() : this + "must only call C runtime or deoptimization stub, not " + call.target; + assert !callTarget.isCompiledStub() : this + " cannot call compiled stub " + callTarget; } return true; } diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java Wed May 15 09:03:43 2013 +0200 @@ -22,13 +22,19 @@ */ package com.oracle.graal.hotspot; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.hotspot.HotSpotRuntimeCallTarget.RegisterEffect.*; + import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.word.*; /** * The details required to link a HotSpot runtime or stub call. @@ -36,17 +42,26 @@ public class HotSpotRuntimeCallTarget implements RuntimeCallTarget, InvokeTarget { /** + * Constants for specifying whether a call destroys or preserves registers. A call will always + * destroy {@link HotSpotRuntimeCallTarget#getCallingConvention() its} + * {@linkplain CallingConvention#getTemporaries() temporary} registers. + */ + public enum RegisterEffect { + DESTROYS_REGISTERS, PRESERVES_REGISTERS + } + + /** * Sentinel marker for a computed jump address. */ public static final long JUMP_ADDRESS = 0xDEADDEADBEEFBEEFL; /** - * The descriptor of the stub. This is for informational purposes only. + * The descriptor of the call. */ - public final Descriptor descriptor; + private final Descriptor descriptor; /** - * The entry point address of the stub. + * The entry point address of this call's target. */ private long address; @@ -56,17 +71,55 @@ private Stub stub; /** - * Where the stub gets its arguments and where it places its result. + * The calling convention for this call. */ private CallingConvention cc; private final CompilerToVM vm; - private final boolean isCRuntimeCall; + private final RegisterEffect effect; + + /** + * Creates a {@link HotSpotRuntimeCallTarget}. + * + * @param descriptor the descriptor of the call + * @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 ccProvider calling convention provider + * @param vm the Java to HotSpot C/C++ runtime interface + */ + public static HotSpotRuntimeCallTarget create(Descriptor descriptor, long address, RegisterEffect effect, Type ccType, RegisterConfig ccProvider, HotSpotRuntime runtime, CompilerToVM vm) { + CallingConvention targetCc = createCallingConvention(descriptor, ccType, ccProvider, runtime); + return new HotSpotRuntimeCallTarget(descriptor, address, effect, targetCc, vm); + } - public HotSpotRuntimeCallTarget(Descriptor descriptor, long address, boolean isCRuntimeCall, CallingConvention cc, CompilerToVM vm) { + /** + * Gets a calling convention for a given descriptor and call type. + */ + public static CallingConvention createCallingConvention(Descriptor descriptor, Type ccType, RegisterConfig ccProvider, HotSpotRuntime runtime) { + Class[] argumentTypes = descriptor.getArgumentTypes(); + JavaType[] parameterTypes = new JavaType[argumentTypes.length]; + for (int i = 0; i < parameterTypes.length; ++i) { + parameterTypes[i] = asJavaType(argumentTypes[i], runtime); + } + TargetDescription target = graalRuntime().getTarget(); + JavaType returnType = asJavaType(descriptor.getResultType(), runtime); + return ccProvider.getCallingConvention(ccType, returnType, parameterTypes, target, false); + } + + private static JavaType asJavaType(Class type, HotSpotRuntime runtime) { + if (WordBase.class.isAssignableFrom(type)) { + return runtime.lookupJavaType(wordKind().toJavaClass()); + } else { + return runtime.lookupJavaType(type); + } + } + + public HotSpotRuntimeCallTarget(Descriptor descriptor, long address, RegisterEffect effect, CallingConvention cc, CompilerToVM vm) { this.address = address; - this.isCRuntimeCall = isCRuntimeCall; + this.effect = effect; this.descriptor = descriptor; this.cc = cc; this.vm = vm; @@ -89,21 +142,23 @@ return descriptor; } - public void setStub(Stub stub) { + public void setCompiledStub(Stub stub) { assert address == 0L : "cannot set stub for linkage that already has an address: " + this; this.stub = stub; } + /** + * Determines if this is a call to a compiled {@linkplain Stub stub}. + */ + public boolean isCompiledStub() { + return address == 0L || stub != null; + } + public void finalizeAddress(Backend backend) { if (address == 0) { assert stub != null : "linkage without an address must be a stub - forgot to register a Stub associated with " + descriptor + "?"; InstalledCode code = stub.getCode(backend); - AllocatableValue[] argumentLocations = new AllocatableValue[cc.getArgumentCount()]; - for (int i = 0; i < argumentLocations.length; i++) { - argumentLocations[i] = cc.getArgument(i); - } - Set destroyedRegisters = stub.getDestroyedRegisters(); AllocatableValue[] temporaryLocations = new AllocatableValue[destroyedRegisters.size()]; int i = 0; @@ -111,7 +166,7 @@ temporaryLocations[i++] = reg.asValue(); } // Update calling convention with temporaries - cc = new CallingConvention(temporaryLocations, cc.getStackSize(), cc.getReturn(), argumentLocations); + cc = new CallingConvention(temporaryLocations, cc.getStackSize(), cc.getReturn(), cc.getArguments()); address = code.getStart(); } } @@ -123,23 +178,6 @@ @Override public boolean destroysRegisters() { - if (isCRuntimeCall) { - // Even though most native ABIs define some callee saved registers, - // for simplicity we force the register allocator to save all live - // registers across a C runtime call as such calls are only made from - // compiled stubs which a) are slow path and b) will typically only - // have very few live registers across a C runtime call - return true; - } - // This is a call to a compiled (or assembler) stub which saves - // all registers (apart from its temporaries) - return false; - } - - /** - * Determines if this is a link to a C/C++ function in the HotSpot runtime. - */ - public boolean isCRuntimeCall() { - return isCRuntimeCall; + return effect == DESTROYS_REGISTERS; } } diff -r 4420f32a6d5c -r 521c4f7aac66 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 May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Wed May 15 09:03:43 2013 +0200 @@ -366,18 +366,10 @@ public int bciProfileWidth; public int typeProfileWidth; - // runtime stubs public long inlineCacheMissStub; public long handleDeoptStub; + public long uncommonTrapStub; - public long uncommonTrapStub; - public long unwindExceptionStub; - public long javaTimeMillisStub; - public long javaTimeNanosStub; - public long arithmeticSinStub; - public long arithmeticCosStub; - public long arithmeticTanStub; - public int deoptReasonNone; public long aescryptEncryptBlockStub; public long aescryptDecryptBlockStub; public long cipherBlockChainingEncryptAESCryptStub; @@ -403,7 +395,13 @@ public long vmErrorAddress; public long writeBarrierPreAddress; public long writeBarrierPostAddress; + public long javaTimeMillisAddress; + public long javaTimeNanosAddress; + public long arithmeticSinAddress; + public long arithmeticCosAddress; + public long arithmeticTanAddress; + public int deoptReasonNone; public int deoptReasonNullCheck; public int deoptReasonRangeCheck; public int deoptReasonClassCheck; diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed May 15 09:03:43 2013 +0200 @@ -340,6 +340,9 @@ @Override public boolean canBeInlined() { + if (dontInline) { + return false; + } return graalRuntime().getCompilerToVM().isMethodCompilable(metaspaceMethod); } diff -r 4420f32a6d5c -r 521c4f7aac66 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 May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed May 15 09:03:43 2013 +0200 @@ -26,10 +26,10 @@ import static com.oracle.graal.api.code.DeoptimizationAction.*; import static com.oracle.graal.api.code.MemoryBarriers.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; -import static com.oracle.graal.api.meta.Value.*; import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.wordKind; +import static com.oracle.graal.hotspot.HotSpotRuntimeCallTarget.RegisterEffect.*; import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*; import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*; import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*; @@ -40,7 +40,7 @@ import static com.oracle.graal.hotspot.nodes.VerifyOopStubCall.*; import static com.oracle.graal.hotspot.nodes.WriteBarrierPostStubCall.*; import static com.oracle.graal.hotspot.nodes.WriteBarrierPreStubCall.*; -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.IDENTITY_HASHCODE; +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*; import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*; import static com.oracle.graal.hotspot.stubs.LogObjectStub.*; @@ -54,8 +54,6 @@ import static com.oracle.graal.hotspot.stubs.ThreadIsInterruptedStub.*; import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*; import static com.oracle.graal.hotspot.stubs.VMErrorStub.*; -import static com.oracle.graal.hotspot.stubs.WriteBarrierPostStub.*; -import static com.oracle.graal.hotspot.stubs.WriteBarrierPreStub.*; import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*; import static com.oracle.graal.replacements.Log.*; @@ -76,6 +74,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.HotSpotRuntimeCallTarget.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult; import com.oracle.graal.hotspot.nodes.*; @@ -105,8 +104,8 @@ public final HotSpotVMConfig config; - protected final RegisterConfig regConfig; - protected final RegisterConfig globalStubRegConfig; + protected final RegisterConfig javaABI; + protected final RegisterConfig nativeABI; protected final HotSpotGraalRuntime graalRuntime; private CheckCastSnippets.Templates checkcastSnippets; @@ -179,312 +178,90 @@ } } - protected AllocatableValue ret(Kind kind) { - if (kind == Kind.Void) { - return ILLEGAL; - } - return globalStubRegConfig.getReturnRegister(kind).asValue(kind); - } - - protected AllocatableValue[] javaCallingConvention(Kind... arguments) { - return callingConvention(arguments, RuntimeCall); - } - - protected AllocatableValue[] nativeCallingConvention(Kind... arguments) { - return callingConvention(arguments, NativeCall); - } - - private AllocatableValue[] callingConvention(Kind[] arguments, CallingConvention.Type type) { - AllocatableValue[] result = new AllocatableValue[arguments.length]; - - TargetDescription target = graalRuntime.getTarget(); - int currentStackOffset = 0; - for (int i = 0; i < arguments.length; i++) { - Kind kind = arguments[i]; - Register[] ccRegs = globalStubRegConfig.getCallingConventionRegisters(type, kind); - if (i < ccRegs.length) { - result[i] = ccRegs[i].asValue(kind); - } else { - result[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, false); - currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize); - } - } - return result; + public HotSpotRuntime(HotSpotVMConfig c, HotSpotGraalRuntime graalRuntime) { + this.config = c; + this.graalRuntime = graalRuntime; + javaABI = createRegisterConfig(false); + nativeABI = createRegisterConfig(true); } - public HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) { - this.config = config; - this.graalRuntime = graalRuntime; - regConfig = createRegisterConfig(false); - globalStubRegConfig = createRegisterConfig(true); - Kind word = graalRuntime.getTarget().wordKind; - - // @formatter:off - - addStubCall(VERIFY_OOP, - /* ret */ ret(Kind.Object), - /* arg0: object */ javaCallingConvention(Kind.Object)); - - addStubCall(OSR_MIGRATION_END, - /* ret */ ret(Kind.Void), - /* arg0: buffer */ javaCallingConvention(word)); - - addCRuntimeCall(OSR_MIGRATION_END_C, config.osrMigrationEndAddress, - /* ret */ ret(Kind.Void), - /* arg0: buffer */ nativeCallingConvention(word)); - - addRuntimeCall(UNCOMMON_TRAP, config.uncommonTrapStub, - /* temps */ null, - /* ret */ ret(Kind.Void)); - - addCRuntimeCall(EXCEPTION_HANDLER_FOR_PC, config.exceptionHandlerForPcAddress, - /* ret */ ret(word), - /* arg0: thread */ nativeCallingConvention(word)); - - addStubCall(UNWIND_EXCEPTION_TO_CALLER, - /* ret */ ret(Kind.Void), - /* arg0: exception */ javaCallingConvention(Kind.Object, - /* arg1: returnAddress */ word)); - - addCRuntimeCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, config.exceptionHandlerForReturnAddressAddress, - /* ret */ ret(word), - /* arg0: thread */ nativeCallingConvention(word, - /* arg1: returnAddress */ word)); - - addStubCall(NEW_ARRAY, - /* ret */ ret(Kind.Object), - /* arg0: hub */ javaCallingConvention(word, - /* arg1: length */ Kind.Int)); - - addCRuntimeCall(NEW_ARRAY_C, config.newArrayAddress, - /* ret */ ret(Kind.Void), - /* arg0: thread */ nativeCallingConvention(word, - /* arg1: hub */ word, - /* arg2: length */ Kind.Int)); - - addStubCall(NEW_INSTANCE, - /* ret */ ret(Kind.Object), - /* arg0: hub */ javaCallingConvention(word)); - - addCRuntimeCall(NEW_INSTANCE_C, config.newInstanceAddress, - /* ret */ ret(Kind.Void), - /* arg0: thread */ nativeCallingConvention(word, - /* arg1: hub */ word)); - - addStubCall(NEW_MULTI_ARRAY, - /* ret */ ret(Kind.Object), - /* arg0: hub */ javaCallingConvention(word, - /* arg1: rank */ Kind.Int, - /* arg2: dims */ word)); - - addCRuntimeCall(NEW_MULTI_ARRAY_C, config.newMultiArrayAddress, - /* ret */ ret(Kind.Void), - /* arg0: thread */ nativeCallingConvention(word, - /* arg1: hub */ word, - /* arg2: rank */ Kind.Int, - /* arg3: dims */ word)); - - addRuntimeCall(JAVA_TIME_MILLIS, config.javaTimeMillisStub, - /* temps */ this.regConfig.getCallerSaveRegisters(), - /* ret */ ret(Kind.Long)); - - addRuntimeCall(JAVA_TIME_NANOS, config.javaTimeNanosStub, - /* temps */ this.regConfig.getCallerSaveRegisters(), - /* ret */ ret(Kind.Long)); - - addRuntimeCall(ARITHMETIC_SIN, config.arithmeticSinStub, - /* temps */ this.regConfig.getCallerSaveRegisters(), - /* ret */ ret(Kind.Double), - /* arg0: index */ javaCallingConvention(Kind.Double)); - - addRuntimeCall(ARITHMETIC_COS, config.arithmeticCosStub, - /* temps */ this.regConfig.getCallerSaveRegisters(), - /* ret */ ret(Kind.Double), - /* arg0: index */ javaCallingConvention(Kind.Double)); - - addRuntimeCall(ARITHMETIC_TAN, config.arithmeticTanStub, - /* temps */ this.regConfig.getCallerSaveRegisters(), - /* ret */ ret(Kind.Double), - /* arg0: index */ javaCallingConvention(Kind.Double)); - - addStubCall(LOG_PRIMITIVE, - /* ret */ ret(Kind.Void), - /* arg0: typeChar */ javaCallingConvention(Kind.Int, - /* arg1: value */ Kind.Long, - /* arg2: newline */ Kind.Boolean)); - - addCRuntimeCall(LOG_PRIMITIVE_C, config.logPrimitiveAddress, - /* ret */ ret(Kind.Void), - /* arg0: thread */ nativeCallingConvention(word, - /* arg1: typeChar */ Kind.Char, - /* arg2: value */ Kind.Long, - /* arg3: newline */ Kind.Boolean)); - - addStubCall(LOG_PRINTF, - /* ret */ ret(Kind.Void), - /* arg0: format */ javaCallingConvention(Kind.Object, - /* arg1: value */ Kind.Long, - /* arg2: value */ Kind.Long, - /* arg3: value */ Kind.Long)); - - addCRuntimeCall(LOG_PRINTF_C, config.logObjectAddress, - /* ret */ ret(Kind.Void), - /* arg0: thread */ nativeCallingConvention(word, - /* arg1: format */ Kind.Object, - /* arg2: v1 */ Kind.Long, - /* arg3: v2 */ Kind.Long, - /* arg4: v3 */ Kind.Long)); - - addCRuntimeCall(VM_MESSAGE_C, config.vmMessageAddress, - /* ret */ ret(Kind.Void), - /* arg0: vmError */ nativeCallingConvention(Kind.Boolean, - /* arg1: format */ word, - /* arg2: value */ Kind.Long, - /* arg3: value */ Kind.Long, - /* arg4: value */ Kind.Long)); - - addStubCall(LOG_OBJECT, - /* ret */ ret(Kind.Void), - /* arg0: object */ javaCallingConvention(Kind.Object, - /* arg1: flags */ Kind.Int)); - - addCRuntimeCall(LOG_OBJECT_C, config.logObjectAddress, - /* ret */ ret(Kind.Void), - /* arg0: thread */ nativeCallingConvention(word, - /* arg1: object */ Kind.Object, - /* arg2: flags */ Kind.Int)); - - addStubCall(THREAD_IS_INTERRUPTED, - /* ret */ ret(Kind.Boolean), - /* arg0: thread */ javaCallingConvention(Kind.Object, - /* arg1: clearInterrupted */ Kind.Boolean)); - - addCRuntimeCall(THREAD_IS_INTERRUPTED_C, config.threadIsInterruptedAddress, - /* ret */ ret(Kind.Boolean), - /* arg0: thread */ nativeCallingConvention(word, - /* arg1: receiverThread */ Kind.Object, - /* arg1: clearInterrupted */ Kind.Boolean)); - - addRuntimeCall(DEOPT_HANDLER, config.handleDeoptStub, - /* temps */ null, - /* ret */ ret(Kind.Void)); - - addRuntimeCall(IC_MISS_HANDLER, config.inlineCacheMissStub, - /* temps */ null, - /* ret */ ret(Kind.Void)); - - addStubCall(VM_ERROR, - /* ret */ ret(Kind.Void), - /* arg0: where */ javaCallingConvention(Kind.Object, - /* arg1: format */ Kind.Object, - /* arg2: value */ Kind.Long)); - - addCRuntimeCall(VM_ERROR_C, config.vmErrorAddress, - /* ret */ ret(Kind.Void), - /* arg0: thread */ nativeCallingConvention(word, - /* arg0: where */ Kind.Object, - /* arg1: format */ Kind.Object, - /* arg2: value */ Kind.Long)); - - addStubCall(WRITE_BARRIER_PRE, - /* ret */ ret(Kind.Void), - /* arg0: object */ javaCallingConvention(Kind.Object)); - - addCRuntimeCall(WRITE_BARRIER_PRE_C, config.writeBarrierPreAddress, - /* ret */ ret(Kind.Void), - /* arg0: thread */ nativeCallingConvention(word, - /* arg1: object */ Kind.Object)); - - addStubCall(WRITE_BARRIER_POST, - /* ret */ ret(Kind.Void), - /* arg0: object */ javaCallingConvention(Kind.Object, - /* arg1: card */ word)); - - addCRuntimeCall(WRITE_BARRIER_POST_C, config.writeBarrierPostAddress, - /* ret */ ret(Kind.Void), - /* arg0: thread */ nativeCallingConvention(word, - /* arg1: object */ Kind.Object, - /* arg2: card */ word)); - // @formatter:on + protected HotSpotRuntimeCallTarget register(HotSpotRuntimeCallTarget call) { + HotSpotRuntimeCallTarget oldValue = runtimeCalls.put(call.getDescriptor(), call); + assert oldValue == null; + return call; } /** - * Registers the details for linking a call to a compiled {@link Stub}. - * - * @param descriptor name and signature of the call - * @param ret where the call returns its result - * @param args where arguments are passed to the call + * Registers the details for linking a call to a {@link Stub}. */ - protected RuntimeCallTarget addStubCall(Descriptor descriptor, AllocatableValue ret, AllocatableValue... args) { - return addRuntimeCall(descriptor, 0L, null, ret, args); - } - - /** - * Registers the details for a jump to a target that has a signature (i.e. expects arguments in - * specified locations). - * - * @param descriptor name and signature of the jump target - * @param args where arguments are passed to the call - */ - protected RuntimeCallTarget addJump(Descriptor descriptor, AllocatableValue... args) { - return addRuntimeCall(descriptor, HotSpotRuntimeCallTarget.JUMP_ADDRESS, null, ret(Kind.Void), args); + protected RuntimeCallTarget registerStubCall(Descriptor descriptor) { + return register(HotSpotRuntimeCallTarget.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCallee, javaABI, this, graalRuntime.getCompilerToVM())); } /** * Registers the details for a call to a runtime C/C++ function. - * - * @param descriptor name and signature of the call - * @param args where arguments are passed to the call */ - protected RuntimeCallTarget addCRuntimeCall(Descriptor descriptor, long address, AllocatableValue ret, AllocatableValue... args) { - assert descriptor.getResultType().isPrimitive() || Word.class.isAssignableFrom(descriptor.getResultType()) : "C runtime call cannot have Object return type - objects must be returned via thread local storage: " + - descriptor; - return addRuntimeCall(descriptor, address, true, null, ret, args); + protected RuntimeCallTarget registerCRuntimeCall(Descriptor descriptor, long address) { + Class resultType = descriptor.getResultType(); + assert resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "C runtime call must return object thread local storage: " + descriptor; + return register(HotSpotRuntimeCallTarget.create(descriptor, address, DESTROYS_REGISTERS, NativeCall, nativeABI, this, graalRuntime.getCompilerToVM())); } - protected RuntimeCallTarget addRuntimeCall(Descriptor descriptor, long address, Register[] tempRegs, AllocatableValue ret, AllocatableValue... args) { - return addRuntimeCall(descriptor, address, false, tempRegs, ret, args); + /** + * Registers the details for a call to a stub that never returns. + */ + protected RuntimeCallTarget registerNoReturnStub(Descriptor descriptor, long address, CallingConvention.Type ccType) { + return register(HotSpotRuntimeCallTarget.create(descriptor, address, PRESERVES_REGISTERS, ccType, javaABI, this, graalRuntime.getCompilerToVM())); } /** - * Registers the details for linking a runtime call. - * - * @param descriptor name and signature of the call - * @param address target address of the call - * @param tempRegs temporary registers used (and killed) by the call (null if none) - * @param ret where the call returns its result - * @param args where arguments are passed to the call + * Registers the details for a call to a leaf function. A leaf function does not lock, GC or + * throw exceptions. That is, the thread's execution state during the call is never inspected by + * another thread. */ - protected RuntimeCallTarget addRuntimeCall(Descriptor descriptor, long address, boolean isCRuntimeCall, Register[] tempRegs, AllocatableValue ret, AllocatableValue... args) { - AllocatableValue[] temps = tempRegs == null || tempRegs.length == 0 ? AllocatableValue.NONE : new AllocatableValue[tempRegs.length]; - for (int i = 0; i < temps.length; i++) { - temps[i] = tempRegs[i].asValue(); - } - assert checkAssignable(descriptor.getResultType(), ret) : descriptor + " incompatible with result location " + ret; - Class[] argTypes = descriptor.getArgumentTypes(); - assert argTypes.length == args.length : descriptor + " incompatible with number of argument locations: " + args.length; - for (int i = 0; i < argTypes.length; i++) { - assert checkAssignable(argTypes[i], args[i]) : descriptor + " incompatible with argument location " + i + ": " + args[i]; - } - HotSpotRuntimeCallTarget runtimeCall = new HotSpotRuntimeCallTarget(descriptor, address, isCRuntimeCall, new CallingConvention(temps, 0, ret, args), graalRuntime.getCompilerToVM()); - runtimeCalls.put(descriptor, runtimeCall); - return runtimeCall; + protected RuntimeCallTarget registerLeafCall(Descriptor descriptor, long address, CallingConvention.Type ccType, RegisterEffect effect) { + return register(HotSpotRuntimeCallTarget.create(descriptor, address, effect, ccType, javaABI, this, graalRuntime.getCompilerToVM())); } - private boolean checkAssignable(Class spec, Value value) { - Kind kind = value.getKind(); - if (kind == Kind.Illegal) { - kind = Kind.Void; - } - if (WordBase.class.isAssignableFrom(spec)) { - return kind == graalRuntime.getTarget().wordKind; - } - return kind == Kind.fromJavaClass(spec); - } - - protected abstract RegisterConfig createRegisterConfig(boolean globalStubConfig); + protected abstract RegisterConfig createRegisterConfig(boolean isNative); public void registerReplacements(Replacements replacements) { + registerStubCall(VERIFY_OOP); + registerStubCall(OSR_MIGRATION_END); + registerStubCall(NEW_ARRAY); + registerStubCall(UNWIND_EXCEPTION_TO_CALLER); + registerStubCall(NEW_INSTANCE); + registerStubCall(NEW_MULTI_ARRAY); + registerStubCall(LOG_PRIMITIVE); + registerStubCall(LOG_PRINTF); + registerStubCall(LOG_OBJECT); + registerStubCall(THREAD_IS_INTERRUPTED); + registerStubCall(VM_ERROR); + + HotSpotVMConfig c = config; + registerNoReturnStub(UNCOMMON_TRAP, c.uncommonTrapStub, NativeCall); + registerNoReturnStub(DEOPT_HANDLER, c.handleDeoptStub, NativeCall); + registerNoReturnStub(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall); + + registerLeafCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS); + registerLeafCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, DESTROYS_REGISTERS); + registerLeafCall(ARITHMETIC_SIN, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS); + registerLeafCall(ARITHMETIC_COS, c.arithmeticCosAddress, NativeCall, DESTROYS_REGISTERS); + registerLeafCall(ARITHMETIC_TAN, c.arithmeticTanAddress, NativeCall, DESTROYS_REGISTERS); + + registerCRuntimeCall(OSR_MIGRATION_END_C, c.osrMigrationEndAddress); + registerCRuntimeCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress); + registerCRuntimeCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress); + registerCRuntimeCall(NEW_ARRAY_C, c.newArrayAddress); + registerCRuntimeCall(NEW_INSTANCE_C, c.newInstanceAddress); + registerCRuntimeCall(NEW_MULTI_ARRAY_C, c.newMultiArrayAddress); + registerCRuntimeCall(LOG_PRIMITIVE_C, c.logPrimitiveAddress); + registerCRuntimeCall(LOG_PRINTF_C, c.logObjectAddress); + registerCRuntimeCall(VM_MESSAGE_C, c.vmMessageAddress); + registerCRuntimeCall(LOG_OBJECT_C, c.logObjectAddress); + registerCRuntimeCall(THREAD_IS_INTERRUPTED_C, c.threadIsInterruptedAddress); + registerCRuntimeCall(VM_ERROR_C, c.vmErrorAddress); + if (GraalOptions.IntrinsifyObjectMethods) { replacements.registerSubstitutions(ObjectSubstitutions.class); } @@ -516,20 +293,19 @@ boxingSnippets = new BoxingSnippets.Templates(this, replacements, graalRuntime.getTarget()); exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(this, replacements, graalRuntime.getTarget()); - link(new NewInstanceStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_INSTANCE))); - link(new NewArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_ARRAY))); - link(new NewMultiArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_MULTI_ARRAY))); - link(new ThreadIsInterruptedStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(THREAD_IS_INTERRUPTED))); - link(new ExceptionHandlerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(EXCEPTION_HANDLER))); - link(new UnwindExceptionToCallerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(UNWIND_EXCEPTION_TO_CALLER))); - link(new VerifyOopStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(VERIFY_OOP))); - link(new OSRMigrationEndStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(OSR_MIGRATION_END))); - link(new LogPrimitiveStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(LOG_PRIMITIVE))); - link(new LogObjectStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(LOG_OBJECT))); - link(new LogPrintfStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(LOG_PRINTF))); - link(new VMErrorStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(VM_ERROR))); - link(new WriteBarrierPreStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(WRITE_BARRIER_PRE))); - link(new WriteBarrierPostStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(WRITE_BARRIER_POST))); + TargetDescription target = getTarget(); + link(new NewInstanceStub(this, replacements, target, runtimeCalls.get(NEW_INSTANCE))); + link(new NewArrayStub(this, replacements, target, runtimeCalls.get(NEW_ARRAY))); + link(new NewMultiArrayStub(this, replacements, target, runtimeCalls.get(NEW_MULTI_ARRAY))); + link(new ThreadIsInterruptedStub(this, replacements, target, runtimeCalls.get(THREAD_IS_INTERRUPTED))); + link(new ExceptionHandlerStub(this, replacements, target, runtimeCalls.get(EXCEPTION_HANDLER))); + link(new UnwindExceptionToCallerStub(this, replacements, target, runtimeCalls.get(UNWIND_EXCEPTION_TO_CALLER))); + link(new VerifyOopStub(this, replacements, target, runtimeCalls.get(VERIFY_OOP))); + link(new OSRMigrationEndStub(this, replacements, target, runtimeCalls.get(OSR_MIGRATION_END))); + link(new LogPrimitiveStub(this, replacements, target, runtimeCalls.get(LOG_PRIMITIVE))); + link(new LogObjectStub(this, replacements, target, runtimeCalls.get(LOG_OBJECT))); + link(new LogPrintfStub(this, replacements, target, runtimeCalls.get(LOG_PRINTF))); + link(new VMErrorStub(this, replacements, target, runtimeCalls.get(VM_ERROR))); linkRuntimeCall(IDENTITY_HASHCODE, config.identityHashCodeAddress, replacements); linkRuntimeCall(REGISTER_FINALIZER, config.registerFinalizerAddress, replacements); @@ -537,17 +313,19 @@ linkRuntimeCall(CREATE_OUT_OF_BOUNDS_EXCEPTION, config.createOutOfBoundsExceptionAddress, replacements); linkRuntimeCall(MONITORENTER, config.monitorenterAddress, replacements); linkRuntimeCall(MONITOREXIT, config.monitorexitAddress, replacements); + linkRuntimeCall(WRITE_BARRIER_PRE, config.writeBarrierPreAddress, replacements); + linkRuntimeCall(WRITE_BARRIER_POST, config.writeBarrierPostAddress, replacements); } private static void link(Stub stub) { - stub.getLinkage().setStub(stub); + stub.getLinkage().setCompiledStub(stub); } private void linkRuntimeCall(Descriptor descriptor, long address, Replacements replacements) { - RuntimeCallStub stub = new RuntimeCallStub(address, descriptor, true, this, replacements, globalStubRegConfig, graalRuntime.getCompilerToVM()); + RuntimeCallStub stub = new RuntimeCallStub(address, descriptor, true, this, replacements, nativeABI, graalRuntime.getCompilerToVM()); HotSpotRuntimeCallTarget linkage = stub.getLinkage(); HotSpotRuntimeCallTarget targetLinkage = stub.getTargetLinkage(); - linkage.setStub(stub); + linkage.setCompiledStub(stub); runtimeCalls.put(linkage.getDescriptor(), linkage); runtimeCalls.put(targetLinkage.getDescriptor(), targetLinkage); } @@ -575,7 +353,7 @@ if (compResult != null) { HexCodeFile.addAnnotations(hcf, compResult.getAnnotations()); addExceptionHandlersComment(compResult, hcf); - Register fp = regConfig.getFrameRegister(); + Register fp = javaABI.getFrameRegister(); RefMapFormatter slotFormatter = new RefMapFormatter(target.arch, target.wordSize, fp, 0); for (Infopoint infopoint : compResult.getInfopoints()) { if (infopoint instanceof Call) { @@ -679,7 +457,7 @@ @Override public RegisterConfig lookupRegisterConfig() { - return regConfig; + return javaABI; } @Override diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java Wed May 15 09:03:43 2013 +0200 @@ -47,7 +47,7 @@ @Override public void generate(LIRGenerator gen) { - RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(MonitorEnterStubCall.MONITORENTER); + RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(MONITORENTER); gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(object), gen.operand(lock)); } diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPostStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPostStubCall.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPostStubCall.java Wed May 15 09:03:43 2013 +0200 @@ -26,13 +26,12 @@ import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; -import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; /** - * Node implementing a call to {@link WriteBarrierPostStub}. + * A call to {@code GraalRuntime::write_barrier_post}. */ public class WriteBarrierPostStubCall extends FixedWithNextNode implements LIRGenLowerable { diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPreStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPreStubCall.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPreStubCall.java Wed May 15 09:03:43 2013 +0200 @@ -26,12 +26,11 @@ import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; -import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; /** - * Node implementing a call to {@link WriteBarrierPreStub}. + * A call to {@code GraalRuntime::write_barrier_pre}. */ public class WriteBarrierPreStubCall extends FixedWithNextNode implements LIRGenLowerable { diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Wed May 15 09:03:43 2013 +0200 @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2013, 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.replacements; + +import java.lang.reflect.Modifier; +import java.util.Arrays; + +import com.oracle.graal.api.meta.Constant; +import com.oracle.graal.api.meta.JavaType; +import com.oracle.graal.api.meta.ResolvedJavaField; +import com.oracle.graal.api.meta.ResolvedJavaMethod; +import com.oracle.graal.api.meta.ResolvedJavaType; +import com.oracle.graal.graph.GraalInternalError; +import com.oracle.graal.graph.NodeInputList; +import com.oracle.graal.hotspot.meta.HotSpotResolvedJavaMethod; +import com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType; +import com.oracle.graal.hotspot.meta.HotSpotSignature; +import com.oracle.graal.nodes.CallTargetNode; +import com.oracle.graal.nodes.Invoke; +import com.oracle.graal.nodes.InvokeNode; +import com.oracle.graal.nodes.PiNode; +import com.oracle.graal.nodes.ValueNode; +import com.oracle.graal.nodes.java.MethodCallTargetNode; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; +import com.oracle.graal.nodes.java.SelfReplacingMethodCallTargetNode; +import com.oracle.graal.nodes.spi.Canonicalizable; +import com.oracle.graal.nodes.type.StampFactory; +import com.oracle.graal.replacements.nodes.MacroNode; + +/** + * Common base class for method handle invoke nodes. + */ +public abstract class AbstractMethodHandleNode extends MacroNode implements Canonicalizable { + + private static final ResolvedJavaField methodHandleFormField; + private static final ResolvedJavaField lambdaFormVmentryField; + private static final ResolvedJavaField memberNameClazzField; + private static final ResolvedJavaField memberNameVmtargetField; + + // Replacement method data + private ResolvedJavaMethod replacementTargetMethod; + private JavaType replacementReturnType; + @Input private NodeInputList replacementArguments; + + /** + * Search for an instance field with the given name in a class. + * + * @param className name of the class to search in + * @param fieldName name of the field to be searched + * @return resolved java field + * @throws ClassNotFoundException + */ + private static ResolvedJavaField findFieldInClass(String className, String fieldName) throws ClassNotFoundException { + Class clazz = Class.forName(className); + ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(clazz); + ResolvedJavaField[] fields = type.getInstanceFields(false); + for (ResolvedJavaField field : fields) { + if (field.getName().equals(fieldName)) { + return field; + } + } + return null; + } + + static { + try { + methodHandleFormField = findFieldInClass("java.lang.invoke.MethodHandle", "form"); + lambdaFormVmentryField = findFieldInClass("java.lang.invoke.LambdaForm", "vmentry"); + memberNameClazzField = findFieldInClass("java.lang.invoke.MemberName", "clazz"); + memberNameVmtargetField = findFieldInClass("java.lang.invoke.MemberName", "vmtarget"); + } catch (ClassNotFoundException | SecurityException ex) { + throw GraalInternalError.shouldNotReachHere(); + } + } + + public AbstractMethodHandleNode(Invoke invoke) { + super(invoke); + + // See if we need to save some replacement method data. + CallTargetNode callTarget = invoke.callTarget(); + if (callTarget instanceof SelfReplacingMethodCallTargetNode) { + SelfReplacingMethodCallTargetNode selfReplacingMethodCallTargetNode = (SelfReplacingMethodCallTargetNode) callTarget; + replacementTargetMethod = selfReplacingMethodCallTargetNode.replacementTargetMethod(); + replacementReturnType = selfReplacingMethodCallTargetNode.replacementReturnType(); + replacementArguments = selfReplacingMethodCallTargetNode.replacementArguments(); + } else { + // NodeInputList can't be null. + replacementArguments = new NodeInputList<>(this); + } + } + + /** + * Get the receiver of a MethodHandle.invokeBasic call. + * + * @return the receiver argument node + */ + private ValueNode getReceiver() { + return arguments.first(); + } + + /** + * Get the MemberName argument of a MethodHandle.linkTo* call. + * + * @return the MemberName argument node (which is the last argument) + */ + private ValueNode getMemberName() { + return arguments.last(); + } + + /** + * Used from {@link MethodHandleInvokeBasicNode} to get the target {@link InvokeNode} if the + * method handle receiver is constant. + * + * @return invoke node for the {@link java.lang.invoke.MethodHandle} target + */ + protected InvokeNode getInvokeBasicTarget() { + ValueNode methodHandleNode = getReceiver(); + if (methodHandleNode.isConstant() && !methodHandleNode.isNullConstant()) { + // Get the data we need from MethodHandle.LambdaForm.MemberName + Constant methodHandle = methodHandleNode.asConstant(); + Constant lambdaForm = methodHandleFormField.readValue(methodHandle); + Constant memberName = lambdaFormVmentryField.readValue(lambdaForm); + return getTargetInvokeNode(memberName); + } + return null; + } + + /** + * Used from {@link MethodHandleLinkToStaticNode}, {@link MethodHandleLinkToSpecialNode}, + * {@link MethodHandleLinkToVirtualNode}, and {@link MethodHandleLinkToInterfaceNode} to get the + * target {@link InvokeNode} if the member name argument is constant. + * + * @return invoke node for the member name target + */ + protected InvokeNode getLinkToTarget() { + ValueNode memberNameNode = getMemberName(); + if (memberNameNode.isConstant() && !memberNameNode.isNullConstant()) { + Constant memberName = memberNameNode.asConstant(); + return getTargetInvokeNode(memberName); + } + return null; + } + + /** + * Helper function to get the {@link InvokeNode} for the vmtarget of a + * java.lang.invoke.MemberName. + * + * @param memberName constant member name node + * @return invoke node for the member name target + */ + private InvokeNode getTargetInvokeNode(Constant memberName) { + // Get the data we need from MemberName + Constant clazz = memberNameClazzField.readValue(memberName); + Constant vmtarget = memberNameVmtargetField.readValue(memberName); + + // Create a method from the vmtarget pointer + Class c = (Class) clazz.asObject(); + HotSpotResolvedObjectType holderClass = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c); + HotSpotResolvedJavaMethod targetMethod = holderClass.createMethod(vmtarget.asLong()); + + // In lamda forms we erase signature types to avoid resolving issues + // involving class loaders. When we optimize a method handle invoke + // to a direct call we must cast the receiver and arguments to its + // actual types. + HotSpotSignature signature = targetMethod.getSignature(); + final boolean isStatic = Modifier.isStatic(targetMethod.getModifiers()); + final int receiverSkip = isStatic ? 0 : 1; + + // Cast receiver to its type. + if (!isStatic) { + JavaType receiverType = holderClass; + maybeCastArgument(0, receiverType); + } + + // Cast reference arguments to its type. + for (int index = 0; index < signature.getParameterCount(false); index++) { + JavaType parameterType = signature.getParameterType(index, holderClass); + maybeCastArgument(receiverSkip + index, parameterType); + } + + // Try to get the most accurate receiver type + if (this instanceof MethodHandleLinkToVirtualNode || this instanceof MethodHandleLinkToInterfaceNode) { + ResolvedJavaType receiverType = getReceiver().objectStamp().type(); + if (receiverType != null) { + ResolvedJavaMethod concreteMethod = receiverType.findUniqueConcreteMethod(targetMethod); + if (concreteMethod != null) { + return createTargetInvokeNode(concreteMethod); + } + } + } + + if (targetMethod.canBeStaticallyBound()) { + return createTargetInvokeNode(targetMethod); + } + + ResolvedJavaMethod concreteMethod = targetMethod.uniqueConcreteMethod(); + if (concreteMethod != null) { + return createTargetInvokeNode(concreteMethod); + } + + return null; + } + + /** + * Inserts a node to cast the argument at index to the given type if the given type is more + * concrete than the argument type. + * + * @param index of the argument to be cast + * @param type the type the argument should be cast to + */ + private void maybeCastArgument(int index, JavaType type) { + if (type instanceof ResolvedJavaType) { + ResolvedJavaType targetType = (ResolvedJavaType) type; + if (!targetType.isPrimitive()) { + ValueNode argument = arguments.get(index); + ResolvedJavaType argumentType = argument.objectStamp().type(); + if (argumentType == null || (argumentType.isAssignableFrom(targetType) && !argumentType.equals(targetType))) { + PiNode piNode = graph().unique(new PiNode(argument, StampFactory.declared(targetType))); + arguments.set(index, piNode); + } + } + } + } + + /** + * Creates an {@link InvokeNode} for the given target method. The {@link CallTargetNode} passed + * to the InvokeNode is in fact a {@link SelfReplacingMethodCallTargetNode}. + * + * @param targetMethod the method the be called + * @return invoke node for the member name target + */ + private InvokeNode createTargetInvokeNode(ResolvedJavaMethod targetMethod) { + InvokeKind invokeKind = Modifier.isStatic(targetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special; + JavaType returnType = targetMethod.getSignature().getReturnType(null); + + // MethodHandleLinkTo* nodes have a trailing MemberName argument which + // needs to be popped. + ValueNode[] originalArguments = arguments.toArray(new ValueNode[arguments.size()]); + ValueNode[] targetArguments; + if (this instanceof MethodHandleInvokeBasicNode) { + targetArguments = originalArguments; + } else { + assert this instanceof MethodHandleLinkToStaticNode || this instanceof MethodHandleLinkToSpecialNode || this instanceof MethodHandleLinkToVirtualNode || + this instanceof MethodHandleLinkToInterfaceNode : this; + targetArguments = Arrays.copyOfRange(originalArguments, 0, arguments.size() - 1); + } + + // If there is already replacement information, use that instead. + MethodCallTargetNode callTarget; + if (replacementTargetMethod == null) { + callTarget = new SelfReplacingMethodCallTargetNode(invokeKind, targetMethod, targetArguments, returnType, getTargetMethod(), originalArguments, getReturnType()); + } else { + ValueNode[] args = replacementArguments.toArray(new ValueNode[replacementArguments.size()]); + callTarget = new SelfReplacingMethodCallTargetNode(invokeKind, targetMethod, targetArguments, returnType, replacementTargetMethod, args, replacementReturnType); + } + + graph().add(callTarget); + InvokeNode invoke = graph().add(new InvokeNode(callTarget, getBci())); + invoke.setStateAfter(stateAfter()); + return invoke; + } + +} diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleInvokeBasicNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleInvokeBasicNode.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleInvokeBasicNode.java Wed May 15 09:03:43 2013 +0200 @@ -22,17 +22,29 @@ */ package com.oracle.graal.hotspot.replacements; -import java.lang.invoke.*; +import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.*; -import com.oracle.graal.replacements.nodes.*; +import com.oracle.graal.nodes.Invoke; +import com.oracle.graal.nodes.InvokeNode; +import com.oracle.graal.nodes.ValueNode; +import com.oracle.graal.nodes.spi.CanonicalizerTool; /** * Macro node for {@link MethodHandle}{@code .invokeBasic(Object...)}. */ -public class MethodHandleInvokeBasicNode extends MacroNode { +public class MethodHandleInvokeBasicNode extends AbstractMethodHandleNode { public MethodHandleInvokeBasicNode(Invoke invoke) { super(invoke); } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + InvokeNode invoke = getInvokeBasicTarget(); + if (invoke != null) { + return invoke; + } + return this; + } + } diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToInterfaceNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToInterfaceNode.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToInterfaceNode.java Wed May 15 09:03:43 2013 +0200 @@ -22,17 +22,29 @@ */ package com.oracle.graal.hotspot.replacements; -import java.lang.invoke.*; +import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.*; -import com.oracle.graal.replacements.nodes.*; +import com.oracle.graal.nodes.Invoke; +import com.oracle.graal.nodes.InvokeNode; +import com.oracle.graal.nodes.ValueNode; +import com.oracle.graal.nodes.spi.CanonicalizerTool; /** * Macro node for {@link MethodHandle}{@code .linkToInterface(Object...)}. */ -public class MethodHandleLinkToInterfaceNode extends MacroNode { +public class MethodHandleLinkToInterfaceNode extends AbstractMethodHandleNode { public MethodHandleLinkToInterfaceNode(Invoke invoke) { super(invoke); } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + InvokeNode invoke = getLinkToTarget(); + if (invoke != null) { + return invoke; + } + return this; + } + } diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToSpecialNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToSpecialNode.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToSpecialNode.java Wed May 15 09:03:43 2013 +0200 @@ -22,17 +22,29 @@ */ package com.oracle.graal.hotspot.replacements; -import java.lang.invoke.*; +import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.*; -import com.oracle.graal.replacements.nodes.*; +import com.oracle.graal.nodes.Invoke; +import com.oracle.graal.nodes.InvokeNode; +import com.oracle.graal.nodes.ValueNode; +import com.oracle.graal.nodes.spi.CanonicalizerTool; /** * Macro node for {@link MethodHandle}{@code .linkToSpecial(Object...)}. */ -public class MethodHandleLinkToSpecialNode extends MacroNode { +public class MethodHandleLinkToSpecialNode extends AbstractMethodHandleNode { public MethodHandleLinkToSpecialNode(Invoke invoke) { super(invoke); } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + InvokeNode invoke = getLinkToTarget(); + if (invoke != null) { + return invoke; + } + return this; + } + } diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToStaticNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToStaticNode.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToStaticNode.java Wed May 15 09:03:43 2013 +0200 @@ -22,17 +22,29 @@ */ package com.oracle.graal.hotspot.replacements; -import java.lang.invoke.*; +import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.*; -import com.oracle.graal.replacements.nodes.*; +import com.oracle.graal.nodes.Invoke; +import com.oracle.graal.nodes.InvokeNode; +import com.oracle.graal.nodes.ValueNode; +import com.oracle.graal.nodes.spi.CanonicalizerTool; /** * Macro node for {@link MethodHandle}{@code .linkToStatic(Object...)}. */ -public class MethodHandleLinkToStaticNode extends MacroNode { +public class MethodHandleLinkToStaticNode extends AbstractMethodHandleNode { public MethodHandleLinkToStaticNode(Invoke invoke) { super(invoke); } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + InvokeNode invoke = getLinkToTarget(); + if (invoke != null) { + return invoke; + } + return this; + } + } diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToVirtualNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToVirtualNode.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToVirtualNode.java Wed May 15 09:03:43 2013 +0200 @@ -22,17 +22,29 @@ */ package com.oracle.graal.hotspot.replacements; -import java.lang.invoke.*; +import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.*; -import com.oracle.graal.replacements.nodes.*; +import com.oracle.graal.nodes.Invoke; +import com.oracle.graal.nodes.InvokeNode; +import com.oracle.graal.nodes.ValueNode; +import com.oracle.graal.nodes.spi.CanonicalizerTool; /** * Macro node for {@link MethodHandle}{@code .linkToVirtual(Object...)}. */ -public class MethodHandleLinkToVirtualNode extends MacroNode { +public class MethodHandleLinkToVirtualNode extends AbstractMethodHandleNode { public MethodHandleLinkToVirtualNode(Invoke invoke) { super(invoke); } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + InvokeNode invoke = getLinkToTarget(); + if (invoke != null) { + return invoke; + } + return this; + } + } diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/RuntimeCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/RuntimeCallStub.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/RuntimeCallStub.java Wed May 15 09:03:43 2013 +0200 @@ -22,23 +22,24 @@ */ package com.oracle.graal.hotspot.stubs; +import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.hotspot.HotSpotRuntimeCallTarget.RegisterEffect.*; import java.lang.reflect.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; @@ -79,12 +80,11 @@ * @param vm the Java to HotSpot C/C++ runtime interface */ public RuntimeCallStub(long address, Descriptor sig, boolean prependThread, HotSpotRuntime runtime, Replacements replacements, RegisterConfig regConfig, CompilerToVM vm) { - super(runtime, replacements, new HotSpotRuntimeCallTarget(sig, 0L, false, createCallingConvention(runtime, regConfig, sig), vm)); + super(runtime, replacements, HotSpotRuntimeCallTarget.create(sig, 0L, PRESERVES_REGISTERS, JavaCallee, regConfig, runtime, vm)); this.prependThread = prependThread; Class[] targetParameterTypes = createTargetParameters(sig); Descriptor targetSig = new Descriptor(sig.getName() + ":C", sig.hasSideEffect(), sig.getResultType(), targetParameterTypes); - CallingConvention targetCc = createCallingConvention(runtime, regConfig, targetSig); - target = new HotSpotRuntimeCallTarget(targetSig, address, true, targetCc, vm); + target = HotSpotRuntimeCallTarget.create(targetSig, address, DESTROYS_REGISTERS, NativeCall, regConfig, runtime, vm); } /** @@ -94,21 +94,6 @@ return target; } - private static CallingConvention createCallingConvention(HotSpotRuntime runtime, RegisterConfig regConfig, Descriptor d) { - Class[] argumentTypes = d.getArgumentTypes(); - JavaType[] parameterTypes = new JavaType[argumentTypes.length]; - for (int i = 0; i < parameterTypes.length; ++i) { - if (WordBase.class.isAssignableFrom(argumentTypes[i])) { - parameterTypes[i] = runtime.lookupJavaType(wordKind().toJavaClass()); - } else { - parameterTypes[i] = runtime.lookupJavaType(argumentTypes[i]); - } - } - TargetDescription target = graalRuntime().getTarget(); - JavaType returnType = runtime.lookupJavaType(d.getResultType()); - return regConfig.getCallingConvention(Type.NativeCall, returnType, parameterTypes, target, false); - } - private Class[] createTargetParameters(Descriptor sig) { Class[] parameters = sig.getArgumentTypes(); if (prependThread) { @@ -130,7 +115,7 @@ return new JavaMethod() { public Signature getSignature() { - Descriptor d = linkage.descriptor; + Descriptor d = linkage.getDescriptor(); Class[] arguments = d.getArgumentTypes(); JavaType[] parameters = new JavaType[arguments.length]; for (int i = 0; i < arguments.length; i++) { @@ -140,7 +125,7 @@ } public String getName() { - return linkage.descriptor.getName(); + return linkage.getDescriptor().getName(); } public JavaType getDeclaringClass() { @@ -165,19 +150,19 @@ final StructuredGraph graph; private FixedWithNextNode lastFixedNode; - T add(T node) { + T add(T node) { + return graph.unique(node); + } + + T append(T node) { T result = graph.add(node); - assert node == result; - if (result instanceof FixedNode) { - assert lastFixedNode != null; - FixedNode fixed = (FixedNode) result; - assert fixed.predecessor() == null; - graph.addAfterFixed(lastFixedNode, fixed); - if (fixed instanceof FixedWithNextNode) { - lastFixedNode = (FixedWithNextNode) fixed; - } else { - lastFixedNode = null; - } + assert lastFixedNode != null; + assert result.predecessor() == null; + graph.addAfterFixed(lastFixedNode, result); + if (result instanceof FixedWithNextNode) { + lastFixedNode = (FixedWithNextNode) result; + } else { + lastFixedNode = null; } return result; } @@ -187,19 +172,17 @@ protected StructuredGraph getGraph() { Class[] args = linkage.getDescriptor().getArgumentTypes(); boolean isObjectResult = linkage.getCallingConvention().getReturn().getKind() == Kind.Object; - GraphBuilder builder = new GraphBuilder(this); - LocalNode[] locals = createLocals(builder, args); - ReadRegisterNode thread = prependThread || isObjectResult ? builder.add(new ReadRegisterNode(runtime.threadRegister(), true, false)) : null; + ReadRegisterNode thread = prependThread || isObjectResult ? builder.append(new ReadRegisterNode(runtime.threadRegister(), true, false)) : null; ValueNode result = createTargetCall(builder, locals, thread); createInvoke(builder, StubUtil.class, "handlePendingException", ConstantNode.forBoolean(isObjectResult, builder.graph)); if (isObjectResult) { InvokeNode object = createInvoke(builder, HotSpotReplacementsUtil.class, "getAndClearObjectResult", thread); result = createInvoke(builder, StubUtil.class, "verifyObject", object); } - builder.add(new ReturnNode(linkage.descriptor.getResultType() == void.class ? null : result)); + builder.append(new ReturnNode(linkage.getDescriptor().getResultType() == void.class ? null : result)); if (Debug.isDumpEnabled()) { Debug.dump(builder.graph, "Initial stub graph"); @@ -245,8 +228,8 @@ } assert method != null : "did not find method in " + declaringClass + " named " + name; JavaType returnType = method.getSignature().getReturnType(null); - MethodCallTargetNode callTarget = builder.add(new MethodCallTargetNode(InvokeKind.Static, method, hpeArgs, returnType)); - InvokeNode invoke = builder.add(new InvokeNode(callTarget, FrameState.UNKNOWN_BCI)); + MethodCallTargetNode callTarget = builder.graph.add(new MethodCallTargetNode(InvokeKind.Static, method, hpeArgs, returnType)); + InvokeNode invoke = builder.append(new InvokeNode(callTarget, FrameState.UNKNOWN_BCI)); return invoke; } @@ -255,9 +238,9 @@ ValueNode[] targetArguments = new ValueNode[1 + locals.length]; targetArguments[0] = thread; System.arraycopy(locals, 0, targetArguments, 1, locals.length); - return builder.add(new CRuntimeCall(target.descriptor, targetArguments)); + return builder.append(new CRuntimeCall(target.getDescriptor(), targetArguments)); } else { - return builder.add(new CRuntimeCall(target.descriptor, locals)); + return builder.append(new CRuntimeCall(target.getDescriptor(), locals)); } } diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/WriteBarrierPostStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/WriteBarrierPostStub.java Wed May 15 09:03:11 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +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.stubs; - -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.hotspot.stubs.StubUtil.*; - -import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; -import com.oracle.graal.api.code.*; -import com.oracle.graal.graph.Node.ConstantNodeParameter; -import com.oracle.graal.graph.Node.NodeIntrinsic; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.replacements.*; -import com.oracle.graal.word.*; - -/** - * Stub called from {@link WriteBarrierPostStubCall}. - */ -public class WriteBarrierPostStub extends CRuntimeStub { - - public WriteBarrierPostStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { - super(runtime, replacements, target, linkage); - } - - @Snippet - private static void writeBarrierPost(Object object, Word card) { - writeBarrierPostC(WRITE_BARRIER_POST_C, thread(), object, card); - } - - public static final Descriptor WRITE_BARRIER_POST_C = descriptorFor(WriteBarrierPostStub.class, "writeBarrierPostC", false); - - @NodeIntrinsic(CRuntimeCall.class) - public static native void writeBarrierPostC(@ConstantNodeParameter Descriptor vmErrorC, Word thread, Object object, Word card); -} diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/WriteBarrierPreStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/WriteBarrierPreStub.java Wed May 15 09:03:11 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +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.stubs; - -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.hotspot.stubs.StubUtil.*; - -import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; -import com.oracle.graal.api.code.*; -import com.oracle.graal.graph.Node.ConstantNodeParameter; -import com.oracle.graal.graph.Node.NodeIntrinsic; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.replacements.*; -import com.oracle.graal.word.*; - -/** - * Stub called from {@link WriteBarrierPreStubCall}. - */ -public class WriteBarrierPreStub extends CRuntimeStub { - - public WriteBarrierPreStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { - super(runtime, replacements, target, linkage); - } - - @Snippet - private static void writeBarrierPre(Object object) { - writeBarrierPreC(WRITE_BARRIER_PRE_C, thread(), object); - } - - public static final Descriptor WRITE_BARRIER_PRE_C = descriptorFor(WriteBarrierPreStub.class, "writeBarrierPreC", false); - - @NodeIntrinsic(CRuntimeCall.class) - public static native void writeBarrierPreC(@ConstantNodeParameter Descriptor vmErrorC, Word thread, Object object); -} diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java Wed May 15 09:03:43 2013 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.lir.asm.*; /** - * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method. + * Convenience class to provide SPARCAssembler for the {@link #emitCode} method. */ public abstract class SPARCLIRInstruction extends LIRInstruction { diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Wed May 15 09:03:43 2013 +0200 @@ -72,6 +72,10 @@ public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); + if (read.usages().count() == 0) { + // Read without usages can be savely removed. + return null; + } if (runtime != null && object != null && object.isConstant()) { if (location.getLocationIdentity() == LocationNode.FINAL_LOCATION && location instanceof ConstantLocationNode) { long displacement = ((ConstantLocationNode) location).getDisplacement(); diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java Wed May 15 09:03:43 2013 +0200 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013, 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.nodes.java; + +import java.lang.reflect.Modifier; + +import com.oracle.graal.api.meta.JavaType; +import com.oracle.graal.api.meta.ResolvedJavaMethod; +import com.oracle.graal.graph.GraalInternalError; +import com.oracle.graal.graph.NodeInputList; +import com.oracle.graal.nodes.ValueNode; +import com.oracle.graal.nodes.spi.LIRGeneratorTool; +import com.oracle.graal.nodes.spi.Lowerable; +import com.oracle.graal.nodes.spi.LoweringTool; + +/** + * A SelfReplacingMethodCallTargetNode replaces itself in the graph when being lowered with a + * {@link MethodCallTargetNode} that calls the stored replacement target method. + * + * This node is used for method handle call nodes which have a constant call target but are not + * inlined. + */ +public class SelfReplacingMethodCallTargetNode extends MethodCallTargetNode implements Lowerable { + + // Replacement method data + private final ResolvedJavaMethod replacementTargetMethod; + private final JavaType replacementReturnType; + @Input private final NodeInputList replacementArguments; + + public SelfReplacingMethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod replacementTargetMethod, + ValueNode[] replacementArguments, JavaType replacementReturnType) { + super(invokeKind, targetMethod, arguments, returnType); + this.replacementTargetMethod = replacementTargetMethod; + this.replacementReturnType = replacementReturnType; + this.replacementArguments = new NodeInputList<>(this, replacementArguments); + } + + public ResolvedJavaMethod replacementTargetMethod() { + return replacementTargetMethod; + } + + public JavaType replacementReturnType() { + return replacementReturnType; + } + + public NodeInputList replacementArguments() { + return replacementArguments; + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + InvokeKind invokeKind = Modifier.isStatic(replacementTargetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special; + MethodCallTargetNode replacement = graph().add( + new MethodCallTargetNode(invokeKind, replacementTargetMethod, replacementArguments.toArray(new ValueNode[replacementArguments.size()]), replacementReturnType)); + + // Replace myself... + this.replaceAndDelete(replacement); + } + + @Override + public void generate(LIRGeneratorTool gen) { + throw GraalInternalError.shouldNotReachHere("should have replaced itself"); + } +} diff -r 4420f32a6d5c -r 521c4f7aac66 graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java --- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Wed May 15 09:03:11 2013 +0200 +++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Wed May 15 09:03:43 2013 +0200 @@ -38,7 +38,7 @@ // SPARC: Define registers. public SPARC() { - super("AMD64", 8, ByteOrder.LITTLE_ENDIAN, null, LOAD_STORE | STORE_STORE, 1, 0, 8); + super("SPARC", 8, ByteOrder.LITTLE_ENDIAN, null, LOAD_STORE | STORE_STORE, 1, 0, 8); // SPARC: Fix architecture parameters. } diff -r 4420f32a6d5c -r 521c4f7aac66 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed May 15 09:03:11 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed May 15 09:03:43 2013 +0200 @@ -768,11 +768,6 @@ set_address("inlineCacheMissStub", SharedRuntime::get_ic_miss_stub()); set_address("handleDeoptStub", SharedRuntime::deopt_blob()->unpack()); - set_address("javaTimeMillisStub", CAST_FROM_FN_PTR(address, os::javaTimeMillis)); - set_address("javaTimeNanosStub", CAST_FROM_FN_PTR(address, os::javaTimeNanos)); - set_address("arithmeticSinStub", CAST_FROM_FN_PTR(address, SharedRuntime::dsin)); - set_address("arithmeticCosStub", CAST_FROM_FN_PTR(address, SharedRuntime::dcos)); - set_address("arithmeticTanStub", CAST_FROM_FN_PTR(address, SharedRuntime::dtan)); set_address("aescryptEncryptBlockStub", StubRoutines::aescrypt_encryptBlock()); set_address("aescryptDecryptBlockStub", StubRoutines::aescrypt_decryptBlock()); set_address("cipherBlockChainingEncryptAESCryptStub", StubRoutines::cipherBlockChaining_encryptAESCrypt()); @@ -799,6 +794,11 @@ set_address("vmErrorAddress", GraalRuntime::vm_error); set_address("writeBarrierPreAddress", GraalRuntime::write_barrier_pre); set_address("writeBarrierPostAddress", GraalRuntime::write_barrier_post); + set_address("javaTimeMillisAddress", CAST_FROM_FN_PTR(address, os::javaTimeMillis)); + set_address("javaTimeNanosAddress", CAST_FROM_FN_PTR(address, os::javaTimeNanos)); + set_address("arithmeticSinAddress", CAST_FROM_FN_PTR(address, SharedRuntime::dsin)); + set_address("arithmeticCosAddress", CAST_FROM_FN_PTR(address, SharedRuntime::dcos)); + set_address("arithmeticTanAddress", CAST_FROM_FN_PTR(address, SharedRuntime::dtan)); set_int("deoptReasonNone", Deoptimization::Reason_none); set_int("deoptReasonNullCheck", Deoptimization::Reason_null_check);