src/share/vm/runtime/sharedRuntime.cpp

Print this page




 642     }
 643   }
 644   return 0;
 645 JRT_END
 646 
 647 // ret_pc points into caller; we are returning caller's exception handler
 648 // for given exception
 649 address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception,
 650                                                     bool force_unwind, bool top_frame_only) {
 651   assert(nm != NULL, "must exist");
 652   ResourceMark rm;
 653 
 654   ScopeDesc* sd = nm->scope_desc_at(ret_pc);
 655   // determine handler bci, if any
 656   EXCEPTION_MARK;
 657 
 658   int handler_bci = -1;
 659   int scope_depth = 0;
 660   if (!force_unwind) {
 661     int bci = sd->bci();

 662     do {
 663       bool skip_scope_increment = false;
 664       // exception handler lookup
 665       KlassHandle ek (THREAD, exception->klass());
 666       handler_bci = sd->method()->fast_exception_handler_bci_for(ek, bci, THREAD);
 667       if (HAS_PENDING_EXCEPTION) {

 668         // We threw an exception while trying to find the exception handler.
 669         // Transfer the new exception to the exception handle which will
 670         // be set into thread local storage, and do another lookup for an
 671         // exception handler for this exception, this time starting at the
 672         // BCI of the exception handler which caused the exception to be
 673         // thrown (bugs 4307310 and 4546590). Set "exception" reference
 674         // argument to ensure that the correct exception is thrown (4870175).
 675         exception = Handle(THREAD, PENDING_EXCEPTION);
 676         CLEAR_PENDING_EXCEPTION;
 677         if (handler_bci >= 0) {
 678           bci = handler_bci;
 679           handler_bci = -1;
 680           skip_scope_increment = true;
 681         }
 682       }



 683       if (!top_frame_only && handler_bci < 0 && !skip_scope_increment) {
 684         sd = sd->sender();
 685         if (sd != NULL) {
 686           bci = sd->bci();
 687         }
 688         ++scope_depth;
 689       }
 690     } while (!top_frame_only && handler_bci < 0 && sd != NULL);
 691   }
 692 
 693   // found handling method => lookup exception handler
 694   int catch_pco = ret_pc - nm->code_begin();
 695 
 696   ExceptionHandlerTable table(nm);
 697   HandlerTableEntry *t = table.entry_for(catch_pco, handler_bci, scope_depth);
 698   if (t == NULL && (nm->is_compiled_by_c1() || handler_bci != -1)) {
 699     // Allow abbreviated catch tables.  The idea is to allow a method
 700     // to materialize its exceptions without committing to the exact
 701     // routing of exceptions.  In particular this is needed for adding
 702     // a synthethic handler to unlock monitors when inlining
 703     // synchonized methods since the unlock path isn't represented in
 704     // the bytecodes.
 705     t = table.entry_for(catch_pco, -1, 0);
 706   }
 707 
 708 #ifdef COMPILER1
 709   if (t == NULL && nm->is_compiled_by_c1()) {
 710     assert(nm->unwind_handler_begin() != NULL, "");




 642     }
 643   }
 644   return 0;
 645 JRT_END
 646 
 647 // ret_pc points into caller; we are returning caller's exception handler
 648 // for given exception
 649 address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception,
 650                                                     bool force_unwind, bool top_frame_only) {
 651   assert(nm != NULL, "must exist");
 652   ResourceMark rm;
 653 
 654   ScopeDesc* sd = nm->scope_desc_at(ret_pc);
 655   // determine handler bci, if any
 656   EXCEPTION_MARK;
 657 
 658   int handler_bci = -1;
 659   int scope_depth = 0;
 660   if (!force_unwind) {
 661     int bci = sd->bci();
 662     bool recursive_exception = false;
 663     do {
 664       bool skip_scope_increment = false;
 665       // exception handler lookup
 666       KlassHandle ek (THREAD, exception->klass());
 667       handler_bci = sd->method()->fast_exception_handler_bci_for(ek, bci, THREAD);
 668       if (HAS_PENDING_EXCEPTION) {
 669         recursive_exception = true;
 670         // We threw an exception while trying to find the exception handler.
 671         // Transfer the new exception to the exception handle which will
 672         // be set into thread local storage, and do another lookup for an
 673         // exception handler for this exception, this time starting at the
 674         // BCI of the exception handler which caused the exception to be
 675         // thrown (bugs 4307310 and 4546590). Set "exception" reference
 676         // argument to ensure that the correct exception is thrown (4870175).
 677         exception = Handle(THREAD, PENDING_EXCEPTION);
 678         CLEAR_PENDING_EXCEPTION;
 679         if (handler_bci >= 0) {
 680           bci = handler_bci;
 681           handler_bci = -1;
 682           skip_scope_increment = true;
 683         }
 684       }
 685       else {
 686         recursive_exception = false;
 687       }
 688       if (!top_frame_only && handler_bci < 0 && !skip_scope_increment) {
 689         sd = sd->sender();
 690         if (sd != NULL) {
 691           bci = sd->bci();
 692         }
 693         ++scope_depth;
 694       }
 695     } while (recursive_exception || (!top_frame_only && handler_bci < 0 && sd != NULL));
 696   }
 697 
 698   // found handling method => lookup exception handler
 699   int catch_pco = ret_pc - nm->code_begin();
 700 
 701   ExceptionHandlerTable table(nm);
 702   HandlerTableEntry *t = table.entry_for(catch_pco, handler_bci, scope_depth);
 703   if (t == NULL && (nm->is_compiled_by_c1() || handler_bci != -1)) {
 704     // Allow abbreviated catch tables.  The idea is to allow a method
 705     // to materialize its exceptions without committing to the exact
 706     // routing of exceptions.  In particular this is needed for adding
 707     // a synthethic handler to unlock monitors when inlining
 708     // synchonized methods since the unlock path isn't represented in
 709     // the bytecodes.
 710     t = table.entry_for(catch_pco, -1, 0);
 711   }
 712 
 713 #ifdef COMPILER1
 714   if (t == NULL && nm->is_compiled_by_c1()) {
 715     assert(nm->unwind_handler_begin() != NULL, "");