1282 *dest++ = Bytes::get_Java_u2((u1*) (src++)); |
1282 *dest++ = Bytes::get_Java_u2((u1*) (src++)); |
1283 } |
1283 } |
1284 } |
1284 } |
1285 |
1285 |
1286 |
1286 |
1287 typeArrayHandle ClassFileParser::parse_exception_table(u4 code_length, |
1287 u2* ClassFileParser::parse_exception_table(u4 code_length, |
1288 u4 exception_table_length, |
1288 u4 exception_table_length, |
1289 constantPoolHandle cp, |
1289 constantPoolHandle cp, |
1290 TRAPS) { |
1290 TRAPS) { |
1291 ClassFileStream* cfs = stream(); |
1291 ClassFileStream* cfs = stream(); |
1292 typeArrayHandle nullHandle; |
1292 |
1293 |
1293 u2* exception_table_start = cfs->get_u2_buffer(); |
1294 // 4-tuples of ints [start_pc, end_pc, handler_pc, catch_type index] |
1294 assert(exception_table_start != NULL, "null exception table"); |
1295 typeArrayOop eh = oopFactory::new_permanent_intArray(exception_table_length*4, CHECK_(nullHandle)); |
1295 cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc, end_pc, handler_pc, catch_type_index |
1296 typeArrayHandle exception_handlers = typeArrayHandle(THREAD, eh); |
1296 // Will check legal target after parsing code array in verifier. |
1297 |
1297 if (_need_verify) { |
1298 int index = 0; |
1298 for (unsigned int i = 0; i < exception_table_length; i++) { |
1299 cfs->guarantee_more(8 * exception_table_length, CHECK_(nullHandle)); // start_pc, end_pc, handler_pc, catch_type_index |
1299 u2 start_pc = cfs->get_u2_fast(); |
1300 for (unsigned int i = 0; i < exception_table_length; i++) { |
1300 u2 end_pc = cfs->get_u2_fast(); |
1301 u2 start_pc = cfs->get_u2_fast(); |
1301 u2 handler_pc = cfs->get_u2_fast(); |
1302 u2 end_pc = cfs->get_u2_fast(); |
1302 u2 catch_type_index = cfs->get_u2_fast(); |
1303 u2 handler_pc = cfs->get_u2_fast(); |
|
1304 u2 catch_type_index = cfs->get_u2_fast(); |
|
1305 // Will check legal target after parsing code array in verifier. |
|
1306 if (_need_verify) { |
|
1307 guarantee_property((start_pc < end_pc) && (end_pc <= code_length), |
1303 guarantee_property((start_pc < end_pc) && (end_pc <= code_length), |
1308 "Illegal exception table range in class file %s", CHECK_(nullHandle)); |
1304 "Illegal exception table range in class file %s", |
|
1305 CHECK_NULL); |
1309 guarantee_property(handler_pc < code_length, |
1306 guarantee_property(handler_pc < code_length, |
1310 "Illegal exception table handler in class file %s", CHECK_(nullHandle)); |
1307 "Illegal exception table handler in class file %s", |
|
1308 CHECK_NULL); |
1311 if (catch_type_index != 0) { |
1309 if (catch_type_index != 0) { |
1312 guarantee_property(valid_cp_range(catch_type_index, cp->length()) && |
1310 guarantee_property(valid_cp_range(catch_type_index, cp->length()) && |
1313 is_klass_reference(cp, catch_type_index), |
1311 is_klass_reference(cp, catch_type_index), |
1314 "Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle)); |
1312 "Catch type in exception table has bad constant type in class file %s", CHECK_NULL); |
1315 } |
1313 } |
1316 } |
1314 } |
1317 exception_handlers->int_at_put(index++, start_pc); |
1315 } else { |
1318 exception_handlers->int_at_put(index++, end_pc); |
1316 cfs->skip_u2_fast(exception_table_length * 4); |
1319 exception_handlers->int_at_put(index++, handler_pc); |
1317 } |
1320 exception_handlers->int_at_put(index++, catch_type_index); |
1318 return exception_table_start; |
1321 } |
|
1322 return exception_handlers; |
|
1323 } |
1319 } |
1324 |
1320 |
1325 void ClassFileParser::parse_linenumber_table( |
1321 void ClassFileParser::parse_linenumber_table( |
1326 u4 code_attribute_length, u4 code_length, |
1322 u4 code_attribute_length, u4 code_length, |
1327 CompressedLineNumberWriteStream** write_stream, TRAPS) { |
1323 CompressedLineNumberWriteStream** write_stream, TRAPS) { |
1796 |
1793 |
1797 // Exception handler table |
1794 // Exception handler table |
1798 cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length |
1795 cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length |
1799 exception_table_length = cfs->get_u2_fast(); |
1796 exception_table_length = cfs->get_u2_fast(); |
1800 if (exception_table_length > 0) { |
1797 if (exception_table_length > 0) { |
1801 exception_handlers = |
1798 exception_table_start = |
1802 parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle)); |
1799 parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle)); |
1803 } |
1800 } |
1804 |
1801 |
1805 // Parse additional attributes in code attribute |
1802 // Parse additional attributes in code attribute |
1806 cfs->guarantee_more(2, CHECK_(nullHandle)); // code_attributes_count |
1803 cfs->guarantee_more(2, CHECK_(nullHandle)); // code_attributes_count |
2000 guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute, |
1997 guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute, |
2001 "Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle)); |
1998 "Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle)); |
2002 } |
1999 } |
2003 |
2000 |
2004 // All sizing information for a methodOop is finally available, now create it |
2001 // All sizing information for a methodOop is finally available, now create it |
2005 methodOop m_oop = oopFactory::new_method(code_length, access_flags, linenumber_table_length, |
2002 methodOop m_oop = oopFactory::new_method(code_length, access_flags, |
2006 total_lvt_length, checked_exceptions_length, |
2003 linenumber_table_length, |
2007 oopDesc::IsSafeConc, CHECK_(nullHandle)); |
2004 total_lvt_length, |
|
2005 exception_table_length, |
|
2006 checked_exceptions_length, |
|
2007 oopDesc::IsSafeConc, |
|
2008 CHECK_(nullHandle)); |
2008 methodHandle m (THREAD, m_oop); |
2009 methodHandle m (THREAD, m_oop); |
2009 |
2010 |
2010 ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize); |
2011 ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize); |
2011 |
2012 |
2012 // Fill in information from fixed part (access_flags already set) |
2013 // Fill in information from fixed part (access_flags already set) |
2033 #endif |
2034 #endif |
2034 |
2035 |
2035 // Fill in code attribute information |
2036 // Fill in code attribute information |
2036 m->set_max_stack(max_stack); |
2037 m->set_max_stack(max_stack); |
2037 m->set_max_locals(max_locals); |
2038 m->set_max_locals(max_locals); |
2038 m->constMethod()->set_stackmap_data(stackmap_data()); |
|
2039 |
2039 |
2040 /** |
2040 /** |
2041 * The exception_table field is the flag used to indicate |
2041 * The stackmap_data field is the flag used to indicate |
2042 * that the methodOop and it's associated constMethodOop are partially |
2042 * that the methodOop and it's associated constMethodOop are partially |
2043 * initialized and thus are exempt from pre/post GC verification. Once |
2043 * initialized and thus are exempt from pre/post GC verification. Once |
2044 * the field is set, the oops are considered fully initialized so make |
2044 * the field is set, the oops are considered fully initialized so make |
2045 * sure that the oops can pass verification when this field is set. |
2045 * sure that the oops can pass verification when this field is set. |
2046 */ |
2046 */ |
2047 m->set_exception_table(exception_handlers()); |
2047 m->constMethod()->set_stackmap_data(stackmap_data()); |
2048 |
2048 |
2049 // Copy byte codes |
2049 // Copy byte codes |
2050 m->set_code(code_start); |
2050 m->set_code(code_start); |
2051 |
2051 |
2052 // Copy line number table |
2052 // Copy line number table |
2053 if (linenumber_table != NULL) { |
2053 if (linenumber_table != NULL) { |
2054 memcpy(m->compressed_linenumber_table(), |
2054 memcpy(m->compressed_linenumber_table(), |
2055 linenumber_table->buffer(), linenumber_table_length); |
2055 linenumber_table->buffer(), linenumber_table_length); |
|
2056 } |
|
2057 |
|
2058 // Copy exception table |
|
2059 if (exception_table_length > 0) { |
|
2060 int size = |
|
2061 exception_table_length * sizeof(ExceptionTableElement) / sizeof(u2); |
|
2062 copy_u2_with_conversion((u2*) m->exception_table_start(), |
|
2063 exception_table_start, size); |
2056 } |
2064 } |
2057 |
2065 |
2058 // Copy checked exceptions |
2066 // Copy checked exceptions |
2059 if (checked_exceptions_length > 0) { |
2067 if (checked_exceptions_length > 0) { |
2060 int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); |
2068 int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); |