Mercurial > hg > graal-compiler
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 } |