/*
 * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "ci/ciCallProfile.hpp"
#include "ci/ciExceptionHandler.hpp"
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciMethod.hpp"
#include "ci/ciMethodBlocks.hpp"
#include "ci/ciMethodData.hpp"
#include "ci/ciReplay.hpp"
#include "ci/ciStreams.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciSymbols.hpp"
#include "ci/ciUtilities.inline.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/compilerDefinitions.inline.hpp"
#include "compiler/compilerOracle.hpp"
#include "compiler/compileTask.hpp"
#include "compiler/methodLiveness.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/linkResolver.hpp"
#include "interpreter/oopMapCache.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/generateOopMap.hpp"
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/trainingData.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/xmlstream.hpp"
#ifdef COMPILER2
#include "ci/bcEscapeAnalyzer.hpp"
#include "ci/ciTypeFlow.hpp"
#include "oops/method.hpp"
#endif

// ciMethod
//
// This class represents a Method* in the HotSpot virtual
// machine.


// ------------------------------------------------------------------
// ciMethod::ciMethod
//
// Loaded method.
ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :
  ciMetadata(h_m()),
  _holder(holder)
{
  assert(h_m() != nullptr, "no null method");
  assert(_holder->get_instanceKlass() == h_m->method_holder(), "");

  // These fields are always filled in in loaded methods.
  _flags = ciFlags(h_m->access_flags());

  // Easy to compute, so fill them in now.
  _max_stack          = h_m->max_stack();
  _max_locals         = h_m->max_locals();
  _code_size          = h_m->code_size();
  _handler_count      = h_m->exception_table_length();
  _size_of_parameters = h_m->size_of_parameters();
  _uses_monitors      = h_m->has_monitor_bytecodes();
  _balanced_monitors  = !_uses_monitors || h_m->guaranteed_monitor_matching();
  _is_c1_compilable   = !h_m->is_not_c1_compilable();
  _is_c2_compilable   = !h_m->is_not_c2_compilable();
  _can_be_parsed      = true;
  _has_reserved_stack_access = h_m->has_reserved_stack_access();
  _is_overpass        = h_m->is_overpass();
  // Lazy fields, filled in on demand.  Require allocation.
  _code               = nullptr;
  _exception_handlers = nullptr;
  _liveness           = nullptr;
  _method_blocks = nullptr;
#if defined(COMPILER2)
  _flow               = nullptr;
  _bcea               = nullptr;
#endif // COMPILER2

  // Check for blackhole intrinsic and then populate the intrinsic ID.
  CompilerOracle::tag_blackhole_if_possible(h_m);
  _intrinsic_id       = h_m->intrinsic_id();

  ciEnv *env = CURRENT_ENV;
  if (env->jvmti_can_hotswap_or_post_breakpoint()) {
    // 6328518 check hotswap conditions under the right lock.
    bool should_take_Compile_lock = !Compile_lock->owned_by_self();
    ConditionalMutexLocker locker(Compile_lock, should_take_Compile_lock, Mutex::_safepoint_check_flag);
    if (Dependencies::check_evol_method(h_m()) != nullptr) {
      _is_c1_compilable = false;
      _is_c2_compilable = false;
      _can_be_parsed = false;
    }
  } else {
    DEBUG_ONLY(CompilerThread::current()->check_possible_safepoint());
  }

  if (h_m->method_holder()->is_linked()) {
    _can_be_statically_bound = h_m->can_be_statically_bound();
    _can_omit_stack_trace = h_m->can_omit_stack_trace();
  } else {
    // Have to use a conservative value in this case.
    _can_be_statically_bound = false;
    _can_omit_stack_trace = true;
  }

  // Adjust the definition of this condition to be more useful:
  // %%% take these conditions into account in vtable generation
  if (!_can_be_statically_bound && h_m->is_private())
    _can_be_statically_bound = true;
  if (_can_be_statically_bound && h_m->is_abstract())
    _can_be_statically_bound = false;

  // generating _signature may allow GC and therefore move m.
  // These fields are always filled in.
  _name = env->get_symbol(h_m->name());
  ciSymbol* sig_symbol = env->get_symbol(h_m->signature());
  constantPoolHandle cpool(Thread::current(), h_m->constants());
  _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol);
  _method_data = nullptr;
  // Take a snapshot of these values, so they will be commensurate with the MDO.
  if (ProfileInterpreter || CompilerConfig::is_c1_profiling()) {
    int invcnt = h_m->interpreter_invocation_count();
    // if the value overflowed report it as max int
    _interpreter_invocation_count = invcnt < 0 ? max_jint : invcnt ;
    _interpreter_throwout_count   = h_m->interpreter_throwout_count();
  } else {
    _interpreter_invocation_count = 0;
    _interpreter_throwout_count = 0;
  }
  if (_interpreter_invocation_count == 0)
    _interpreter_invocation_count = 1;
  _inline_instructions_size = -1;
  if (ReplayCompiles) {
    ciReplay::initialize(this);
  }
}


// ------------------------------------------------------------------
// ciMethod::ciMethod
//
// Unloaded method.
ciMethod::ciMethod(ciInstanceKlass* holder,
                   ciSymbol*        name,
                   ciSymbol*        signature,
                   ciInstanceKlass* accessor) :
  ciMetadata((Metadata*)nullptr),
  _name(                   name),
  _holder(                 holder),
  _method_data(            nullptr),
  _method_blocks(          nullptr),
  _intrinsic_id(           vmIntrinsics::_none),
  _inline_instructions_size(-1),
  _can_be_statically_bound(false),
  _can_omit_stack_trace(true),
  _liveness(               nullptr)
#if defined(COMPILER2)
  ,
  _flow(                   nullptr),
  _bcea(                   nullptr)
#endif // COMPILER2
{
  // Usually holder and accessor are the same type but in some cases
  // the holder has the wrong class loader (e.g. invokedynamic call
  // sites) so we pass the accessor.
  _signature = new (CURRENT_ENV->arena()) ciSignature(accessor, constantPoolHandle(), signature);
}


// ------------------------------------------------------------------
// ciMethod::load_code
//
// Load the bytecodes and exception handler table for this method.
void ciMethod::load_code() {
  VM_ENTRY_MARK;
  assert(is_loaded(), "only loaded methods have code");

  Method* me = get_Method();
  Arena* arena = CURRENT_THREAD_ENV->arena();

  // Load the bytecodes.
  _code = (address)arena->Amalloc(code_size());
  memcpy(_code, me->code_base(), code_size());

#if INCLUDE_JVMTI
  // Revert any breakpoint bytecodes in ci's copy
  if (me->number_of_breakpoints() > 0) {
    BreakpointInfo* bp = me->method_holder()->breakpoints();
    for (; bp != nullptr; bp = bp->next()) {
      if (bp->match(me)) {
        code_at_put(bp->bci(), bp->orig_bytecode());
      }
    }
  }
#endif

  // And load the exception table.
  ExceptionTable exc_table(me);

  // Allocate one extra spot in our list of exceptions.  This
  // last entry will be used to represent the possibility that
  // an exception escapes the method.  See ciExceptionHandlerStream
  // for details.
  _exception_handlers =
    (ciExceptionHandler**)arena->Amalloc(sizeof(ciExceptionHandler*)
                                         * (_handler_count + 1));
  if (_handler_count > 0) {
    for (int i=0; i<_handler_count; i++) {
      _exception_handlers[i] = new (arena) ciExceptionHandler(
                                holder(),
            /* start    */      exc_table.start_pc(i),
            /* limit    */      exc_table.end_pc(i),
            /* goto pc  */      exc_table.handler_pc(i),
            /* cp index */      exc_table.catch_type_index(i));
    }
  }

  // Put an entry at the end of our list to represent the possibility
  // of exceptional exit.
  _exception_handlers[_handler_count] =
    new (arena) ciExceptionHandler(holder(), 0, code_size(), -1, 0);

  if (CIPrintMethodCodes) {
    print_codes();
  }
}


