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