1 /*
  2  * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "cds/archiveBuilder.hpp"
 26 #include "cppstdlib/type_traits.hpp"
 27 #include "oops/method.hpp"
 28 #include "oops/resolvedMethodEntry.hpp"
 29 
 30 static_assert(std::is_trivially_copyable_v<ResolvedMethodEntry>);
 31 
 32 // Detect inadvertently introduced trailing padding.
 33 class ResolvedMethodEntryWithExtra : public ResolvedMethodEntry {
 34   u1 _extra_field;
 35 };
 36 static_assert(sizeof(ResolvedMethodEntryWithExtra) > sizeof(ResolvedMethodEntry));
 37 
 38 bool ResolvedMethodEntry::check_no_old_or_obsolete_entry() {
 39   // return false if m refers to a non-deleted old or obsolete method
 40   if (_method != nullptr) {
 41     assert(_method->is_valid() && _method->is_method(), "m is a valid method");
 42     return !_method->is_old() && !_method->is_obsolete(); // old is always set for old and obsolete
 43   } else {
 44     return true;
 45   }
 46 }
 47 
 48 void ResolvedMethodEntry::reset_entry() {
 49   if (has_resolved_references_index()) {
 50     u2 saved_resolved_references_index = _entry_specific._resolved_references_index;
 51     *this = ResolvedMethodEntry(_cpool_index);
 52     set_resolved_references_index(saved_resolved_references_index);
 53   } else {
 54     *this = ResolvedMethodEntry(_cpool_index);
 55   }
 56 }
 57 
 58 #if INCLUDE_CDS
 59 void ResolvedMethodEntry::remove_unshareable_info() {
 60   reset_entry();
 61 }
 62 
 63 void ResolvedMethodEntry::mark_and_relocate(ConstantPool* src_cp) {
 64   if (_method == nullptr) {
 65     assert(bytecode2() == Bytecodes::_invokevirtual, "");
 66   } else {
 67     ArchiveBuilder::current()->mark_and_relocate_to_buffered_addr(&_method);
 68   }
 69   if (bytecode1() == Bytecodes::_invokeinterface) {
 70     ArchiveBuilder::current()->mark_and_relocate_to_buffered_addr(&_entry_specific._interface_klass);
 71   }
 72 }
 73 #endif
 74 
 75 void ResolvedMethodEntry::print_on(outputStream* st) const {
 76   st->print_cr("Method Entry:");
 77 
 78   if (method() != nullptr) {
 79     st->print_cr(" - Method: " INTPTR_FORMAT " %s", p2i(method()), method()->external_name());
 80   } else {
 81     st->print_cr("- Method: null");
 82   }
 83   // Some fields are mutually exclusive and are only used by certain invoke codes
 84   if (bytecode1() == Bytecodes::_invokeinterface && interface_klass() != nullptr) {
 85     st->print_cr(" - Klass: " INTPTR_FORMAT " %s", p2i(interface_klass()), interface_klass()->external_name());
 86   } else {
 87     st->print_cr("- Klass: null");
 88   }
 89   if (bytecode1() == Bytecodes::_invokehandle) {
 90     st->print_cr(" - Resolved References Index: %d", resolved_references_index());
 91   } else {
 92     st->print_cr(" - Resolved References Index: none");
 93   }
 94   if (bytecode2() == Bytecodes::_invokevirtual) {
 95 #ifdef ASSERT
 96     if (_has_table_index) {
 97       st->print_cr(" - Table Index: %d", table_index());
 98     }
 99 #else
100     st->print_cr(" - Table Index: %d", table_index());
101 #endif
102   } else {
103     st->print_cr(" - Table Index: none");
104   }
105   st->print_cr(" - CP Index: %d", constant_pool_index());
106   st->print_cr(" - TOS: %s", type2name(as_BasicType((TosState)tos_state())));
107   st->print_cr(" - Number of Parameters: %d", number_of_parameters());
108   st->print_cr(" - Is Virtual Final: %d", is_vfinal());
109   st->print_cr(" - Is Final: %d", is_final());
110   st->print_cr(" - Is Forced Virtual: %d", is_forced_virtual());
111   st->print_cr(" - Has Appendix: %d", has_appendix());
112   st->print_cr(" - Has Local Signature: %d", has_local_signature());
113   st->print_cr(" - Bytecode 1: %s", Bytecodes::name((Bytecodes::Code)bytecode1()));
114   st->print_cr(" - Bytecode 2: %s", Bytecodes::name((Bytecodes::Code)bytecode2()));
115 }