// ------------------------------------------------------------------
// ciMethod::has_linenumber_table
//
// length unknown until decompression
bool    ciMethod::has_linenumber_table() const {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_Method()->has_linenumber_table();
}


// ------------------------------------------------------------------
// ciMethod::line_number_from_bci
int ciMethod::line_number_from_bci(int bci) const {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_Method()->line_number_from_bci(bci);
}


// ------------------------------------------------------------------
// ciMethod::vtable_index
//
// Get the position of this method's entry in the vtable, if any.
int ciMethod::vtable_index() {
  check_is_loaded();
  assert(holder()->is_linked(), "must be linked");
  VM_ENTRY_MARK;
  return get_Method()->vtable_index();
}

// ------------------------------------------------------------------
// ciMethod::uses_balanced_monitors
//
// Does this method use monitors in a strict stack-disciplined manner?
bool ciMethod::has_balanced_monitors() {
  check_is_loaded();
  if (_balanced_monitors) return true;

  // Analyze the method to see if monitors are used properly.
  VM_ENTRY_MARK;
  methodHandle method(THREAD, get_Method());
  assert(method->has_monitor_bytecodes(), "should have checked this");

  // Check to see if a previous compilation computed the
  // monitor-matching analysis.
  if (method->guaranteed_monitor_matching()) {
    _balanced_monitors = true;
    return true;
  }

  {
    ExceptionMark em(THREAD);
    ResourceMark rm(THREAD);
    GeneratePairingInfo gpi(method);
    if (!gpi.compute_map(THREAD)) {
      fatal("Unrecoverable verification or out-of-memory error");
    }
    if (!gpi.monitor_safe()) {
      return false;
    }
    method->set_guaranteed_monitor_matching();
    _balanced_monitors = true;
  }
  return true;
}


// ------------------------------------------------------------------
// ciMethod::get_flow_analysis
ciTypeFlow* ciMethod::get_flow_analysis() {
#if defined(COMPILER2)
  if (_flow == nullptr) {
    ciEnv* env = CURRENT_ENV;
    _flow = new (env->arena()) ciTypeFlow(env, this);
    _flow->do_flow();
  }
  return _flow;
#else // COMPILER2
  ShouldNotReachHere();
  return nullptr;
#endif // COMPILER2
}


// ------------------------------------------------------------------
// ciMethod::get_osr_flow_analysis
ciTypeFlow* ciMethod::get_osr_flow_analysis(int osr_bci) {
#if defined(COMPILER2)
  // OSR entry points are always place after a call bytecode of some sort
  assert(osr_bci >= 0, "must supply valid OSR entry point");
  ciEnv* env = CURRENT_ENV;
  ciTypeFlow* flow = new (env->arena()) ciTypeFlow(env, this, osr_bci);
  flow->do_flow();
  return flow;
#else // COMPILER2
  ShouldNotReachHere();
  return nullptr;
#endif // COMPILER2
}

// ------------------------------------------------------------------
// ciMethod::raw_liveness_at_bci
//
// Which local variables are live at a specific bci?
MethodLivenessResult ciMethod::raw_liveness_at_bci(int bci) {
  check_is_loaded();
  if (_liveness == nullptr) {
    // Create the liveness analyzer.
    Arena* arena = CURRENT_ENV->arena();
    _liveness = new (arena) MethodLiveness(arena, this);
    _liveness->compute_liveness();
  }
  return _liveness->get_liveness_at(bci);
}

// ------------------------------------------------------------------
// ciMethod::liveness_at_bci
//
// Which local variables are live at a specific bci?  When debugging
// will return true for all locals in some cases to improve debug
// information.
MethodLivenessResult ciMethod::liveness_at_bci(int bci) {
  if (CURRENT_ENV->should_retain_local_variables() || DeoptimizeALot) {
    // Keep all locals live for the user's edification and amusement.
    MethodLivenessResult result(_max_locals);
    result.set_range(0, _max_locals);
    result.set_is_valid();
    return result;
  }
  return raw_liveness_at_bci(bci);
}

// ciMethod::live_local_oops_at_bci
//
// find all the live oops in the locals array for a particular bci
// Compute what the interpreter believes by using the interpreter
// oopmap generator. This is used as a double check during osr to
// guard against conservative result from MethodLiveness making us
// think a dead oop is live.  MethodLiveness is conservative in the
// sense that it may consider locals to be live which cannot be live,
// like in the case where a local could contain an oop or  a primitive
// along different paths.  In that case the local must be dead when
// those paths merge. Since the interpreter's viewpoint is used when
// gc'ing an interpreter frame we need to use its viewpoint  during
// OSR when loading the locals.

ResourceBitMap ciMethod::live_local_oops_at_bci(int bci) {
  VM_ENTRY_MARK;
  InterpreterOopMap mask;
  OopMapCache::compute_one_oop_map(methodHandle(THREAD, get_Method()), bci, &mask);
  int mask_size = max_locals();
  ResourceBitMap result(mask_size);
  int i;
  for (i = 0; i < mask_size ; i++ ) {
    if (mask.is_oop(i)) result.set_bit(i);
  }
  return result;
}


