8011311: Private interface methods. Default conflicts:ICCE. no erased_super_default.

Tue, 01 Oct 2013 08:10:42 -0400

author
acorn
date
Tue, 01 Oct 2013 08:10:42 -0400
changeset 5786
36b97be47bde
parent 5785
a5ac0873476c
child 5789
31f0118ea584
child 5825
5b3b75d9eb2f

8011311: Private interface methods. Default conflicts:ICCE. no erased_super_default.
Reviewed-by: coleenp, bharadwaj, minqi

src/share/vm/classfile/classFileParser.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/defaultMethods.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/defaultMethods.hpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/linkResolver.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/instanceKlass.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/klassVtable.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/classfile/classFileParser.cpp	Fri Sep 27 10:08:56 2013 -0400
     1.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Tue Oct 01 08:10:42 2013 -0400
     1.3 @@ -2545,7 +2545,9 @@
     1.4        if (method->is_final()) {
     1.5          *has_final_method = true;
     1.6        }
     1.7 -      if (is_interface && !method->is_abstract() && !method->is_static()) {
     1.8 +      if (is_interface && !(*has_default_methods)
     1.9 +        && !method->is_abstract() && !method->is_static()
    1.10 +        && !method->is_private()) {
    1.11          // default method
    1.12          *has_default_methods = true;
    1.13        }
     2.1 --- a/src/share/vm/classfile/defaultMethods.cpp	Fri Sep 27 10:08:56 2013 -0400
     2.2 +++ b/src/share/vm/classfile/defaultMethods.cpp	Tue Oct 01 08:10:42 2013 -0400
     2.3 @@ -325,6 +325,7 @@
     2.4  
     2.5    Method* _selected_target;  // Filled in later, if a unique target exists
     2.6    Symbol* _exception_message; // If no unique target is found
     2.7 +  Symbol* _exception_name;    // If no unique target is found
     2.8  
     2.9    bool contains_method(Method* method) {
    2.10      int* lookup = _member_index.get(method);
    2.11 @@ -350,7 +351,7 @@
    2.12   public:
    2.13  
    2.14    MethodFamily()
    2.15 -      : _selected_target(NULL), _exception_message(NULL) {}
    2.16 +      : _selected_target(NULL), _exception_message(NULL), _exception_name(NULL) {}
    2.17  
    2.18    void set_target_if_empty(Method* m) {
    2.19      if (_selected_target == NULL && !m->is_overpass()) {
    2.20 @@ -383,6 +384,7 @@
    2.21  
    2.22    Method* get_selected_target() { return _selected_target; }
    2.23    Symbol* get_exception_message() { return _exception_message; }
    2.24 +  Symbol* get_exception_name() { return _exception_name; }
    2.25  
    2.26    // Either sets the target or the exception error message
    2.27    void determine_target(InstanceKlass* root, TRAPS) {
    2.28 @@ -400,15 +402,18 @@
    2.29  
    2.30      if (qualified_methods.length() == 0) {
    2.31        _exception_message = generate_no_defaults_message(CHECK);
    2.32 +      _exception_name = vmSymbols::java_lang_AbstractMethodError();
    2.33      } else if (qualified_methods.length() == 1) {
    2.34        Method* method = qualified_methods.at(0);
    2.35        if (method->is_abstract()) {
    2.36          _exception_message = generate_abstract_method_message(method, CHECK);
    2.37 +        _exception_name = vmSymbols::java_lang_AbstractMethodError();
    2.38        } else {
    2.39          _selected_target = qualified_methods.at(0);
    2.40        }
    2.41      } else {
    2.42        _exception_message = generate_conflicts_message(&qualified_methods,CHECK);
    2.43 +      _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError();
    2.44      }
    2.45  
    2.46      assert((has_target() ^ throws_exception()) == 1,
    2.47 @@ -459,8 +464,9 @@
    2.48  
    2.49    void print_exception(outputStream* str, int indent) {
    2.50      assert(throws_exception(), "Should be called otherwise");
    2.51 +    assert(_exception_name != NULL, "exception_name should be set");
    2.52      streamIndentor si(str, indent * 2);
    2.53 -    str->indent().print_cr("%s", _exception_message->as_C_string());
    2.54 +    str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string());
    2.55    }
    2.56  #endif // ndef PRODUCT
    2.57  };
    2.58 @@ -670,7 +676,10 @@
    2.59      InstanceKlass* iklass = current_class();
    2.60  
    2.61      Method* m = iklass->find_method(_method_name, _method_signature);
    2.62 -    if (m != NULL) {
    2.63 +    // private interface methods are not candidates for default methods
    2.64 +    // invokespecial to private interface methods doesn't use default method logic
    2.65 +    // future: take access controls into account for superclass methods
    2.66 +    if (m != NULL && (!iklass->is_interface() || m->is_public())) {
    2.67        if (_family == NULL) {
    2.68          _family = new StatefulMethodFamily();
    2.69        }
    2.70 @@ -782,200 +791,7 @@
    2.71  #endif // ndef PRODUCT
    2.72  }
    2.73  
    2.74 -/**
    2.75 - * Interface inheritance rules were used to find a unique default method
    2.76 - * candidate for the resolved class. This
    2.77 - * method is only viable if it would also be in the set of default method
    2.78 - * candidates if we ran a full analysis on the current class.
    2.79 - *
    2.80 - * The only reason that the method would not be in the set of candidates for
    2.81 - * the current class is if that there's another matching method
    2.82 - * which is "more specific" than the found method -- i.e., one could find a
    2.83 - * path in the interface hierarchy in which the matching method appears
    2.84 - * before we get to '_target'.
    2.85 - *
    2.86 - * In order to determine this, we examine all of the implemented
    2.87 - * interfaces.  If we find path that leads to the '_target' interface, then
    2.88 - * we examine that path to see if there are any methods that would shadow
    2.89 - * the selected method along that path.
    2.90 - */
    2.91 -class ShadowChecker : public HierarchyVisitor<ShadowChecker> {
    2.92 - protected:
    2.93 -  Thread* THREAD;
    2.94  
    2.95 -  InstanceKlass* _target;
    2.96 -
    2.97 -  Symbol* _method_name;
    2.98 -  InstanceKlass* _method_holder;
    2.99 -  bool _found_shadow;
   2.100 -
   2.101 -
   2.102 - public:
   2.103 -
   2.104 -  ShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder,
   2.105 -                InstanceKlass* target)
   2.106 -                : THREAD(thread), _method_name(name), _method_holder(holder),
   2.107 -                _target(target), _found_shadow(false) {}
   2.108 -
   2.109 -  void* new_node_data(InstanceKlass* cls) { return NULL; }
   2.110 -  void free_node_data(void* data) { return; }
   2.111 -
   2.112 -  bool visit() {
   2.113 -    InstanceKlass* ik = current_class();
   2.114 -    if (ik == _target && current_depth() == 1) {
   2.115 -      return false; // This was the specified super -- no need to search it
   2.116 -    }
   2.117 -    if (ik == _method_holder || ik == _target) {
   2.118 -      // We found a path that should be examined to see if it shadows _method
   2.119 -      if (path_has_shadow()) {
   2.120 -        _found_shadow = true;
   2.121 -        cancel_iteration();
   2.122 -      }
   2.123 -      return false; // no need to continue up hierarchy
   2.124 -    }
   2.125 -    return true;
   2.126 -  }
   2.127 -
   2.128 -  virtual bool path_has_shadow() = 0;
   2.129 -  bool found_shadow() { return _found_shadow; }
   2.130 -};
   2.131 -
   2.132 -// Used for Invokespecial.
   2.133 -// Invokespecial is allowed to invoke a concrete interface method
   2.134 -// and can be used to disambuiguate among qualified candidates,
   2.135 -// which are methods in immediate superinterfaces,
   2.136 -// but may not be used to invoke a candidate that would be shadowed
   2.137 -// from the perspective of the caller.
   2.138 -// Invokespecial is also used in the overpass generation today
   2.139 -// We re-run the shadowchecker because we can't distinguish this case,
   2.140 -// but it should return the same answer, since the overpass target
   2.141 -// is now the invokespecial caller.
   2.142 -class ErasedShadowChecker : public ShadowChecker {
   2.143 - private:
   2.144 -  bool path_has_shadow() {
   2.145 -
   2.146 -    for (int i = current_depth() - 1; i > 0; --i) {
   2.147 -      InstanceKlass* ik = class_at_depth(i);
   2.148 -
   2.149 -      if (ik->is_interface()) {
   2.150 -        int end;
   2.151 -        int start = ik->find_method_by_name(_method_name, &end);
   2.152 -        if (start != -1) {
   2.153 -          return true;
   2.154 -        }
   2.155 -      }
   2.156 -    }
   2.157 -    return false;
   2.158 -  }
   2.159 - public:
   2.160 -
   2.161 -  ErasedShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder,
   2.162 -                InstanceKlass* target)
   2.163 -    : ShadowChecker(thread, name, holder, target) {}
   2.164 -};
   2.165 -
   2.166 -// Find the unique qualified candidate from the perspective of the super_class
   2.167 -// which is the resolved_klass, which must be an immediate superinterface
   2.168 -// of klass
   2.169 -Method* find_erased_super_default(InstanceKlass* current_class, InstanceKlass* super_class, Symbol* method_name, Symbol* sig, TRAPS) {
   2.170 -
   2.171 -  FindMethodsByErasedSig visitor(method_name, sig);
   2.172 -  visitor.run(super_class);      // find candidates from resolved_klass
   2.173 -
   2.174 -  MethodFamily* family;
   2.175 -  visitor.get_discovered_family(&family);
   2.176 -
   2.177 -  if (family != NULL) {
   2.178 -    family->determine_target(current_class, CHECK_NULL);  // get target from current_class
   2.179 -
   2.180 -    if (family->has_target()) {
   2.181 -      Method* target = family->get_selected_target();
   2.182 -      InstanceKlass* holder = InstanceKlass::cast(target->method_holder());
   2.183 -
   2.184 -      // Verify that the identified method is valid from the context of
   2.185 -      // the current class, which is the caller class for invokespecial
   2.186 -      // link resolution, i.e. ensure there it is not shadowed.
   2.187 -      // You can use invokespecial to disambiguate interface methods, but
   2.188 -      // you can not use it to skip over an interface method that would shadow it.
   2.189 -      ErasedShadowChecker checker(THREAD, target->name(), holder, super_class);
   2.190 -      checker.run(current_class);
   2.191 -
   2.192 -      if (checker.found_shadow()) {
   2.193 -#ifndef PRODUCT
   2.194 -        if (TraceDefaultMethods) {
   2.195 -          tty->print_cr("    Only candidate found was shadowed.");
   2.196 -        }
   2.197 -#endif // ndef PRODUCT
   2.198 -        THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
   2.199 -                   "Accessible default method not found", NULL);
   2.200 -      } else {
   2.201 -#ifndef PRODUCT
   2.202 -        if (TraceDefaultMethods) {
   2.203 -          family->print_sig_on(tty, target->signature(), 1);
   2.204 -        }
   2.205 -#endif // ndef PRODUCT
   2.206 -        return target;
   2.207 -      }
   2.208 -    } else {
   2.209 -      assert(family->throws_exception(), "must have target or throw");
   2.210 -      THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
   2.211 -                 family->get_exception_message()->as_C_string(), NULL);
   2.212 -   }
   2.213 -  } else {
   2.214 -    // no method found
   2.215 -    ResourceMark rm(THREAD);
   2.216 -    THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(),
   2.217 -              Method::name_and_sig_as_C_string(current_class,
   2.218 -                                               method_name, sig), NULL);
   2.219 -  }
   2.220 -}
   2.221 -// This is called during linktime when we find an invokespecial call that
   2.222 -// refers to a direct superinterface.  It indicates that we should find the
   2.223 -// default method in the hierarchy of that superinterface, and if that method
   2.224 -// would have been a candidate from the point of view of 'this' class, then we
   2.225 -// return that method.
   2.226 -// This logic assumes that the super is a direct superclass of the caller
   2.227 -Method* DefaultMethods::find_super_default(
   2.228 -    Klass* cls, Klass* super, Symbol* method_name, Symbol* sig, TRAPS) {
   2.229 -
   2.230 -  ResourceMark rm(THREAD);
   2.231 -
   2.232 -  assert(cls != NULL && super != NULL, "Need real classes");
   2.233 -
   2.234 -  InstanceKlass* current_class = InstanceKlass::cast(cls);
   2.235 -  InstanceKlass* super_class = InstanceKlass::cast(super);
   2.236 -
   2.237 -  // Keep entire hierarchy alive for the duration of the computation
   2.238 -  KeepAliveRegistrar keepAlive(THREAD);
   2.239 -  KeepAliveVisitor loadKeepAlive(&keepAlive);
   2.240 -  loadKeepAlive.run(current_class);   // get hierarchy from current class
   2.241 -
   2.242 -#ifndef PRODUCT
   2.243 -  if (TraceDefaultMethods) {
   2.244 -    tty->print_cr("Finding super default method %s.%s%s from %s",
   2.245 -      super_class->name()->as_C_string(),
   2.246 -      method_name->as_C_string(), sig->as_C_string(),
   2.247 -      current_class->name()->as_C_string());
   2.248 -  }
   2.249 -#endif // ndef PRODUCT
   2.250 -
   2.251 -  assert(super_class->is_interface(), "only call for default methods");
   2.252 -
   2.253 -  Method* target = NULL;
   2.254 -  target = find_erased_super_default(current_class, super_class,
   2.255 -                                     method_name, sig, CHECK_NULL);
   2.256 -
   2.257 -#ifndef PRODUCT
   2.258 -  if (target != NULL) {
   2.259 -    if (TraceDefaultMethods) {
   2.260 -      tty->print("    Returning ");
   2.261 -      print_method(tty, target, true);
   2.262 -      tty->print_cr("");
   2.263 -    }
   2.264 -  }
   2.265 -#endif // ndef PRODUCT
   2.266 -  return target;
   2.267 -}
   2.268  
   2.269  #ifndef PRODUCT
   2.270  // Return true is broad type is a covariant return of narrow type
   2.271 @@ -1035,10 +851,9 @@
   2.272    return parameter_count;
   2.273  }
   2.274  
   2.275 -static int assemble_abstract_method_error(
   2.276 -    BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* message, TRAPS) {
   2.277 +static int assemble_method_error(
   2.278 +    BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) {
   2.279  
   2.280 -  Symbol* errorName = vmSymbols::java_lang_AbstractMethodError();
   2.281    Symbol* init = vmSymbols::object_initializer_name();
   2.282    Symbol* sig = vmSymbols::string_void_signature();
   2.283  
   2.284 @@ -1150,8 +965,7 @@
   2.285              &bpool, &buffer, slot->signature(), selected, CHECK);
   2.286          }
   2.287        } else if (method->throws_exception()) {
   2.288 -        max_stack = assemble_abstract_method_error(
   2.289 -            &bpool, &buffer, method->get_exception_message(), CHECK);
   2.290 +        max_stack = assemble_method_error(&bpool, &buffer, method->get_exception_name(), method->get_exception_message(), CHECK);
   2.291        }
   2.292        if (max_stack != 0) {
   2.293          AccessFlags flags = accessFlags_from(
     3.1 --- a/src/share/vm/classfile/defaultMethods.hpp	Fri Sep 27 10:08:56 2013 -0400
     3.2 +++ b/src/share/vm/classfile/defaultMethods.hpp	Tue Oct 01 08:10:42 2013 -0400
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -44,15 +44,5 @@
    3.11    // the class.
    3.12    static void generate_default_methods(
    3.13        InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS);
    3.14 -
    3.15 -
    3.16 -  // Called during linking when an invokespecial to an direct interface
    3.17 -  // method is found.  Selects and returns a method if there is a unique
    3.18 -  // default method in the 'super_iface' part of the hierarchy which is
    3.19 -  // also a candidate default for 'this_klass'.  Otherwise throws an AME.
    3.20 -  static Method* find_super_default(
    3.21 -      Klass* this_klass, Klass* super_iface,
    3.22 -      Symbol* method_name, Symbol* method_sig, TRAPS);
    3.23  };
    3.24 -
    3.25  #endif // SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
     4.1 --- a/src/share/vm/interpreter/linkResolver.cpp	Fri Sep 27 10:08:56 2013 -0400
     4.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Tue Oct 01 08:10:42 2013 -0400
     4.3 @@ -1,5 +1,4 @@
     4.4  /*
     4.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     4.6   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7   *
     4.8   * This code is free software; you can redistribute it and/or modify it
     4.9 @@ -573,6 +572,16 @@
    4.10    }
    4.11  
    4.12    if (check_access) {
    4.13 +    // JDK8 adds non-public interface methods, and accessability check requirement
    4.14 +    assert(current_klass.not_null() , "current_klass should not be null");
    4.15 +
    4.16 +    // check if method can be accessed by the referring class
    4.17 +    check_method_accessability(current_klass,
    4.18 +                               resolved_klass,
    4.19 +                               KlassHandle(THREAD, resolved_method->method_holder()),
    4.20 +                               resolved_method,
    4.21 +                               CHECK);
    4.22 +
    4.23      HandleMark hm(THREAD);
    4.24      Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
    4.25      Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
    4.26 @@ -604,6 +613,20 @@
    4.27        }
    4.28      }
    4.29    }
    4.30 +
    4.31 +  if (TraceItables && Verbose) {
    4.32 +    ResourceMark rm(THREAD);
    4.33 +    tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
    4.34 +                   (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
    4.35 +                   (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
    4.36 +                   Method::name_and_sig_as_C_string(resolved_klass(),
    4.37 +                                                    resolved_method->name(),
    4.38 +                                                    resolved_method->signature()),
    4.39 +                   resolved_method->method_holder()->internal_name()
    4.40 +                  );
    4.41 +    resolved_method->access_flags().print_on(tty);
    4.42 +    tty->cr();
    4.43 +  }
    4.44  }
    4.45  
    4.46  //------------------------------------------------------------------------------------------------------------------------
    4.47 @@ -795,26 +818,12 @@
    4.48                                                     Symbol* method_name, Symbol* method_signature,
    4.49                                                     KlassHandle current_klass, bool check_access, TRAPS) {
    4.50  
    4.51 -  if (resolved_klass->is_interface() && current_klass() != NULL) {
    4.52 -    // If the target class is a direct interface, treat this as a "super"
    4.53 -    // default call.
    4.54 -    //
    4.55 -    // If the current method is an overpass that happens to call a direct
    4.56 -    // super-interface's method, then we'll end up rerunning the default method
    4.57 -    // analysis even though we don't need to, but that's ok since it will end
    4.58 -    // up with the same answer.
    4.59 -    InstanceKlass* ik = InstanceKlass::cast(current_klass());
    4.60 -    Array<Klass*>* interfaces = ik->local_interfaces();
    4.61 -    int num_interfaces = interfaces->length();
    4.62 -    for (int index = 0; index < num_interfaces; index++) {
    4.63 -      if (interfaces->at(index) == resolved_klass()) {
    4.64 -        Method* method = DefaultMethods::find_super_default(current_klass(),
    4.65 -            resolved_klass(), method_name, method_signature, CHECK);
    4.66 -        resolved_method = methodHandle(THREAD, method);
    4.67 -        return;
    4.68 -      }
    4.69 -    }
    4.70 -  }
    4.71 +  // Invokespecial is called for multiple special reasons:
    4.72 +  // <init>
    4.73 +  // local private method invocation, for classes and interfaces
    4.74 +  // superclass.method, which can also resolve to a default method
    4.75 +  // and the selected method is recalculated relative to the direct superclass
    4.76 +  // superinterface.method, which explicitly does not check shadowing
    4.77  
    4.78    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
    4.79  
    4.80 @@ -844,6 +853,26 @@
    4.81                                                           resolved_method->signature()));
    4.82      THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
    4.83    }
    4.84 +  if (TraceItables && Verbose) {
    4.85 +    ResourceMark rm(THREAD);
    4.86 +    tty->print("invokespecial resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
    4.87 +                (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
    4.88 +                (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
    4.89 +                Method::name_and_sig_as_C_string(resolved_klass(),
    4.90 +                                                 resolved_method->name(),
    4.91 +                                                 resolved_method->signature()),
    4.92 +                resolved_method->method_holder()->internal_name()
    4.93 +               );
    4.94 +    resolved_method->access_flags().print_on(tty);
    4.95 +    if (resolved_method->method_holder()->is_interface() &&
    4.96 +        !resolved_method->is_abstract()) {
    4.97 +      tty->print("default");
    4.98 +    }
    4.99 +    if (resolved_method->is_overpass()) {
   4.100 +      tty->print("overpass");
   4.101 +    }
   4.102 +    tty->cr();
   4.103 +  }
   4.104  }
   4.105  
   4.106  // throws runtime exceptions
   4.107 @@ -851,23 +880,24 @@
   4.108                                                    KlassHandle current_klass, bool check_access, TRAPS) {
   4.109  
   4.110    // resolved method is selected method unless we have an old-style lookup
   4.111 +  // for a superclass method
   4.112 +  // Invokespecial for a superinterface, resolved method is selected method,
   4.113 +  // no checks for shadowing
   4.114    methodHandle sel_method(THREAD, resolved_method());
   4.115  
   4.116    // check if this is an old-style super call and do a new lookup if so
   4.117    { KlassHandle method_klass  = KlassHandle(THREAD,
   4.118                                              resolved_method->method_holder());
   4.119  
   4.120 -    const bool direct_calling_default_method =
   4.121 -      resolved_klass() != NULL && resolved_method() != NULL &&
   4.122 -      resolved_klass->is_interface() && !resolved_method->is_abstract();
   4.123 -
   4.124 -    if (!direct_calling_default_method &&
   4.125 -        check_access &&
   4.126 +    if (check_access &&
   4.127          // a) check if ACC_SUPER flag is set for the current class
   4.128          (current_klass->is_super() || !AllowNonVirtualCalls) &&
   4.129 -        // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
   4.130 -        current_klass->is_subtype_of(method_klass()) &&
   4.131 -        current_klass() != method_klass() &&
   4.132 +        // b) check if the class of the resolved_klass is a superclass
   4.133 +        // (not supertype in order to exclude interface classes) of the current class.
   4.134 +        // This check is not performed for super.invoke for interface methods
   4.135 +        // in super interfaces.
   4.136 +        current_klass->is_subclass_of(resolved_klass()) &&
   4.137 +        current_klass() != resolved_klass() &&
   4.138          // c) check if the method is not <init>
   4.139          resolved_method->name() != vmSymbols::object_initializer_name()) {
   4.140        // Lookup super method
   4.141 @@ -905,6 +935,23 @@
   4.142                                                        sel_method->signature()));
   4.143    }
   4.144  
   4.145 +  if (TraceItables && Verbose) {
   4.146 +    ResourceMark rm(THREAD);
   4.147 +    tty->print("invokespecial selected method: resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
   4.148 +                 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
   4.149 +                 Method::name_and_sig_as_C_string(resolved_klass(),
   4.150 +                                                  sel_method->name(),
   4.151 +                                                  sel_method->signature()),
   4.152 +                 sel_method->method_holder()->internal_name()
   4.153 +                );
   4.154 +    sel_method->access_flags().print_on(tty);
   4.155 +    if (sel_method->method_holder()->is_interface() &&
   4.156 +        !sel_method->is_abstract()) {
   4.157 +      tty->print("default");
   4.158 +    }
   4.159 +    tty->cr();
   4.160 +  }
   4.161 +
   4.162    // setup result
   4.163    result.set_static(resolved_klass, sel_method, CHECK);
   4.164  }
   4.165 @@ -927,6 +974,18 @@
   4.166    assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
   4.167    assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
   4.168  
   4.169 +  // check if private interface method
   4.170 +  if (resolved_klass->is_interface() && resolved_method->is_private()) {
   4.171 +    ResourceMark rm(THREAD);
   4.172 +    char buf[200];
   4.173 +    jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s",
   4.174 +                 Method::name_and_sig_as_C_string(resolved_klass(),
   4.175 +                                                  resolved_method->name(),
   4.176 +                                                  resolved_method->signature()),
   4.177 +                   (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()));
   4.178 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   4.179 +  }
   4.180 +
   4.181    // check if not static
   4.182    if (resolved_method->is_static()) {
   4.183      ResourceMark rm(THREAD);
   4.184 @@ -936,6 +995,27 @@
   4.185                                                                                                               resolved_method->signature()));
   4.186      THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   4.187    }
   4.188 +
   4.189 + if (PrintVtables && Verbose) {
   4.190 +   ResourceMark rm(THREAD);
   4.191 +   tty->print("invokevirtual resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
   4.192 +                  (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
   4.193 +                  (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
   4.194 +                  Method::name_and_sig_as_C_string(resolved_klass(),
   4.195 +                                                   resolved_method->name(),
   4.196 +                                                   resolved_method->signature()),
   4.197 +                  resolved_method->method_holder()->internal_name()
   4.198 +                 );
   4.199 +   resolved_method->access_flags().print_on(tty);
   4.200 +   if (resolved_method->method_holder()->is_interface() &&
   4.201 +       !resolved_method->is_abstract()) {
   4.202 +     tty->print("default");
   4.203 +   }
   4.204 +   if (resolved_method->is_overpass()) {
   4.205 +     tty->print("overpass");
   4.206 +   }
   4.207 +   tty->cr();
   4.208 + }
   4.209  }
   4.210  
   4.211  // throws runtime exceptions
   4.212 @@ -1012,6 +1092,27 @@
   4.213                                                        selected_method->signature()));
   4.214    }
   4.215  
   4.216 +  if (PrintVtables && Verbose) {
   4.217 +    ResourceMark rm(THREAD);
   4.218 +    tty->print("invokevirtual selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, vtable_index:%d, access_flags: ",
   4.219 +                   (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
   4.220 +                   (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
   4.221 +                   Method::name_and_sig_as_C_string(resolved_klass(),
   4.222 +                                                    resolved_method->name(),
   4.223 +                                                    resolved_method->signature()),
   4.224 +                   selected_method->method_holder()->internal_name(),
   4.225 +                   vtable_index
   4.226 +                  );
   4.227 +    selected_method->access_flags().print_on(tty);
   4.228 +    if (selected_method->method_holder()->is_interface() &&
   4.229 +        !selected_method->is_abstract()) {
   4.230 +      tty->print("default");
   4.231 +    }
   4.232 +    if (resolved_method->is_overpass()) {
   4.233 +      tty->print("overpass");
   4.234 +    }
   4.235 +    tty->cr();
   4.236 +  }
   4.237    // setup result
   4.238    result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
   4.239  }
   4.240 @@ -1042,6 +1143,17 @@
   4.241      THROW(vmSymbols::java_lang_NullPointerException());
   4.242    }
   4.243  
   4.244 +  // check if private interface method
   4.245 +  if (resolved_klass->is_interface() && resolved_method->is_private()) {
   4.246 +    ResourceMark rm(THREAD);
   4.247 +    char buf[200];
   4.248 +    jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s",
   4.249 +                 Method::name_and_sig_as_C_string(resolved_klass(),
   4.250 +                                                  resolved_method->name(),
   4.251 +                                                  resolved_method->signature()));
   4.252 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   4.253 +  }
   4.254 +
   4.255    // check if receiver klass implements the resolved interface
   4.256    if (!recv_klass->is_subtype_of(resolved_klass())) {
   4.257      ResourceMark rm(THREAD);
   4.258 @@ -1071,28 +1183,15 @@
   4.259                                                        resolved_method->signature()));
   4.260    }
   4.261    // check access
   4.262 -  if (sel_method->method_holder()->is_interface()) {
   4.263 -    // Method holder is an interface. Throw Illegal Access Error if sel_method
   4.264 -    // is neither public nor private.
   4.265 -    if (!(sel_method->is_public() || sel_method->is_private())) {
   4.266 -      ResourceMark rm(THREAD);
   4.267 -      THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
   4.268 -                Method::name_and_sig_as_C_string(recv_klass(),
   4.269 -                                                 sel_method->name(),
   4.270 -                                                 sel_method->signature()));
   4.271 -    }
   4.272 +  // Throw Illegal Access Error if sel_method is not public.
   4.273 +  if (!sel_method->is_public()) {
   4.274 +    ResourceMark rm(THREAD);
   4.275 +    THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
   4.276 +              Method::name_and_sig_as_C_string(recv_klass(),
   4.277 +                                               sel_method->name(),
   4.278 +                                               sel_method->signature()));
   4.279    }
   4.280 -  else {
   4.281 -    // Method holder is a class. Throw Illegal Access Error if sel_method
   4.282 -    // is not public.
   4.283 -    if (!sel_method->is_public()) {
   4.284 -      ResourceMark rm(THREAD);
   4.285 -      THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
   4.286 -                Method::name_and_sig_as_C_string(recv_klass(),
   4.287 -                                                 sel_method->name(),
   4.288 -                                                 sel_method->signature()));
   4.289 -    }
   4.290 -  }
   4.291 +
   4.292    // check if abstract
   4.293    if (check_null_and_abstract && sel_method->is_abstract()) {
   4.294      ResourceMark rm(THREAD);
   4.295 @@ -1109,6 +1208,27 @@
   4.296      return;
   4.297    }
   4.298    int itable_index = resolved_method()->itable_index();
   4.299 +
   4.300 +  if (TraceItables && Verbose) {
   4.301 +    ResourceMark rm(THREAD);
   4.302 +    tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
   4.303 +                   (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
   4.304 +                   (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
   4.305 +                   Method::name_and_sig_as_C_string(resolved_klass(),
   4.306 +                                                    resolved_method->name(),
   4.307 +                                                    resolved_method->signature()),
   4.308 +                   sel_method->method_holder()->internal_name()
   4.309 +                  );
   4.310 +    sel_method->access_flags().print_on(tty);
   4.311 +    if (sel_method->method_holder()->is_interface() &&
   4.312 +        !sel_method->is_abstract()) {
   4.313 +      tty->print("default");
   4.314 +    }
   4.315 +    if (resolved_method->is_overpass()) {
   4.316 +      tty->print("overpass");
   4.317 +    }
   4.318 +    tty->cr();
   4.319 +  }
   4.320    result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
   4.321  }
   4.322  
     5.1 --- a/src/share/vm/oops/instanceKlass.cpp	Fri Sep 27 10:08:56 2013 -0400
     5.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Tue Oct 01 08:10:42 2013 -0400
     5.3 @@ -1419,6 +1419,8 @@
     5.4  }
     5.5  
     5.6  // lookup a method in all the interfaces that this class implements
     5.7 +// Do NOT return private or static methods, new in JDK8 which are not externally visible
     5.8 +// They should only be found in the initial InterfaceMethodRef
     5.9  Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
    5.10                                                           Symbol* signature) const {
    5.11    Array<Klass*>* all_ifs = transitive_interfaces();
    5.12 @@ -1427,7 +1429,7 @@
    5.13    for (int i = 0; i < num_ifs; i++) {
    5.14      ik = InstanceKlass::cast(all_ifs->at(i));
    5.15      Method* m = ik->lookup_method(name, signature);
    5.16 -    if (m != NULL) {
    5.17 +    if (m != NULL && m->is_public() && !m->is_static()) {
    5.18        return m;
    5.19      }
    5.20    }
     6.1 --- a/src/share/vm/oops/klassVtable.cpp	Fri Sep 27 10:08:56 2013 -0400
     6.2 +++ b/src/share/vm/oops/klassVtable.cpp	Tue Oct 01 08:10:42 2013 -0400
     6.3 @@ -292,9 +292,10 @@
     6.4      return allocate_new;
     6.5    }
     6.6  
     6.7 -  // private methods always have a new entry in the vtable
     6.8 +  // private methods in classes always have a new entry in the vtable
     6.9    // specification interpretation since classic has
    6.10    // private methods not overriding
    6.11 +  // JDK8 adds private methods in interfaces which require invokespecial
    6.12    if (target_method()->is_private()) {
    6.13      return allocate_new;
    6.14    }
    6.15 @@ -442,9 +443,10 @@
    6.16      return true;
    6.17    }
    6.18  
    6.19 -  // private methods always have a new entry in the vtable
    6.20 +  // private methods in classes always have a new entry in the vtable
    6.21    // specification interpretation since classic has
    6.22    // private methods not overriding
    6.23 +  // JDK8 adds private methods in interfaces which require invokespecial
    6.24    if (target_method()->is_private()) {
    6.25      return true;
    6.26    }
    6.27 @@ -520,7 +522,7 @@
    6.28    Klass* method_holder = m->method_holder();
    6.29    InstanceKlass *mhk = InstanceKlass::cast(method_holder);
    6.30  
    6.31 -  // miranda methods are interface methods in a class's vtable
    6.32 +  // miranda methods are public abstract instance interface methods in a class's vtable
    6.33    if (mhk->is_interface()) {
    6.34      assert(m->is_public(), "should be public");
    6.35      assert(ik()->implements_interface(method_holder) , "this class should implement the interface");
    6.36 @@ -534,6 +536,8 @@
    6.37  // "miranda" means not static, not defined by this class, and not defined
    6.38  // in super unless it is private and therefore inaccessible to this class.
    6.39  // the caller must make sure that the method belongs to an interface implemented by the class
    6.40 +// Miranda methods only include public interface instance methods
    6.41 +// Not private methods, not static methods, not default = concrete abstract
    6.42  bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* super) {
    6.43    if (m->is_static()) {
    6.44      return false;

mercurial