void Compilation::add_exception_handlers_for_pco(int pco, XHandlers* exception_handlers) { #ifndef PRODUCT if (PrintExceptionHandlers && Verbose) { tty->print_cr(" added exception scope for pco %d", pco); } #endif // Note: we do not have program counters for these exception handlers yet exception_info_list()->push(new ExceptionInfo(pco, exception_handlers)); }
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); } }
void Compilation::emit_code_epilog(LIR_Assembler* assembler) { CHECK_BAILOUT(); // generate code or slow cases assembler->emit_slow_case_stubs(); CHECK_BAILOUT(); // generate exception adapters assembler->emit_exception_entries(exception_info_list()); CHECK_BAILOUT(); // generate code for exception handler assembler->emit_exception_handler(); CHECK_BAILOUT(); assembler->emit_deopt_handler(); CHECK_BAILOUT(); // done masm()->flush(); }
void Compilation::emit_code_epilog(LIR_Assembler* assembler) { CHECK_BAILOUT(); CodeOffsets* code_offsets = assembler->offsets(); // generate code or slow cases assembler->emit_slow_case_stubs(); CHECK_BAILOUT(); // generate exception adapters assembler->emit_exception_entries(exception_info_list()); CHECK_BAILOUT(); // Generate code for exception handler. code_offsets->set_value(CodeOffsets::Exceptions, assembler->emit_exception_handler()); CHECK_BAILOUT(); // Generate code for deopt handler. code_offsets->set_value(CodeOffsets::Deopt, assembler->emit_deopt_handler()); CHECK_BAILOUT(); // Emit the MethodHandle deopt handler code (if required). if (has_method_handle_invokes()) { // We can use the same code as for the normal deopt handler, we // just need a different entry point address. code_offsets->set_value(CodeOffsets::DeoptMH, assembler->emit_deopt_handler()); CHECK_BAILOUT(); } // Emit the handler to remove the activation from the stack and // dispatch to the caller. offsets()->set_value(CodeOffsets::UnwindHandler, assembler->emit_unwind_handler()); // done masm()->flush(); }