#ifdef COMPILER1
// ------------------------------------------------------------------
// ciMethod::bci_block_start
//
// Marks all bcis where a new basic block starts
const BitMap& ciMethod::bci_block_start() {
  check_is_loaded();
  if (_liveness == nullptr) {
    // Create the liveness analyzer.
    Arena* arena = CURRENT_ENV->arena();
    _liveness = new (arena) MethodLiveness(arena, this);
    _liveness->compute_liveness();
  }

  return _liveness->get_bci_block_start();
}
#endif // COMPILER1


// ------------------------------------------------------------------
// ciMethod::check_overflow
//
// Check whether the profile counter is overflowed and adjust if true.
// For invoke* it will turn negative values into max_jint,
// and for checkcast/aastore/instanceof turn positive values into min_jint.
int ciMethod::check_overflow(int c, Bytecodes::Code code) {
  switch (code) {
    case Bytecodes::_aastore:    // fall-through
    case Bytecodes::_checkcast:  // fall-through
    case Bytecodes::_instanceof: {
      if (VM_Version::profile_all_receivers_at_type_check()) {
        return (c < 0 ? max_jint : c); // always non-negative
      }
      return (c > 0 ? min_jint : c); // always non-positive
    }
    default: {
      assert(Bytecodes::is_invoke(code), "%s", Bytecodes::name(code));
      return (c < 0 ? max_jint : c); // always non-negative
    }
  }
}


// ------------------------------------------------------------------
// ciMethod::call_profile_at_bci
//
// Get the ciCallProfile for the invocation of this method.
// Also reports receiver types for non-call type checks (if TypeProfileCasts).
ciCallProfile ciMethod::call_profile_at_bci(int bci) {
  ResourceMark rm;
  ciCallProfile result;
  if (method_data() != nullptr && method_data()->is_mature()) {
    ciProfileData* data = method_data()->bci_to_data(bci);
    if (data != nullptr && data->is_CounterData()) {
      // Every profiled call site has a counter.
      int count = check_overflow(data->as_CounterData()->count(), java_code_at_bci(bci));

      if (!data->is_ReceiverTypeData()) {
        result._receiver_count[0] = 0;  // that's a definite zero
      } else { // ReceiverTypeData is a subclass of CounterData
        ciReceiverTypeData* call = (ciReceiverTypeData*)data->as_ReceiverTypeData();
        // In addition, virtual call sites have receiver type information
        int receivers_count_total = 0;
        int morphism = 0;
        // Precompute morphism for the possible fixup
        for (uint i = 0; i < call->row_limit(); i++) {
          ciKlass* receiver = call->receiver(i);
          if (receiver == nullptr)  continue;
          morphism++;
        }
        int epsilon = 0;
        // For a call, it is assumed that either the type of the receiver(s)
        // is recorded or an associated counter is incremented, but not both. With
        // tiered compilation, however, both can happen due to the interpreter and
        // C1 profiling invocations differently. Address that inconsistency here.
        if (morphism == 1 && count > 0) {
          epsilon = count;
          count = 0;
        }
        for (uint i = 0; i < call->row_limit(); i++) {
          ciKlass* receiver = call->receiver(i);
          if (receiver == nullptr)  continue;
          int rcount = saturated_add(call->receiver_count(i), epsilon);
          if (rcount == 0) rcount = 1; // Should be valid value
          receivers_count_total = saturated_add(receivers_count_total, rcount);
          // Add the receiver to result data.
          result.add_receiver(receiver, rcount);
          // If we extend profiling to record methods,
          // we will set result._method also.
        }
        // Determine call site's morphism.
        // The call site count is 0 with known morphism (only 1 or 2 receivers)
        // or < 0 in the case of a type check failure for checkcast, aastore, instanceof.
        // The call site count is > 0 in the case of a polymorphic virtual call.
        if (morphism > 0 && morphism == result._limit) {
           // The morphism <= MorphismLimit.
           if ((morphism <  ciCallProfile::MorphismLimit) ||
               (morphism == ciCallProfile::MorphismLimit && count == 0)) {
#ifdef ASSERT
             if (count > 0) {
               this->print_short_name(tty);
               tty->print_cr(" @ bci:%d", bci);
               this->print_codes();
               assert(false, "this call site should not be polymorphic");
             }
#endif
             result._morphism = morphism;
           }
        }
        // Make the count consistent if this is a call profile. If count is
        // zero or less, presume that this is a typecheck profile and
        // do nothing.  Otherwise, increase count to be the sum of all
        // receiver's counts.
        if (count >= 0) {
          count = saturated_add(count, receivers_count_total);
        }
      }
      result._count = count;
    }
  }
  return result;
}

// ------------------------------------------------------------------
// Add new receiver and sort data by receiver's profile count.
void ciCallProfile::add_receiver(ciKlass* receiver, int receiver_count) {
  // Add new receiver and sort data by receiver's counts when we have space
  // for it otherwise replace the less called receiver (less called receiver
  // is placed to the last array element which is not used).
  // First array's element contains most called receiver.
  int i = _limit;
  for (; i > 0 && receiver_count > _receiver_count[i-1]; i--) {
    _receiver[i] = _receiver[i-1];
    _receiver_count[i] = _receiver_count[i-1];
  }
  _receiver[i] = receiver;
  _receiver_count[i] = receiver_count;
  if (_limit < MorphismLimit) _limit++;
}


