65 } else { |
65 } else { |
66 // We are done with our backwards walk |
66 // We are done with our backwards walk |
67 break; |
67 break; |
68 } |
68 } |
69 } |
69 } |
|
70 // Move an exception handler information if needed. |
|
71 if (former_block->is_handler()) { |
|
72 int ex_start = former_block->ex_start_bci(); |
|
73 int ex_end = former_block->ex_limit_bci(); |
|
74 new_block->set_exception_range(ex_start, ex_end); |
|
75 // Clear information in former_block. |
|
76 former_block->clear_exception_handler(); |
|
77 } |
70 return former_block; |
78 return former_block; |
71 } |
79 } |
72 |
80 |
73 ciBlock *ciMethodBlocks::make_block_at(int bci) { |
81 ciBlock *ciMethodBlocks::make_block_at(int bci) { |
74 ciBlock *cb = block_containing(bci); |
82 ciBlock *cb = block_containing(bci); |
100 // Determine if a new block has been made at the current bci. If |
108 // Determine if a new block has been made at the current bci. If |
101 // this block differs from our current range, switch to the new |
109 // this block differs from our current range, switch to the new |
102 // one and end the old one. |
110 // one and end the old one. |
103 assert(cur_block != NULL, "must always have a current block"); |
111 assert(cur_block != NULL, "must always have a current block"); |
104 ciBlock *new_block = block_containing(bci); |
112 ciBlock *new_block = block_containing(bci); |
105 if (new_block == NULL) { |
113 if (new_block == NULL || new_block == cur_block) { |
106 // We have not marked this bci as the start of a new block. |
114 // We have not marked this bci as the start of a new block. |
107 // Keep interpreting the current_range. |
115 // Keep interpreting the current_range. |
108 _bci_to_block[bci] = cur_block; |
116 _bci_to_block[bci] = cur_block; |
109 } else { |
117 } else { |
110 cur_block->set_limit_bci(bci); |
118 cur_block->set_limit_bci(bci); |
252 // create blocks for exception handlers |
260 // create blocks for exception handlers |
253 if (meth->has_exception_handlers()) { |
261 if (meth->has_exception_handlers()) { |
254 for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) { |
262 for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) { |
255 ciExceptionHandler* handler = str.handler(); |
263 ciExceptionHandler* handler = str.handler(); |
256 ciBlock *eb = make_block_at(handler->handler_bci()); |
264 ciBlock *eb = make_block_at(handler->handler_bci()); |
257 eb->set_handler(); |
265 // |
|
266 // Several exception handlers can have the same handler_bci: |
|
267 // |
|
268 // try { |
|
269 // if (a.foo(b) < 0) { |
|
270 // return a.error(); |
|
271 // } |
|
272 // return CoderResult.UNDERFLOW; |
|
273 // } finally { |
|
274 // a.position(b); |
|
275 // } |
|
276 // |
|
277 // The try block above is divided into 2 exception blocks |
|
278 // separated by 'areturn' bci. |
|
279 // |
258 int ex_start = handler->start(); |
280 int ex_start = handler->start(); |
259 int ex_end = handler->limit(); |
281 int ex_end = handler->limit(); |
|
282 if (eb->is_handler()) { |
|
283 // Extend old handler exception range to cover additional range. |
|
284 int old_ex_start = eb->ex_start_bci(); |
|
285 int old_ex_end = eb->ex_limit_bci(); |
|
286 if (ex_start > old_ex_start) |
|
287 ex_start = old_ex_start; |
|
288 if (ex_end < old_ex_end) |
|
289 ex_end = old_ex_end; |
|
290 eb->clear_exception_handler(); // Reset exception information |
|
291 } |
260 eb->set_exception_range(ex_start, ex_end); |
292 eb->set_exception_range(ex_start, ex_end); |
261 // ensure a block at the start of exception range and start of following code |
293 // ensure a block at the start of exception range and start of following code |
262 (void) make_block_at(ex_start); |
294 (void) make_block_at(ex_start); |
263 if (ex_end < _code_size) |
295 if (ex_end < _code_size) |
264 (void) make_block_at(ex_end); |
296 (void) make_block_at(ex_end); |
310 _ex_start_bci(-1), _ex_limit_bci(-1) { |
342 _ex_start_bci(-1), _ex_limit_bci(-1) { |
311 } |
343 } |
312 |
344 |
313 void ciBlock::set_exception_range(int start_bci, int limit_bci) { |
345 void ciBlock::set_exception_range(int start_bci, int limit_bci) { |
314 assert(limit_bci >= start_bci, "valid range"); |
346 assert(limit_bci >= start_bci, "valid range"); |
315 assert(is_handler(), "must be handler"); |
347 assert(!is_handler() && _ex_start_bci == -1 && _ex_limit_bci == -1, "must not be handler"); |
316 _ex_start_bci = start_bci; |
348 _ex_start_bci = start_bci; |
317 _ex_limit_bci = limit_bci; |
349 _ex_limit_bci = limit_bci; |
|
350 set_handler(); |
318 } |
351 } |
319 |
352 |
320 #ifndef PRODUCT |
353 #ifndef PRODUCT |
321 static char *flagnames[] = { |
354 static char *flagnames[] = { |
322 "Processed", |
355 "Processed", |