diff graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2835:c1c8a0291771

merge
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 31 May 2011 13:37:45 +0200
parents bfce42cd9c07 1cd59ca9ac86
children 7b5831f0e913
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Tue May 31 13:34:52 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Tue May 31 13:37:45 2011 +0200
@@ -69,6 +69,9 @@
     private Block[] blockFromBci;
     private ArrayList<Block> blockList;
 
+    private Block syncBlock;
+    private CiExceptionHandler syncHandler;
+
     // the constant pool
     private final RiConstantPool constantPool;
 
@@ -79,9 +82,6 @@
         }
     });
 
-    // Exception handler list
-    private List<ExceptionHandler> exceptionHandlers;
-
     private FrameStateBuilder frameState;          // the current execution state
     private Instruction lastInstr;                 // the last instruction added
 
@@ -133,21 +133,6 @@
             if (block.startBci >= 0) {
                 blockFromBci[block.startBci] = block;
             }
-//            System.out.println("block " + blockID + " @ " + block.startBci);
-        }
-
-        RiExceptionHandler[] handlers = rootMethod.exceptionHandlers();
-        if (handlers != null && handlers.length > 0) {
-            exceptionHandlers = new ArrayList<ExceptionHandler>(handlers.length);
-            for (RiExceptionHandler ch : handlers) {
-                Block entry = blockFromBci[ch.handlerBCI()];
-                // entry == null means that the exception handler is unreachable according to the BlockMap conservative analysis
-                if (entry != null) {
-                    ExceptionHandler h = new ExceptionHandler(ch);
-                    h.setEntryBlock(entry);
-                    exceptionHandlers.add(h);
-                }
-            }
         }
 
         // 1. create the start block
@@ -156,7 +141,6 @@
         lastInstr = createTarget(startBlock, frameState);
         graph.start().setStart(lastInstr);
 
-        Block syncBlock = null;
         if (isSynchronized(rootMethod.accessFlags())) {
             // 4A.1 add a monitor enter to the start block
             rootMethodSynchronizedObject = synchronizedObject(frameState, compilation.method);
@@ -168,9 +152,7 @@
             syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
             markOnWorkList(syncBlock);
 
-            ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null));
-            h.setEntryBlock(syncBlock);
-            addExceptionHandler(h);
+            syncHandler = new CiExceptionHandler(0, rootMethod.code().length, Instruction.SYNCHRONIZATION_ENTRY_BCI, 0, null);
         } else {
             // 4B.1 simply finish the start block
             finishStartBlock(startBlock);
@@ -347,25 +329,34 @@
         frameState.storeLocal(index, frameState.pop(kind));
     }
 
