src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java
changeset 49873 26ebfe8ce852
parent 48861 47f19ff9903c
child 50330 2cbc42a5764b
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java	Tue Apr 24 08:13:30 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java	Tue Apr 24 09:04:57 2018 -0700
@@ -38,6 +38,7 @@
 import static org.graalvm.compiler.bytecode.Bytecodes.FASTORE;
 import static org.graalvm.compiler.bytecode.Bytecodes.FRETURN;
 import static org.graalvm.compiler.bytecode.Bytecodes.GETFIELD;
+import static org.graalvm.compiler.bytecode.Bytecodes.GETSTATIC;
 import static org.graalvm.compiler.bytecode.Bytecodes.GOTO;
 import static org.graalvm.compiler.bytecode.Bytecodes.GOTO_W;
 import static org.graalvm.compiler.bytecode.Bytecodes.IALOAD;
@@ -71,6 +72,7 @@
 import static org.graalvm.compiler.bytecode.Bytecodes.LOOKUPSWITCH;
 import static org.graalvm.compiler.bytecode.Bytecodes.LRETURN;
 import static org.graalvm.compiler.bytecode.Bytecodes.PUTFIELD;
+import static org.graalvm.compiler.bytecode.Bytecodes.PUTSTATIC;
 import static org.graalvm.compiler.bytecode.Bytecodes.RET;
 import static org.graalvm.compiler.bytecode.Bytecodes.RETURN;
 import static org.graalvm.compiler.bytecode.Bytecodes.SALOAD;
@@ -81,13 +83,12 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.TreeSet;
 
-import org.graalvm.collections.EconomicMap;
-import org.graalvm.collections.Equivalence;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.bytecode.BytecodeLookupSwitch;
 import org.graalvm.compiler.bytecode.BytecodeStream;
@@ -142,20 +143,20 @@
 
     public static class BciBlock implements Cloneable {
 
-        protected int id;
-        public int startBci;
-        public int endBci;
-        public boolean isExceptionEntry;
-        public boolean isLoopHeader;
-        public int loopId;
-        public int loopEnd;
-        protected List<BciBlock> successors;
+        int id;
+        final int startBci;
+        int endBci;
+        private boolean isExceptionEntry;
+        private boolean isLoopHeader;
+        int loopId;
+        int loopEnd;
+        List<BciBlock> successors;
         private int predecessorCount;
 
         private boolean visited;
         private boolean active;
-        public long loops;
-        public JSRData jsrData;
+        long loops;
+        JSRData jsrData;
 
         public static class JSRData implements Cloneable {
             public EconomicMap<JsrScope, BciBlock> jsrAlternatives;
@@ -174,8 +175,21 @@
             }
         }
 
