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, "");
|