comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2773:27512ea6bbcb

exception dispatch simplification: * BlockMap creates exception dispatch blocks (so they're iterated in the right order) * GraphBuilder uses exception dispatch blocks, simplified handleException, removed updateDispatchChain * simplified mergeOrClone * removed successor & predecessor methods from BlockBegin
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 24 May 2011 12:07:17 +0200
parents 056e392d63d4
children 93fd92c9f8b0
comparison
equal deleted inserted replaced
2772:3e3338a1abb9 2773:27512ea6bbcb
30 30
31 import com.oracle.graal.graph.*; 31 import com.oracle.graal.graph.*;
32 import com.sun.c1x.*; 32 import com.sun.c1x.*;
33 import com.sun.c1x.debug.*; 33 import com.sun.c1x.debug.*;
34 import com.sun.c1x.graph.BlockMap.Block; 34 import com.sun.c1x.graph.BlockMap.Block;
35 import com.sun.c1x.graph.BlockMap.ExceptionBlock;
35 import com.sun.c1x.ir.*; 36 import com.sun.c1x.ir.*;
36 import com.sun.c1x.util.*; 37 import com.sun.c1x.util.*;
37 import com.sun.c1x.value.*; 38 import com.sun.c1x.value.*;
38 import com.sun.cri.bytecode.*; 39 import com.sun.cri.bytecode.*;
39 import com.sun.cri.ci.*; 40 import com.sun.cri.ci.*;
82 private final C1XCompilation compilation; 83 private final C1XCompilation compilation;
83 private final CiStatistics stats; 84 private final CiStatistics stats;
84 85
85 private final BytecodeStream stream; // the bytecode stream 86 private final BytecodeStream stream; // the bytecode stream
86 // bci-to-block mapping 87 // bci-to-block mapping
87 private Block[] blockList; 88 private Block[] blockFromBci;
89 private ArrayList<Block> blockList;
88 90
89 // the constant pool 91 // the constant pool
90 private final RiConstantPool constantPool; 92 private final RiConstantPool constantPool;
91 93
92 // the worklist of blocks, sorted by depth first number 94 // the worklist of blocks, sorted by depth first number
150 } 152 }
151 153
152 // 2. compute the block map, setup exception handlers and get the entrypoint(s) 154 // 2. compute the block map, setup exception handlers and get the entrypoint(s)
153 BlockMap blockMap = compilation.getBlockMap(rootMethod); 155 BlockMap blockMap = compilation.getBlockMap(rootMethod);
154 156
155 blockList = new Block[rootMethod.code().length]; 157 blockList = new ArrayList<Block>(blockMap.blocks);
156 for (int i = 0; i < blockMap.blocks.size(); i++) { 158 blockFromBci = new Block[rootMethod.code().length];
159 for (int i = 0; i < blockList.size(); i++) {
157 int blockID = ir.nextBlockNumber(); 160 int blockID = ir.nextBlockNumber();
158 assert blockID == i; 161 assert blockID == i;
159 Block block = blockMap.blocks.get(i); 162 Block block = blockList.get(i);
160 blockList[block.startBci] = block; 163 if (block.startBci >= 0) {
164 blockFromBci[block.startBci] = block;
165 }
166 // System.out.println("block " + blockID + " @ " + block.startBci);
161 } 167 }
162 168
163 // 1. create the start block 169 // 1. create the start block
164 Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); 170 Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
165 BlockBegin startBlockBegin = new BlockBegin(0, startBlock.blockID, false, graph); 171 BlockBegin startBlockBegin = new BlockBegin(0, startBlock.blockID, false, graph);
169 175
170 RiExceptionHandler[] handlers = rootMethod.exceptionHandlers(); 176 RiExceptionHandler[] handlers = rootMethod.exceptionHandlers();
171 if (handlers != null && handlers.length > 0) { 177 if (handlers != null && handlers.length > 0) {
172 exceptionHandlers = new ArrayList<ExceptionHandler>(handlers.length); 178 exceptionHandlers = new ArrayList<ExceptionHandler>(handlers.length);
173 for (RiExceptionHandler ch : handlers) { 179 for (RiExceptionHandler ch : handlers) {
174 Block entry = blockList[ch.handlerBCI()]; 180 Block entry = blockFromBci[ch.handlerBCI()];
175 // entry == null means that the exception handler is unreachable according to the BlockMap conservative analysis 181 // entry == null means that the exception handler is unreachable according to the BlockMap conservative analysis
176 if (entry != null) { 182 if (entry != null) {
177 ExceptionHandler h = new ExceptionHandler(ch); 183 ExceptionHandler h = new ExceptionHandler(ch);
178 h.setEntryBlock(entry); 184 h.setEntryBlock(entry);
179 exceptionHandlers.add(h); 185 exceptionHandlers.add(h);
180 } 186 }
181 } 187 }
182 flags |= Flag.HasHandler.mask; 188 flags |= Flag.HasHandler.mask;
183 } 189 }
184 190
185 mergeOrClone(startBlockBegin, frameState, false); 191 mergeOrClone(startBlock, frameState);
186 192
187 // 3. setup internal state for appending instructions 193 // 3. setup internal state for appending instructions
188 lastInstr = startBlockBegin; 194 lastInstr = startBlockBegin;
189 lastInstr.appendNext(null); 195 lastInstr.appendNext(null);
190 196
201 syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); 207 syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
202 syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, syncBlock.blockID, false, graph); 208 syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, syncBlock.blockID, false, graph);
203 syncBlock.firstInstruction = syncHandler; 209 syncBlock.firstInstruction = syncHandler;
204 markOnWorkList(syncBlock); 210 markOnWorkList(syncBlock);
205 211
212 ExceptionBlock excBlock = new ExceptionBlock();
213 excBlock.startBci = -1;
214 excBlock.endBci = -1;
215 excBlock.blockID = ir.nextBlockNumber();
216 blockList.add(excBlock);
206 ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null)); 217 ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null));
207 h.setEntryBlock(syncBlock); 218 h.setEntryBlock(syncBlock);
208 addExceptionHandler(h); 219 addExceptionHandler(h);
209 } else { 220 } else {
210 // 4B.1 simply finish the start block 221 // 4B.1 simply finish the start block
212 } 223 }
213 224
214 // 5. SKIPPED: look for intrinsics 225 // 5. SKIPPED: look for intrinsics
215 226
216 // 6B.1 do the normal parsing 227 // 6B.1 do the normal parsing
217 addToWorkList(blockList[0]); 228 addToWorkList(blockFromBci[0]);
218 iterateAllBlocks(); 229 iterateAllBlocks();
219 230
220 if (syncBlock != null && syncHandler.stateBefore() != null) { 231 if (syncBlock != null && syncHandler.stateBefore() != null) {
221 // generate unlocking code if the exception handler is reachable 232 // generate unlocking code if the exception handler is reachable
222 fillSyncHandler(rootMethodSynchronizedObject, syncBlock); 233 fillSyncHandler(rootMethodSynchronizedObject, syncBlock);
223 } 234 }
235
236 // for (Node n : graph.getNodes()) {
237 // if (n instanceof FrameState) {
238 // boolean delete = false;
239 // if (n.usages().size() == 0 && n.predecessors().size() == 0) {
240 // delete = true;
241 // }
242 // if (n.predecessors().size() == 0 && n.usages().size() == 1 && n.usages().get(0) instanceof BlockBegin) {
243 // n.usages().get(0).inputs().replace(n, null);
244 // delete = true;
245 // }
246 // if (delete) {
247 // n.delete();
248 // System.out.println("deleted framestate");
249 // }
250 // }
251 // }
224 } 252 }
225 253
226 private Block nextBlock(int bci) { 254 private Block nextBlock(int bci) {
227 Block block = new Block(); 255 Block block = new Block();
228 block.startBci = bci; 256 block.startBci = bci;
258 Goto base = new Goto(target, stateAfter, graph); 286 Goto base = new Goto(target, stateAfter, graph);
259 appendWithBCI(base); 287 appendWithBCI(base);
260 } 288 }
261 289
262 public void mergeOrClone(Block target, FrameStateAccess newState) { 290 public void mergeOrClone(Block target, FrameStateAccess newState) {
263 assert target.firstInstruction instanceof BlockBegin; 291 Instruction first = target.firstInstruction;
264 if (target.isLoopHeader) { 292 int bci = target.startBci;
265 mergeOrClone(target.firstInstruction, newState, true); 293 boolean loopHeader = target.isLoopHeader;
266 } else { 294
267 mergeOrClone(target.firstInstruction, newState, false); 295 FrameState existingState;
268 } 296 if (first instanceof Placeholder) {
269 } 297 existingState = ((Placeholder) first).stateBefore();
270 298 } else {
271 299 assert first instanceof BlockBegin;
272 private void mergeOrClone(Instruction first, FrameStateAccess stateAfter, boolean loopHeader) { 300 existingState = ((BlockBegin) first).stateBefore();
273 mergeOrClone(first, stateAfter, loopHeader, false); 301 }
274 } 302
275 303 if (existingState == null) {
276 private void mergeOrClone(Instruction first, FrameStateAccess stateAfter, boolean loopHeader, boolean blockAppended) { 304 // copy state because it is modified
277 if (first instanceof BlockBegin) { 305 FrameState duplicate = newState.duplicate(bci);
278 BlockBegin block = (BlockBegin) first; 306
279 FrameState existingState = block.stateBefore(); 307 // if the block is a loop header, insert all necessary phis
280 308 if (loopHeader) {
281 if (existingState == null) { 309 assert first instanceof BlockBegin;
282 // copy state because it is modified 310 insertLoopPhis((BlockBegin) first, duplicate);
283 FrameState duplicate = stateAfter.duplicate(block.bci()); 311 ((BlockBegin) first).setStateBefore(duplicate);
284 312 } else {
285 // if the block is a loop header, insert all necessary phis 313 if (first instanceof Placeholder) {
286 if (loopHeader) { 314 ((Placeholder) first).setStateBefore(duplicate);
287 insertLoopPhis(block, duplicate); 315 } else {
316 ((BlockBegin) first).setStateBefore(duplicate);
288 } 317 }
289 318 }
290 block.setStateBefore(duplicate); 319 } else {
291 } else { 320
292 if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(stateAfter)) { 321 if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) {
293 // stacks or locks do not match--bytecodes would not verify 322 // stacks or locks do not match--bytecodes would not verify
294 throw new CiBailout("stack or locks do not match"); 323 throw new CiBailout("stack or locks do not match");
295 } 324 }
296 325
297 assert existingState.localsSize() == stateAfter.localsSize(); 326 assert existingState.localsSize() == newState.localsSize();
298 assert existingState.stackSize() == stateAfter.stackSize(); 327 assert existingState.stackSize() == newState.stackSize();
299 328
300 existingState.merge(block, stateAfter, blockAppended); 329 existingState.merge((BlockBegin) first, newState);
301 } 330 }
302 } else {
303 assert false;
304 }
305
306
307
308 331
309 for (int j = 0; j < frameState.localsSize() + frameState.stackSize(); ++j) { 332 for (int j = 0; j < frameState.localsSize() + frameState.stackSize(); ++j) {
310 if (frameState.valueAt(j) != null) { 333 if (frameState.valueAt(j) != null) {
311 assert !frameState.valueAt(j).isDeleted(); 334 assert !frameState.valueAt(j).isDeleted();
312 } 335 }
354 private void handleException(Instruction x, int bci) { 377 private void handleException(Instruction x, int bci) {
355 if (!hasHandler()) { 378 if (!hasHandler()) {
356 return; 379 return;
357 } 380 }
358 381
359 ArrayList<ExceptionHandler> exceptionHandlers = new ArrayList<ExceptionHandler>();
360
361 assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci"; 382 assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci";
362 383
384 ExceptionHandler firstHandler = null;
363 // join with all potential exception handlers 385 // join with all potential exception handlers
364 if (this.exceptionHandlers != null) { 386 if (this.exceptionHandlers != null) {
365 for (ExceptionHandler handler : this.exceptionHandlers) { 387 for (ExceptionHandler handler : this.exceptionHandlers) {
366 // if the handler covers this bytecode index, add it to the list 388 // if the handler covers this bytecode index, add it to the list
367 if (handler.covers(bci)) { 389 if (handler.covers(bci)) {
368 ExceptionHandler newHandler = addExceptionHandler(handler, frameState); 390 firstHandler = new ExceptionHandler(handler);
369 exceptionHandlers.add(newHandler); 391 break;
370 392 }
371 // stop when reaching catch all 393 }
372 if (handler.isCatchAll()) { 394 }
395
396 if (firstHandler != null) {
397 compilation.setHasExceptionHandlers();
398
399 Block dispatchBlock = null;
400 for (Block block : blockList) {
401 if (block instanceof ExceptionBlock) {
402 ExceptionBlock excBlock = (ExceptionBlock) block;
403 if (excBlock.handler == firstHandler.handler) {
404 dispatchBlock = block;
373 break; 405 break;
374 } 406 }
375 } 407 }
376 } 408 }
377 } 409 // if there's no dispatch block then the catch block needs to be a catch all
378 410 if (dispatchBlock == null) {
379 if (!exceptionHandlers.isEmpty()) { 411 assert firstHandler.isCatchAll();
380 Instruction successor; 412 dispatchBlock = firstHandler.entryBlock();
381 413 }
382 ArrayList<BlockBegin> newBlocks = new ArrayList<BlockBegin>();
383
384 int current = exceptionHandlers.size() - 1;
385 if (exceptionHandlers.get(current).isCatchAll()) {
386 successor = createTarget(exceptionHandlers.get(current).entryBlock(), null);
387 current--;
388 } else {
389 if (unwindBlock == null) {
390 unwindBlock = new BlockBegin(bci, ir.nextBlockNumber(), false, graph);
391 Unwind unwind = new Unwind(null, graph);
392 unwindBlock.appendNext(unwind);
393 }
394 successor = unwindBlock;
395 }
396
397 for (; current >= 0; current--) {
398 ExceptionHandler handler = exceptionHandlers.get(current);
399
400 BlockBegin newSucc = null;
401 for (Node pred : successor.predecessors()) {
402 if (pred instanceof ExceptionDispatch) {
403 ExceptionDispatch dispatch = (ExceptionDispatch) pred;
404 if (dispatch.handler().handler == handler.handler) {
405 newSucc = dispatch.begin();
406 break;
407 }
408 }
409 }
410 if (newSucc != null) {
411 successor = newSucc;
412 } else {
413 BlockBegin dispatchEntry = new BlockBegin(handler.handlerBCI(), ir.nextBlockNumber(), false, graph);
414
415 if (handler.handler.catchType().isResolved()) {
416 Instruction entry = createTarget(handler.entryBlock(), null);
417 ExceptionDispatch end = new ExceptionDispatch(null, entry, null, handler, null, graph);
418 end.setBlockSuccessor(0, successor);
419 dispatchEntry.appendNext(end);
420 } else {
421 Deoptimize deopt = new Deoptimize(graph);
422 dispatchEntry.appendNext(deopt);
423 Goto end = new Goto(successor, null, graph);
424 deopt.appendNext(end);
425 }
426
427 newBlocks.add(dispatchEntry);
428 successor = dispatchEntry;
429 }
430 }
431
432 FrameState entryState = frameState.duplicateWithEmptyStack(bci); 414 FrameState entryState = frameState.duplicateWithEmptyStack(bci);
433 415
434 BlockBegin entry = new BlockBegin(bci, ir.nextBlockNumber(), false, graph); 416 BlockBegin entry = new BlockBegin(bci, ir.nextBlockNumber(), false, graph);
435 entry.setStateBefore(entryState); 417 entry.setStateBefore(entryState);
436 ExceptionObject exception = new ExceptionObject(graph); 418 ExceptionObject exception = new ExceptionObject(graph);
437 entry.appendNext(exception); 419 entry.appendNext(exception);
438 FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception); 420 FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception);
421
422 Instruction successor = createTarget(dispatchBlock, stateWithException);
439 BlockEnd end = new Goto(successor, stateWithException, graph); 423 BlockEnd end = new Goto(successor, stateWithException, graph);
440 exception.appendNext(end); 424 exception.appendNext(end);
441 425
442 if (x instanceof Invoke) { 426 if (x instanceof Invoke) {
443 ((Invoke) x).setExceptionEdge(entry); 427 ((Invoke) x).setExceptionEdge(entry);
444 } else { 428 } else {
445 ((Throw) x).setExceptionEdge(entry); 429 ((Throw) x).setExceptionEdge(entry);
446 } 430 }
447 431 }
448 updateDispatchChain(end.blockSuccessor(0), stateWithException, bci);
449 }
450 }
451
452 private void updateDispatchChain(BlockBegin dispatchEntry, FrameStateAccess state, int bci) {
453 FrameState oldState = dispatchEntry.stateBefore();
454 if (oldState != null && dispatchEntry.predecessors().size() == 1) {
455 dispatchEntry.setStateBefore(null);
456 }
457 mergeOrClone(dispatchEntry, state, false, true);
458 FrameState mergedState = dispatchEntry.stateBefore();
459
460 if (dispatchEntry.next() instanceof ExceptionDispatch) {
461 // ordinary dispatch handler
462 ExceptionDispatch dispatch = (ExceptionDispatch) dispatchEntry.next();
463 dispatch.setStateAfter(mergedState.duplicate(bci));
464 dispatch.setException(mergedState.stackAt(0));
465 dispatch.catchSuccessor().setStateBefore(mergedState.duplicate(bci));
466 updateDispatchChain(dispatch.otherSuccessor(), mergedState, bci);
467 } else if (dispatchEntry.next() instanceof Deoptimize) {
468 // deoptimizing handler
469 dispatchEntry.end().setStateAfter(mergedState.duplicate(bci));
470 updateDispatchChain(dispatchEntry.end().blockSuccessor(0), mergedState, bci);
471 } else if (dispatchEntry.next() instanceof Unwind) {
472 // unwind handler
473 Unwind unwind = (Unwind) dispatchEntry.next();
474 unwind.setStateAfter(mergedState.duplicate(bci));
475 unwind.setException(mergedState.stackAt(0));
476 } else {
477 // synchronization or default exception handler, nothing to do
478 }
479 }
480
481 /**
482 * Adds an exception handler to the {@linkplain BlockBegin#exceptionHandlerBlocks() list}
483 * of exception handlers for the {@link #curBlock current block}.
484 */
485 private ExceptionHandler addExceptionHandler(ExceptionHandler handler, FrameStateAccess curState) {
486 compilation.setHasExceptionHandlers();
487
488 BlockMap.Block entry = handler.entryBlock();
489
490 // clone exception handler
491 ExceptionHandler newHandler = new ExceptionHandler(handler);
492
493 // fill in exception handler subgraph lazily
494 if (!isVisited(entry)) {
495 if (handler.handlerBCI() != Instruction.SYNCHRONIZATION_ENTRY_BCI) {
496 addToWorkList(entry);
497 }
498 } else {
499 // This will occur for exception handlers that cover themselves. This code
500 // pattern is generated by javac for synchronized blocks. See the following
501 // for why this change to javac was made:
502 //
503 // http://www.cs.arizona.edu/projects/sumatra/hallofshame/java-async-race.html
504 }
505 return newHandler;
506 } 432 }
507 433
508 private void genLoadConstant(int cpi) { 434 private void genLoadConstant(int cpi) {
509 Object con = constantPool().lookupConstant(cpi); 435 Object con = constantPool().lookupConstant(cpi);
510 436
1122 } 1048 }
1123 1049
1124 return x; 1050 return x;
1125 } 1051 }
1126 1052
1127 private Instruction blockAtOrNull(int bci) {
1128 return blockList[bci] != null ? blockList[bci].firstInstruction : null;
1129 }
1130
1131 private Instruction blockAt(int bci) {
1132 Instruction result = blockAtOrNull(bci);
1133 assert result != null : "Expected a block to begin at " + bci;
1134 return result;
1135 }
1136
1137 private Instruction createTargetAt(int bci, FrameStateAccess stateAfter) { 1053 private Instruction createTargetAt(int bci, FrameStateAccess stateAfter) {
1138 return createTarget(blockList[bci], stateAfter); 1054 return createTarget(blockFromBci[bci], stateAfter);
1139 } 1055 }
1140 1056
1141 private Instruction createTarget(Block block, FrameStateAccess stateAfter) { 1057 private Instruction createTarget(Block block, FrameStateAccess stateAfter) {
1058 assert block != null && stateAfter != null;
1142 if (block.firstInstruction == null) { 1059 if (block.firstInstruction == null) {
1143 BlockBegin blockBegin = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph); 1060 // if (block.isLoopHeader) {
1144 block.firstInstruction = blockBegin; 1061 block.firstInstruction = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph);
1145 } 1062 // } else {
1146 if (stateAfter != null) { 1063 // block.firstInstruction = new Placeholder(graph);
1147 mergeOrClone(block, stateAfter); 1064 // }
1148 } 1065 }
1066 mergeOrClone(block, stateAfter);
1149 addToWorkList(block); 1067 addToWorkList(block);
1150 return block.firstInstruction; 1068 return block.firstInstruction;
1151 } 1069 }
1152 1070
1153 private Value synchronizedObject(FrameStateAccess state, RiMethod target) { 1071 private Value synchronizedObject(FrameStateAccess state, RiMethod target) {
1207 // now parse the block 1125 // now parse the block
1208 frameState.initializeFrom(((BlockBegin) block.firstInstruction).stateBefore()); 1126 frameState.initializeFrom(((BlockBegin) block.firstInstruction).stateBefore());
1209 lastInstr = block.firstInstruction; 1127 lastInstr = block.firstInstruction;
1210 assert block.firstInstruction.next() == null; 1128 assert block.firstInstruction.next() == null;
1211 1129
1212 iterateBytecodesForBlock(block); 1130 if (block instanceof ExceptionBlock) {
1131 createExceptionDispatch((ExceptionBlock) block);
1132 } else {
1133 iterateBytecodesForBlock(block);
1134 }
1135 }
1136 }
1137 }
1138
1139 private void createExceptionDispatch(ExceptionBlock block) {
1140 if (block.handler == null) {
1141 assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize();
1142 if (Modifier.isSynchronized(method().accessFlags())) {
1143 // unlock before exiting the method
1144 int lockNumber = frameState.locksSize() - 1;
1145 MonitorAddress lockAddress = null;
1146 if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
1147 lockAddress = new MonitorAddress(lockNumber, graph);
1148 append(lockAddress);
1149 }
1150 append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, graph));
1151 frameState.unlock();
1152 }
1153 append(new Unwind(frameState.apop(), graph));
1154 } else {
1155 assert frameState.stackSize() == 1;
1156
1157 if (block.handler.catchType().isResolved()) {
1158 Instruction catchSuccessor = createTarget(block.handlerBlock, frameState);
1159 Instruction nextDispatch = createTarget(block.next, frameState);
1160 append(new ExceptionDispatch(frameState.stackAt(0), catchSuccessor, nextDispatch, block.handler.catchType(), frameState.duplicate(bci()), graph));
1161 } else {
1162 Deoptimize deopt = new Deoptimize(graph);
1163 deopt.setMessage("unresolved " + block.handler.catchType().name());
1164 append(deopt);
1165 Instruction nextDispatch = createTarget(block.next, frameState);
1166 append(new Goto(nextDispatch, frameState.duplicate(bci()), graph));
1213 } 1167 }
1214 } 1168 }
1215 } 1169 }
1216 1170
1217 private BlockEnd iterateBytecodesForBlock(Block block) { 1171 private BlockEnd iterateBytecodesForBlock(Block block) {
1223 int endBCI = stream.endBCI(); 1177 int endBCI = stream.endBCI();
1224 boolean blockStart = true; 1178 boolean blockStart = true;
1225 1179
1226 int bci = block.startBci; 1180 int bci = block.startBci;
1227 while (bci < endBCI) { 1181 while (bci < endBCI) {
1228 Block nextBlock = blockList[bci]; 1182 Block nextBlock = blockFromBci[bci];
1229 if (nextBlock != null && nextBlock != block) { 1183 if (nextBlock != null && nextBlock != block) {
1230 // we fell through to the next block, add a goto and break 1184 // we fell through to the next block, add a goto and break
1231 Instruction next = createTarget(nextBlock, frameState); 1185 Instruction next = createTarget(nextBlock, frameState);
1232 end = new Goto(next, null, graph); 1186 end = new Goto(next, null, graph);
1233 lastInstr = lastInstr.appendNext(end); 1187 lastInstr = lastInstr.appendNext(end);
1261 } 1215 }
1262 1216
1263 // connect to begin and set state 1217 // connect to begin and set state
1264 // NOTE that inlining may have changed the block we are parsing 1218 // NOTE that inlining may have changed the block we are parsing
1265 assert end != null : "end should exist after iterating over bytecodes"; 1219 assert end != null : "end should exist after iterating over bytecodes";
1266 FrameState stateAtEnd = frameState.create(bci()); 1220 end.setStateAfter(frameState.create(bci()));
1267 end.setStateAfter(stateAtEnd);
1268 return end; 1221 return end;
1269 } 1222 }
1270 1223
1271 private void traceState() { 1224 private void traceState() {
1272 if (C1XOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) { 1225 if (C1XOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) {