Mercurial > hg > graal-jvmci-8
comparison src/share/vm/classfile/classFileParser.cpp @ 6213:8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
Summary: Change constMethodOop::_exception_table to optionally inlined u2 table.
Reviewed-by: bdelsart, coleenp, kamg
author | jiangli |
---|---|
date | Tue, 26 Jun 2012 19:08:44 -0400 |
parents | 71afdabfd05b |
children | e74da3c2b827 |
comparison
equal
deleted
inserted
replaced
6177:06320b1578cb | 6213:8150fa46d2ed |
---|---|
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) { |
1710 u2 max_stack = 0; | 1706 u2 max_stack = 0; |
1711 u2 max_locals = 0; | 1707 u2 max_locals = 0; |
1712 u4 code_length = 0; | 1708 u4 code_length = 0; |
1713 u1* code_start = 0; | 1709 u1* code_start = 0; |
1714 u2 exception_table_length = 0; | 1710 u2 exception_table_length = 0; |
1711 u2* exception_table_start = NULL; | |
1715 typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array()); | 1712 typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array()); |
1716 u2 checked_exceptions_length = 0; | 1713 u2 checked_exceptions_length = 0; |
1717 u2* checked_exceptions_start = NULL; | 1714 u2* checked_exceptions_start = NULL; |
1718 CompressedLineNumberWriteStream* linenumber_table = NULL; | 1715 CompressedLineNumberWriteStream* linenumber_table = NULL; |
1719 int linenumber_table_length = 0; | 1716 int linenumber_table_length = 0; |
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); |