--- old/src/share/vm/classfile/verifier.cpp 2012-06-19 17:55:58.348271570 -0700 +++ new/src/share/vm/classfile/verifier.cpp 2012-06-19 17:55:58.273022213 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1368,47 +1368,47 @@ } void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) { - typeArrayHandle exhandlers (THREAD, _method->exception_table()); + ExceptionTable exhandlers(_method()); constantPoolHandle cp (THREAD, _method->constants()); - if (exhandlers() != NULL) { - for(int i = 0; i < exhandlers->length();) { - u2 start_pc = exhandlers->int_at(i++); - u2 end_pc = exhandlers->int_at(i++); - u2 handler_pc = exhandlers->int_at(i++); - if (start_pc >= code_length || code_data[start_pc] == 0) { - class_format_error("Illegal exception table start_pc %d", start_pc); + for(int i = 0; i < exhandlers.length(); i++) { + //reacquire the table in case a GC happened + ExceptionTable exhandlers(_method()); + u2 start_pc = exhandlers.start_pc(i); + u2 end_pc = exhandlers.end_pc(i); + u2 handler_pc = exhandlers.handler_pc(i); + if (start_pc >= code_length || code_data[start_pc] == 0) { + class_format_error("Illegal exception table start_pc %d", start_pc); + return; + } + if (end_pc != code_length) { // special case: end_pc == code_length + if (end_pc > code_length || code_data[end_pc] == 0) { + class_format_error("Illegal exception table end_pc %d", end_pc); return; } - if (end_pc != code_length) { // special case: end_pc == code_length - if (end_pc > code_length || code_data[end_pc] == 0) { - class_format_error("Illegal exception table end_pc %d", end_pc); - return; - } - } - if (handler_pc >= code_length || code_data[handler_pc] == 0) { - class_format_error("Illegal exception table handler_pc %d", handler_pc); + } + if (handler_pc >= code_length || code_data[handler_pc] == 0) { + class_format_error("Illegal exception table handler_pc %d", handler_pc); + return; + } + int catch_type_index = exhandlers.catch_type_index(i); + if (catch_type_index != 0) { + VerificationType catch_type = cp_index_to_type( + catch_type_index, cp, CHECK_VERIFY(this)); + VerificationType throwable = + VerificationType::reference_type(vmSymbols::java_lang_Throwable()); + bool is_subclass = throwable.is_assignable_from( + catch_type, this, CHECK_VERIFY(this)); + if (!is_subclass) { + // 4286534: should throw VerifyError according to recent spec change + verify_error( + "Catch type is not a subclass of Throwable in handler %d", + handler_pc); return; } - int catch_type_index = exhandlers->int_at(i++); - if (catch_type_index != 0) { - VerificationType catch_type = cp_index_to_type( - catch_type_index, cp, CHECK_VERIFY(this)); - VerificationType throwable = - VerificationType::reference_type(vmSymbols::java_lang_Throwable()); - bool is_subclass = throwable.is_assignable_from( - catch_type, this, CHECK_VERIFY(this)); - if (!is_subclass) { - // 4286534: should throw VerifyError according to recent spec change - verify_error( - "Catch type is not a subclass of Throwable in handler %d", - handler_pc); - return; - } - } - if (start_pc < min) min = start_pc; - if (end_pc > max) max = end_pc; } + if (start_pc < min) min = start_pc; + if (end_pc > max) max = end_pc; } } @@ -1474,35 +1474,35 @@ void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame, StackMapTable* stackmap_table, TRAPS) { constantPoolHandle cp (THREAD, _method->constants()); - typeArrayHandle exhandlers (THREAD, _method->exception_table()); - if (exhandlers() != NULL) { - for(int i = 0; i < exhandlers->length();) { - u2 start_pc = exhandlers->int_at(i++); - u2 end_pc = exhandlers->int_at(i++); - u2 handler_pc = exhandlers->int_at(i++); - int catch_type_index = exhandlers->int_at(i++); - if(bci >= start_pc && bci < end_pc) { - u1 flags = current_frame->flags(); - if (this_uninit) { flags |= FLAG_THIS_UNINIT; } - StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); - if (catch_type_index != 0) { - // We know that this index refers to a subclass of Throwable - VerificationType catch_type = cp_index_to_type( - catch_type_index, cp, CHECK_VERIFY(this)); - new_frame->push_stack(catch_type, CHECK_VERIFY(this)); - } else { - VerificationType throwable = - VerificationType::reference_type(vmSymbols::java_lang_Throwable()); - new_frame->push_stack(throwable, CHECK_VERIFY(this)); - } - bool match = stackmap_table->match_stackmap( - new_frame, handler_pc, true, false, CHECK_VERIFY(this)); - if (!match) { - verify_error(bci, - "Stack map does not match the one at exception handler %d", - handler_pc); - return; - } + ExceptionTable exhandlers(_method()); + for(int i = 0; i < exhandlers.length(); i++) { + //reacquire the table in case a GC happened + ExceptionTable exhandlers(_method()); + u2 start_pc = exhandlers.start_pc(i); + u2 end_pc = exhandlers.end_pc(i); + u2 handler_pc = exhandlers.handler_pc(i); + int catch_type_index = exhandlers.catch_type_index(i); + if(bci >= start_pc && bci < end_pc) { + u1 flags = current_frame->flags(); + if (this_uninit) { flags |= FLAG_THIS_UNINIT; } + StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); + if (catch_type_index != 0) { + // We know that this index refers to a subclass of Throwable + VerificationType catch_type = cp_index_to_type( + catch_type_index, cp, CHECK_VERIFY(this)); + new_frame->push_stack(catch_type, CHECK_VERIFY(this)); + } else { + VerificationType throwable = + VerificationType::reference_type(vmSymbols::java_lang_Throwable()); + new_frame->push_stack(throwable, CHECK_VERIFY(this)); + } + bool match = stackmap_table->match_stackmap( + new_frame, handler_pc, true, false, CHECK_VERIFY(this)); + if (!match) { + verify_error(bci, + "Stack map does not match the one at exception handler %d", + handler_pc); + return; } } }