diff graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2840:75e0d39833a0

new CompilerGraph, create only one Return and one Unwind per CompilerGraph
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 31 May 2011 16:53:19 +0200
parents 7b5831f0e913
children 7596ae867a7b
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Tue May 31 13:42:01 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Tue May 31 16:53:19 2011 +0200
@@ -29,17 +29,18 @@
 import java.util.*;
 
 import com.oracle.graal.graph.*;
-import com.oracle.max.graal.schedule.Schedule;
+import com.oracle.max.graal.schedule.*;
 import com.sun.c1x.*;
 import com.sun.c1x.debug.*;
-import com.sun.c1x.graph.BlockMap.*;
+import com.sun.c1x.graph.BlockMap.Block;
+import com.sun.c1x.graph.BlockMap.ExceptionBlock;
 import com.sun.c1x.ir.*;
 import com.sun.c1x.util.*;
 import com.sun.c1x.value.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ri.*;
-import com.sun.cri.ri.RiType.*;
+import com.sun.cri.ri.RiType.Representation;
 
 /**
  * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
@@ -72,6 +73,9 @@
     private Block syncBlock;
     private CiExceptionHandler syncHandler;
 
+    private Block unwindBlock;
+    private Block returnBlock;
+
     // the constant pool
     private final RiConstantPool constantPool;
 
@@ -89,7 +93,7 @@
 
     private Value rootMethodSynchronizedObject;
 
-    private final Graph graph;
+    private final CompilerGraph graph;
 
     /**
      * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation.
@@ -98,7 +102,7 @@
      * @param ir the IR to build the graph into
      * @param graph
      */
-    public GraphBuilder(C1XCompilation compilation, IR ir, Graph graph) {
+    public GraphBuilder(C1XCompilation compilation, IR ir, CompilerGraph graph) {
         this.compilation = compilation;
         this.ir = ir;
         this.stats = compilation.stats;
@@ -149,9 +153,6 @@
             finishStartBlock(startBlock);
 
             // 4A.3 setup an exception handler to unlock the root method synchronized object
-            syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
-            markOnWorkList(syncBlock);
-
             syncHandler = new CiExceptionHandler(0, rootMethod.code().length, Instruction.SYNCHRONIZATION_ENTRY_BCI, 0, null);
         } else {
             // 4B.1 simply finish the start block
@@ -164,11 +165,6 @@
         addToWorkList(blockFromBci[0]);
         iterateAllBlocks();
 
-        if (syncBlock != null && syncBlock.firstInstruction != null) {
-            // generate unlocking code if the exception handler is reachable
-            fillSyncHandler(rootMethodSynchronizedObject, syncBlock);
-        }
-
         for (Node n : graph.getNodes()) {
             if (n instanceof Placeholder) {
                 Placeholder p = (Placeholder) n;
@@ -210,6 +206,29 @@
         return block;
     }
 
+    private Block unwindBlock() {
+        if (unwindBlock == null) {
+            unwindBlock = new Block();
+            unwindBlock.startBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            unwindBlock.endBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            unwindBlock.blockID = ir.nextBlockNumber();
+            addToWorkList(unwindBlock);
+        }
+        return unwindBlock;
+    }
+
+    private Block returnBlock() {
+        if (returnBlock == null) {
+            returnBlock = new Block();
+            returnBlock.startBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            returnBlock.endBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            returnBlock.blockID = ir.nextBlockNumber();
+            addToWorkList(returnBlock);
+        }
+        return returnBlock;
+    }
+
+
     private Set<Block> blocksOnWorklist = new HashSet<Block>();
 
     private void markOnWorkList(Block block) {
@@ -375,7 +394,7 @@
                 assert isCatchAll(firstHandler);
                 int handlerBCI = firstHandler.handlerBCI();
                 if (handlerBCI == Instruction.SYNCHRONIZATION_ENTRY_BCI) {
-                    dispatchBlock = syncBlock;
+                    dispatchBlock = unwindBlock();
                 } else {
                     dispatchBlock = blockFromBci[handlerBCI];
                 }
@@ -609,11 +628,15 @@
     private void genThrow(int 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);
+        if (entry != null) {
+            append(entry);
+        } else {
+            frameState.clearStack();
+            frameState.apush(exception);
+            appendGoto(createTarget(unwindBlock(), frameState));
         }
-        append(entry);
     }
 
     private void genCheckCast() {
@@ -893,23 +916,11 @@
     }
 
     private void genReturn(Value x) {
-        if (method().isConstructor() && method().holder().superType() == null) {
-            callRegisterFinalizer();
+        frameState.clearStack();
+        if (x != null) {
+            frameState.push(x.kind, x);
         }
-
-        frameState.clearStack();
-        if (Modifier.isSynchronized(method().accessFlags())) {
-            // unlock before exiting the method
-            int lockNumber = frameState.locksSize() - 1;
-            MonitorAddress lockAddress = null;
-            if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
-                lockAddress = new MonitorAddress(lockNumber, graph);
-                append(lockAddress);
-            }
-            append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, graph));
-            frameState.unlock();
-        }
-        append(new Return(x, graph));
+        appendGoto(createTarget(returnBlock(), frameState));
     }
 
     private void genMonitorEnter(Value x, int bci) {
@@ -1066,27 +1077,6 @@
         }
     }
 
