785 ciExceptionHandlerStream handlers(method(), bci(), 786 ex_type->klass()->as_instance_klass(), 787 ex_type->klass_is_exact()); 788 789 // Start executing from the given throw state. (Keep its stack, for now.) 790 // Get the exception oop as known at compile time. 791 ex_node = use_exception_state(ex_map); 792 793 // Get the exception oop klass from its header 794 Node* ex_klass_node = NULL; 795 if (has_ex_handler() && !ex_type->klass_is_exact()) { 796 Node* p = basic_plus_adr( ex_node, ex_node, oopDesc::klass_offset_in_bytes()); 797 ex_klass_node = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) ); 798 799 // Compute the exception klass a little more cleverly. 800 // Obvious solution is to simple do a LoadKlass from the 'ex_node'. 801 // However, if the ex_node is a PhiNode, I'm going to do a LoadKlass for 802 // each arm of the Phi. If I know something clever about the exceptions 803 // I'm loading the class from, I can replace the LoadKlass with the 804 // klass constant for the exception oop. 805 if( ex_node->is_Phi() ) { 806 ex_klass_node = new PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT ); 807 for( uint i = 1; i < ex_node->req(); i++ ) { 808 Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() ); 809 Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) ); 810 ex_klass_node->init_req( i, k ); 811 } 812 _gvn.set_type(ex_klass_node, TypeKlassPtr::OBJECT); 813 814 } 815 } 816 817 // Scan the exception table for applicable handlers. 818 // If none, we can call rethrow() and be done! 819 // If precise (loaded with no subklasses), insert a D.S. style 820 // pointer compare to the correct handler and loop back. 821 // If imprecise, switch to the Rethrow VM-call style handling. 822 823 int remaining = handlers.count_remaining(); 824 825 // iterate through all entries sequentially 826 for (;!handlers.is_done(); handlers.next()) { 827 ciExceptionHandler* handler = handlers.handler(); 828 | 785 ciExceptionHandlerStream handlers(method(), bci(), 786 ex_type->klass()->as_instance_klass(), 787 ex_type->klass_is_exact()); 788 789 // Start executing from the given throw state. (Keep its stack, for now.) 790 // Get the exception oop as known at compile time. 791 ex_node = use_exception_state(ex_map); 792 793 // Get the exception oop klass from its header 794 Node* ex_klass_node = NULL; 795 if (has_ex_handler() && !ex_type->klass_is_exact()) { 796 Node* p = basic_plus_adr( ex_node, ex_node, oopDesc::klass_offset_in_bytes()); 797 ex_klass_node = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) ); 798 799 // Compute the exception klass a little more cleverly. 800 // Obvious solution is to simple do a LoadKlass from the 'ex_node'. 801 // However, if the ex_node is a PhiNode, I'm going to do a LoadKlass for 802 // each arm of the Phi. If I know something clever about the exceptions 803 // I'm loading the class from, I can replace the LoadKlass with the 804 // klass constant for the exception oop. 805 if (ex_node->is_Phi()) { 806 ex_klass_node = new PhiNode(ex_node->in(0), TypeKlassPtr::OBJECT); 807 for (uint i = 1; i < ex_node->req(); i++) { 808 Node* ex_in = ex_node->in(i); 809 if (ex_in == top() || ex_in == NULL) { 810 // This path was not taken. 811 ex_klass_node->init_req(i, top()); 812 continue; 813 } 814 Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes()); 815 Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) ); 816 ex_klass_node->init_req( i, k ); 817 } 818 _gvn.set_type(ex_klass_node, TypeKlassPtr::OBJECT); 819 820 } 821 } 822 823 // Scan the exception table for applicable handlers. 824 // If none, we can call rethrow() and be done! 825 // If precise (loaded with no subklasses), insert a D.S. style 826 // pointer compare to the correct handler and loop back. 827 // If imprecise, switch to the Rethrow VM-call style handling. 828 829 int remaining = handlers.count_remaining(); 830 831 // iterate through all entries sequentially 832 for (;!handlers.is_done(); handlers.next()) { 833 ciExceptionHandler* handler = handlers.handler(); 834 |