comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2824:244921d7cf50

Merge
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Mon, 30 May 2011 16:41:05 +0200
parents ac4b086cbd72 2b8ef0a06391
children 9ba6a8abe894
comparison
equal deleted inserted replaced
2823:ac4b086cbd72 2824:244921d7cf50
58 * The minimum value to which {@link C1XOptions#TraceBytecodeParserLevel} must be set to trace 58 * The minimum value to which {@link C1XOptions#TraceBytecodeParserLevel} must be set to trace
59 * the frame state before each bytecode instruction as it is parsed. 59 * the frame state before each bytecode instruction as it is parsed.
60 */ 60 */
61 public static final int TRACELEVEL_STATE = 2; 61 public static final int TRACELEVEL_STATE = 2;
62 62
63 /**
64 * An enumeration of flags describing scope attributes.
65 */
66 public enum Flag {
67 /**
68 * Scope is protected by an exception handler.
69 * This attribute is inherited by nested scopes.
70 */
71 HasHandler,
72
73 /**
74 * Code in scope cannot contain safepoints.
75 * This attribute is inherited by nested scopes.
76 */
77 NoSafepoints;
78
79 public final int mask = 1 << ordinal();
80 }
81
82 private final IR ir; 63 private final IR ir;
83 private final C1XCompilation compilation; 64 private final C1XCompilation compilation;
84 private final CiStatistics stats; 65 private final CiStatistics stats;
85 66
86 private final BytecodeStream stream; // the bytecode stream 67 private final BytecodeStream stream; // the bytecode stream
96 public int compare(Block o1, Block o2) { 77 public int compare(Block o1, Block o2) {
97 return o1.blockID - o2.blockID; 78 return o1.blockID - o2.blockID;
98 } 79 }
99 }); 80 });
100 81
101 /**
102 * Mask of {@link Flag} values.
103 */
104 private int flags;
105
106 // Exception handler list 82 // Exception handler list
107 private List<ExceptionHandler> exceptionHandlers; 83 private List<ExceptionHandler> exceptionHandlers;
108 84
109 private FrameStateBuilder frameState; // the current execution state 85 private FrameStateBuilder frameState; // the current execution state
110 private Instruction lastInstr; // the last instruction added 86 private Instruction lastInstr; // the last instruction added
112 private final LogStream log; 88 private final LogStream log;
113 89
114 private Value rootMethodSynchronizedObject; 90 private Value rootMethodSynchronizedObject;
115 91
116 private final Graph graph; 92 private final Graph graph;
117
118 private Merge unwindBlock;
119 93
120 /** 94 /**
121 * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation. 95 * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation.
122 * 96 *
123 * @param compilation the compilation 97 * @param compilation the compilation
145 if (log != null) { 119 if (log != null) {
146 log.println(); 120 log.println();
147 log.println("Compiling " + compilation.method); 121 log.println("Compiling " + compilation.method);
148 } 122 }
149 123
150 if (rootMethod.noSafepoints()) {
151 flags |= Flag.NoSafepoints.mask;
152 }
153
154 // 2. compute the block map, setup exception handlers and get the entrypoint(s) 124 // 2. compute the block map, setup exception handlers and get the entrypoint(s)
155 BlockMap blockMap = compilation.getBlockMap(rootMethod); 125 BlockMap blockMap = compilation.getBlockMap(rootMethod);
156 126
157 blockList = new ArrayList<Block>(blockMap.blocks); 127 blockList = new ArrayList<Block>(blockMap.blocks);
158 blockFromBci = new Block[rootMethod.code().length]; 128 blockFromBci = new Block[rootMethod.code().length];
176 ExceptionHandler h = new ExceptionHandler(ch); 146 ExceptionHandler h = new ExceptionHandler(ch);
177 h.setEntryBlock(entry); 147 h.setEntryBlock(entry);
178 exceptionHandlers.add(h); 148 exceptionHandlers.add(h);
179 } 149 }
180 } 150 }
181 flags |= Flag.HasHandler.mask;
182
183 } 151 }
184 152
185 // 1. create the start block 153 // 1. create the start block
186 Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); 154 Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
187 markOnWorkList(startBlock); 155 markOnWorkList(startBlock);
296 int bci = target.startBci; 264 int bci = target.startBci;
297 265
298 FrameState existingState = ((StateSplit) first).stateBefore(); 266 FrameState existingState = ((StateSplit) first).stateBefore();
299 267
300 if (existingState == null) { 268 if (existingState == null) {
301 // assert first instanceof Merge ^ !target.isLoopHeader : "isLoopHeader: " + target.isLoopHeader;
302
303 // copy state because it is modified 269 // copy state because it is modified
304 FrameState duplicate = newState.duplicate(bci); 270 FrameState duplicate = newState.duplicate(bci);
305 271
306 // if the block is a loop header, insert all necessary phis 272 // if the block is a loop header, insert all necessary phis
307 if (first instanceof LoopBegin && target.isLoopHeader) { 273 if (first instanceof LoopBegin && target.isLoopHeader) {
421 FrameState entryState = frameState.duplicateWithEmptyStack(bci); 387 FrameState entryState = frameState.duplicateWithEmptyStack(bci);
422 388
423 StateSplit entry = new Placeholder(graph); 389 StateSplit entry = new Placeholder(graph);
424 entry.setStateBefore(entryState); 390 entry.setStateBefore(entryState);
425 ExceptionObject exception = new ExceptionObject(graph); 391 ExceptionObject exception = new ExceptionObject(graph);
426 entry.appendNext(exception); 392 entry.setNext(exception);
427 FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception); 393 FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception);
428 394
429 Instruction successor = createTarget(dispatchBlock, stateWithException); 395 Instruction successor = createTarget(dispatchBlock, stateWithException);
430 Anchor end = new Anchor(successor, graph); 396 Anchor end = new Anchor(successor, graph);
431 exception.appendNext(end); 397 exception.setNext(end);
432
433 if (x instanceof Invoke) { 398 if (x instanceof Invoke) {
434 ((Invoke) x).setExceptionEdge(entry); 399 ((Invoke) x).setExceptionEdge(entry);
435 } else { 400 } else {
436 ((Throw) x).setExceptionEdge(entry); 401 ((Throw) x).setExceptionEdge(entry);
437 } 402 }
1042 private Value append(Value v) { 1007 private Value append(Value v) {
1043 return v; 1008 return v;
1044 } 1009 }
1045 1010
1046 private Value appendWithBCI(Instruction x) { 1011 private Value appendWithBCI(Instruction x) {
1047 if (x.isAppended()) { 1012 assert x.next() == null && x.predecessors().size() == 0 : "instruction should not have been appended yet";
1048 // the instruction has already been added
1049 return x;
1050 }
1051
1052 assert x.next() == null : "instruction should not have been appended yet";
1053 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; 1013 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
1054 1014 lastInstr.setNext(x);
1055 lastInstr = lastInstr.appendNext(x); 1015
1016 lastInstr = x;
1056 if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) { 1017 if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) {
1057 // bailout if we've exceeded the maximum inlining size 1018 // bailout if we've exceeded the maximum inlining size
1058 throw new CiBailout("Method and/or inlining is too large"); 1019 throw new CiBailout("Method and/or inlining is too large");
1059 } 1020 }
1060 1021
1113 1074
1114 frameState.initializeFrom(((StateSplit) syncHandler.firstInstruction).stateBefore()); 1075 frameState.initializeFrom(((StateSplit) syncHandler.firstInstruction).stateBefore());
1115 1076
1116 assert lock != null; 1077 assert lock != null;
1117 assert frameState.locksSize() > 0 && frameState.lockAt(frameState.locksSize() - 1) == lock; 1078 assert frameState.locksSize() > 0 && frameState.lockAt(frameState.locksSize() - 1) == lock;
1118 if (lock instanceof Instruction) { 1079
1119 Instruction l = (Instruction) lock;
1120 if (!l.isAppended()) {
1121 lock = appendWithBCI(l);
1122 }
1123 }
1124 // Exit the monitor and unwind the stack. 1080 // Exit the monitor and unwind the stack.
1125 genMonitorExit(lock); 1081 genMonitorExit(lock);
1126 append(new Unwind(frameState.apop(), graph)); 1082 append(new Unwind(frameState.apop(), graph));
1127 1083
1128 // The sync handler is always the last thing to add => we can clear the frameState. 1084 // The sync handler is always the last thing to add => we can clear the frameState.
1209 } 1165 }
1210 } 1166 }
1211 } 1167 }
1212 1168
1213 private void appendGoto(Instruction target) { 1169 private void appendGoto(Instruction target) {
1214 //if (target instanceof BlockBegin && !((BlockBegin)target).isLoopHeader) { 1170 lastInstr.setNext(target);
1215 // System.out.println("NOTOMITTED");
1216 //append(new Goto(target, graph));
1217 //} else {
1218 // System.out.println("omitted");
1219 lastInstr.appendNext(target);
1220 //}
1221 } 1171 }
1222 1172
1223 private void iterateBytecodesForBlock(Block block) { 1173 private void iterateBytecodesForBlock(Block block) {
1224 assert frameState != null; 1174 assert frameState != null;
1225 1175
1524 private void addExceptionHandler(ExceptionHandler handler) { 1474 private void addExceptionHandler(ExceptionHandler handler) {
1525 if (exceptionHandlers == null) { 1475 if (exceptionHandlers == null) {
1526 exceptionHandlers = new ArrayList<ExceptionHandler>(); 1476 exceptionHandlers = new ArrayList<ExceptionHandler>();
1527 } 1477 }
1528 exceptionHandlers.add(handler); 1478 exceptionHandlers.add(handler);
1529 flags |= Flag.HasHandler.mask;
1530 } 1479 }
1531 1480
1532 /** 1481 /**
1533 * Adds a block to the worklist, if it is not already in the worklist. 1482 * Adds a block to the worklist, if it is not already in the worklist.
1534 * This method will keep the worklist topologically stored (i.e. the lower 1483 * This method will keep the worklist topologically stored (i.e. the lower
1559 /** 1508 /**
1560 * Checks whether this graph has any handlers. 1509 * Checks whether this graph has any handlers.
1561 * @return {@code true} if there are any exception handlers 1510 * @return {@code true} if there are any exception handlers
1562 */ 1511 */
1563 private boolean hasHandler() { 1512 private boolean hasHandler() {
1564 return (flags & Flag.HasHandler.mask) != 0; 1513 return Modifier.isSynchronized(compilation.method.accessFlags()) || (compilation.method.exceptionHandlers() != null && compilation.method.exceptionHandlers().length > 0);
1565 }
1566
1567 /**
1568 * Checks whether this graph can contain safepoints.
1569 */
1570 private boolean noSafepoints() {
1571 return (flags & Flag.NoSafepoints.mask) != 0;
1572 } 1514 }
1573 } 1515 }