1.1 --- a/src/share/vm/classfile/stackMapFrame.cpp Mon Feb 28 14:19:52 2011 +0100 1.2 +++ b/src/share/vm/classfile/stackMapFrame.cpp Mon Feb 28 16:01:59 2011 -0500 1.3 @@ -170,6 +170,44 @@ 1.4 return true; 1.5 } 1.6 1.7 +bool StackMapFrame::has_flag_match_exception( 1.8 + const StackMapFrame* target) const { 1.9 + // We allow flags of {UninitThis} to assign to {} if-and-only-if the 1.10 + // target frame does not depend upon the current type. 1.11 + // This is slightly too strict, as we need only enforce that the 1.12 + // slots that were initialized by the <init> (the things that were 1.13 + // UninitializedThis before initialize_object() converted them) are unused. 1.14 + // However we didn't save that information so we'll enforce this upon 1.15 + // anything that might have been initialized. This is a rare situation 1.16 + // and javac never generates code that would end up here, but some profilers 1.17 + // (such as NetBeans) might, when adding exception handlers in <init> 1.18 + // methods to cover the invokespecial instruction. See 7020118. 1.19 + 1.20 + assert(max_locals() == target->max_locals() && 1.21 + stack_size() == target->stack_size(), "StackMap sizes must match"); 1.22 + 1.23 + VerificationType top = VerificationType::top_type(); 1.24 + VerificationType this_type = verifier()->current_type(); 1.25 + 1.26 + if (!flag_this_uninit() || target->flags() != 0) { 1.27 + return false; 1.28 + } 1.29 + 1.30 + for (int i = 0; i < target->locals_size(); ++i) { 1.31 + if (locals()[i] == this_type && target->locals()[i] != top) { 1.32 + return false; 1.33 + } 1.34 + } 1.35 + 1.36 + for (int i = 0; i < target->stack_size(); ++i) { 1.37 + if (stack()[i] == this_type && target->stack()[i] != top) { 1.38 + return false; 1.39 + } 1.40 + } 1.41 + 1.42 + return true; 1.43 +} 1.44 + 1.45 bool StackMapFrame::is_assignable_to(const StackMapFrame* target, TRAPS) const { 1.46 if (_max_locals != target->max_locals() || _stack_size != target->stack_size()) { 1.47 return false; 1.48 @@ -182,7 +220,9 @@ 1.49 bool match_stack = is_assignable_to( 1.50 _stack, target->stack(), _stack_size, CHECK_false); 1.51 bool match_flags = (_flags | target->flags()) == target->flags(); 1.52 - return (match_locals && match_stack && match_flags); 1.53 + 1.54 + return match_locals && match_stack && 1.55 + (match_flags || has_flag_match_exception(target)); 1.56 } 1.57 1.58 VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) {