1.1 --- a/src/share/vm/ci/ciMethodBlocks.cpp Wed Feb 20 17:23:43 2008 -0800 1.2 +++ b/src/share/vm/ci/ciMethodBlocks.cpp Thu Feb 21 14:03:41 2008 -0800 1.3 @@ -67,6 +67,14 @@ 1.4 break; 1.5 } 1.6 } 1.7 + // Move an exception handler information if needed. 1.8 + if (former_block->is_handler()) { 1.9 + int ex_start = former_block->ex_start_bci(); 1.10 + int ex_end = former_block->ex_limit_bci(); 1.11 + new_block->set_exception_range(ex_start, ex_end); 1.12 + // Clear information in former_block. 1.13 + former_block->clear_exception_handler(); 1.14 + } 1.15 return former_block; 1.16 } 1.17 1.18 @@ -102,7 +110,7 @@ 1.19 // one and end the old one. 1.20 assert(cur_block != NULL, "must always have a current block"); 1.21 ciBlock *new_block = block_containing(bci); 1.22 - if (new_block == NULL) { 1.23 + if (new_block == NULL || new_block == cur_block) { 1.24 // We have not marked this bci as the start of a new block. 1.25 // Keep interpreting the current_range. 1.26 _bci_to_block[bci] = cur_block; 1.27 @@ -254,9 +262,33 @@ 1.28 for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) { 1.29 ciExceptionHandler* handler = str.handler(); 1.30 ciBlock *eb = make_block_at(handler->handler_bci()); 1.31 - eb->set_handler(); 1.32 + // 1.33 + // Several exception handlers can have the same handler_bci: 1.34 + // 1.35 + // try { 1.36 + // if (a.foo(b) < 0) { 1.37 + // return a.error(); 1.38 + // } 1.39 + // return CoderResult.UNDERFLOW; 1.40 + // } finally { 1.41 + // a.position(b); 1.42 + // } 1.43 + // 1.44 + // The try block above is divided into 2 exception blocks 1.45 + // separated by 'areturn' bci. 1.46 + // 1.47 int ex_start = handler->start(); 1.48 int ex_end = handler->limit(); 1.49 + if (eb->is_handler()) { 1.50 + // Extend old handler exception range to cover additional range. 1.51 + int old_ex_start = eb->ex_start_bci(); 1.52 + int old_ex_end = eb->ex_limit_bci(); 1.53 + if (ex_start > old_ex_start) 1.54 + ex_start = old_ex_start; 1.55 + if (ex_end < old_ex_end) 1.56 + ex_end = old_ex_end; 1.57 + eb->clear_exception_handler(); // Reset exception information 1.58 + } 1.59 eb->set_exception_range(ex_start, ex_end); 1.60 // ensure a block at the start of exception range and start of following code 1.61 (void) make_block_at(ex_start); 1.62 @@ -312,9 +344,10 @@ 1.63 1.64 void ciBlock::set_exception_range(int start_bci, int limit_bci) { 1.65 assert(limit_bci >= start_bci, "valid range"); 1.66 - assert(is_handler(), "must be handler"); 1.67 + assert(!is_handler() && _ex_start_bci == -1 && _ex_limit_bci == -1, "must not be handler"); 1.68 _ex_start_bci = start_bci; 1.69 _ex_limit_bci = limit_bci; 1.70 + set_handler(); 1.71 } 1.72 1.73 #ifndef PRODUCT