# HG changeset patch # User Roland Schatz # Date 1390387467 -3600 # Node ID 343541fb3b49c27ffa65e778aa47392ac75fab15 # Parent 8d8732e14447407eef9d2cb0e69583e8939adbb9 Support narrow oops in reference maps. diff -r 8d8732e14447 -r 343541fb3b49 graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java --- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Wed Jan 22 11:27:28 2014 +0100 +++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Wed Jan 22 11:44:27 2014 +0100 @@ -146,6 +146,7 @@ case Short: case Int: case Long: + case NarrowOop: case Object: return true; } diff -r 8d8732e14447 -r 343541fb3b49 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Wed Jan 22 11:27:28 2014 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Wed Jan 22 11:44:27 2014 +0100 @@ -223,6 +223,8 @@ return 8; case Object: return wordSize; + case NarrowOop: + return wordSize / 2; default: return 0; } diff -r 8d8732e14447 -r 343541fb3b49 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Wed Jan 22 11:27:28 2014 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Wed Jan 22 11:44:27 2014 +0100 @@ -31,24 +31,51 @@ private static final long serialVersionUID = -1052183095979496819L; + /** + * Contains 2 bits per register. + * + */ private final BitSet registerRefMap; + + /** + * Contains 3 bits per stack slot. + * + */ private final BitSet frameRefMap; public ReferenceMap(int registerCount, int frameSlotCount) { if (registerCount > 0) { - this.registerRefMap = new BitSet(registerCount); + this.registerRefMap = new BitSet(registerCount * 2); } else { this.registerRefMap = null; } - this.frameRefMap = new BitSet(frameSlotCount); + this.frameRefMap = new BitSet(frameSlotCount * 3); } - public void setRegister(int idx) { - registerRefMap.set(idx); + public void setRegister(int idx, boolean narrow) { + registerRefMap.set(2 * idx); + if (narrow) { + registerRefMap.set(2 * idx + 1); + } } - public void setStackSlot(int idx) { - frameRefMap.set(idx); + public void setStackSlot(int idx, boolean narrow1, boolean narrow2) { + frameRefMap.set(3 * idx); + if (narrow1) { + frameRefMap.set(3 * idx + 1); + } + if (narrow2) { + frameRefMap.set(3 * idx + 2); + } } public boolean hasRegisterRefMap() { @@ -76,8 +103,8 @@ formatter = new NumberedRefMapFormatter(); } - for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 1)) { - sb.append(' ').append(formatter.formatRegister(reg)); + for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 2)) { + sb.append(' ').append(formatter.formatRegister(reg / 2)); } } @@ -87,8 +114,8 @@ formatter = new NumberedRefMapFormatter(); } - for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 1)) { - sb.append(' ').append(formatter.formatStackSlot(slot)); + for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 3)) { + sb.append(' ').append(formatter.formatStackSlot(slot / 3)); } } } diff -r 8d8732e14447 -r 343541fb3b49 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Wed Jan 22 11:27:28 2014 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Wed Jan 22 11:44:27 2014 +0100 @@ -159,6 +159,7 @@ case Double: return asDouble(); case Object: + case NarrowOop: return object; case Illegal: return this; @@ -171,7 +172,7 @@ if (!ignoreKind && getKind() != other.getKind()) { return false; } - if (getKind() == Kind.Object) { + if (getKind() == Kind.Object || getKind() == Kind.NarrowOop) { return object == other.object; } return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation(); @@ -234,12 +235,12 @@ /** * Returns the object reference this constant represents. The constant must have kind - * {@link Kind#Object}. + * {@link Kind#Object} or {@link Kind#NarrowOop}. * * @return the constant value */ public Object asObject() { - assert getKind() == Kind.Object; + assert getKind() == Kind.Object || getKind() == Kind.NarrowOop; return object; } @@ -249,7 +250,7 @@ * @return null if this constant is not primitive or has no annotation */ public Object getPrimitiveAnnotation() { - return getKind() == Kind.Object ? null : object; + return getKind() == Kind.Object || getKind() == Kind.NarrowOop ? null : object; } /** @@ -259,7 +260,7 @@ */ @Override public int hashCode() { - if (getKind() == Kind.Object) { + if (getKind() == Kind.Object || getKind() == Kind.NarrowOop) { return System.identityHashCode(object); } return (int) primitive * getKind().ordinal(); @@ -393,6 +394,16 @@ } /** + * Creates a boxed narrow oop constant. + * + * @param o the object value to box + * @return a boxed copy of {@code value} + */ + public static Constant forNarrowOop(Object o) { + return new Constant(Kind.NarrowOop, o, 0L); + } + + /** * Creates an annotated int or long constant. An annotation enables a client to associate some * extra semantic or debugging information with a primitive. An annotated primitive constant is * never {@linkplain #equals(Object) equal} to a non-annotated constant. @@ -440,6 +451,8 @@ return forDouble((Double) value); case Object: return forObject(value); + case NarrowOop: + return forNarrowOop(value); default: throw new RuntimeException("cannot create Constant for boxed " + kind + " value"); } @@ -472,6 +485,8 @@ return LONG_0; case Object: return NULL_OBJECT; + case NarrowOop: + return forNarrowOop(null); default: throw new IllegalArgumentException(kind.toString()); } diff -r 8d8732e14447 -r 343541fb3b49 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Wed Jan 22 11:27:28 2014 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Wed Jan 22 11:44:27 2014 +0100 @@ -57,6 +57,9 @@ /** The Object kind, also used for arrays. */ Object('a', "Object", false, null, null), + /** The narrow oop kind. */ + NarrowOop('n', "NarrowOop", false, null, null), + /** The void float kind. */ Void('v', "void", false, java.lang.Void.TYPE, java.lang.Void.class), diff -r 8d8732e14447 -r 343541fb3b49 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 Jan 22 11:27:28 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Jan 22 11:44:27 2014 +0100 @@ -458,7 +458,7 @@ if (c.getKind() == Kind.Long) { return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); } else if (c.getKind() == Kind.Object) { - return Constant.forIntegerKind(Kind.Int, 0xdeaddead, c.asObject()); + return Constant.forNarrowOop(c.asObject()); } else { throw GraalInternalError.shouldNotReachHere(); } diff -r 8d8732e14447 -r 343541fb3b49 graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java --- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java Wed Jan 22 11:27:28 2014 +0100 +++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java Wed Jan 22 11:44:27 2014 +0100 @@ -29,7 +29,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.Register.RegisterCategory; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; /** * Represents the HSAIL architecture. @@ -166,39 +165,16 @@ Register reg; int encoding = 0; String regPrefix = null; - String argType = arg.getKind().getJavaName(); - if (argType.equals("double") || argType.equals("long")) { + Kind kind = arg.getKind(); + if (kind == Kind.Double || kind == Kind.Long) { regPrefix = "$d"; - } else if (argType.equals("int") || argType.equals("float")) { + } else if (kind == Kind.Int || kind == Kind.Float || kind == Kind.NarrowOop) { regPrefix = "$s"; } else { regPrefix = "$d"; } - switch (argType) { - case "float": - reg = asFloatReg(arg); - encoding = reg.encoding(); - break; - case "int": - reg = asIntReg(arg); - encoding = reg.encoding(); - break; - case "long": - reg = asLongReg(arg); - encoding = reg.encoding(); - break; - case "double": - reg = asDoubleReg(arg); - encoding = reg.encoding(); - break; - case "Object": - reg = asObjectReg(arg); - encoding = reg.encoding(); - break; - default: - GraalInternalError.shouldNotReachHere(); - break; - } + reg = asRegister(arg); + encoding = reg.encoding(); return new String(regPrefix + encoding); } @@ -217,6 +193,7 @@ case Int: case Long: case Object: + case NarrowOop: return true; } } else if (category == FPU) { diff -r 8d8732e14447 -r 343541fb3b49 graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java --- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java Wed Jan 22 11:27:28 2014 +0100 +++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java Wed Jan 22 11:44:27 2014 +0100 @@ -150,6 +150,7 @@ case Short: case Byte: case Float: + case NarrowOop: return regBitness32.clone(); case Long: case Double: diff -r 8d8732e14447 -r 343541fb3b49 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Wed Jan 22 11:27:28 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Wed Jan 22 11:44:27 2014 +0100 @@ -360,12 +360,19 @@ * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}. */ public void setReference(Value location, ReferenceMap refMap) { - if (location.getKind() == Kind.Object) { + Kind kind = location.getKind(); + if (kind == Kind.Object || kind == Kind.NarrowOop) { if (isRegister(location)) { - refMap.setRegister(asRegister(location).number); + refMap.setRegister(asRegister(location).number, kind == Kind.NarrowOop); } else if (isStackSlot(location)) { - int index = indexForStackSlot(asStackSlot(location)); - refMap.setStackSlot(index); + if (kind == Kind.NarrowOop) { + int offset = offsetForStackSlot(asStackSlot(location)); + assert offset % target.wordSize == 0 || offset % target.wordSize == target.wordSize / 2; + refMap.setStackSlot(offset / target.wordSize, offset % target.wordSize == 0, offset % target.wordSize != 0); + } else { + int index = indexForStackSlot(asStackSlot(location)); + refMap.setStackSlot(index, false, false); + } } else { assert isConstant(location); } diff -r 8d8732e14447 -r 343541fb3b49 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 Jan 22 11:27:28 2014 +0100 +++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Wed Jan 22 11:44:27 2014 +0100 @@ -162,6 +162,7 @@ case Int: case Long: case Object: + case NarrowOop: return true; } } else if (category == FPU) { diff -r 8d8732e14447 -r 343541fb3b49 src/cpu/x86/vm/graalCodeInstaller_x86.hpp --- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Wed Jan 22 11:27:28 2014 +0100 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Wed Jan 22 11:44:27 2014 +0100 @@ -72,9 +72,10 @@ case 'b': case 's': case 'c': + case 'i': fatal("int-sized values not expected in DataPatch"); break; - case 'i': { + case 'n': { address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); Handle obj = Constant::object(inlineData); diff -r 8d8732e14447 -r 343541fb3b49 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Wed Jan 22 11:27:28 2014 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Wed Jan 22 11:44:27 2014 +0100 @@ -91,22 +91,38 @@ if (register_map != NULL) { for (jint i = 0; i < RegisterImpl::number_of_registers; i++) { - bool is_oop = is_bit_set(register_map, i); + bool is_oop = is_bit_set(register_map, 2 * i); VMReg hotspot_reg = get_hotspot_reg(i); if (is_oop) { - map->set_oop(hotspot_reg); + if (is_bit_set(register_map, 2 * i + 1)) { + map->set_narrowoop(hotspot_reg); + } else { + map->set_oop(hotspot_reg); + } } else { map->set_value(hotspot_reg); } } } - for (jint i = 0; i < bitset_size(frame_map); i++) { - bool is_oop = is_bit_set(frame_map, i); + for (jint i = 0; i < bitset_size(frame_map) / 3; i++) { + bool is_oop = is_bit_set(frame_map, i * 3); // HotSpot stack slots are 4 bytes VMReg reg = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word); if (is_oop) { - map->set_oop(reg); + bool narrow1 = is_bit_set(frame_map, i * 3 + 1); + bool narrow2 = is_bit_set(frame_map, i * 3 + 2); + if(narrow1 || narrow2) { + if(narrow1) { + map->set_narrowoop(reg); + } + if(narrow2) { + VMReg reg2 = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word + 1); + map->set_narrowoop(reg2); + } + } else { + map->set_oop(reg); + } } else { map->set_value(reg); }