-    private void handleException(Instruction x, int bci) {
-        if (!hasHandler()) {
-            return;
-        }
+    public boolean covers(RiExceptionHandler handler, int bci) {
+        return handler.startBCI() <= bci && bci < handler.endBCI();
+    }
 
+    public boolean isCatchAll(RiExceptionHandler handler) {
+        return handler.catchTypeCPI() == 0;
+    }
+
+    private Instruction handleException(Value exceptionObject, int bci) {
         assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci";
 
-        ExceptionHandler firstHandler = null;
+        RiExceptionHandler firstHandler = null;
+        RiExceptionHandler[] exceptionHandlers = compilation.method.exceptionHandlers();
         // join with all potential exception handlers
-        if (this.exceptionHandlers != null) {
-            for (ExceptionHandler handler : this.exceptionHandlers) {
+        if (exceptionHandlers != null) {
+            for (RiExceptionHandler handler : exceptionHandlers) {
                 // if the handler covers this bytecode index, add it to the list
-                if (handler.covers(bci)) {
-                    firstHandler = new ExceptionHandler(handler);
+                if (covers(handler, bci)) {
+                    firstHandler = handler;
                     break;
                 }
             }
         }
 
+        if (firstHandler == null) {
+            firstHandler = syncHandler;
+        }
+
         if (firstHandler != null) {
             compilation.setHasExceptionHandlers();
 
@@ -373,7 +364,7 @@
             for (Block block : blockList) {
                 if (block instanceof ExceptionBlock) {
                     ExceptionBlock excBlock = (ExceptionBlock) block;
-                    if (excBlock.handler == firstHandler.handler) {
+                    if (excBlock.handler == firstHandler) {
                         dispatchBlock = block;
                         break;
                     }
@@ -381,26 +372,35 @@
             }
             // if there's no dispatch block then the catch block needs to be a catch all
             if (dispatchBlock == null) {
-                assert firstHandler.isCatchAll();
-                dispatchBlock = firstHandler.entryBlock();
+                assert isCatchAll(firstHandler);
+                int handlerBCI = firstHandler.handlerBCI();
+                if (handlerBCI == Instruction.SYNCHRONIZATION_ENTRY_BCI) {
+                    dispatchBlock = syncBlock;
+                } else {
+                    dispatchBlock = blockFromBci[handlerBCI];
+                }
             }
             FrameState entryState = frameState.duplicateWithEmptyStack(bci);
 
             StateSplit entry = new Placeholder(graph);
             entry.setStateBefore(entryState);
-            ExceptionObject exception = new ExceptionObject(graph);
-            entry.setNext(exception);
-            FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception);
+
+            Instruction currentNext = entry;
+            Value currentExceptionObject = exceptionObject;
+            if (currentExceptionObject == null) {
+                ExceptionObject exception = new ExceptionObject(graph);
+                entry.setNext(exception);
+                currentNext = exception;
+                currentExceptionObject = exception;
+            }
+            FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, currentExceptionObject);
 
             Instruction successor = createTarget(dispatchBlock, stateWithException);
             Anchor end = new Anchor(successor, graph);
-            exception.setNext(end);
-            if (x instanceof Invoke) {
-                ((Invoke) x).setExceptionEdge(entry);
-            } else {
-                ((Throw) x).setExceptionEdge(entry);
-            }
+            currentNext.setNext(end);
+            return entry;
         }
+        return null;
     }
 
     private void genLoadConstant(int cpi) {
@@ -608,11 +608,13 @@
     }
 
     private void genThrow(int bci) {
-        FrameState stateBefore = frameState.create(bci);
-        Throw t = new Throw(frameState.apop(), graph);
-        t.setStateBefore(stateBefore);
-        appendWithBCI(t);
-        handleException(t, bci);
+        Value exception = frameState.apop();
+        append(new NullCheck(exception, graph));
+        Instruction entry = handleException(exception, bci);
+        if (entry == null) {
+            entry = new Unwind(exception, graph.end(), graph);
+        }
+        append(entry);
     }
 
     private void genCheckCast() {
@@ -831,7 +833,7 @@
         CiKind resultType = returnKind(target);
         Invoke invoke = new Invoke(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), graph);
         Value result = appendWithBCI(invoke);
-        handleException(invoke, bci());
+        invoke.setExceptionEdge(handleException(null, bci()));
         frameState.pushReturn(resultType, result);
     }
 
@@ -1009,7 +1011,7 @@
     }
 
     private Value appendWithBCI(Instruction x) {
-        assert x.next() == null && x.predecessors().size() == 0 : "instruction should not have been appended yet";
+        assert x.predecessors().size() == 0 : "instruction should not have been appended yet";
         assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
         lastInstr.setNext(x);
 
@@ -1153,7 +1155,7 @@
             assert frameState.stackSize() == 1;
 
             if (block.handler.catchType().isResolved()) {
-                Instruction catchSuccessor = createTarget(block.handlerBlock, frameState);
+                Instruction catchSuccessor = createTarget(blockFromBci[block.handler.handlerBCI()], frameState);
                 Instruction nextDispatch = createTarget(block.next, frameState);
                 append(new ExceptionDispatch(frameState.stackAt(0), catchSuccessor, nextDispatch, block.handler.catchType(), graph));
             } else {
@@ -1468,17 +1470,6 @@
     }
 
     /**
-     * Adds an exception handler.
-     * @param handler the handler to add
-     */
-    private void addExceptionHandler(ExceptionHandler handler) {
-        if (exceptionHandlers == null) {
-            exceptionHandlers = new ArrayList<ExceptionHandler>();
-        }
-        exceptionHandlers.add(handler);
-    }
-
-    /**
      * Adds a block to the worklist, if it is not already in the worklist.
      * This method will keep the worklist topologically stored (i.e. the lower
      * DFNs are earlier in the list).
@@ -1504,12 +1495,4 @@
     private Block removeFromWorkList() {
         return workList.poll();
     }
-
-    /**
-     * Checks whether this graph has any handlers.
-     * @return {@code true} if there are any exception handlers
-     */
-    private boolean hasHandler() {
-        return Modifier.isSynchronized(compilation.method.accessFlags()) || (compilation.method.exceptionHandlers() != null && compilation.method.exceptionHandlers().length > 0);
-    }
 }