# HG changeset patch # User Roland Schatz # Date 1429273680 -7200 # Node ID e413295a3c95dd72108344f2e3ee718c11e94a8c # Parent 0e1e8879b655788980bb1831e2176091f5026ebe Track all values in ReferenceMap. diff -r 0e1e8879b655 -r e413295a3c95 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 Fri Apr 17 12:04:12 2015 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Fri Apr 17 14:28:00 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2015, 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 @@ -29,12 +29,8 @@ public abstract void setRegister(int idx, LIRKind kind); - public abstract void clearRegister(int idx, LIRKind kind); - public abstract void setStackSlot(int offset, LIRKind kind); - public abstract void clearStackSlot(int offset, LIRKind kind); - public abstract boolean hasRegisterRefMap(); public abstract boolean hasFrameRefMap(); @@ -42,12 +38,4 @@ public abstract void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg); public abstract void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg); - - @Override - public abstract ReferenceMap clone(); - - /** - * Updates this map with all references marked in {@code other}. - */ - public abstract void updateUnion(ReferenceMap other); } diff -r 0e1e8879b655 -r e413295a3c95 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Fri Apr 17 12:04:12 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Fri Apr 17 14:28:00 2015 +0200 @@ -128,15 +128,6 @@ return getEntry(i); } - private boolean isEmpty() { - for (int i = 0; i < words.length; i++) { - if (words[i] != 0) { - return false; - } - } - return true; - } - public void or(HotSpotOopMap src) { if (words.length < src.words.length) { long[] newWords = new long[src.words.length]; @@ -224,14 +215,6 @@ return ((int) (words[wordIndex] >>> shift)) & 0b1111; } - private void clearOop(int offset) { - setEntry(offset, 0); - } - - private void clearNarrowOop(int offset) { - setNarrowEntry(offset, 0); - } - @Override public boolean equals(Object other) { if (this == other) { @@ -404,58 +387,6 @@ return registerRefMap == null ? null : (HotSpotOopMap) registerRefMap.clone(); } - // clear - @Override - public void clearRegister(int idx, LIRKind kind) { - clear(registerRefMap, idx * 2, kind); - } - - @Override - public void clearStackSlot(int offset, LIRKind kind) { - assert offset % bytesPerElement(kind) == 0 : "unaligned value in ReferenceMap"; - clear(frameRefMap, offset / 4, kind); - } - - private void clear(HotSpotOopMap refMap, int index, LIRKind kind) { - int bytesPerElement = bytesPerElement(kind); - int length = kind.getPlatformKind().getVectorLength(); - if (bytesPerElement == 8) { - for (int i = 0; i < length; i++) { - refMap.clearOop(index + i * 2); - } - } else if (bytesPerElement == 4) { - for (int i = 0; i < length; i++) { - refMap.clearNarrowOop(index + i); - } - } else { - assert kind.isValue() : "unknown reference kind " + kind; - } - } - - @Override - public void updateUnion(ReferenceMap otherArg) { - HotSpotReferenceMap other = (HotSpotReferenceMap) otherArg; - if (registerRefMap != null) { - assert other.registerRefMap != null; - updateUnionOopMapRaw(registerRefMap, other.registerRefMap); - } else { - assert other.registerRefMap == null || other.registerRefMap.isEmpty() : "Target register reference map is empty but the source is not: " + other.registerRefMap; - } - updateUnionOopMapRaw(frameRefMap, other.frameRefMap); - } - - /** - * Update {@code src} with the union of {@code src} and {@code dst}. - * - * @see HotSpotReferenceMap#registerRefMap - * @see HotSpotReferenceMap#frameRefMap - */ - private static void updateUnionOopMapRaw(HotSpotOopMap dst, HotSpotOopMap src) { - assert verifyUpdate(dst, src); - dst.or(src); - assert verifyUpdate(dst, dst); - } - static MapEntry[] entries(HotSpotOopMap fixedMap) { MapEntry[] result = new MapEntry[fixedMap.size()]; for (int idx = 0; idx < fixedMap.size(); idx++) { diff -r 0e1e8879b655 -r e413295a3c95 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Fri Apr 17 12:04:12 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Fri Apr 17 14:28:00 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2015, 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 @@ -162,7 +162,7 @@ } /** - * Called by the register allocator before {@link #updateUnion} to initialize the frame state. + * Called by the register allocator to initialize the frame state. * * @param frameMap The frame map. * @param canHaveRegisters True if there can be any register map entries. @@ -171,13 +171,6 @@ debugInfo = new DebugInfo(topFrame, frameMap.initReferenceMap(canHaveRegisters), virtualObjects); } - /** - * Updates this reference map with all references that are marked in {@code refMap}. - */ - public void updateUnion(ReferenceMap refMap) { - debugInfo.getReferenceMap().updateUnion(refMap); - } - @Override public String toString() { return debugInfo != null ? debugInfo.toString() : topFrame != null ? topFrame.toString() : ""; diff -r 0e1e8879b655 -r e413295a3c95 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Fri Apr 17 12:04:12 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Fri Apr 17 14:28:00 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -30,6 +30,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; @@ -102,12 +103,56 @@ } } + private static final class LiveValueSet implements Iterable { + private static final Object MARKER = new Object(); + + private final HashMap map; + + public LiveValueSet() { + map = new HashMap<>(); + } + + public LiveValueSet(LiveValueSet s) { + map = new HashMap<>(s.map); + } + + public void put(Value v) { + map.put(v, MARKER); + } + + public void putAll(LiveValueSet v) { + map.putAll(v.map); + } + + public void remove(Value v) { + map.remove(v); + } + + public Iterator iterator() { + return map.keySet().iterator(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof LiveValueSet) { + return map.equals(((LiveValueSet) obj).map); + } else { + return false; + } + } + + @Override + public int hashCode() { + return map.hashCode(); + } + } + private static final class Marker> { private final LIR lir; private final FrameMap frameMap; private final RegisterAttributes[] registerAttributes; - private final BlockMap liveInMap; - private final BlockMap liveOutMap; + private final BlockMap liveInMap; + private final BlockMap liveOutMap; private Marker(LIR lir, FrameMap frameMap) { this.lir = lir; @@ -124,7 +169,7 @@ worklist.add((T) lir.getControlFlowGraph().getBlocks().get(i)); } for (AbstractBlockBase block : lir.getControlFlowGraph().getBlocks()) { - liveInMap.put(block, frameMap.initReferenceMap(true)); + liveInMap.put(block, new LiveValueSet()); } while (!worklist.isEmpty()) { AbstractBlockBase block = worklist.poll(); @@ -136,9 +181,9 @@ * Merge outSet with in-set of successors. */ private boolean updateOutBlock(AbstractBlockBase block) { - ReferenceMap union = frameMap.initReferenceMap(true); - block.getSuccessors().forEach(succ -> union.updateUnion(liveInMap.get(succ))); - ReferenceMap outSet = liveOutMap.get(block); + LiveValueSet union = new LiveValueSet(); + block.getSuccessors().forEach(succ -> union.putAll(liveInMap.get(succ))); + LiveValueSet outSet = liveOutMap.get(block); // check if changed if (outSet == null || !union.equals(outSet)) { liveOutMap.put(block, union); @@ -150,7 +195,7 @@ private void processBlock(AbstractBlockBase block, UniqueWorkList worklist) { if (updateOutBlock(block)) { try (Indent indent = Debug.logAndIndent("handle block %s", block)) { - BlockClosure closure = new BlockClosure(liveOutMap.get(block).clone()); + BlockClosure closure = new BlockClosure(new LiveValueSet(liveOutMap.get(block))); List instructions = lir.getLIRforBlock(block); for (int i = instructions.size() - 1; i >= 0; i--) { LIRInstruction inst = instructions.get(i); @@ -166,13 +211,13 @@ private static final LIRKind REFERENCE_KIND = LIRKind.reference(Kind.Object); private final class BlockClosure { - private final ReferenceMap currentSet; + private final LiveValueSet currentSet; - private BlockClosure(ReferenceMap set) { + private BlockClosure(LiveValueSet set) { currentSet = set; } - private ReferenceMap getCurrentSet() { + private LiveValueSet getCurrentSet() { return currentSet; } @@ -210,13 +255,12 @@ ValueConsumer useConsumer = new ValueConsumer() { public void visitValue(Value operand, OperandMode mode, EnumSet flags) { - LIRKind kind = operand.getLIRKind(); - if (shouldProcessValue(operand) && !kind.isValue() && !kind.isDerivedReference()) { + if (shouldProcessValue(operand)) { // no need to insert values and derived reference if (Debug.isLogEnabled()) { Debug.log("set operand: %s", operand); } - frameMap.setReference(operand, currentSet); + currentSet.put(operand); } } }; @@ -227,7 +271,7 @@ if (Debug.isLogEnabled()) { Debug.log("clear operand: %s", operand); } - frameMap.clearReference(operand, currentSet); + 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); @@ -243,11 +287,23 @@ /** * This method does the actual marking. */ - private void markLocation(LIRInstruction op, LIRFrameState info, ReferenceMap refMap) { + private void markLocation(LIRInstruction op, LIRFrameState info, LiveValueSet values) { if (!info.hasDebugInfo()) { info.initDebugInfo(frameMap, !op.destroysCallerSavedRegisters() || !frameMap.getRegisterConfig().areAllAllocatableRegistersCallerSaved()); } - info.updateUnion(refMap); + + try (Scope s = Debug.scope("markLocation", op)) { + ReferenceMap refMap = info.debugInfo().getReferenceMap(); + for (Value v : values) { + try (Scope x = Debug.scope("loop", v)) { + frameMap.setReference(v, refMap); + } catch (Throwable e) { + throw Debug.handle(e); + } + } + } catch (Throwable e) { + throw Debug.handle(e); + } } /** diff -r 0e1e8879b655 -r e413295a3c95 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java Fri Apr 17 12:04:12 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java Fri Apr 17 14:28:00 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2015, 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 @@ -347,16 +347,4 @@ assert isConstant(location); } } - - public void clearReference(Value location, ReferenceMap refMap) { - LIRKind kind = location.getLIRKind(); - if (isRegister(location)) { - refMap.clearRegister(asRegister(location).getReferenceMapIndex(), kind); - } else if (isStackSlot(location)) { - int offset = offsetForStackSlot(asStackSlot(location)); - refMap.clearStackSlot(offset, kind); - } else { - assert isConstant(location); - } - } }