void ciMethod::assert_virtual_call_type_ok(int bci) {
  assert(java_code_at_bci(bci) == Bytecodes::_invokevirtual ||
         java_code_at_bci(bci) == Bytecodes::_invokeinterface, "unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci)));
}

void ciMethod::assert_call_type_ok(int bci) {
  assert(java_code_at_bci(bci) == Bytecodes::_invokestatic ||
         java_code_at_bci(bci) == Bytecodes::_invokespecial ||
         java_code_at_bci(bci) == Bytecodes::_invokedynamic, "unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci)));
}

/**
 * Check whether profiling provides a type for the argument i to the
 * call at bci bci
 *
 * @param [in]bci         bci of the call
 * @param [in]i           argument number
 * @param [out]type       profiled type of argument, null if none
 * @param [out]ptr_kind   whether always null, never null or maybe null
 * @return                true if profiling exists
 *
 */
bool ciMethod::argument_profiled_type(int bci, int i, ciKlass*& type, ProfilePtrKind& ptr_kind) {
  if (MethodData::profile_parameters() && method_data() != nullptr && method_data()->is_mature()) {
    ciProfileData* data = method_data()->bci_to_data(bci);
    if (data != nullptr) {
      if (data->is_VirtualCallTypeData()) {
        assert_virtual_call_type_ok(bci);
        ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
        if (i >= call->number_of_arguments()) {
          return false;
        }
        type = call->valid_argument_type(i);
        ptr_kind = call->argument_ptr_kind(i);
        return true;
      } else if (data->is_CallTypeData()) {
        assert_call_type_ok(bci);
        ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
        if (i >= call->number_of_arguments()) {
          return false;
        }
        type = call->valid_argument_type(i);
        ptr_kind = call->argument_ptr_kind(i);
        return true;
      }
    }
  }
  return false;
}

/**
 * Check whether profiling provides a type for the return value from
 * the call at bci bci
 *
 * @param [in]bci         bci of the call
 * @param [out]type       profiled type of argument, null if none
 * @param [out]ptr_kind   whether always null, never null or maybe null
 * @return                true if profiling exists
 *
 */
bool ciMethod::return_profiled_type(int bci, ciKlass*& type, ProfilePtrKind& ptr_kind) {
  if (MethodData::profile_return() && method_data() != nullptr && method_data()->is_mature()) {
    ciProfileData* data = method_data()->bci_to_data(bci);
    if (data != nullptr) {
      if (data->is_VirtualCallTypeData()) {
        assert_virtual_call_type_ok(bci);
        ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
        if (call->has_return()) {
          type = call->valid_return_type();
          ptr_kind = call->return_ptr_kind();
          return true;
        }
      } else if (data->is_CallTypeData()) {
        assert_call_type_ok(bci);
        ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
        if (call->has_return()) {
          type = call->valid_return_type();
          ptr_kind = call->return_ptr_kind();
        }
        return true;
      }
    }
  }
  return false;
}

/**
 * Check whether profiling provides a type for the parameter i
 *
 * @param [in]i           parameter number
 * @param [out]type       profiled type of parameter, null if none
 * @param [out]ptr_kind   whether always null, never null or maybe null
 * @return                true if profiling exists
 *
 */
bool ciMethod::parameter_profiled_type(int i, ciKlass*& type, ProfilePtrKind& ptr_kind) {
  if (MethodData::profile_parameters() && method_data() != nullptr && method_data()->is_mature()) {
    ciParametersTypeData* parameters = method_data()->parameters_type_data();
    if (parameters != nullptr && i < parameters->number_of_parameters()) {
      type = parameters->valid_parameter_type(i);
      ptr_kind = parameters->parameter_ptr_kind(i);
      return true;
    }
  }
  return false;
}


// ------------------------------------------------------------------
// ciMethod::find_monomorphic_target
//
// Given a certain calling environment, find the monomorphic target
// for the call.  Return null if the call is not monomorphic in
// its calling environment, or if there are only abstract methods.
// The returned method is never abstract.
// Note: If caller uses a non-null result, it must inform dependencies
// via assert_unique_concrete_method or assert_leaf_type.
ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller,
                                            ciInstanceKlass* callee_holder,
                                            ciInstanceKlass* actual_recv,
                                            bool check_access) {
  check_is_loaded();

  if (actual_recv->is_interface()) {
    // %%% We cannot trust interface types, yet.  See bug 6312651.
    return nullptr;
  }

  ciMethod* root_m = resolve_invoke(caller, actual_recv, check_access, true /* allow_abstract */);
  if (root_m == nullptr) {
    // Something went wrong looking up the actual receiver method.
    return nullptr;
  }

  // Make certain quick checks even if UseCHA is false.

  // Is it private or final?
  if (root_m->can_be_statically_bound()) {
    assert(!root_m->is_abstract(), "sanity");
    return root_m;
  }

  if (actual_recv->is_leaf_type() && actual_recv == root_m->holder()) {
    // Easy case.  There is no other place to put a method, so don't bother
    // to go through the VM_ENTRY_MARK and all the rest.
    if (root_m->is_abstract()) {
      return nullptr;
    }
    return root_m;
  }

  // Array methods (clone, hashCode, etc.) are always statically bound.
  // If we were to see an array type here, we'd return root_m.
  // However, this method processes only ciInstanceKlasses.  (See 4962591.)
  // The inline_native_clone intrinsic narrows Object to T[] properly,
  // so there is no need to do the same job here.

  if (!UseCHA)  return nullptr;

  VM_ENTRY_MARK;

  methodHandle target;
  {
    MutexLocker locker(Compile_lock);
    InstanceKlass* context = actual_recv->get_instanceKlass();
    target = methodHandle(THREAD, Dependencies::find_unique_concrete_method(context,
                                                                            root_m->get_Method(),
                                                                            callee_holder->get_Klass(),
                                                                            this->get_Method()));
    assert(target() == nullptr || !target()->is_abstract(), "not allowed");
    // %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods.
  }

#ifndef PRODUCT
  LogTarget(Debug, dependencies) lt;
  if (lt.is_enabled() && target() != nullptr && target() != root_m->get_Method()) {
    LogStream ls(&lt);
    ls.print("found a non-root unique target method");
    ls.print_cr("  context = %s", actual_recv->get_Klass()->external_name());
    ls.print("  method  = ");
    target->print_short_name(&ls);
    ls.cr();
  }
#endif //PRODUCT

  if (target() == nullptr) {
    return nullptr;
  }

  // Redefinition support.
  if (this->is_old() || root_m->is_old() || target->is_old()) {
    guarantee(CURRENT_THREAD_ENV->jvmti_state_changed(), "old method not detected");
    return nullptr;
  }

  if (target() == root_m->get_Method()) {
    return root_m;
  }
  if (!root_m->is_public() &&
      !root_m->is_protected()) {
    // If we are going to reason about inheritance, it's easiest
    // if the method in question is public, protected, or private.
    // If the answer is not root_m, it is conservatively correct
    // to return null, even if the CHA encountered irrelevant
    // methods in other packages.
    // %%% TO DO: Work out logic for package-private methods
    // with the same name but different vtable indexes.
    return nullptr;
  }
  return CURRENT_THREAD_ENV->get_method(target());
}

// ------------------------------------------------------------------
// ciMethod::can_be_statically_bound
//
// Tries to determine whether a method can be statically bound in some context.
bool ciMethod::can_be_statically_bound(ciInstanceKlass* context) const {
  return (holder() == context) && can_be_statically_bound();
}

// ------------------------------------------------------------------
// ciMethod::can_omit_stack_trace
//
// Tries to determine whether a method can omit stack trace in throw in compiled code.
bool ciMethod::can_omit_stack_trace() const {
  if (!StackTraceInThrowable) {
    return true; // stack trace is switched off.
  }
  if (!OmitStackTraceInFastThrow) {
    return false; // Have to provide stack trace.
  }
  return _can_omit_stack_trace;
}

// ------------------------------------------------------------------
// ciMethod::resolve_invoke
//
// Given a known receiver klass, find the target for the call.
// Return null if the call has no target or the target is abstract.
ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, bool check_access, bool allow_abstract) {
  check_is_loaded();
  VM_ENTRY_MARK;

  Klass* caller_klass = caller->get_Klass();
  Klass* recv         = exact_receiver->get_Klass();
  Klass* resolved     = holder()->get_Klass();
  Symbol* h_name      = name()->get_symbol();
  Symbol* h_signature = signature()->get_symbol();

  LinkInfo link_info(resolved, h_name, h_signature, caller_klass,
                     check_access ? LinkInfo::AccessCheck::required : LinkInfo::AccessCheck::skip,
                     check_access ? LinkInfo::LoaderConstraintCheck::required : LinkInfo::LoaderConstraintCheck::skip);
  Method* m = nullptr;
  // Only do exact lookup if receiver klass has been linked.  Otherwise,
  // the vtable has not been setup, and the LinkResolver will fail.
  if (recv->is_array_klass()
       ||
      (InstanceKlass::cast(recv)->is_linked() && !exact_receiver->is_interface())) {
    if (holder()->is_interface()) {
      m = LinkResolver::resolve_interface_call_or_null(recv, link_info);
    } else {
      m = LinkResolver::resolve_virtual_call_or_null(recv, link_info);
    }
  }

  if (m == nullptr) {
    // Return null only if there was a problem with lookup (uninitialized class, etc.)
    return nullptr;
  }

  ciMethod* result = this;
  if (m != get_Method()) {
    // Redefinition support.
    if (this->is_old() || m->is_old()) {
      guarantee(CURRENT_THREAD_ENV->jvmti_state_changed(), "old method not detected");
      return nullptr;
    }

    result = CURRENT_THREAD_ENV->get_method(m);
  }

  if (result->is_abstract() && !allow_abstract) {
    // Don't return abstract methods because they aren't optimizable or interesting.
    return nullptr;
  }
  return result;
}

