< prev index next >

src/hotspot/share/oops/cpCache.cpp

Print this page

        

*** 171,191 **** assert(method->interpreter_entry() != NULL, "should have been set at this point"); assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); int byte_no = -1; bool change_to_virtual = false; ! switch (invoke_code) { case Bytecodes::_invokeinterface: // We get here from InterpreterRuntime::resolve_invoke when an invokeinterface ! // instruction somehow links to a non-interface method (in Object). // In that case, the method has no itable index and must be invoked as a virtual. // Set a flag to keep track of this corner case. assert(method->is_public(), "Calling non-public method in Object with invokeinterface"); change_to_virtual = true; // ...and fall through as if we were handling invokevirtual: case Bytecodes::_invokevirtual: { if (!is_vtable_call) { assert(method->can_be_statically_bound(), ""); // set_f2_as_vfinal_method checks if is_vfinal flag is true. --- 171,211 ---- assert(method->interpreter_entry() != NULL, "should have been set at this point"); assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); int byte_no = -1; bool change_to_virtual = false; ! InstanceKlass* holder = NULL; // have to declare this outside the switch switch (invoke_code) { case Bytecodes::_invokeinterface: + holder = method->method_holder(); + // check for private interface method invocations + if (vtable_index == Method::nonvirtual_vtable_index && holder->is_interface() ) { + assert(method->is_private(), "unexpected non-private method"); + assert(method->can_be_statically_bound(), "unexpected non-statically-bound method"); + // set_f2_as_vfinal_method checks if is_vfinal flag is true. + set_method_flags(as_TosState(method->result_type()), + ( 1 << is_vfinal_shift) | + ((method->is_final_method() ? 1 : 0) << is_final_shift), + method()->size_of_parameters()); + set_f2_as_vfinal_method(method()); + byte_no = 2; + set_f1(holder); // interface klass* + break; + } + else { // We get here from InterpreterRuntime::resolve_invoke when an invokeinterface ! // instruction links to a non-interface method (in Object). This can happen when ! // an interface redeclares an Object method (like CharSequence declaring toString()) ! // or when invokeinterface is used explicitly. // In that case, the method has no itable index and must be invoked as a virtual. // Set a flag to keep track of this corner case. + assert(holder->is_interface() || holder == SystemDictionary::Object_klass(), "unexpected holder class"); assert(method->is_public(), "Calling non-public method in Object with invokeinterface"); change_to_virtual = true; // ...and fall through as if we were handling invokevirtual: + } case Bytecodes::_invokevirtual: { if (!is_vtable_call) { assert(method->can_be_statically_bound(), ""); // set_f2_as_vfinal_method checks if is_vfinal flag is true.
*** 254,264 **** // because the actual selected method may not be public. // // We set bytecode_2() to _invokevirtual. // See also interpreterRuntime.cpp. (8/25/2000) } else { ! assert(invoke_code == Bytecodes::_invokevirtual, ""); } // set up for invokevirtual, even if linking for invokeinterface also: set_bytecode_2(Bytecodes::_invokevirtual); } else { ShouldNotReachHere(); --- 274,295 ---- // because the actual selected method may not be public. // // We set bytecode_2() to _invokevirtual. // See also interpreterRuntime.cpp. (8/25/2000) } else { ! assert(invoke_code == Bytecodes::_invokevirtual || ! (invoke_code == Bytecodes::_invokeinterface && ! ((method->is_private() || ! (method->is_final() && method->method_holder() == SystemDictionary::Object_klass())))), ! "unexpected invocation mode"); ! if (invoke_code == Bytecodes::_invokeinterface && ! (method->is_private() || method->is_final())) { ! // We set bytecode_1() to _invokeinterface, because that is the ! // bytecode # used by the interpreter to see if it is resolved. ! // We set bytecode_2() to _invokevirtual. ! set_bytecode_1(invoke_code); ! } } // set up for invokevirtual, even if linking for invokeinterface also: set_bytecode_2(Bytecodes::_invokevirtual); } else { ShouldNotReachHere();
< prev index next >