-        public BciBlock() {
-            this.successors = new ArrayList<>(4);
+        BciBlock(int startBci) {
+            this.startBci = startBci;
+            this.successors = new ArrayList<>();
+        }
+
+        public int getStartBci() {
+            return startBci;
+        }
+
+        public int getEndBci() {
+            return endBci;
+        }
+
+        public long getLoops() {
+            return loops;
         }
 
         public BciBlock exceptionDispatchBlock() {
@@ -216,14 +230,16 @@
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder("B").append(getId());
-            sb.append('[').append(startBci).append("->").append(endBci);
-            if (isLoopHeader || isExceptionEntry) {
+            sb.append('[').append(startBci).append("..").append(endBci);
+            if (isLoopHeader || isExceptionEntry || this instanceof ExceptionDispatchBlock) {
                 sb.append(' ');
                 if (isLoopHeader) {
                     sb.append('L');
                 }
                 if (isExceptionEntry) {
                     sb.append('!');
+                } else if (this instanceof ExceptionDispatchBlock) {
+                    sb.append("<!>");
                 }
             }
             sb.append(']');
@@ -412,11 +428,40 @@
             }
             successors.clear();
         }
+
+        public boolean isExceptionDispatch() {
+            return false;
+        }
     }
 
     public static class ExceptionDispatchBlock extends BciBlock {
-        public ExceptionHandler handler;
-        public int deoptBci;
+        public final ExceptionHandler handler;
+        public final int deoptBci;
+
+        /**
+         * Constructor for a normal dispatcher.
+         */
+        ExceptionDispatchBlock(ExceptionHandler handler, int deoptBci) {
+            super(handler.getHandlerBCI());
+            this.endBci = startBci;
+            this.deoptBci = deoptBci;
+            this.handler = handler;
+        }
+
+        /**
+         * Constructor for the method unwind dispatcher.
+         */
+        ExceptionDispatchBlock(int deoptBci) {
+            super(deoptBci);
+            this.endBci = deoptBci;
+            this.deoptBci = deoptBci;
+            this.handler = null;
+        }
+
+        @Override
+        public boolean isExceptionDispatch() {
+            return true;
+        }
     }
 
     /**
@@ -480,7 +525,6 @@
     private boolean verify() {
         for (BciBlock block : blocks) {
             assert blocks[block.getId()] == block;
-
             for (int i = 0; i < block.getSuccessorCount(); i++) {
                 BciBlock sux = block.getSuccessor(i);
                 if (sux instanceof ExceptionDispatchBlock) {
@@ -623,6 +667,8 @@
                 case CALOAD:
                 case SALOAD:
                 case ARRAYLENGTH:
+                case PUTSTATIC:
+                case GETSTATIC:
                 case PUTFIELD:
                 case GETFIELD: {
                     ExceptionDispatchBlock handler = handleExceptions(blockMap, bci);
@@ -640,18 +686,16 @@
     private BciBlock makeBlock(BciBlock[] blockMap, int startBci) {
         BciBlock oldBlock = blockMap[startBci];
         if (oldBlock == null) {
-            BciBlock newBlock = new BciBlock();
+            BciBlock newBlock = new BciBlock(startBci);
             blocksNotYetAssignedId++;
-            newBlock.startBci = startBci;
             blockMap[startBci] = newBlock;
             return newBlock;
 
         } else if (oldBlock.startBci != startBci) {
             // Backward branch into the middle of an already processed block.
             // Add the correct fall-through successor.
-            BciBlock newBlock = new BciBlock();
+            BciBlock newBlock = new BciBlock(startBci);
             blocksNotYetAssignedId++;
-            newBlock.startBci = startBci;
             newBlock.endBci = oldBlock.endBci;
             for (BciBlock oldSuccessor : oldBlock.getSuccessors()) {
                 newBlock.addSuccessor(oldSuccessor);
@@ -747,6 +791,7 @@
 
     private ExceptionDispatchBlock handleExceptions(BciBlock[] blockMap, int bci) {
         ExceptionDispatchBlock lastHandler = null;
+        int dispatchBlocks = 0;
 
         for (int i = exceptionHandlers.length - 1; i >= 0; i--) {
             ExceptionHandler h = exceptionHandlers[i];
@@ -754,17 +799,14 @@
                 if (h.isCatchAll()) {
                     // Discard all information about succeeding exception handlers, since they can
                     // never be reached.
+                    dispatchBlocks = 0;
                     lastHandler = null;
                 }
 
                 // We do not reuse exception dispatch blocks, because nested exception handlers
                 // might have problems reasoning about the correct frame state.
-                ExceptionDispatchBlock curHandler = new ExceptionDispatchBlock();
-                blocksNotYetAssignedId++;
-                curHandler.startBci = -1;
-                curHandler.endBci = -1;
-                curHandler.deoptBci = bci;
-                curHandler.handler = h;
+                ExceptionDispatchBlock curHandler = new ExceptionDispatchBlock(h, bci);
+                dispatchBlocks++;
                 curHandler.addSuccessor(blockMap[h.getHandlerBCI()]);
                 if (lastHandler != null) {
                     curHandler.addSuccessor(lastHandler);
@@ -772,6 +814,7 @@
                 lastHandler = curHandler;
             }
         }
+        blocksNotYetAssignedId += dispatchBlocks;
         return lastHandler;
     }
 
@@ -827,10 +870,8 @@
         assert next == newBlocks.length - 1;
 
         // Add unwind block.
-        ExceptionDispatchBlock unwindBlock = new ExceptionDispatchBlock();
-        unwindBlock.startBci = -1;
-        unwindBlock.endBci = -1;
-        unwindBlock.deoptBci = code.getMethod().isSynchronized() ? BytecodeFrame.UNWIND_BCI : BytecodeFrame.AFTER_EXCEPTION_BCI;
+        int deoptBci = code.getMethod().isSynchronized() ? BytecodeFrame.UNWIND_BCI : BytecodeFrame.AFTER_EXCEPTION_BCI;
+        ExceptionDispatchBlock unwindBlock = new ExceptionDispatchBlock(deoptBci);
         unwindBlock.setId(newBlocks.length - 1);
         newBlocks[newBlocks.length - 1] = unwindBlock;
 
@@ -858,42 +899,54 @@
 
     public void log(BciBlock[] blockMap, String name) {
         if (debug.isLogEnabled()) {
-            String n = System.lineSeparator();
-            StringBuilder sb = new StringBuilder(debug.getCurrentScopeName()).append("BlockMap ").append(name).append(" :");
-            sb.append(n);
-            Iterable<BciBlock> it;
-            if (blocks == null) {
-                it = new HashSet<>(Arrays.asList(blockMap));
-            } else {
-                it = Arrays.asList(blocks);
+            debug.log("%sBlockMap %s: %n%s", debug.getCurrentScopeName(), name, toString(blockMap, loopHeaders));
+        }
+    }
+
+    public static String toString(BciBlock[] blockMap, BciBlock[] loopHeadersMap) {
+        StringBuilder sb = new StringBuilder();
+        for (BciBlock b : blockMap) {
+            if (b == null) {
+                continue;
+            }
+            sb.append("B").append(b.getId()).append("[").append(b.startBci).append("..").append(b.endBci).append("]");
+            if (b.isLoopHeader) {
+                sb.append(" LoopHeader");
             }
-            for (BciBlock b : it) {
-                if (b == null) {
-                    continue;
-                }
-                sb.append("B").append(b.getId()).append(" (").append(b.startBci).append(" -> ").append(b.endBci).append(")");
-                if (b.isLoopHeader) {
-                    sb.append(" LoopHeader");
+            if (b.isExceptionEntry) {
+                sb.append(" ExceptionEntry");
+            }
+            if (b instanceof ExceptionDispatchBlock) {
+                sb.append(" ExceptionDispatch");
+            }
+            if (!b.successors.isEmpty()) {
+                sb.append(" Successors=[");
+                for (BciBlock s : b.getSuccessors()) {
+                    if (sb.charAt(sb.length() - 1) != '[') {
+                        sb.append(", ");
+                    }
+                    sb.append("B").append(s.getId());
                 }
-                if (b.isExceptionEntry) {
-                    sb.append(" ExceptionEntry");
-                }
-                sb.append(n).append("  Sux : ");
-                for (BciBlock s : b.getSuccessors()) {
-                    sb.append("B").append(s.getId()).append(" (").append(s.startBci).append(" -> ").append(s.endBci).append(")");
-                    if (s.isExceptionEntry) {
-                        sb.append("!");
+                sb.append("]");
+            }
+            if (b.loops != 0L) {
+                sb.append(" Loops=[");
+                for (int pos : b.loopIdIterable()) {
+                    if (sb.charAt(sb.length() - 1) == '[') {
+                        sb.append(", ");
                     }
-                    sb.append(" ");
+                    sb.append("B").append(loopHeadersMap[pos].getId());
                 }
-                sb.append(n).append("  Loop : ");
-                for (int pos : b.loopIdIterable()) {
-                    sb.append("B").append(loopHeaders[pos].getId()).append(" ");
-                }
-                sb.append(n);
+                sb.append("]");
             }
-            debug.log("%s", sb);
+            sb.append(System.lineSeparator());
         }
+        return sb.toString();
+    }
+
+    @Override
+    public String toString() {
+        return toString(blocks, loopHeaders);
     }
 
     /**