changeset 21005:e413295a3c95

Track all values in ReferenceMap.
author Roland Schatz <roland.schatz@oracle.com>
date Fri, 17 Apr 2015 14:28:00 +0200
parents 0e1e8879b655
children 44ee46c753b1
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java
diffstat 5 files changed, 77 insertions(+), 121 deletions(-) [+]
line wrap: on
line diff
--- 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);
 }
--- 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++) {
--- 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() : "<empty>";
--- 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<Value> {
+        private static final Object MARKER = new Object();
+
+        private final HashMap<Value, Object> 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<Value> 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<T extends AbstractBlockBase<T>> {
         private final LIR lir;
         private final FrameMap frameMap;
         private final RegisterAttributes[] registerAttributes;
-        private final BlockMap<ReferenceMap> liveInMap;
-        private final BlockMap<ReferenceMap> liveOutMap;
+        private final BlockMap<LiveValueSet> liveInMap;
+        private final BlockMap<LiveValueSet> 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<T> 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<T> block, UniqueWorkList<T> 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<LIRInstruction> 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<OperandFlag> 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);
+            }
         }
 
         /**
--- 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);
-        }
-    }
 }