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