hotspot/src/share/vm/classfile/classFileParser.cpp
changeset 13282 9872915dd78d
parent 12772 d317e5e08194
child 13286 b8b0898d5f3a
equal deleted inserted replaced
13102:7342fd50f8d7 13282:9872915dd78d
  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);