Mercurial > hg > graal-jvmci-8
changeset 21733:27943aac2e3c
Merge
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Thu, 04 Jun 2015 11:08:12 -0700 |
parents | bc2ec35a7189 (diff) 009842dce4f0 (current diff) |
children | c2e90b2b3fcc |
files | graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/BitOpsTest.java graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/IncrementDecrementMacroTest.java graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64AsmOptions.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCInstructionCounter.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java graal/com.oracle.graal.asm/overview.html graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AsmOptions.java graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java graal/com.oracle.graal.asm/src/com/oracle/graal/asm/NumUtil.java graal/com.oracle.graal.bytecode/overview.html graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeLookupSwitch.java graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeStream.java graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeSwitch.java graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeTableSwitch.java graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytecodes.java graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytes.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/jvmci/AMD64HotSpotJVMCIBackendFactory.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/jvmci/SPARCHotSpotJVMCIBackendFactory.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/ConstantTest.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/FieldUniverse.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/MethodUniverse.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/NameAndSignature.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/ResolvedJavaTypeResolveConcreteMethodTest.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/ResolvedJavaTypeResolveMethodTest.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestConstantReflectionProvider.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestJavaField.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestJavaMethod.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestJavaType.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestMetaAccessProvider.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestResolvedJavaField.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestResolvedJavaMethod.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestResolvedJavaType.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TypeUniverse.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/DisassemblerProvider.java graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HexCodeFile.java graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ExcludeFromIdentityComparisonVerification.java graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Value.java graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTest.java |
diffstat | 18 files changed, 410 insertions(+), 739 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Thu Jun 04 11:08:12 2015 -0700 @@ -64,8 +64,6 @@ public static final class LabelOp extends LIRInstruction { public static final LIRInstructionClass<LabelOp> TYPE = LIRInstructionClass.create(LabelOp.class); - private static final Value[] NO_VALUES = new Value[0]; - /** * In the LIR, every register and variable must be defined before it is used. For method * parameters that are passed in fixed registers, exception objects passed to the exception @@ -83,7 +81,7 @@ super(TYPE); this.label = label; this.align = align; - this.incomingValues = NO_VALUES; + this.incomingValues = Value.NO_VALUES; } public void setIncomingValues(Value[] values) { @@ -101,7 +99,7 @@ } public void clearIncomingValues() { - incomingValues = NO_VALUES; + incomingValues = Value.NO_VALUES; } @Override @@ -130,8 +128,6 @@ public static class JumpOp extends LIRInstruction implements BlockEndOp { public static final LIRInstructionClass<JumpOp> TYPE = LIRInstructionClass.create(JumpOp.class); - private static final Value[] NO_VALUES = new Value[0]; - @Alive({REG, STACK, CONST}) private Value[] outgoingValues; private final LabelRef destination; @@ -143,7 +139,7 @@ protected JumpOp(LIRInstructionClass<? extends JumpOp> c, LabelRef destination) { super(c); this.destination = destination; - this.outgoingValues = NO_VALUES; + this.outgoingValues = Value.NO_VALUES; } public void setOutgoingValues(Value[] values) { @@ -161,7 +157,7 @@ } public void clearOutgoingValues() { - outgoingValues = NO_VALUES; + outgoingValues = Value.NO_VALUES; } @Override
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Thu Jun 04 11:08:12 2015 -0700 @@ -25,6 +25,7 @@ import static com.oracle.jvmci.code.ValueUtil.*; import java.util.*; +import java.util.function.*; import com.oracle.graal.compiler.common.alloc.*; import com.oracle.graal.compiler.common.cfg.*; @@ -104,51 +105,203 @@ } } - private static final class LiveValueSet implements Iterable<Value> { - private static final Object MARKER = new Object(); + private static final class ValueSet { + private Value[] values; - private final HashMap<Value, Object> map; - - public LiveValueSet() { - map = new HashMap<>(); + ValueSet() { + values = Value.NO_VALUES; } - public LiveValueSet(LiveValueSet s) { - map = new HashMap<>(s.map); + ValueSet(ValueSet other) { + int limit = other.values.length; + while (limit > 0) { + if (other.values[limit - 1] == null) { + limit--; + continue; + } + break; + } + values = new Value[limit]; + System.arraycopy(other.values, 0, values, 0, values.length); } - public void put(Value v) { - map.put(v, MARKER); + void put(int index, Value value) { + if (value != null && value.getLIRKind().isValue()) { + return; + } + if (values.length <= index) { + if (value == null) { + return; + } + Value[] newValues = new Value[index + 1]; + System.arraycopy(values, 0, newValues, 0, values.length); + values = newValues; + values[index] = value; + } else { + values[index] = value; + } } - public void putAll(LiveValueSet v) { - map.putAll(v.map); - } - - public void remove(Value v) { - map.remove(v); - } - - public Iterator<Value> iterator() { - return map.keySet().iterator(); + public void putAll(ValueSet stack) { + Value[] otherValues = stack.values; + int limit = otherValues.length; + if (limit > values.length) { + while (limit > 0) { + if (otherValues[limit - 1] == null) { + limit--; + continue; + } + break; + } + if (limit > values.length) { + Value[] newValues = new Value[limit]; + System.arraycopy(values, 0, newValues, 0, values.length); + values = newValues; + } + } + for (int i = 0; i < limit; i++) { + Value value = otherValues[i]; + if (value != null) { + values[i] = value; + } + } } @Override - public boolean equals(Object obj) { - if (obj instanceof LiveValueSet) { - return map.equals(((LiveValueSet) obj).map); - } else { - return false; + public boolean equals(Object other) { + if (other instanceof ValueSet) { + ValueSet that = (ValueSet) other; + int limit = Math.min(values.length, that.values.length); + for (int i = 0; i < limit; i++) { + if (!Objects.equals(values[i], that.values[i])) { + return false; + } + } + for (int i = limit; i < values.length; i++) { + if (values[i] != null) { + return false; + } + } + for (int i = limit; i < that.values.length; i++) { + if (that.values[i] != null) { + return false; + } + } + return true; + } + return false; + } + + public void addLiveValues(ReferenceMap refMap) { + for (Value v : values) { + if (v != null) { + refMap.addLiveValue(v); + } } } @Override public int hashCode() { - return map.hashCode(); + throw new UnsupportedOperationException(); } } private static final class Marker<T extends AbstractBlockBase<T>> { + + private final class LiveValueSet implements Consumer<AbstractBlockBase<T>> { + + public void accept(AbstractBlockBase<T> succ) { + putAll(liveInMap.get(succ)); + } + + private final ValueSet registers; + private final ValueSet stack; + private Set<Value> extraStack; + + public LiveValueSet() { + registers = new ValueSet(); + stack = new ValueSet(); + } + + public LiveValueSet(LiveValueSet s) { + registers = new ValueSet(s.registers); + stack = new ValueSet(s.stack); + if (s.extraStack != null) { + extraStack = new HashSet<>(s.extraStack); + } + } + + public void put(Value v) { + if (isRegister(v)) { + int index = asRegister(v).getReferenceMapIndex(); + registers.put(index, v); + } else if (isStackSlot(v)) { + int index = frameMap.offsetForStackSlot(asStackSlot(v)); + assert index >= 0; + if (index % 4 == 0) { + stack.put(index / 4, v); + } else { + if (extraStack == null) { + extraStack = new HashSet<>(); + } + extraStack.add(v); + } + } + } + + public void putAll(LiveValueSet v) { + registers.putAll(v.registers); + stack.putAll(v.stack); + if (v.extraStack != null) { + if (extraStack == null) { + extraStack = new HashSet<>(); + } + extraStack.addAll(v.extraStack); + } + } + + public void remove(Value v) { + if (isRegister(v)) { + int index = asRegister(v).getReferenceMapIndex(); + registers.put(index, null); + } else if (isStackSlot(v)) { + int index = frameMap.offsetForStackSlot(asStackSlot(v)); + assert index >= 0; + if (index % 4 == 0) { + stack.put(index / 4, null); + } else { + extraStack.remove(v); + } + } + } + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object obj) { + if (obj instanceof Marker.LiveValueSet) { + LiveValueSet other = (LiveValueSet) obj; + return registers.equals(other.registers) && stack.equals(other.stack) && Objects.equals(extraStack, other.extraStack); + } else { + return false; + } + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException(); + } + + public void addLiveValues(ReferenceMap refMap) { + registers.addLiveValues(refMap); + stack.addLiveValues(refMap); + if (extraStack != null) { + for (Value v : extraStack) { + refMap.addLiveValue(v); + } + } + } + } + private final LIR lir; private final FrameMap frameMap; private final RegisterAttributes[] registerAttributes; @@ -181,9 +334,9 @@ /** * Merge outSet with in-set of successors. */ - private boolean updateOutBlock(AbstractBlockBase<?> block) { + private boolean updateOutBlock(AbstractBlockBase<T> block) { LiveValueSet union = new LiveValueSet(); - block.getSuccessors().forEach(succ -> union.putAll(liveInMap.get(succ))); + block.getSuccessors().forEach(union); LiveValueSet outSet = liveOutMap.get(block); // check if changed if (outSet == null || !union.equals(outSet)) { @@ -196,13 +349,14 @@ private void processBlock(AbstractBlockBase<T> block, UniqueWorkList<T> worklist) { if (updateOutBlock(block)) { try (Indent indent = Debug.logAndIndent("handle block %s", block)) { - BlockClosure closure = new BlockClosure(new LiveValueSet(liveOutMap.get(block))); + currentSet = new LiveValueSet(liveOutMap.get(block)); List<LIRInstruction> instructions = lir.getLIRforBlock(block); for (int i = instructions.size() - 1; i >= 0; i--) { LIRInstruction inst = instructions.get(i); - closure.processInstructionBottomUp(inst); + processInstructionBottomUp(inst); } - liveInMap.put(block, closure.getCurrentSet()); + liveInMap.put(block, currentSet); + currentSet = null; worklist.addAll(block.getPredecessors()); } } @@ -211,78 +365,68 @@ private static final EnumSet<OperandFlag> REGISTER_FLAG_SET = EnumSet.of(OperandFlag.REG); private static final LIRKind REFERENCE_KIND = LIRKind.reference(Kind.Object); - private final class BlockClosure { - private final LiveValueSet currentSet; + private LiveValueSet currentSet; - private BlockClosure(LiveValueSet set) { - currentSet = set; - } + /** + * Process all values of an instruction bottom-up, i.e. definitions before usages. Values + * that start or end at the current operation are not included. + */ + private void processInstructionBottomUp(LIRInstruction op) { + try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) { + // kills - private LiveValueSet getCurrentSet() { - return currentSet; - } + op.visitEachTemp(defConsumer); + op.visitEachOutput(defConsumer); + if (op.destroysCallerSavedRegisters()) { + for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) { + defConsumer.visitValue(reg.asValue(REFERENCE_KIND), OperandMode.TEMP, REGISTER_FLAG_SET); + } + } - /** - * Process all values of an instruction bottom-up, i.e. definitions before usages. - * Values that start or end at the current operation are not included. - */ - private void processInstructionBottomUp(LIRInstruction op) { - try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) { - // kills + // gen - values that are considered alive for this state + op.visitEachAlive(useConsumer); + op.visitEachState(useConsumer); + // mark locations + op.forEachState(stateConsumer); + // gen + op.visitEachInput(useConsumer); + } + } - op.visitEachTemp(defConsumer); - op.visitEachOutput(defConsumer); - if (op.destroysCallerSavedRegisters()) { - for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) { - defConsumer.visitValue(reg.asValue(REFERENCE_KIND), OperandMode.TEMP, REGISTER_FLAG_SET); - } - } + InstructionStateProcedure stateConsumer = new InstructionStateProcedure() { + public void doState(LIRInstruction inst, LIRFrameState info) { + markLocation(inst, info, currentSet); + } + }; - // gen - values that are considered alive for this state - op.visitEachAlive(useConsumer); - op.visitEachState(useConsumer); - // mark locations - op.forEachState(stateConsumer); - // gen - op.visitEachInput(useConsumer); + ValueConsumer useConsumer = new ValueConsumer() { + public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { + if (shouldProcessValue(operand)) { + // no need to insert values and derived reference + if (Debug.isLogEnabled()) { + Debug.log("set operand: %s", operand); + } + currentSet.put(operand); } } - - InstructionStateProcedure stateConsumer = new InstructionStateProcedure() { - public void doState(LIRInstruction inst, LIRFrameState info) { - markLocation(inst, info, getCurrentSet()); - } - }; + }; - ValueConsumer useConsumer = new ValueConsumer() { - public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { - if (shouldProcessValue(operand)) { - // no need to insert values and derived reference - if (Debug.isLogEnabled()) { - Debug.log("set operand: %s", operand); - } - currentSet.put(operand); + ValueConsumer defConsumer = new ValueConsumer() { + public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { + if (shouldProcessValue(operand)) { + if (Debug.isLogEnabled()) { + Debug.log("clear operand: %s", operand); } + currentSet.remove(operand); + } else { + assert isIllegal(operand) || operand.getPlatformKind() != Kind.Illegal || mode == OperandMode.TEMP : String.format("Illegal PlatformKind is only allowed for TEMP mode: %s, %s", + operand, mode); } - }; + } + }; - ValueConsumer defConsumer = new ValueConsumer() { - public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { - if (shouldProcessValue(operand)) { - if (Debug.isLogEnabled()) { - Debug.log("clear operand: %s", operand); - } - currentSet.remove(operand); - } else { - assert isIllegal(operand) || operand.getPlatformKind() != Kind.Illegal || mode == OperandMode.TEMP : String.format( - "Illegal PlatformKind is only allowed for TEMP mode: %s, %s", operand, mode); - } - } - }; - - protected boolean shouldProcessValue(Value operand) { - return (isRegister(operand) && attributes(asRegister(operand)).isAllocatable() || isStackSlot(operand)) && operand.getPlatformKind() != Kind.Illegal; - } + protected boolean shouldProcessValue(Value operand) { + return (isRegister(operand) && attributes(asRegister(operand)).isAllocatable() || isStackSlot(operand)) && operand.getPlatformKind() != Kind.Illegal; } /** @@ -294,9 +438,10 @@ } ReferenceMap refMap = info.debugInfo().getReferenceMap(); - for (Value v : values) { - frameMap.setReference(v, refMap); - } + refMap.reset(); + frameMap.addLiveValues(refMap); + values.addLiveValues(refMap); + refMap.finish(); } /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java Thu Jun 04 11:08:12 2015 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.lir.framemap; -import static com.oracle.jvmci.code.ValueUtil.*; - import java.util.*; import com.oracle.graal.asm.*; @@ -103,6 +101,12 @@ return target; } + public void addLiveValues(ReferenceMap refMap) { + for (Value value : objectStackSlots) { + refMap.addLiveValue(value); + } + } + protected int returnAddressSize() { return getTarget().arch.getReturnAddressSize(); } @@ -322,29 +326,6 @@ public ReferenceMap initReferenceMap(boolean hasRegisters) { ReferenceMap refMap = getTarget().createReferenceMap(hasRegisters, frameSize() / getTarget().wordSize); - for (StackSlot slot : objectStackSlots) { - setReference(slot, refMap); - } return refMap; } - - /** - * Marks the specified location as a reference in the reference map of the debug information. - * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a - * {@link JavaConstant} is automatically tracked. - * - * @param location The location to be added to the reference map. - * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}. - */ - public void setReference(Value location, ReferenceMap refMap) { - LIRKind kind = location.getLIRKind(); - if (isRegister(location)) { - refMap.setRegister(asRegister(location).getReferenceMapIndex(), kind); - } else if (isStackSlot(location)) { - int offset = offsetForStackSlot(asStackSlot(location)); - refMap.setStackSlot(offset, kind); - } else { - assert isConstant(location); - } - } }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Thu Jun 04 11:08:12 2015 -0700 @@ -459,9 +459,9 @@ inst.forEachState(state -> { if (state.hasDebugInfo()) { DebugInfo di = state.debugInfo(); - stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo(), target.arch)); + stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo())); } else { - stateString.append(debugInfoToString(state.topFrame, null, null, target.arch)); + stateString.append(debugInfoToString(state.topFrame, null, null)); } }); if (stateString.length() > 0) {
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Thu Jun 04 11:08:12 2015 -0700 @@ -22,22 +22,12 @@ */ package com.oracle.graal.printer; -import com.oracle.jvmci.code.Architecture; -import com.oracle.jvmci.code.VirtualObject; -import com.oracle.jvmci.code.BytecodePosition; -import com.oracle.jvmci.code.BytecodeFrame; -import com.oracle.jvmci.code.Register; -import com.oracle.jvmci.code.CodeUtil; -import com.oracle.jvmci.code.RegisterSaveLayout; -import com.oracle.jvmci.code.ReferenceMap; -import com.oracle.jvmci.meta.MetaUtil; -import com.oracle.jvmci.meta.Value; -import com.oracle.jvmci.meta.JavaMethod; import java.io.*; import java.util.*; -import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.debug.*; +import com.oracle.jvmci.meta.*; /** * Utility for printing compilation related data structures at various compilation phases. The @@ -122,19 +112,10 @@ /** * Formats given debug info as a multi line string. */ - protected String debugInfoToString(BytecodePosition codePos, ReferenceMap refMap, RegisterSaveLayout calleeSaveInfo, Architecture arch) { + protected String debugInfoToString(BytecodePosition codePos, ReferenceMap refMap, RegisterSaveLayout calleeSaveInfo) { StringBuilder sb = new StringBuilder(); - RefMapFormatter formatter = new CodeUtil.NumberedRefMapFormatter(); - - if (refMap != null && refMap.hasRegisterRefMap()) { - sb.append("reg-ref-map:"); - refMap.appendRegisterMap(sb, arch != null ? new CodeUtil.DefaultRegFormatter(arch) : formatter); - sb.append("\n"); - } - - if (refMap != null && refMap.hasFrameRefMap()) { - sb.append("frame-ref-map:"); - refMap.appendFrameMap(sb, formatter); + if (refMap != null) { + sb.append(refMap.toString()); sb.append("\n"); }
--- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CodeUtil.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CodeUtil.java Thu Jun 04 11:08:12 2015 -0700 @@ -429,15 +429,8 @@ } String nl = NEW_LINE; ReferenceMap refMap = info.getReferenceMap(); - if (refMap != null && refMap.hasRegisterRefMap()) { - sb.append(" reg-ref-map:"); - refMap.appendRegisterMap(sb, formatter); - sb.append(nl); - } - if (refMap != null && refMap.hasFrameRefMap()) { - sb.append("frame-ref-map:"); - refMap.appendFrameMap(sb, formatter); - sb.append(nl); + if (refMap != null) { + sb.append(refMap.toString()); } RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); if (calleeSaveInfo != null) {
--- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java Thu Jun 04 11:08:12 2015 -0700 @@ -27,7 +27,6 @@ import java.util.*; -import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; import com.oracle.jvmci.meta.Assumptions.Assumption; import com.oracle.jvmci.meta.*; @@ -858,17 +857,8 @@ if (info != null) { ReferenceMap refMap = info.getReferenceMap(); if (refMap != null) { - RefMapFormatter formatter = new CodeUtil.NumberedRefMapFormatter(); - if (refMap.hasFrameRefMap()) { - sb.append(" stackMap["); - refMap.appendFrameMap(sb, formatter); - sb.append(']'); - } - if (refMap.hasRegisterRefMap()) { - sb.append(" registerMap["); - refMap.appendRegisterMap(sb, formatter); - sb.append(']'); - } + sb.append(refMap.toString()); + sb.append(']'); } RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); if (calleeSaveInfo != null) {
--- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/ReferenceMap.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/ReferenceMap.java Thu Jun 04 11:08:12 2015 -0700 @@ -22,20 +22,24 @@ */ package com.oracle.jvmci.code; -import com.oracle.jvmci.meta.LIRKind; -import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; +import com.oracle.jvmci.meta.*; + +public abstract class ReferenceMap { -public abstract class ReferenceMap implements Cloneable { - - public abstract void setRegister(int idx, LIRKind kind); - - public abstract void setStackSlot(int offset, LIRKind kind); + /** + * Empty out the reference map. + */ + public abstract void reset(); - public abstract boolean hasRegisterRefMap(); - - public abstract boolean hasFrameRefMap(); + /** + * Add {@code value} to the current set of reference values. + * + * @param v + */ + public abstract void addLiveValue(Value v); - public abstract void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg); - - public abstract void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg); + /** + * Perform any final encoding needed before use. + */ + public abstract void finish(); }
--- a/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotReferenceMap.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotReferenceMap.java Thu Jun 04 11:08:12 2015 -0700 @@ -22,351 +22,60 @@ */ package com.oracle.jvmci.hotspot; +import static com.oracle.jvmci.code.ValueUtil.*; + import java.util.*; -import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; import com.oracle.jvmci.code.*; -import com.oracle.jvmci.common.*; import com.oracle.jvmci.meta.*; public final class HotSpotReferenceMap extends ReferenceMap { - static final int OOP64 = 0b1010; - static final int OOP32 = 0b01; - static final int NARROW_LOW = OOP32; - static final int NARROW_HIGH = OOP32 << 2; - static final int NARROW_BOTH = NARROW_LOW | NARROW_HIGH; + private Value[] objects; + private int[] bytesPerElement; + private int maxRegisterSize; + private ArrayList<Value> objectValues; - private enum MapEntry { - NoReference(0), - WideOop(OOP64), - NarrowOopLowerHalf(NARROW_LOW), - NarrowOopUpperHalf(NARROW_HIGH), - TwoNarrowOops(NARROW_BOTH), - Illegal(-1); + private final TargetDescription target; - MapEntry(int pattern) { - this.pattern = pattern; - } - - final int pattern; + public HotSpotReferenceMap(TargetDescription target) { + this.target = target; + this.objects = Value.NO_VALUES; + } - /** - * Create enum values from OopMap. - * <p> - * These bits can have the following values (MSB first): - * - * <pre> - * 0000 - contains no references - * 1010 - contains a wide oop - * 0001 - contains a narrow oop in the lower half - * 0101 - contains a narrow oop in the upper half - * 0101 - contains two narrow oops - * </pre> - * - * @see HotSpotReferenceMap#registerRefMap - * @see HotSpotReferenceMap#frameRefMap - */ - static MapEntry getFromBits(int idx, HotSpotOopMap set) { - int n = set.get(idx); - switch (n) { - case 0: - return NoReference; - case OOP64: - return WideOop; - case NARROW_LOW: - return NarrowOopLowerHalf; - case NARROW_HIGH: - return NarrowOopUpperHalf; - case NARROW_BOTH: - return TwoNarrowOops; - default: - return Illegal; + @Override + public void reset() { + objectValues = new ArrayList<>(); + objects = Value.NO_VALUES; + bytesPerElement = null; + maxRegisterSize = 0; + } + + @Override + public void addLiveValue(Value v) { + if (isConstant(v)) { + return; + } + LIRKind lirKind = v.getLIRKind(); + if (!lirKind.isValue()) { + objectValues.add(v); + } + if (isRegister(v)) { + int size = target.getSizeInBytes(lirKind.getPlatformKind()); + if (size > maxRegisterSize) { + maxRegisterSize = size; } } - - String toBitString() { - int bits = toBit(this); - if (bits == -1) { - return "---"; - } - return String.format("%3s", Integer.toBinaryString(bits)).replace(' ', '0'); - } - - static int toBit(MapEntry type) { - return type.pattern; - } } - /** - * A specialized bit set that represents both wide and narrow oops in an efficient manner. The - * map consists of 4 bit entries that represent 8 bytes of memory. - * - */ - class HotSpotOopMap implements Cloneable { - - /** - * Each entry is 4 bits long and covers 8 bytes of memory. - */ - private static final int BITS_PER_ENTRY = 4; - private static final int BITS_PER_ELEMENT = 64; - - public HotSpotOopMap(int i) { - words = new long[(i * BITS_PER_ENTRY + BITS_PER_ELEMENT) / BITS_PER_ELEMENT]; - } - - public HotSpotOopMap(HotSpotOopMap other) { - words = other.words.clone(); - } - - private long[] words; - - private int get(int i) { - return getEntry(i); - } - - public void or(HotSpotOopMap src) { - if (words.length < src.words.length) { - long[] newWords = new long[src.words.length]; - System.arraycopy(src.words, 0, newWords, 0, src.words.length); - for (int i = 0; i < words.length; i++) { - newWords[i] |= words[i]; - } - words = newWords; - } else { - for (int i = 0; i < src.words.length; i++) { - words[i] |= src.words[i]; - } - } - } - - private void setOop(int regIdx) { - setEntry(regIdx, OOP64); - } - - public int size() { - return words.length * BITS_PER_ELEMENT / BITS_PER_ENTRY; - } - - @Override - public HotSpotOopMap clone() { - return new HotSpotOopMap(this); - } - - private void setNarrowOop(int offset) { - setNarrowEntry(offset, OOP32); - } - - private void setEntry(int regIdx, int value) { - assert regIdx % 2 == 0 : "must be alinged"; - int bitIndex = (regIdx >> 1) * BITS_PER_ENTRY; - int wordIndex = bitIndex / BITS_PER_ELEMENT; - int shift = bitIndex - wordIndex * BITS_PER_ELEMENT; - if (wordIndex >= words.length) { - if (value == 0) { - // Nothing to do since bits are clear - return; - } - words = Arrays.copyOf(words, wordIndex + 1); - } - assert verifyUpdate(this, this); - long orig = words[wordIndex]; - words[wordIndex] = (orig & (~(0b1111L << shift))) | ((long) value << shift); - assert get(regIdx / 2) == value; - assert verifyUpdate(this, this); - } - - private void setNarrowEntry(int offset, int value) { - int regIdx = offset >> 1; - boolean low = offset % 2 == 0; - int bitIndex = regIdx * BITS_PER_ENTRY; - int wordIndex = bitIndex / BITS_PER_ELEMENT; - int shift = bitIndex - wordIndex * BITS_PER_ELEMENT; - if (wordIndex >= words.length) { - if (value == 0) { - // Nothing to do since bits are clear - return; - } - words = Arrays.copyOf(words, wordIndex + 1); - } - long originalValue = words[wordIndex]; - int current = ((int) (originalValue >> shift)) & 0b1111; - if (current == OOP64) { - current = 0; - } - long newValue; - if (value != 0) { - newValue = current | (low ? value : (value << 2)); - } else { - newValue = current & (low ? 0b1100 : 0b0011); - } - long masked = originalValue & (~(0b1111L << shift)); - words[wordIndex] = masked | (newValue << shift); - assert verifyUpdate(this, this); - } - - private int getEntry(int regIdx) { - int bitIndex = regIdx * BITS_PER_ENTRY; - int wordIndex = bitIndex / BITS_PER_ELEMENT; - int shift = bitIndex - wordIndex * BITS_PER_ELEMENT; - return ((int) (words[wordIndex] >>> shift)) & 0b1111; + @Override + public void finish() { + objects = objectValues.toArray(new Value[objectValues.size()]); + this.bytesPerElement = new int[objects.length]; + for (int i = 0; i < objects.length; i++) { + bytesPerElement[i] = bytesPerElement(objects[i].getLIRKind()); } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - - if (other instanceof HotSpotOopMap) { - HotSpotOopMap otherMap = (HotSpotOopMap) other; - int limit = Math.min(words.length, otherMap.words.length); - for (int i = 0; i < limit; i++) { - if (words[i] != otherMap.words[i]) { - return false; - } - } - for (int i = limit; i < words.length; i++) { - if (words[i] != 0) { - return false; - } - } - for (int i = limit; i < otherMap.words.length; i++) { - if (otherMap.words[i] != 0) { - return false; - } - } - return true; - } - return false; - } - - @Override - public int hashCode() { - long h = 1234; - for (int i = words.length; --i >= 0;) { - h ^= words[i] * (i + 1); - } - return (int) ((h >> 32) ^ h); - } - - @Override - public String toString() { - int count = 0; - StringBuilder sb = new StringBuilder(); - sb.append("["); - for (int idx = 0; idx < size(); idx++) { - MapEntry dstType = MapEntry.getFromBits(idx, this); - if (dstType == MapEntry.NoReference) { - continue; - } - if (count > 0) { - sb.append(", "); - } - if (dstType == MapEntry.Illegal) { - int value = get(idx); - sb.append("0x"); - sb.append(Integer.toHexString(value)); - } else { - sb.append(idx); - sb.append(':'); - sb.append(dstType); - } - count++; - } - sb.append("]"); - return sb.toString(); - } - } - - /** - * Contains 3 bits per scalar register, and n*3 bits per n-word vector register (e.g., on a - * 64-bit system, a 256-bit vector register requires 12 reference map bits). - * <p> - * These bits can have the following values (LSB first): - * - * <pre> - * 000 - contains no references - * 100 - contains a wide oop - * 110 - contains a narrow oop in the lower half - * 101 - contains a narrow oop in the upper half - * 111 - contains two narrow oops - * </pre> - */ - private final HotSpotOopMap registerRefMap; - - /** - * Contains 3 bits per stack word. - * <p> - * These bits can have the following values (LSB first): - * - * <pre> - * 000 - contains no references - * 100 - contains a wide oop - * 110 - contains a narrow oop in the lower half - * 101 - contains a narrow oop in the upper half - * 111 - contains two narrow oops - * </pre> - */ - private final HotSpotOopMap frameRefMap; - - private final TargetDescription target; - - public HotSpotReferenceMap(int registerCount, int frameSlotCount, TargetDescription target) { - if (registerCount > 0) { - this.registerRefMap = new HotSpotOopMap(registerCount); - } else { - this.registerRefMap = null; - } - this.frameRefMap = new HotSpotOopMap(frameSlotCount); - this.target = target; - } - - private HotSpotReferenceMap(HotSpotReferenceMap other) { - this.registerRefMap = other.registerRefMap.clone(); - this.frameRefMap = other.frameRefMap.clone(); - this.target = other.target; - } - - @Override - public ReferenceMap clone() { - return new HotSpotReferenceMap(this); - } - - // setters - @Override - public void setRegister(int idx, LIRKind kind) { - set(registerRefMap, idx * 2, kind); - } - - @Override - public void setStackSlot(int offset, LIRKind kind) { - assert offset % bytesPerElement(kind) == 0 : "unaligned value in ReferenceMap"; - set(frameRefMap, offset / 4, kind); - } - - private void set(HotSpotOopMap refMap, int index, LIRKind kind) { - if (kind.isDerivedReference()) { - throw new JVMCIError("derived reference cannot be inserted in ReferenceMap"); - } - - int bytesPerElement = bytesPerElement(kind); - int length = kind.getPlatformKind().getVectorLength(); - if (bytesPerElement == 8) { - for (int i = 0; i < length; i++) { - if (kind.isReference(i)) { - refMap.setOop(index + i * 2); - } - } - } else if (bytesPerElement == 4) { - for (int i = 0; i < length; i++) { - if (kind.isReference(i)) { - refMap.setNarrowOop(index + i); - } - } - } else { - assert kind.isValue() : "unknown reference kind " + kind; - } + objectValues = null; } private int bytesPerElement(LIRKind kind) { @@ -374,74 +83,6 @@ return target.getSizeInBytes(platformKind) / platformKind.getVectorLength(); } - public HotSpotOopMap getFrameMap() { - return frameRefMap == null ? null : (HotSpotOopMap) frameRefMap.clone(); - } - - public HotSpotOopMap getRegisterMap() { - return registerRefMap == null ? null : (HotSpotOopMap) registerRefMap.clone(); - } - - static MapEntry[] entries(HotSpotOopMap fixedMap) { - MapEntry[] result = new MapEntry[fixedMap.size()]; - for (int idx = 0; idx < fixedMap.size(); idx++) { - MapEntry dstType = MapEntry.getFromBits(idx, fixedMap); - result[idx] = dstType; - } - return result; - } - - private static boolean verifyUpdate(HotSpotOopMap dst, HotSpotOopMap src) { - return verifyUpdate(dst, src, true); - } - - private static boolean verifyUpdate(HotSpotOopMap dst, HotSpotOopMap src, boolean doAssert) { - for (int idx = 0; idx < Math.min(src.size(), dst.size()); idx++) { - if (!verifyUpdateEntry(idx, dst, src, doAssert)) { - return false; - } - } - return true; - } - - private static boolean verifyUpdateEntry(int idx, HotSpotOopMap dst, HotSpotOopMap src, boolean doAssert) { - MapEntry dstType = MapEntry.getFromBits(idx, dst); - MapEntry srcType = MapEntry.getFromBits(idx, src); - - if (dstType == MapEntry.Illegal || srcType == MapEntry.Illegal) { - assert !doAssert : String.format("Illegal RefMap bit pattern: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); - return false; - } - switch (dstType) { - case NoReference: - return true; - case WideOop: - switch (srcType) { - case NoReference: - case WideOop: - return true; - default: - assert false : String.format("Illegal RefMap combination: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); - return false; - } - case TwoNarrowOops: - case NarrowOopLowerHalf: - case NarrowOopUpperHalf: - switch (srcType) { - case TwoNarrowOops: - case NarrowOopLowerHalf: - case NarrowOopUpperHalf: - case NoReference: - return true; - default: - assert false : String.format("Illegal RefMap combination: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); - return false; - } - default: - return false; - } - } - @Override public int hashCode() { throw new UnsupportedOperationException(); @@ -454,7 +95,7 @@ } if (obj instanceof HotSpotReferenceMap) { HotSpotReferenceMap that = (HotSpotReferenceMap) obj; - if (this.frameRefMap.equals(that.frameRefMap) && Objects.equals(this.registerRefMap, that.registerRefMap) && this.target.equals(that.target)) { + if (Arrays.equals(objects, that.objects) && this.target.equals(that.target)) { return true; } } @@ -462,49 +103,7 @@ } @Override - public boolean hasRegisterRefMap() { - return registerRefMap != null && registerRefMap.size() > 0; - } - - @Override - public boolean hasFrameRefMap() { - return frameRefMap != null && frameRefMap.size() > 0; - } - - @Override - public void appendRegisterMap(StringBuilder sb, RefMapFormatter formatter) { - for (int idx = 0; idx < registerRefMap.size(); idx++) { - MapEntry dstType = MapEntry.getFromBits(idx, registerRefMap); - if (dstType != MapEntry.NoReference) { - sb.append(' ').append(formatter.formatRegister(idx)).append(':').append(dstType); - } - } - } - - @Override - public void appendFrameMap(StringBuilder sb, RefMapFormatter formatter) { - for (int idx = 0; idx < frameRefMap.size(); idx++) { - MapEntry dstType = MapEntry.getFromBits(idx, frameRefMap); - if (dstType != MapEntry.NoReference) { - sb.append(' ').append(formatter.formatStackSlot(idx)).append(':').append(dstType); - } - } - } - - @Override public String toString() { - StringBuilder sb = new StringBuilder(); - if (registerRefMap != null) { - sb.append("Registers = "); - sb.append(registerRefMap); - } - sb.append("Stack = "); - sb.append(frameRefMap); - return sb.toString(); - } - - public void verify() { - assert verifyUpdate(frameRefMap, frameRefMap); - assert registerRefMap == null || verifyUpdate(registerRefMap, registerRefMap); + return Arrays.toString(objects); } }
--- a/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java Thu Jun 04 11:08:12 2015 -0700 @@ -32,6 +32,6 @@ @Override public ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount) { - return new HotSpotReferenceMap(hasRegisters ? arch.getRegisterReferenceMapSize() : 0, stackSlotCount, this); + return new HotSpotReferenceMap(this); } }
--- a/graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Value.java Thu Jun 04 17:04:21 2015 +0200 +++ b/graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Value.java Thu Jun 04 11:08:12 2015 -0700 @@ -28,7 +28,14 @@ */ public interface Value extends KindProvider, TrustedInterface { - AllocatableValue ILLEGAL = new AllocatableValue(LIRKind.Illegal) { + Value[] NO_VALUES = new Value[0]; + + AllocatableValue ILLEGAL = new IllegalValue(); + + public final class IllegalValue extends AllocatableValue { + private IllegalValue() { + super(LIRKind.Illegal); + } @Override public String toString() { @@ -39,9 +46,9 @@ public boolean equals(Object other) { // Due to de-serialization this object may exist multiple times. So we compare classes // instead of the individual objects. (This anonymous class has always the same meaning) - return other != null && this.getClass() == other.getClass(); + return other instanceof IllegalValue; } - }; + } LIRKind getLIRKind();
--- a/src/share/vm/classfile/systemDictionary.hpp Thu Jun 04 17:04:21 2015 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Thu Jun 04 11:08:12 2015 -0700 @@ -205,7 +205,6 @@ JVMCI_ONLY(do_klass(HotSpotCompiledNmethod_klass, com_oracle_jvmci_hotspot_HotSpotCompiledNmethod, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotForeignCallTarget_klass, com_oracle_jvmci_hotspot_HotSpotForeignCallTarget, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotReferenceMap_klass, com_oracle_jvmci_hotspot_HotSpotReferenceMap, Jvmci)) \ - JVMCI_ONLY(do_klass(HotSpotOopMap_klass, com_oracle_jvmci_hotspot_HotSpotReferenceMap_HotSpotOopMap, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotInstalledCode_klass, com_oracle_jvmci_hotspot_HotSpotInstalledCode, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotNmethod_klass, com_oracle_jvmci_hotspot_HotSpotNmethod, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotResolvedJavaMethodImpl_klass, com_oracle_jvmci_hotspot_HotSpotResolvedJavaMethodImpl, Jvmci)) \
--- a/src/share/vm/classfile/vmSymbols.hpp Thu Jun 04 17:04:21 2015 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Thu Jun 04 11:08:12 2015 -0700 @@ -306,7 +306,6 @@ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotCompiledNmethod, "com/oracle/jvmci/hotspot/HotSpotCompiledNmethod")) \ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotForeignCallTarget, "com/oracle/jvmci/hotspot/HotSpotForeignCallTarget")) \ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotReferenceMap, "com/oracle/jvmci/hotspot/HotSpotReferenceMap")) \ - JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotReferenceMap_HotSpotOopMap, "com/oracle/jvmci/hotspot/HotSpotReferenceMap$HotSpotOopMap")) \ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_CompilerToVMImpl, "com/oracle/jvmci/hotspot/CompilerToVMImpl")) \ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotInstalledCode, "com/oracle/jvmci/hotspot/HotSpotInstalledCode")) \ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotNmethod, "com/oracle/jvmci/hotspot/HotSpotNmethod")) \
--- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp Thu Jun 04 17:04:21 2015 +0200 +++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp Thu Jun 04 11:08:12 2015 -0700 @@ -69,83 +69,62 @@ return asMethod(HotSpotResolvedJavaMethodImpl::metaspaceMethod(hotspot_method)); } -const int MapWordBits = 64; - -static int entry_value(typeArrayOop words, int i) { - jint words_idx = i / MapWordBits; - assert(words_idx >= 0 && words_idx < words->length(), "unexpected index"); - jlong word = words->long_at(words_idx); - return (word >> (i % MapWordBits)) & 15LL; -} - -static int fixedmap_size(oop bitset) { - typeArrayOop arr = HotSpotOopMap::words(bitset); - return arr->length() * MapWordBits; -} - -static void set_vmreg_oops(OopMap* map, VMReg reg, typeArrayOop words, int idx) { - int value = entry_value(words, 4 * idx); - switch (value) { - case 10: - map->set_oop(reg); - break; - case 5: - map->set_narrowoop(reg); - map->set_narrowoop(reg->next()); - break; - case 1: - map->set_narrowoop(reg); - break; - case 4: - map->set_narrowoop(reg->next()); - break; - case 0: - break; - default: - assert(false, err_msg("unexpected bit pattern at %d = 0x%x", idx, value)); - ShouldNotReachHere(); +// creates a HotSpot oop map out of the byte arrays provided by DebugInfo +OopMap* CodeInstaller::create_oop_map(oop debug_info) { + oop reference_map = DebugInfo::referenceMap(debug_info); + if (HotSpotReferenceMap::maxRegisterSize(reference_map) > 16) { + _has_wide_vector = true; } -} - -// creates a HotSpot oop map out of the byte arrays provided by DebugInfo -static OopMap* create_oop_map(jint total_frame_size, jint parameter_count, oop debug_info) { - OopMap* map = new OopMap(total_frame_size, parameter_count); - oop reference_map = DebugInfo::referenceMap(debug_info); - oop register_map = HotSpotReferenceMap::registerRefMap(reference_map); - oop frame_map = HotSpotReferenceMap::frameRefMap(reference_map); - oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info); - - if (register_map != NULL) { - typeArrayOop words = HotSpotOopMap::words(register_map); - int mapIdx = 0; - for (jint i = 0; i < RegisterImpl::number_of_registers; i++) { - set_vmreg_oops(map, as_Register(i)->as_VMReg(), words, mapIdx); - mapIdx++; + OopMap* map = new OopMap(_total_frame_size, _parameter_count); + objArrayOop objects = HotSpotReferenceMap::objects(reference_map); + typeArrayOop bytesPerArray = HotSpotReferenceMap::bytesPerElement(reference_map); + for (int i = 0; i < objects->length(); i++) { + oop value = objects->obj_at(i); + oop lirKind = AbstractValue::lirKind(value); + oop platformKind = LIRKind::platformKind(lirKind); + int bytesPerElement = bytesPerArray->int_at(i); + assert(bytesPerElement == 4 || bytesPerElement == 8, "wrong sizes"); + jint referenceMask = LIRKind::referenceMask(lirKind); + assert(referenceMask != 0, "must be a reference type"); + assert(referenceMask != -1, "must not be a derived reference type"); + + VMReg vmReg; + if (value->is_a(RegisterValue::klass())) { + oop reg = RegisterValue::reg(value); + jint number = code_Register::number(reg); + vmReg = CodeInstaller::get_hotspot_reg(number); + } else if (value->is_a(StackSlot::klass())) { + jint offset = StackSlot::offset(value); +#ifdef TARGET_ARCH_sparc + if(offset >= 0) { + offset += 128; + } +#endif + if (StackSlot::addFrameSize(value)) { + offset += _total_frame_size; + } + assert(offset % 4 == 0, "must be aligned"); + vmReg = VMRegImpl::stack2reg(offset / 4); } -#ifdef TARGET_ARCH_x86 - for (jint i = 0; i < XMMRegisterImpl::number_of_registers; i++) { - VMReg reg = as_XMMRegister(i)->as_VMReg(); - for (jint j = 0; j < 4; j++) { - set_vmreg_oops(map, reg->next(2 * j), words, mapIdx++); + + int bit = 1; + while (referenceMask != 0) { + if (referenceMask & bit) { + if (bytesPerElement == 8) { + map->set_oop(vmReg); + } else { + map->set_narrowoop(vmReg); + } + referenceMask &= ~bit; } + vmReg = vmReg->next(); + if (bytesPerElement == 8) { + vmReg = vmReg->next(); + } + bit <<= 1; } -#endif -#ifdef TARGET_ARCH_sparc - for (jint i = 0; i < FloatRegisterImpl::number_of_registers; i++) { - VMReg reg = as_FloatRegister(i)->as_VMReg(); - set_vmreg_oops(map, reg, words, mapIdx++); - } -#endif } - - typeArrayOop words = HotSpotOopMap::words(frame_map); - int size = fixedmap_size(frame_map) / 4; - for (jint i = 0; i < size; i++) { - // HotSpot stack slots are 4 bytes - VMReg reg = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word); - set_vmreg_oops(map, reg, words, i); - } - + oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info); if (callee_save_info != NULL) { objArrayOop registers = RegisterSaveLayout::registers(callee_save_info); typeArrayOop slots = RegisterSaveLayout::slots(callee_save_info); @@ -261,7 +240,17 @@ return value; } } else if (value->is_a(StackSlot::klass())) { - Location::Type locationType; + jint offset = StackSlot::offset(value); +#ifdef TARGET_ARCH_sparc + if(offset >= 0) { + offset += 128; + } +#endif + if (StackSlot::addFrameSize(value)) { + offset += _total_frame_size; + } + + Location::Type locationType; if (type == T_LONG) { locationType = reference ? Location::oop : Location::lng; } else if (type == T_INT) { @@ -278,15 +267,6 @@ assert(type == T_OBJECT && reference, "unexpected type in stack slot"); locationType = Location::oop; } - jint offset = StackSlot::offset(value); -#ifdef TARGET_ARCH_sparc - if(offset >= 0) { - offset += 128; - } -#endif - if (StackSlot::addFrameSize(value)) { - offset += _total_frame_size; - } ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset)); if (type == T_DOUBLE || (type == T_LONG && !reference)) { second = value; @@ -470,8 +450,10 @@ // Make sure a valid compile_id is associated with every compile id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci); } - result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, - JVMCICompiler::instance(), _debug_recorder, _dependencies, env, id, false, installed_code, compiled_code, speculation_log); + result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, + stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, + JVMCICompiler::instance(), _debug_recorder, _dependencies, env, id, + false, _has_wide_vector, installed_code, compiled_code, speculation_log); cb = nm; } @@ -513,6 +495,8 @@ #endif _next_call_type = INVOKE_INVALID; + + _has_wide_vector = false; } int CodeInstaller::estimate_stub_entries() { @@ -856,7 +840,7 @@ // address instruction = _instructions->start() + pc_offset; // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start(); - _debug_recorder->add_safepoint(pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info)); + _debug_recorder->add_safepoint(pc_offset, create_oop_map(debug_info)); record_scope(pc_offset, debug_info); _debug_recorder->end_safepoint(pc_offset); } @@ -891,7 +875,7 @@ jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method); if (debug_info != NULL) { - _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info)); + _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(debug_info)); record_scope(next_pc_offset, debug_info); }
--- a/src/share/vm/jvmci/jvmciCodeInstaller.hpp Thu Jun 04 17:04:21 2015 +0200 +++ b/src/share/vm/jvmci/jvmciCodeInstaller.hpp Thu Jun 04 11:08:12 2015 -0700 @@ -70,6 +70,8 @@ jobject _comments_handle; #endif + bool _has_wide_vector; + MarkId _next_call_type; address _invoke_mark_pc; @@ -139,6 +141,8 @@ void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site); void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site); + OopMap* create_oop_map(oop debug_info); + void record_scope(jint pc_offset, oop debug_info); void record_scope(jint pc_offset, oop code_pos, GrowableArray<ScopeValue*>* objects); void record_object_value(ObjectValue* sv, oop value, GrowableArray<ScopeValue*>* objects);
--- a/src/share/vm/jvmci/jvmciEnv.cpp Thu Jun 04 17:04:21 2015 +0200 +++ b/src/share/vm/jvmci/jvmciEnv.cpp Thu Jun 04 11:08:12 2015 -0700 @@ -483,6 +483,7 @@ JVMCIEnv* env, int compile_id, bool has_unsafe_access, + bool has_wide_vector, Handle installed_code, Handle compiled_code, Handle speculation_log) { @@ -546,12 +547,7 @@ } } else { nm->set_has_unsafe_access(has_unsafe_access); -#ifdef TARGET_ARCH_x86 - // It might be preferable to set this only for methods which - // use vector instructions but we currently don't track this - // and it probably wouldn't make much difference. - nm->set_has_wide_vectors(MaxVectorSize > 16); -#endif + nm->set_has_wide_vectors(has_wide_vector); // Record successful registration. // (Put nm into the task handle *before* publishing to the Java heap.)
--- a/src/share/vm/jvmci/jvmciEnv.hpp Thu Jun 04 17:04:21 2015 +0200 +++ b/src/share/vm/jvmci/jvmciEnv.hpp Thu Jun 04 11:08:12 2015 -0700 @@ -157,6 +157,7 @@ JVMCIEnv* env, int compile_id, bool has_unsafe_access, + bool has_wide_vector, Handle installed_code, Handle compiled_code, Handle speculation_log);
--- a/src/share/vm/jvmci/jvmciJavaAccess.hpp Thu Jun 04 17:04:21 2015 +0200 +++ b/src/share/vm/jvmci/jvmciJavaAccess.hpp Thu Jun 04 11:08:12 2015 -0700 @@ -157,16 +157,14 @@ objArrayOop_field(DebugInfo, virtualObjectMapping, "[Lcom/oracle/jvmci/meta/Value;") \ end_class \ start_class(HotSpotReferenceMap) \ - oop_field(HotSpotReferenceMap, registerRefMap, "Lcom/oracle/jvmci/hotspot/HotSpotReferenceMap$HotSpotOopMap;") \ - oop_field(HotSpotReferenceMap, frameRefMap, "Lcom/oracle/jvmci/hotspot/HotSpotReferenceMap$HotSpotOopMap;") \ + objArrayOop_field(HotSpotReferenceMap, objects, "[Lcom/oracle/jvmci/meta/Value;") \ + typeArrayOop_field(HotSpotReferenceMap, bytesPerElement, "[I") \ + int_field(HotSpotReferenceMap, maxRegisterSize) \ end_class \ start_class(RegisterSaveLayout) \ objArrayOop_field(RegisterSaveLayout, registers, "[Lcom/oracle/jvmci/code/Register;") \ typeArrayOop_field(RegisterSaveLayout, slots, "[I") \ end_class \ - start_class(HotSpotOopMap) \ - typeArrayOop_field(HotSpotOopMap, words, "[J") \ - end_class \ start_class(BytecodeFrame) \ objArrayOop_field(BytecodeFrame, values, "[Lcom/oracle/jvmci/meta/Value;") \ int_field(BytecodeFrame, numLocals) \ @@ -223,15 +221,9 @@ start_class(RegisterValue) \ oop_field(RegisterValue, reg, "Lcom/oracle/jvmci/code/Register;") \ end_class \ - start_class(RegisterCategory) \ - oop_field(RegisterCategory, name, "Ljava/lang/String;") \ - int_field(RegisterCategory, referenceMapOffset) \ - int_field(RegisterCategory, referenceMapShift) \ - end_class \ start_class(code_Register) \ int_field(code_Register, number) \ int_field(code_Register, encoding) \ - oop_field(code_Register, registerCategory, "Lcom/oracle/jvmci/code/Register$RegisterCategory;") \ end_class \ start_class(StackSlot) \ int_field(StackSlot, offset) \