// Return true if the interpreter can prove that the given bytecode has // not yet been executed (in Java semantics, not in actual operation). bool AbstractInterpreter::is_not_reached(methodHandle method, int bci) { Bytecodes::Code code = method()->code_at(bci); if (!Bytecodes::must_rewrite(code)) { // might have been reached return false; } // the bytecode might not be rewritten if the method is an accessor, etc. address ientry = method->interpreter_entry(); if (ientry != entry_for_kind(AbstractInterpreter::zerolocals) && ientry != entry_for_kind(AbstractInterpreter::zerolocals_synchronized)) return false; // interpreter does not run this method! // otherwise, we can be sure this bytecode has never been executed return true; }
void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, methodHandle method, int vtable_index) { assert(method->interpreter_entry() != NULL, "should have been set at this point"); assert(!method->is_old_version(), "attempt to write old method to cpCache"); bool change_to_virtual = (invoke_code == Bytecodes::_invokeinterface); int byte_no = -1; bool needs_vfinal_flag = false; switch (invoke_code) { case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: { if (Klass::can_be_statically_bound(method())) { set_f2((intptr_t)method()); needs_vfinal_flag = true; } else { set_f2(vtable_index); } byte_no = 2; break; } case Bytecodes::_invokespecial: // Preserve the value of the vfinal flag on invokevirtual bytecode // which may be shared with this constant pool cache entry. needs_vfinal_flag = is_resolved(Bytecodes::_invokevirtual) && is_vfinal(); // fall through case Bytecodes::_invokestatic: set_f1(method()); byte_no = 1; break; default: ShouldNotReachHere(); break; } set_flags(as_flags(as_TosState(method->result_type()), method->is_final_method(), needs_vfinal_flag, false, change_to_virtual, true)| method()->size_of_parameters()); // Note: byte_no also appears in TemplateTable::resolve. if (byte_no == 1) { set_bytecode_1(invoke_code); } else if (byte_no == 2) { if (change_to_virtual) { // NOTE: THIS IS A HACK - BE VERY CAREFUL!!! // // Workaround for the case where we encounter an invokeinterface, but we // should really have an _invokevirtual since the resolved method is a // virtual method in java.lang.Object. This is a corner case in the spec // but is presumably legal. javac does not generate this code. // // 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. // See also interpreterRuntime.cpp. (8/25/2000) set_bytecode_1(invoke_code); set_bytecode_2(Bytecodes::_invokevirtual); } else { set_bytecode_2(invoke_code); } } else { ShouldNotReachHere(); } verify(tty); }
void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code, methodHandle method, int vtable_index) { bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean 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. 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. set_method_flags(as_TosState(method->result_type()), ( 1 << is_vfinal_shift) | ((method->is_final_method() ? 1 : 0) << is_final_shift) | ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift), method()->size_of_parameters()); set_f2_as_vfinal_method(method()); } else { assert(!method->can_be_statically_bound(), ""); assert(vtable_index >= 0, "valid index"); assert(!method->is_final_method(), "sanity"); set_method_flags(as_TosState(method->result_type()), ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift), method()->size_of_parameters()); set_f2(vtable_index); } byte_no = 2; break; } case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: assert(!is_vtable_call, ""); // Note: Read and preserve the value of the is_vfinal flag on any // invokevirtual bytecode shared with this constant pool cache entry. // It is cheap and safe to consult is_vfinal() at all times. // Once is_vfinal is set, it must stay that way, lest we get a dangling oop. set_method_flags(as_TosState(method->result_type()), ((is_vfinal() ? 1 : 0) << is_vfinal_shift) | ((method->is_final_method() ? 1 : 0) << is_final_shift), method()->size_of_parameters()); set_f1(method()); byte_no = 1; break; default: ShouldNotReachHere(); break; } // Note: byte_no also appears in TemplateTable::resolve. if (byte_no == 1) { assert(invoke_code != Bytecodes::_invokevirtual && invoke_code != Bytecodes::_invokeinterface, ""); set_bytecode_1(invoke_code); } else if (byte_no == 2) { if (change_to_virtual) { assert(invoke_code == Bytecodes::_invokeinterface, ""); // NOTE: THIS IS A HACK - BE VERY CAREFUL!!! // // Workaround for the case where we encounter an invokeinterface, but we // should really have an _invokevirtual since the resolved method is a // virtual method in java.lang.Object. This is a corner case in the spec // but is presumably legal. javac does not generate this code. // // 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. // See also interpreterRuntime.cpp. (8/25/2000) // Only set resolved for the invokeinterface case if method is public. // Otherwise, the method needs to be reresolved with caller for each // interface call. if (method->is_public()) set_bytecode_1(invoke_code); } else { assert(invoke_code == Bytecodes::_invokevirtual, ""); } // set up for invokevirtual, even if linking for invokeinterface also: set_bytecode_2(Bytecodes::_invokevirtual); } else { ShouldNotReachHere(); } NOT_PRODUCT(verify(tty)); }