// ------------------------------------------------------------------
// ciMethod::resolve_vtable_index
//
// Given a known receiver klass, find the vtable index for the call.
// Return Method::invalid_vtable_index if the vtable_index is unknown.
int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) {
   check_is_loaded();

   int vtable_index = Method::invalid_vtable_index;
   // Only do lookup if receiver klass has been linked.  Otherwise,
   // the vtable has not been setup, and the LinkResolver will fail.
   if (!receiver->is_interface()
       && (!receiver->is_instance_klass() ||
           receiver->as_instance_klass()->is_linked())) {
     VM_ENTRY_MARK;

     Klass* caller_klass = caller->get_Klass();
     Klass* recv         = receiver->get_Klass();
     Symbol* h_name = name()->get_symbol();
     Symbol* h_signature = signature()->get_symbol();

     LinkInfo link_info(recv, h_name, h_signature, caller_klass);
     vtable_index = LinkResolver::resolve_virtual_vtable_index(recv, link_info);
     if (vtable_index == Method::nonvirtual_vtable_index) {
       // A statically bound method.  Return "no such index".
       vtable_index = Method::invalid_vtable_index;
     }
   }

   return vtable_index;
}

// ------------------------------------------------------------------
// ciMethod::get_field_at_bci
ciField* ciMethod::get_field_at_bci(int bci, bool &will_link) {
  ciBytecodeStream iter(this);
  iter.reset_to_bci(bci);
  iter.next();
  return iter.get_field(will_link);
}

// ------------------------------------------------------------------
// ciMethod::get_method_at_bci
ciMethod* ciMethod::get_method_at_bci(int bci, bool &will_link, ciSignature* *declared_signature) {
  ciBytecodeStream iter(this);
  iter.reset_to_bci(bci);
  iter.next();
  return iter.get_method(will_link, declared_signature);
}

// ------------------------------------------------------------------
ciKlass* ciMethod::get_declared_method_holder_at_bci(int bci) {
  ciBytecodeStream iter(this);
  iter.reset_to_bci(bci);
  iter.next();
  return iter.get_declared_method_holder();
}

// ------------------------------------------------------------------
// Adjust a CounterData count to be commensurate with
// interpreter_invocation_count.  If the MDO exists for
// only 25% of the time the method exists, then the
// counts in the MDO should be scaled by 4X, so that
// they can be usefully and stably compared against the
// invocation counts in methods.
int ciMethod::scale_count(int count, float prof_factor) {
  if (count > 0 && method_data() != nullptr) {
    int counter_life = method_data()->invocation_count();
    int method_life = interpreter_invocation_count();
    if (method_life < counter_life) { // may happen because of the snapshot timing
      method_life = counter_life;
    }
    if (counter_life > 0) {
      double count_d = (double)count * prof_factor * method_life / counter_life + 0.5;
      if (count_d >= static_cast<double>(INT_MAX)) {
        // Clamp in case of overflowing int range.
        count = INT_MAX;
      } else {
        count = int(count_d);
        count = (count > 0) ? count : 1;
      }
    } else {
      count = 1;
    }
  }
  return count;
}


// ------------------------------------------------------------------
// ciMethod::is_special_get_caller_class_method
//
bool ciMethod::is_ignored_by_security_stack_walk() const {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_Method()->is_ignored_by_security_stack_walk();
}

// ------------------------------------------------------------------
// ciMethod::needs_clinit_barrier
//
bool ciMethod::needs_clinit_barrier() const {
  check_is_loaded();
  return is_static() && !holder()->is_initialized();
}

// ------------------------------------------------------------------
// invokedynamic support

// ------------------------------------------------------------------
// ciMethod::is_method_handle_intrinsic
//
// Return true if the method is an instance of the JVM-generated
// signature-polymorphic MethodHandle methods, _invokeBasic, _linkToVirtual, etc.
bool ciMethod::is_method_handle_intrinsic() const {
  vmIntrinsics::ID iid = _intrinsic_id;  // do not check if loaded
  return (MethodHandles::is_signature_polymorphic(iid) &&
          MethodHandles::is_signature_polymorphic_intrinsic(iid));
}

