Tue, 01 Oct 2013 08:10:42 -0400
8011311: Private interface methods. Default conflicts:ICCE. no erased_super_default.
Reviewed-by: coleenp, bharadwaj, minqi
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;