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