-    private void fillSyncHandler(Value lock, Block syncHandler) {
-        lastInstr = syncHandler.firstInstruction;
-        while (lastInstr.next() != null) {
-            // go forward to the end of the block
-            lastInstr = lastInstr.next();
-        }
-
-        frameState.initializeFrom(((StateSplit) syncHandler.firstInstruction).stateBefore());
-
-        assert lock != null;
-        assert frameState.locksSize() > 0 && frameState.lockAt(frameState.locksSize() - 1) == lock;
-
-        // Exit the monitor and unwind the stack.
-        genMonitorExit(lock);
-        append(new Unwind(frameState.apop(), graph.end(), graph));
-
-        // The sync handler is always the last thing to add => we can clear the frameState.
-        frameState = null;
-        lastInstr = null;
-    }
-
     private void iterateAllBlocks() {
         Block block;
         while ((block = removeFromWorkList()) != null) {
@@ -1104,7 +1094,11 @@
                 lastInstr = block.firstInstruction;
                 assert block.firstInstruction.next() == null : "instructions already appended at block " + block.blockID;
 
-                if (block instanceof ExceptionBlock) {
+                if (block == returnBlock) {
+                    createReturnBlock(block);
+                } else if (block == unwindBlock) {
+                    createUnwindBlock(block);
+                } else if (block instanceof ExceptionBlock) {
                     createExceptionDispatch((ExceptionBlock) block);
                 } else {
                     iterateBytecodesForBlock(block);
@@ -1135,33 +1129,44 @@
         }
     }
 
+    private void createUnwindBlock(Block block) {
+        if (Modifier.isSynchronized(method().accessFlags())) {
+            genMonitorExit(rootMethodSynchronizedObject);
+        }
+        append(graph.createUnwind(frameState.apop()));
+    }
+
+    private void createReturnBlock(Block block) {
+        if (method().isConstructor() && method().holder().superType() == null) {
+            callRegisterFinalizer();
+        }
+        CiKind returnKind = method().signature().returnKind().stackKind();
+        Value x = returnKind == CiKind.Void ? null : frameState.pop(returnKind);
+        assert frameState.stackSize() == 0;
+
+        if (Modifier.isSynchronized(method().accessFlags())) {
+            genMonitorExit(rootMethodSynchronizedObject);
+        }
+        append(graph.createReturn(x));
+    }
+
     private void createExceptionDispatch(ExceptionBlock block) {
         if (block.handler == null) {
             assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize();
-            if (Modifier.isSynchronized(method().accessFlags())) {
-                // unlock before exiting the method
-                int lockNumber = frameState.locksSize() - 1;
-                MonitorAddress lockAddress = null;
-                if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
-                    lockAddress = new MonitorAddress(lockNumber, graph);
-                    append(lockAddress);
-                }
-                append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, graph));
-                frameState.unlock();
-            }
-            append(new Unwind(frameState.apop(), graph.end(), graph));
+            createUnwindBlock(block);
         } else {
             assert frameState.stackSize() == 1;
 
+            Block nextBlock = block.next == null ? unwindBlock() : block.next;
             if (block.handler.catchType().isResolved()) {
                 Instruction catchSuccessor = createTarget(blockFromBci[block.handler.handlerBCI()], frameState);
-                Instruction nextDispatch = createTarget(block.next, frameState);
+                Instruction nextDispatch = createTarget(nextBlock, frameState);
                 append(new ExceptionDispatch(frameState.stackAt(0), catchSuccessor, nextDispatch, block.handler.catchType(), graph));
             } else {
                 Deoptimize deopt = new Deoptimize(graph);
                 deopt.setMessage("unresolved " + block.handler.catchType().name());
                 append(deopt);
-                Instruction nextDispatch = createTarget(block.next, frameState);
+                Instruction nextDispatch = createTarget(nextBlock, frameState);
                 appendGoto(nextDispatch);
             }
         }
@@ -1185,8 +1190,7 @@
             if (nextBlock != null && nextBlock != block) {
                 assert !nextBlock.isExceptionEntry;
                 // we fell through to the next block, add a goto and break
-                Instruction next = createTarget(nextBlock, frameState);
-                appendGoto(next);
+                appendGoto(createTarget(nextBlock, frameState));
                 break;
             }
             // read the opcode