src/share/vm/classfile/stackMapFrame.cpp

changeset 2585
c1a6154012c8
parent 2497
3582bf76420e
child 2708
1d1603768966
child 2754
7144a1d6e0a9
     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) {

mercurial