// ------------------------------------------------------------------
// ciMethod::is_compiled_lambda_form
//
// Return true if the method is a generated MethodHandle adapter.
// These are built by Java code.
bool ciMethod::is_compiled_lambda_form() const {
  vmIntrinsics::ID iid = _intrinsic_id;  // do not check if loaded
  return iid == vmIntrinsics::_compiledLambdaForm;
}

// ------------------------------------------------------------------
// ciMethod::is_object_initializer
//
bool ciMethod::is_object_initializer() const {
   return name() == ciSymbols::object_initializer_name();
}

// ------------------------------------------------------------------
// ciMethod::is_scoped
//
// Return true for methods annotated with @Scoped
bool ciMethod::is_scoped() const {
   return get_Method()->is_scoped();
}

// ------------------------------------------------------------------
// ciMethod::has_member_arg
//
// Return true if the method is a linker intrinsic like _linkToVirtual.
// These are built by the JVM.
bool ciMethod::has_member_arg() const {
  vmIntrinsics::ID iid = _intrinsic_id;  // do not check if loaded
  return (MethodHandles::is_signature_polymorphic(iid) &&
          MethodHandles::has_member_arg(iid));
}

// ------------------------------------------------------------------
// ciMethod::ensure_method_data
//
// Generate new MethodData* objects at compile time.
// Return true if allocation was successful or no MDO is required.
bool ciMethod::ensure_method_data(const methodHandle& h_m) {
  EXCEPTION_CONTEXT;
  if (is_native() || is_abstract() || h_m()->is_accessor()) {
    return true;
  }
  if (h_m()->method_data() == nullptr) {
    Method::build_profiling_method_data(h_m, THREAD);
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
    }
  }
  if (h_m()->method_data() != nullptr) {
    _method_data = CURRENT_ENV->get_method_data(h_m()->method_data());
    return _method_data->load_data();
  } else {
    _method_data = CURRENT_ENV->get_empty_methodData();
    return false;
  }
}

// public, retroactive version
bool ciMethod::ensure_method_data() {
  bool result = true;
  if (_method_data == nullptr || _method_data->is_empty()) {
    GUARDED_VM_ENTRY({
      methodHandle mh(Thread::current(), get_Method());
      result = ensure_method_data(mh);
    });
  }
  return result;
}


// ------------------------------------------------------------------
// ciMethod::method_data
//
ciMethodData* ciMethod::method_data() {
  if (_method_data != nullptr) {
    return _method_data;
  }
  VM_ENTRY_MARK;
  ciEnv* env = CURRENT_ENV;
  Thread* my_thread = JavaThread::current();
  methodHandle h_m(my_thread, get_Method());

  if (h_m()->method_data() != nullptr) {
    _method_data = CURRENT_ENV->get_method_data(h_m()->method_data());
    _method_data->load_data();
  } else {
    _method_data = CURRENT_ENV->get_empty_methodData();
  }
  return _method_data;

}

// ------------------------------------------------------------------
// ciMethod::method_data_or_null
// Returns a pointer to ciMethodData if MDO exists on the VM side,
// null otherwise.
ciMethodData* ciMethod::method_data_or_null() {
  ciMethodData *md = method_data();
  if (md->is_empty()) {
    return nullptr;
  }
  return md;
}

// ------------------------------------------------------------------
// ciMethod::ensure_method_counters
//
MethodCounters* ciMethod::ensure_method_counters() {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  MethodCounters* method_counters = mh->get_method_counters(CHECK_NULL);
  return method_counters;
}

// ------------------------------------------------------------------
// ciMethod::has_option
//
bool ciMethod::has_option(CompileCommandEnum option) {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  return CompilerOracle::has_option(mh, option);
}

// ------------------------------------------------------------------
// ciMethod::has_option_value
//
bool ciMethod::has_option_value(CompileCommandEnum option, double& value) {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  return CompilerOracle::has_option_value(mh, option, value);
}
// ------------------------------------------------------------------
// ciMethod::can_be_compiled
//
// Have previous compilations of this method succeeded?
bool ciMethod::can_be_compiled() {
  check_is_loaded();
  ciEnv* env = CURRENT_ENV;
  if (is_c1_compile(env->comp_level())) {
    return _is_c1_compilable;
  }
  return _is_c2_compilable;
}

// ------------------------------------------------------------------
// ciMethod::has_compiled_code
bool ciMethod::has_compiled_code() {
  return inline_instructions_size() > 0;
}

int ciMethod::highest_osr_comp_level() {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_Method()->highest_osr_comp_level();
}

// ------------------------------------------------------------------
// ciMethod::code_size_for_inlining
//
// Code size for inlining decisions.  This method returns a code
// size of 1 for methods which has the ForceInline annotation.
int ciMethod::code_size_for_inlining() {
  check_is_loaded();
  if (get_Method()->force_inline()) {
    return 1;
  }
  return code_size();
}

// ------------------------------------------------------------------
// ciMethod::inline_instructions_size
//
// This is a rough metric for "fat" methods, compared before inlining
// with InlineSmallCode.  The CodeBlob::code_size accessor includes
// junk like exception handler, stubs, and constant table, which are
// not highly relevant to an inlined method.  So we use the more
// specific accessor nmethod::insts_size.
// Also some instructions inside the code are excluded from inline
// heuristic (e.g. post call nop instructions; see InlineSkippedInstructionsCounter)
int ciMethod::inline_instructions_size() {
  if (_inline_instructions_size == -1) {
    if (TrainingData::have_data()) {
      GUARDED_VM_ENTRY(
        CompLevel level = static_cast<CompLevel>(CURRENT_ENV->comp_level());
        methodHandle top_level_mh(Thread::current(), CURRENT_ENV->task()->method());
        MethodTrainingData* mtd = MethodTrainingData::find(top_level_mh);
        if (mtd != nullptr) {
          CompileTrainingData* ctd = mtd->last_toplevel_compile(level);
          if (ctd != nullptr) {
            methodHandle mh(Thread::current(), get_Method());
            MethodTrainingData* this_mtd = MethodTrainingData::find(mh);
            if (this_mtd != nullptr) {
              auto r = ctd->ci_records().ciMethod__inline_instructions_size.find(this_mtd);
              if (r.is_valid()) {
                _inline_instructions_size = r.result();
              }
            }
          }
        }
      );
    }
  }
  if (_inline_instructions_size == -1) {
    GUARDED_VM_ENTRY(
      nmethod* code = get_Method()->code();
      if (code != nullptr && (code->comp_level() == CompLevel_full_optimization)) {
        int isize = code->insts_end() - code->verified_entry_point() - code->skipped_instructions_size();
        _inline_instructions_size = isize > 0 ? isize : 0;
      } else {
        _inline_instructions_size = 0;
      }
      if (TrainingData::need_data()) {
        CompileTrainingData* ctd = CURRENT_ENV->task()->training_data();
        if (ctd != nullptr) {
          methodHandle mh(Thread::current(), get_Method());
          MethodTrainingData* this_mtd = MethodTrainingData::make(mh);
          ctd->ci_records().ciMethod__inline_instructions_size.append_if_missing(_inline_instructions_size, this_mtd);
        }
      }
    );
  }
  return _inline_instructions_size;
}

