src/share/vm/classfile/classFileParser.cpp

Print this page

        

*** 1244,1289 **** *dest++ = Bytes::get_Java_u2((u1*) (src++)); } } ! typeArrayHandle ClassFileParser::parse_exception_table(u4 code_length, u4 exception_table_length, constantPoolHandle cp, TRAPS) { ClassFileStream* cfs = stream(); - typeArrayHandle nullHandle; - - // 4-tuples of ints [start_pc, end_pc, handler_pc, catch_type index] - typeArrayOop eh = oopFactory::new_permanent_intArray(exception_table_length*4, CHECK_(nullHandle)); - typeArrayHandle exception_handlers = typeArrayHandle(THREAD, eh); ! int index = 0; ! cfs->guarantee_more(8 * exception_table_length, CHECK_(nullHandle)); // start_pc, end_pc, handler_pc, catch_type_index for (unsigned int i = 0; i < exception_table_length; i++) { u2 start_pc = cfs->get_u2_fast(); u2 end_pc = cfs->get_u2_fast(); u2 handler_pc = cfs->get_u2_fast(); u2 catch_type_index = cfs->get_u2_fast(); - // Will check legal target after parsing code array in verifier. - if (_need_verify) { guarantee_property((start_pc < end_pc) && (end_pc <= code_length), ! "Illegal exception table range in class file %s", CHECK_(nullHandle)); guarantee_property(handler_pc < code_length, ! "Illegal exception table handler in class file %s", CHECK_(nullHandle)); if (catch_type_index != 0) { guarantee_property(valid_cp_range(catch_type_index, cp->length()) && is_klass_reference(cp, catch_type_index), ! "Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle)); } } ! exception_handlers->int_at_put(index++, start_pc); ! exception_handlers->int_at_put(index++, end_pc); ! exception_handlers->int_at_put(index++, handler_pc); ! exception_handlers->int_at_put(index++, catch_type_index); } ! return exception_handlers; } void ClassFileParser::parse_linenumber_table( u4 code_attribute_length, u4 code_length, CompressedLineNumberWriteStream** write_stream, TRAPS) { --- 1244,1285 ---- *dest++ = Bytes::get_Java_u2((u1*) (src++)); } } ! u2* ClassFileParser::parse_exception_table(u4 code_length, u4 exception_table_length, constantPoolHandle cp, TRAPS) { ClassFileStream* cfs = stream(); ! u2* exception_table_start = cfs->get_u2_buffer(); ! assert(exception_table_start != NULL, "null exception table"); ! cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc, end_pc, handler_pc, catch_type_index ! // Will check legal target after parsing code array in verifier. ! if (_need_verify) { for (unsigned int i = 0; i < exception_table_length; i++) { u2 start_pc = cfs->get_u2_fast(); u2 end_pc = cfs->get_u2_fast(); u2 handler_pc = cfs->get_u2_fast(); u2 catch_type_index = cfs->get_u2_fast(); guarantee_property((start_pc < end_pc) && (end_pc <= code_length), ! "Illegal exception table range in class file %s", ! CHECK_NULL); guarantee_property(handler_pc < code_length, ! "Illegal exception table handler in class file %s", ! CHECK_NULL); if (catch_type_index != 0) { guarantee_property(valid_cp_range(catch_type_index, cp->length()) && is_klass_reference(cp, catch_type_index), ! "Catch type in exception table has bad constant type in class file %s", CHECK_NULL); } } ! } else { ! cfs->skip_u2_fast(exception_table_length * 4); } ! return exception_table_start; } void ClassFileParser::parse_linenumber_table( u4 code_attribute_length, u4 code_length, CompressedLineNumberWriteStream** write_stream, TRAPS) {
*** 1672,1681 **** --- 1668,1678 ---- u2 max_stack = 0; u2 max_locals = 0; u4 code_length = 0; u1* code_start = 0; u2 exception_table_length = 0; + u2* exception_table_start = NULL; typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array()); u2 checked_exceptions_length = 0; u2* checked_exceptions_start = NULL; CompressedLineNumberWriteStream* linenumber_table = NULL; int linenumber_table_length = 0;
*** 1758,1768 **** // Exception handler table cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length exception_table_length = cfs->get_u2_fast(); if (exception_table_length > 0) { ! exception_handlers = parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle)); } // Parse additional attributes in code attribute cfs->guarantee_more(2, CHECK_(nullHandle)); // code_attributes_count --- 1755,1765 ---- // Exception handler table cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length exception_table_length = cfs->get_u2_fast(); if (exception_table_length > 0) { ! exception_table_start = parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle)); } // Parse additional attributes in code attribute cfs->guarantee_more(2, CHECK_(nullHandle)); // code_attributes_count
*** 1962,1974 **** guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute, "Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle)); } // All sizing information for a methodOop is finally available, now create it ! methodOop m_oop = oopFactory::new_method(code_length, access_flags, linenumber_table_length, ! total_lvt_length, checked_exceptions_length, ! oopDesc::IsSafeConc, CHECK_(nullHandle)); methodHandle m (THREAD, m_oop); ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize); // Fill in information from fixed part (access_flags already set) --- 1959,1975 ---- guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute, "Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle)); } // All sizing information for a methodOop is finally available, now create it ! methodOop m_oop = oopFactory::new_method(code_length, access_flags, ! linenumber_table_length, ! total_lvt_length, ! exception_table_length, ! checked_exceptions_length, ! oopDesc::IsSafeConc, ! CHECK_(nullHandle)); methodHandle m (THREAD, m_oop); ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize); // Fill in information from fixed part (access_flags already set)
*** 1995,2024 **** #endif // Fill in code attribute information m->set_max_stack(max_stack); m->set_max_locals(max_locals); - m->constMethod()->set_stackmap_data(stackmap_data()); /** ! * The exception_table field is the flag used to indicate * that the methodOop and it's associated constMethodOop are partially * initialized and thus are exempt from pre/post GC verification. Once * the field is set, the oops are considered fully initialized so make * sure that the oops can pass verification when this field is set. */ ! m->set_exception_table(exception_handlers()); // Copy byte codes m->set_code(code_start); // Copy line number table if (linenumber_table != NULL) { memcpy(m->compressed_linenumber_table(), linenumber_table->buffer(), linenumber_table_length); } // Copy checked exceptions if (checked_exceptions_length > 0) { int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); copy_u2_with_conversion((u2*) m->checked_exceptions_start(), checked_exceptions_start, size); } --- 1996,2032 ---- #endif // Fill in code attribute information m->set_max_stack(max_stack); m->set_max_locals(max_locals); /** ! * The stackmap_data field is the flag used to indicate * that the methodOop and it's associated constMethodOop are partially * initialized and thus are exempt from pre/post GC verification. Once * the field is set, the oops are considered fully initialized so make * sure that the oops can pass verification when this field is set. */ ! m->constMethod()->set_stackmap_data(stackmap_data()); // Copy byte codes m->set_code(code_start); // Copy line number table if (linenumber_table != NULL) { memcpy(m->compressed_linenumber_table(), linenumber_table->buffer(), linenumber_table_length); } + // Copy exception table + if (exception_table_length > 0) { + int size = + exception_table_length * sizeof(ExceptionTableElement) / sizeof(u2); + copy_u2_with_conversion((u2*) m->exception_table_start(), + exception_table_start, size); + } + // Copy checked exceptions if (checked_exceptions_length > 0) { int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); copy_u2_with_conversion((u2*) m->checked_exceptions_start(), checked_exceptions_start, size); }