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 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); } }