// ------------------------------------------------------------------
// ciMethod::log_nmethod_identity
void ciMethod::log_nmethod_identity(xmlStream* log) {
  GUARDED_VM_ENTRY(
    nmethod* code = get_Method()->code();
    if (code != nullptr) {
      code->log_identity(log);
    }
  )
}

// ------------------------------------------------------------------
// ciMethod::is_not_reached
bool ciMethod::is_not_reached(int bci) {
  check_is_loaded();
  VM_ENTRY_MARK;
  return Interpreter::is_not_reached(
               methodHandle(THREAD, get_Method()), bci);
}

// ------------------------------------------------------------------
// ciMethod::was_never_executed
bool ciMethod::was_executed_more_than(int times) {
  VM_ENTRY_MARK;
  return get_Method()->was_executed_more_than(times);
}

// ------------------------------------------------------------------
// ciMethod::has_unloaded_classes_in_signature
bool ciMethod::has_unloaded_classes_in_signature() {
  // ciSignature is resolved against some accessing class and
  // signature classes aren't required to be local. As a benefit,
  // it makes signature classes visible through loader constraints.
  // So, encountering an unloaded class signals it is absent both in
  // the callee (local) and caller contexts.
  return signature()->has_unloaded_classes();
}

// ------------------------------------------------------------------
// ciMethod::is_klass_loaded
bool ciMethod::is_klass_loaded(int refinfo_index, Bytecodes::Code bc, bool must_be_resolved) const {
  VM_ENTRY_MARK;
  return get_Method()->is_klass_loaded(refinfo_index, bc, must_be_resolved);
}

// ------------------------------------------------------------------
// ciMethod::check_call
bool ciMethod::check_call(int refinfo_index, bool is_static) const {
  // This method is used only in C2 from InlineTree::ok_to_inline,
  // and is only used under -Xcomp.
  // It appears to fail when applied to an invokeinterface call site.
  // FIXME: Remove this method and resolve_method_statically; refactor to use the other LinkResolver entry points.
  VM_ENTRY_MARK;
  {
    ExceptionMark em(THREAD);
    HandleMark hm(THREAD);
    constantPoolHandle pool (THREAD, get_Method()->constants());
    Bytecodes::Code code = (is_static ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual);
    Method* spec_method = LinkResolver::resolve_method_statically(code, pool, refinfo_index, THREAD);
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
      return false;
    } else {
      return (spec_method->is_static() == is_static);
    }
  }
  return false;
}
// ------------------------------------------------------------------
// ciMethod::print_codes
//
// Print the bytecodes for this method.
void ciMethod::print_codes_on(outputStream* st) {
  check_is_loaded();
  GUARDED_VM_ENTRY(get_Method()->print_codes_on(st);)
}


#define FETCH_FLAG_FROM_VM(flag_accessor) { \
  check_is_loaded(); \
  VM_ENTRY_MARK; \
  return get_Method()->flag_accessor(); \
}

bool ciMethod::has_loops      () const {         FETCH_FLAG_FROM_VM(has_loops); }
bool ciMethod::has_jsrs       () const {         FETCH_FLAG_FROM_VM(has_jsrs);  }
bool ciMethod::is_getter      () const {         FETCH_FLAG_FROM_VM(is_getter); }
bool ciMethod::is_setter      () const {         FETCH_FLAG_FROM_VM(is_setter); }
bool ciMethod::is_accessor    () const {         FETCH_FLAG_FROM_VM(is_accessor); }
bool ciMethod::is_empty       () const {         FETCH_FLAG_FROM_VM(is_empty_method); }

bool ciMethod::is_boxing_method() const {
  if (intrinsic_id() != vmIntrinsics::_none && holder()->is_box_klass()) {
    switch (intrinsic_id()) {
      case vmIntrinsics::_Boolean_valueOf:
      case vmIntrinsics::_Byte_valueOf:
      case vmIntrinsics::_Character_valueOf:
      case vmIntrinsics::_Short_valueOf:
      case vmIntrinsics::_Integer_valueOf:
      case vmIntrinsics::_Long_valueOf:
      case vmIntrinsics::_Float_valueOf:
      case vmIntrinsics::_Double_valueOf:
        return true;
      default:
        return false;
    }
  }
  return false;
}

bool ciMethod::is_unboxing_method() const {
  if (intrinsic_id() != vmIntrinsics::_none && holder()->is_box_klass()) {
    switch (intrinsic_id()) {
      case vmIntrinsics::_booleanValue:
      case vmIntrinsics::_byteValue:
      case vmIntrinsics::_charValue:
      case vmIntrinsics::_shortValue:
      case vmIntrinsics::_intValue:
      case vmIntrinsics::_longValue:
      case vmIntrinsics::_floatValue:
      case vmIntrinsics::_doubleValue:
        return true;
      default:
        return false;
    }
  }
  return false;
}

bool ciMethod::is_vector_method() const {
  return (holder() == ciEnv::current()->vector_VectorSupport_klass()) &&
         (intrinsic_id() != vmIntrinsics::_none);
}

BCEscapeAnalyzer  *ciMethod::get_bcea() {
#ifdef COMPILER2
  if (_bcea == nullptr) {
    _bcea = new (CURRENT_ENV->arena()) BCEscapeAnalyzer(this, nullptr);
  }
  return _bcea;
#else // COMPILER2
  ShouldNotReachHere();
  return nullptr;
#endif // COMPILER2
}

ciMethodBlocks  *ciMethod::get_method_blocks() {
  if (_method_blocks == nullptr) {
    Arena *arena = CURRENT_ENV->arena();
    _method_blocks = new (arena) ciMethodBlocks(arena, this);
  }
  return _method_blocks;
}

