void LIR_Assembler::emit_exception_entries(ExceptionInfoList* info_list) { for (int i = 0; i < info_list->length(); i++) { XHandlers* handlers = info_list->at(i)->exception_handlers(); for (int j = 0; j < handlers->length(); j++) { XHandler* handler = handlers->handler_at(j); assert(handler->lir_op_id() != -1, "handler not processed by LinearScan"); assert(handler->entry_code() == NULL || handler->entry_code()->instructions_list()->last()->code() == lir_branch || handler->entry_code()->instructions_list()->last()->code() == lir_delay_slot, "last operation must be branch"); if (handler->entry_pco() == -1) { // entry code not emitted yet if (handler->entry_code() != NULL && handler->entry_code()->instructions_list()->length() > 1) { handler->set_entry_pco(code_offset()); if (CommentedAssembly) { _masm->block_comment("Exception adapter block"); } emit_lir_list(handler->entry_code()); } else { handler->set_entry_pco(handler->entry_block()->exception_handler_pco()); } assert(handler->entry_pco() != -1, "must be set now"); } } } }
void FpuStackAllocator::compute_debug_information(LIR_Op* op) { if (!_debug_information_computed && op->id() != -1 && allocator()->has_info(op->id())) { visitor.visit(op); // exception handling if (allocator()->compilation()->has_exception_handlers()) { XHandlers* xhandlers = visitor.all_xhandler(); int n = xhandlers->length(); for (int k = 0; k < n; k++) { allocate_exception_handler(xhandlers->handler_at(k)); } } else { assert(visitor.all_xhandler()->length() == 0, "missed exception handler"); } // compute debug information int n = visitor.info_count(); assert(n > 0, "should not visit operation otherwise"); for (int j = 0; j < n; j++) { CodeEmitInfo* info = visitor.info_at(j); // Compute debug information allocator()->compute_debug_info(info, op->id()); } } _debug_information_computed = true; }
bool LIR_OopMapGenerator::exception_handler_covers(CodeEmitInfo* info, BlockBegin* handler) { int bci = info->bci(); for (IRScope* scope = info->scope(); scope != NULL; bci = scope->caller_bci(), scope = scope->caller()) { if (scope == handler->scope()) { XHandlers* xh = scope->xhandlers(); for (int i = 0; i < xh->number_of_handlers(); i++) { if (xh->handler_at(i)->handler_bci() == handler->bci()) { if (xh->handler_at(i)->covers(bci)) { #ifndef PRODUCT if (TraceLIROopMaps) { tty->print_cr(" Found exception handler: block %d", handler->block_id()); } #endif return true; } } } } } #ifndef PRODUCT if (TraceLIROopMaps) { tty->print_cr(" No exception handler found"); } #endif return false; }
void LIR_Assembler::emit_exception_entries(ExceptionInfoList* info_list) { // tell these to the MacroAssembler for (int i = 0; i < info_list->length(); i++) { XHandlers* handlers = info_list->at(i)->exception_handlers(); for (int j = 0; j < handlers->length(); j++) { XHandler* handler = handlers->handler_at(j); assert(handler->lir_op_id() != -1, "handler not processed by LinearScan"); assert(handler->entry_code() == NULL || handler->entry_code()->instructions_list()->last()->code()==lir_branch,"last operation must be branch"); if (!handler->entry_lbl()) { // entry code not emitted yet if (handler->entry_code() != NULL && handler->entry_code()->instructions_list()->length() > 1) { handler->set_entry_lbl(new Label(_masm)); // bind label here _masm->block_comment("Exception adapter block"); emit_lir_list(handler->entry_code()); } else { handler->set_entry_lbl(handler->entry_block()->label()); } } } } }
void Compilation::generate_exception_handler_table() { // Generate an ExceptionHandlerTable from the exception handler // information accumulated during the compilation. ExceptionInfoList* info_list = exception_info_list(); if (info_list->length() == 0) { return; } // allocate some arrays for use by the collection code. const int num_handlers = 5; GrowableArray<intptr_t>* bcis = new GrowableArray<intptr_t>(num_handlers); GrowableArray<intptr_t>* scope_depths = new GrowableArray<intptr_t>(num_handlers); GrowableArray<intptr_t>* pcos = new GrowableArray<intptr_t>(num_handlers); for (int i = 0; i < info_list->length(); i++) { ExceptionInfo* info = info_list->at(i); XHandlers* handlers = info->exception_handlers(); // empty the arrays bcis->trunc_to(0); scope_depths->trunc_to(0); pcos->trunc_to(0); for (int i = 0; i < handlers->length(); i++) { XHandler* handler = handlers->handler_at(i); assert(handler->entry_pco() != -1, "must have been generated"); int e = bcis->find(handler->handler_bci()); if (e >= 0 && scope_depths->at(e) == handler->scope_count()) { // two different handlers are declared to dispatch to the same // catch bci. During parsing we created edges for each // handler but we really only need one. The exception handler // table will also get unhappy if we try to declare both since // it's nonsensical. Just skip this handler. continue; } bcis->append(handler->handler_bci()); if (handler->handler_bci() == -1) { // insert a wildcard handler at scope depth 0 so that the // exception lookup logic with find it. scope_depths->append(0); } else { scope_depths->append(handler->scope_count()); } pcos->append(handler->entry_pco()); // stop processing once we hit a catch any if (handler->is_catch_all()) { assert(i == handlers->length() - 1, "catch all must be last handler"); } } exception_handler_table()->add_subtable(info->pco(), bcis, scope_depths, pcos); } }