#undef FETCH_FLAG_FROM_VM

void ciMethod::dump_name_as_ascii(outputStream* st, Method* method) {
  st->print("%s %s %s",
            CURRENT_ENV->replay_name(method->method_holder()),
            method->name()->as_quoted_ascii(),
            method->signature()->as_quoted_ascii());
}

void ciMethod::dump_name_as_ascii(outputStream* st) {
  Method* method = get_Method();
  dump_name_as_ascii(st, method);
}

void ciMethod::dump_replay_data(outputStream* st) {
  ResourceMark rm;
  Method* method = get_Method();
  if (MethodHandles::is_signature_polymorphic_method(method)) {
    // ignore for now
    return;
  }
  MethodCounters* mcs = method->method_counters();
  st->print("ciMethod ");
  dump_name_as_ascii(st);
  st->print_cr(" %d %d %d %d %d",
               mcs == nullptr ? 0 : mcs->invocation_counter()->raw_counter(),
               mcs == nullptr ? 0 : mcs->backedge_counter()->raw_counter(),
               interpreter_invocation_count(),
               interpreter_throwout_count(),
               _inline_instructions_size);
}

// ------------------------------------------------------------------
// ciMethod::print_codes
//
// Print a range of the bytecodes for this method.
void ciMethod::print_codes_on(int from, int to, outputStream* st) {
  check_is_loaded();
  GUARDED_VM_ENTRY(get_Method()->print_codes_on(from, to, st);)
}

// ------------------------------------------------------------------
// ciMethod::print_name
//
// Print the name of this method, including signature and some flags.
void ciMethod::print_name(outputStream* st) {
  check_is_loaded();
  GUARDED_VM_ENTRY(get_Method()->print_name(st);)
}

// ------------------------------------------------------------------
// ciMethod::print_short_name
//
// Print the name of this method, without signature.
void ciMethod::print_short_name(outputStream* st) {
  if (is_loaded()) {
    GUARDED_VM_ENTRY(get_Method()->print_short_name(st););
  } else {
    // Fall back if method is not loaded.
    holder()->print_name_on(st);
    st->print("::");
    name()->print_symbol_on(st);
    if (WizardMode)
      signature()->as_symbol()->print_symbol_on(st);
  }
}

// ------------------------------------------------------------------
// ciMethod::print_impl
//
// Implementation of the print method.
void ciMethod::print_impl(outputStream* st) {
  ciMetadata::print_impl(st);
  st->print(" name=");
  name()->print_symbol_on(st);
  st->print(" holder=");
  holder()->print_name_on(st);
  st->print(" signature=");
  signature()->as_symbol()->print_symbol_on(st);
  if (is_loaded()) {
    st->print(" loaded=true");
    st->print(" arg_size=%d", arg_size());
    st->print(" flags=");
    flags().print_member_flags(st);
  } else {
    st->print(" loaded=false");
  }
}

// ------------------------------------------------------------------

static BasicType erase_to_word_type(BasicType bt) {
  if (is_subword_type(bt))   return T_INT;
  if (is_reference_type(bt)) return T_OBJECT;
  return bt;
}

static bool basic_types_match(ciType* t1, ciType* t2) {
  if (t1 == t2)  return true;
  return erase_to_word_type(t1->basic_type()) == erase_to_word_type(t2->basic_type());
}

bool ciMethod::is_consistent_info(ciMethod* declared_method, ciMethod* resolved_method) {
  bool invoke_through_mh_intrinsic = declared_method->is_method_handle_intrinsic() &&
                                  !resolved_method->is_method_handle_intrinsic();

  if (!invoke_through_mh_intrinsic) {
    // Method name & descriptor should stay the same.
    // Signatures may reference unloaded types and thus they may be not strictly equal.
    ciSymbol* declared_signature = declared_method->signature()->as_symbol();
    ciSymbol* resolved_signature = resolved_method->signature()->as_symbol();

    return (declared_method->name()->equals(resolved_method->name())) &&
           (declared_signature->equals(resolved_signature));
  }

  ciMethod* linker = declared_method;
  ciMethod* target = resolved_method;
  // Linkers have appendix argument which is not passed to callee.
  int has_appendix = MethodHandles::has_member_arg(linker->intrinsic_id()) ? 1 : 0;
  if (linker->arg_size() != (target->arg_size() + has_appendix)) {
    return false; // argument slot count mismatch
  }

  ciSignature* linker_sig = linker->signature();
  ciSignature* target_sig = target->signature();

  if (linker_sig->count() + (linker->is_static() ? 0 : 1) !=
      target_sig->count() + (target->is_static() ? 0 : 1) + has_appendix) {
    return false; // argument count mismatch
  }

  int sbase = 0, rbase = 0;
  switch (linker->intrinsic_id()) {
    case vmIntrinsics::_linkToVirtual:
    case vmIntrinsics::_linkToInterface:
    case vmIntrinsics::_linkToSpecial: {
      if (target->is_static()) {
        return false;
      }
      if (linker_sig->type_at(0)->is_primitive_type()) {
        return false;  // receiver should be an oop
      }
      sbase = 1; // skip receiver
      break;
    }
    case vmIntrinsics::_linkToStatic: {
      if (!target->is_static()) {
        return false;
      }
      break;
    }
    case vmIntrinsics::_invokeBasic: {
      if (target->is_static()) {
        if (target_sig->type_at(0)->is_primitive_type()) {
          return false; // receiver should be an oop
        }
        rbase = 1; // skip receiver
      }
      break;
    }
    default:
      break;
  }
  assert(target_sig->count() - rbase == linker_sig->count() - sbase - has_appendix, "argument count mismatch");
  int arg_count = target_sig->count() - rbase;
  for (int i = 0; i < arg_count; i++) {
    if (!basic_types_match(linker_sig->type_at(sbase + i), target_sig->type_at(rbase + i))) {
      return false;
    }
  }
  // Only check the return type if the symbolic info has non-void return type.
  // I.e. the return value of the resolved method can be dropped.
  if (!linker->return_type()->is_void() &&
      !basic_types_match(linker->return_type(), target->return_type())) {
    return false;
  }
  return true; // no mismatch found
}

// ------------------------------------------------------------------
// ciMethod::is_old
//
// Return true for redefined methods
bool ciMethod::is_old() const {
  ASSERT_IN_VM;
  return get_Method()->is_old();
}
