Path: blob/master/src/hotspot/share/ci/ciMethod.cpp
40931 views
/*1* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "ci/ciCallProfile.hpp"26#include "ci/ciExceptionHandler.hpp"27#include "ci/ciInstanceKlass.hpp"28#include "ci/ciMethod.hpp"29#include "ci/ciMethodBlocks.hpp"30#include "ci/ciMethodData.hpp"31#include "ci/ciStreams.hpp"32#include "ci/ciSymbol.hpp"33#include "ci/ciReplay.hpp"34#include "ci/ciSymbols.hpp"35#include "ci/ciUtilities.inline.hpp"36#include "compiler/abstractCompiler.hpp"37#include "compiler/methodLiveness.hpp"38#include "interpreter/interpreter.hpp"39#include "interpreter/linkResolver.hpp"40#include "interpreter/oopMapCache.hpp"41#include "memory/allocation.inline.hpp"42#include "memory/resourceArea.hpp"43#include "oops/generateOopMap.hpp"44#include "oops/method.inline.hpp"45#include "oops/oop.inline.hpp"46#include "prims/methodHandles.hpp"47#include "runtime/deoptimization.hpp"48#include "runtime/handles.inline.hpp"49#include "utilities/bitMap.inline.hpp"50#include "utilities/xmlstream.hpp"51#ifdef COMPILER252#include "ci/bcEscapeAnalyzer.hpp"53#include "ci/ciTypeFlow.hpp"54#include "oops/method.hpp"55#endif5657// ciMethod58//59// This class represents a Method* in the HotSpot virtual60// machine.616263// ------------------------------------------------------------------64// ciMethod::ciMethod65//66// Loaded method.67ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :68ciMetadata(h_m()),69_holder(holder)70{71assert(h_m() != NULL, "no null method");7273if (LogTouchedMethods) {74h_m->log_touched(Thread::current());75}76// These fields are always filled in in loaded methods.77_flags = ciFlags(h_m->access_flags());7879// Easy to compute, so fill them in now.80_max_stack = h_m->max_stack();81_max_locals = h_m->max_locals();82_code_size = h_m->code_size();83_intrinsic_id = h_m->intrinsic_id();84_handler_count = h_m->exception_table_length();85_size_of_parameters = h_m->size_of_parameters();86_uses_monitors = h_m->access_flags().has_monitor_bytecodes();87_balanced_monitors = !_uses_monitors || h_m->access_flags().is_monitor_matching();88_is_c1_compilable = !h_m->is_not_c1_compilable();89_is_c2_compilable = !h_m->is_not_c2_compilable();90_can_be_parsed = true;91_has_reserved_stack_access = h_m->has_reserved_stack_access();92_is_overpass = h_m->is_overpass();93// Lazy fields, filled in on demand. Require allocation.94_code = NULL;95_exception_handlers = NULL;96_liveness = NULL;97_method_blocks = NULL;98#if defined(COMPILER2)99_flow = NULL;100_bcea = NULL;101#endif // COMPILER2102103ciEnv *env = CURRENT_ENV;104if (env->jvmti_can_hotswap_or_post_breakpoint()) {105// 6328518 check hotswap conditions under the right lock.106MutexLocker locker(Compile_lock);107if (Dependencies::check_evol_method(h_m()) != NULL) {108_is_c1_compilable = false;109_is_c2_compilable = false;110_can_be_parsed = false;111}112} else {113DEBUG_ONLY(CompilerThread::current()->check_possible_safepoint());114}115116if (h_m->method_holder()->is_linked()) {117_can_be_statically_bound = h_m->can_be_statically_bound();118} else {119// Have to use a conservative value in this case.120_can_be_statically_bound = false;121}122123// Adjust the definition of this condition to be more useful:124// %%% take these conditions into account in vtable generation125if (!_can_be_statically_bound && h_m->is_private())126_can_be_statically_bound = true;127if (_can_be_statically_bound && h_m->is_abstract())128_can_be_statically_bound = false;129130// generating _signature may allow GC and therefore move m.131// These fields are always filled in.132_name = env->get_symbol(h_m->name());133ciSymbol* sig_symbol = env->get_symbol(h_m->signature());134constantPoolHandle cpool(Thread::current(), h_m->constants());135_signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol);136_method_data = NULL;137_nmethod_age = h_m->nmethod_age();138// Take a snapshot of these values, so they will be commensurate with the MDO.139if (ProfileInterpreter || CompilerConfig::is_c1_profiling()) {140int invcnt = h_m->interpreter_invocation_count();141// if the value overflowed report it as max int142_interpreter_invocation_count = invcnt < 0 ? max_jint : invcnt ;143_interpreter_throwout_count = h_m->interpreter_throwout_count();144} else {145_interpreter_invocation_count = 0;146_interpreter_throwout_count = 0;147}148if (_interpreter_invocation_count == 0)149_interpreter_invocation_count = 1;150_instructions_size = -1;151#ifdef ASSERT152if (ReplayCompiles) {153ciReplay::initialize(this);154}155#endif156157CompilerOracle::tag_blackhole_if_possible(h_m);158}159160161// ------------------------------------------------------------------162// ciMethod::ciMethod163//164// Unloaded method.165ciMethod::ciMethod(ciInstanceKlass* holder,166ciSymbol* name,167ciSymbol* signature,168ciInstanceKlass* accessor) :169ciMetadata((Metadata*)NULL),170_name( name),171_holder( holder),172_method_data( NULL),173_method_blocks( NULL),174_intrinsic_id( vmIntrinsics::_none),175_instructions_size(-1),176_can_be_statically_bound(false),177_liveness( NULL)178#if defined(COMPILER2)179,180_flow( NULL),181_bcea( NULL)182#endif // COMPILER2183{184// Usually holder and accessor are the same type but in some cases185// the holder has the wrong class loader (e.g. invokedynamic call186// sites) so we pass the accessor.187_signature = new (CURRENT_ENV->arena()) ciSignature(accessor, constantPoolHandle(), signature);188}189190191// ------------------------------------------------------------------192// ciMethod::load_code193//194// Load the bytecodes and exception handler table for this method.195void ciMethod::load_code() {196VM_ENTRY_MARK;197assert(is_loaded(), "only loaded methods have code");198199Method* me = get_Method();200Arena* arena = CURRENT_THREAD_ENV->arena();201202// Load the bytecodes.203_code = (address)arena->Amalloc(code_size());204memcpy(_code, me->code_base(), code_size());205206#if INCLUDE_JVMTI207// Revert any breakpoint bytecodes in ci's copy208if (me->number_of_breakpoints() > 0) {209BreakpointInfo* bp = me->method_holder()->breakpoints();210for (; bp != NULL; bp = bp->next()) {211if (bp->match(me)) {212code_at_put(bp->bci(), bp->orig_bytecode());213}214}215}216#endif217218// And load the exception table.219ExceptionTable exc_table(me);220221// Allocate one extra spot in our list of exceptions. This222// last entry will be used to represent the possibility that223// an exception escapes the method. See ciExceptionHandlerStream224// for details.225_exception_handlers =226(ciExceptionHandler**)arena->Amalloc(sizeof(ciExceptionHandler*)227* (_handler_count + 1));228if (_handler_count > 0) {229for (int i=0; i<_handler_count; i++) {230_exception_handlers[i] = new (arena) ciExceptionHandler(231holder(),232/* start */ exc_table.start_pc(i),233/* limit */ exc_table.end_pc(i),234/* goto pc */ exc_table.handler_pc(i),235/* cp index */ exc_table.catch_type_index(i));236}237}238239// Put an entry at the end of our list to represent the possibility240// of exceptional exit.241_exception_handlers[_handler_count] =242new (arena) ciExceptionHandler(holder(), 0, code_size(), -1, 0);243244if (CIPrintMethodCodes) {245print_codes();246}247}248249250// ------------------------------------------------------------------251// ciMethod::has_linenumber_table252//253// length unknown until decompression254bool ciMethod::has_linenumber_table() const {255check_is_loaded();256VM_ENTRY_MARK;257return get_Method()->has_linenumber_table();258}259260261// ------------------------------------------------------------------262// ciMethod::line_number_from_bci263int ciMethod::line_number_from_bci(int bci) const {264check_is_loaded();265VM_ENTRY_MARK;266return get_Method()->line_number_from_bci(bci);267}268269270// ------------------------------------------------------------------271// ciMethod::vtable_index272//273// Get the position of this method's entry in the vtable, if any.274int ciMethod::vtable_index() {275check_is_loaded();276assert(holder()->is_linked(), "must be linked");277VM_ENTRY_MARK;278return get_Method()->vtable_index();279}280281// ------------------------------------------------------------------282// ciMethod::uses_balanced_monitors283//284// Does this method use monitors in a strict stack-disciplined manner?285bool ciMethod::has_balanced_monitors() {286check_is_loaded();287if (_balanced_monitors) return true;288289// Analyze the method to see if monitors are used properly.290VM_ENTRY_MARK;291methodHandle method(THREAD, get_Method());292assert(method->has_monitor_bytecodes(), "should have checked this");293294// Check to see if a previous compilation computed the295// monitor-matching analysis.296if (method->guaranteed_monitor_matching()) {297_balanced_monitors = true;298return true;299}300301{302ExceptionMark em(THREAD);303ResourceMark rm(THREAD);304GeneratePairingInfo gpi(method);305if (!gpi.compute_map(THREAD)) {306fatal("Unrecoverable verification or out-of-memory error");307}308if (!gpi.monitor_safe()) {309return false;310}311method->set_guaranteed_monitor_matching();312_balanced_monitors = true;313}314return true;315}316317318// ------------------------------------------------------------------319// ciMethod::get_flow_analysis320ciTypeFlow* ciMethod::get_flow_analysis() {321#if defined(COMPILER2)322if (_flow == NULL) {323ciEnv* env = CURRENT_ENV;324_flow = new (env->arena()) ciTypeFlow(env, this);325_flow->do_flow();326}327return _flow;328#else // COMPILER2329ShouldNotReachHere();330return NULL;331#endif // COMPILER2332}333334335// ------------------------------------------------------------------336// ciMethod::get_osr_flow_analysis337ciTypeFlow* ciMethod::get_osr_flow_analysis(int osr_bci) {338#if defined(COMPILER2)339// OSR entry points are always place after a call bytecode of some sort340assert(osr_bci >= 0, "must supply valid OSR entry point");341ciEnv* env = CURRENT_ENV;342ciTypeFlow* flow = new (env->arena()) ciTypeFlow(env, this, osr_bci);343flow->do_flow();344return flow;345#else // COMPILER2346ShouldNotReachHere();347return NULL;348#endif // COMPILER2349}350351// ------------------------------------------------------------------352// ciMethod::raw_liveness_at_bci353//354// Which local variables are live at a specific bci?355MethodLivenessResult ciMethod::raw_liveness_at_bci(int bci) {356check_is_loaded();357if (_liveness == NULL) {358// Create the liveness analyzer.359Arena* arena = CURRENT_ENV->arena();360_liveness = new (arena) MethodLiveness(arena, this);361_liveness->compute_liveness();362}363return _liveness->get_liveness_at(bci);364}365366// ------------------------------------------------------------------367// ciMethod::liveness_at_bci368//369// Which local variables are live at a specific bci? When debugging370// will return true for all locals in some cases to improve debug371// information.372MethodLivenessResult ciMethod::liveness_at_bci(int bci) {373if (CURRENT_ENV->should_retain_local_variables() || DeoptimizeALot) {374// Keep all locals live for the user's edification and amusement.375MethodLivenessResult result(_max_locals);376result.set_range(0, _max_locals);377result.set_is_valid();378return result;379}380return raw_liveness_at_bci(bci);381}382383// ciMethod::live_local_oops_at_bci384//385// find all the live oops in the locals array for a particular bci386// Compute what the interpreter believes by using the interpreter387// oopmap generator. This is used as a double check during osr to388// guard against conservative result from MethodLiveness making us389// think a dead oop is live. MethodLiveness is conservative in the390// sense that it may consider locals to be live which cannot be live,391// like in the case where a local could contain an oop or a primitive392// along different paths. In that case the local must be dead when393// those paths merge. Since the interpreter's viewpoint is used when394// gc'ing an interpreter frame we need to use its viewpoint during395// OSR when loading the locals.396397ResourceBitMap ciMethod::live_local_oops_at_bci(int bci) {398VM_ENTRY_MARK;399InterpreterOopMap mask;400OopMapCache::compute_one_oop_map(methodHandle(THREAD, get_Method()), bci, &mask);401int mask_size = max_locals();402ResourceBitMap result(mask_size);403int i;404for (i = 0; i < mask_size ; i++ ) {405if (mask.is_oop(i)) result.set_bit(i);406}407return result;408}409410411#ifdef COMPILER1412// ------------------------------------------------------------------413// ciMethod::bci_block_start414//415// Marks all bcis where a new basic block starts416const BitMap& ciMethod::bci_block_start() {417check_is_loaded();418if (_liveness == NULL) {419// Create the liveness analyzer.420Arena* arena = CURRENT_ENV->arena();421_liveness = new (arena) MethodLiveness(arena, this);422_liveness->compute_liveness();423}424425return _liveness->get_bci_block_start();426}427#endif // COMPILER1428429430// ------------------------------------------------------------------431// ciMethod::check_overflow432//433// Check whether the profile counter is overflowed and adjust if true.434// For invoke* it will turn negative values into max_jint,435// and for checkcast/aastore/instanceof turn positive values into min_jint.436int ciMethod::check_overflow(int c, Bytecodes::Code code) {437switch (code) {438case Bytecodes::_aastore: // fall-through439case Bytecodes::_checkcast: // fall-through440case Bytecodes::_instanceof: {441return (c > 0 ? min_jint : c); // always non-positive442}443default: {444assert(Bytecodes::is_invoke(code), "%s", Bytecodes::name(code));445return (c < 0 ? max_jint : c); // always non-negative446}447}448}449450451// ------------------------------------------------------------------452// ciMethod::call_profile_at_bci453//454// Get the ciCallProfile for the invocation of this method.455// Also reports receiver types for non-call type checks (if TypeProfileCasts).456ciCallProfile ciMethod::call_profile_at_bci(int bci) {457ResourceMark rm;458ciCallProfile result;459if (method_data() != NULL && method_data()->is_mature()) {460ciProfileData* data = method_data()->bci_to_data(bci);461if (data != NULL && data->is_CounterData()) {462// Every profiled call site has a counter.463int count = check_overflow(data->as_CounterData()->count(), java_code_at_bci(bci));464465if (!data->is_ReceiverTypeData()) {466result._receiver_count[0] = 0; // that's a definite zero467} else { // ReceiverTypeData is a subclass of CounterData468ciReceiverTypeData* call = (ciReceiverTypeData*)data->as_ReceiverTypeData();469// In addition, virtual call sites have receiver type information470int receivers_count_total = 0;471int morphism = 0;472// Precompute morphism for the possible fixup473for (uint i = 0; i < call->row_limit(); i++) {474ciKlass* receiver = call->receiver(i);475if (receiver == NULL) continue;476morphism++;477}478int epsilon = 0;479// For a call, it is assumed that either the type of the receiver(s)480// is recorded or an associated counter is incremented, but not both. With481// tiered compilation, however, both can happen due to the interpreter and482// C1 profiling invocations differently. Address that inconsistency here.483if (morphism == 1 && count > 0) {484epsilon = count;485count = 0;486}487for (uint i = 0; i < call->row_limit(); i++) {488ciKlass* receiver = call->receiver(i);489if (receiver == NULL) continue;490int rcount = saturated_add(call->receiver_count(i), epsilon);491if (rcount == 0) rcount = 1; // Should be valid value492receivers_count_total = saturated_add(receivers_count_total, rcount);493// Add the receiver to result data.494result.add_receiver(receiver, rcount);495// If we extend profiling to record methods,496// we will set result._method also.497}498// Determine call site's morphism.499// The call site count is 0 with known morphism (only 1 or 2 receivers)500// or < 0 in the case of a type check failure for checkcast, aastore, instanceof.501// The call site count is > 0 in the case of a polymorphic virtual call.502if (morphism > 0 && morphism == result._limit) {503// The morphism <= MorphismLimit.504if ((morphism < ciCallProfile::MorphismLimit) ||505(morphism == ciCallProfile::MorphismLimit && count == 0)) {506#ifdef ASSERT507if (count > 0) {508this->print_short_name(tty);509tty->print_cr(" @ bci:%d", bci);510this->print_codes();511assert(false, "this call site should not be polymorphic");512}513#endif514result._morphism = morphism;515}516}517// Make the count consistent if this is a call profile. If count is518// zero or less, presume that this is a typecheck profile and519// do nothing. Otherwise, increase count to be the sum of all520// receiver's counts.521if (count >= 0) {522count = saturated_add(count, receivers_count_total);523}524}525result._count = count;526}527}528return result;529}530531// ------------------------------------------------------------------532// Add new receiver and sort data by receiver's profile count.533void ciCallProfile::add_receiver(ciKlass* receiver, int receiver_count) {534// Add new receiver and sort data by receiver's counts when we have space535// for it otherwise replace the less called receiver (less called receiver536// is placed to the last array element which is not used).537// First array's element contains most called receiver.538int i = _limit;539for (; i > 0 && receiver_count > _receiver_count[i-1]; i--) {540_receiver[i] = _receiver[i-1];541_receiver_count[i] = _receiver_count[i-1];542}543_receiver[i] = receiver;544_receiver_count[i] = receiver_count;545if (_limit < MorphismLimit) _limit++;546}547548549void ciMethod::assert_virtual_call_type_ok(int bci) {550assert(java_code_at_bci(bci) == Bytecodes::_invokevirtual ||551java_code_at_bci(bci) == Bytecodes::_invokeinterface, "unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci)));552}553554void ciMethod::assert_call_type_ok(int bci) {555assert(java_code_at_bci(bci) == Bytecodes::_invokestatic ||556java_code_at_bci(bci) == Bytecodes::_invokespecial ||557java_code_at_bci(bci) == Bytecodes::_invokedynamic, "unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci)));558}559560/**561* Check whether profiling provides a type for the argument i to the562* call at bci bci563*564* @param [in]bci bci of the call565* @param [in]i argument number566* @param [out]type profiled type of argument, NULL if none567* @param [out]ptr_kind whether always null, never null or maybe null568* @return true if profiling exists569*570*/571bool ciMethod::argument_profiled_type(int bci, int i, ciKlass*& type, ProfilePtrKind& ptr_kind) {572if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {573ciProfileData* data = method_data()->bci_to_data(bci);574if (data != NULL) {575if (data->is_VirtualCallTypeData()) {576assert_virtual_call_type_ok(bci);577ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();578if (i >= call->number_of_arguments()) {579return false;580}581type = call->valid_argument_type(i);582ptr_kind = call->argument_ptr_kind(i);583return true;584} else if (data->is_CallTypeData()) {585assert_call_type_ok(bci);586ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();587if (i >= call->number_of_arguments()) {588return false;589}590type = call->valid_argument_type(i);591ptr_kind = call->argument_ptr_kind(i);592return true;593}594}595}596return false;597}598599/**600* Check whether profiling provides a type for the return value from601* the call at bci bci602*603* @param [in]bci bci of the call604* @param [out]type profiled type of argument, NULL if none605* @param [out]ptr_kind whether always null, never null or maybe null606* @return true if profiling exists607*608*/609bool ciMethod::return_profiled_type(int bci, ciKlass*& type, ProfilePtrKind& ptr_kind) {610if (MethodData::profile_return() && method_data() != NULL && method_data()->is_mature()) {611ciProfileData* data = method_data()->bci_to_data(bci);612if (data != NULL) {613if (data->is_VirtualCallTypeData()) {614assert_virtual_call_type_ok(bci);615ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();616if (call->has_return()) {617type = call->valid_return_type();618ptr_kind = call->return_ptr_kind();619return true;620}621} else if (data->is_CallTypeData()) {622assert_call_type_ok(bci);623ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();624if (call->has_return()) {625type = call->valid_return_type();626ptr_kind = call->return_ptr_kind();627}628return true;629}630}631}632return false;633}634635/**636* Check whether profiling provides a type for the parameter i637*638* @param [in]i parameter number639* @param [out]type profiled type of parameter, NULL if none640* @param [out]ptr_kind whether always null, never null or maybe null641* @return true if profiling exists642*643*/644bool ciMethod::parameter_profiled_type(int i, ciKlass*& type, ProfilePtrKind& ptr_kind) {645if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {646ciParametersTypeData* parameters = method_data()->parameters_type_data();647if (parameters != NULL && i < parameters->number_of_parameters()) {648type = parameters->valid_parameter_type(i);649ptr_kind = parameters->parameter_ptr_kind(i);650return true;651}652}653return false;654}655656657// ------------------------------------------------------------------658// ciMethod::find_monomorphic_target659//660// Given a certain calling environment, find the monomorphic target661// for the call. Return NULL if the call is not monomorphic in662// its calling environment, or if there are only abstract methods.663// The returned method is never abstract.664// Note: If caller uses a non-null result, it must inform dependencies665// via assert_unique_concrete_method or assert_leaf_type.666ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller,667ciInstanceKlass* callee_holder,668ciInstanceKlass* actual_recv,669bool check_access) {670check_is_loaded();671672if (actual_recv->is_interface()) {673// %%% We cannot trust interface types, yet. See bug 6312651.674return NULL;675}676677ciMethod* root_m = resolve_invoke(caller, actual_recv, check_access, true /* allow_abstract */);678if (root_m == NULL) {679// Something went wrong looking up the actual receiver method.680return NULL;681}682683// Make certain quick checks even if UseCHA is false.684685// Is it private or final?686if (root_m->can_be_statically_bound()) {687assert(!root_m->is_abstract(), "sanity");688return root_m;689}690691if (actual_recv->is_leaf_type() && actual_recv == root_m->holder()) {692// Easy case. There is no other place to put a method, so don't bother693// to go through the VM_ENTRY_MARK and all the rest.694if (root_m->is_abstract()) {695return NULL;696}697return root_m;698}699700// Array methods (clone, hashCode, etc.) are always statically bound.701// If we were to see an array type here, we'd return root_m.702// However, this method processes only ciInstanceKlasses. (See 4962591.)703// The inline_native_clone intrinsic narrows Object to T[] properly,704// so there is no need to do the same job here.705706if (!UseCHA) return NULL;707708VM_ENTRY_MARK;709710methodHandle target;711{712MutexLocker locker(Compile_lock);713InstanceKlass* context = actual_recv->get_instanceKlass();714if (UseVtableBasedCHA) {715target = methodHandle(THREAD, Dependencies::find_unique_concrete_method(context,716root_m->get_Method(),717callee_holder->get_Klass(),718this->get_Method()));719} else {720if (root_m->is_abstract()) {721return NULL; // not supported722}723target = methodHandle(THREAD, Dependencies::find_unique_concrete_method(context, root_m->get_Method()));724}725assert(target() == NULL || !target()->is_abstract(), "not allowed");726// %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods.727}728729#ifndef PRODUCT730if (TraceDependencies && target() != NULL && target() != root_m->get_Method()) {731tty->print("found a non-root unique target method");732tty->print_cr(" context = %s", actual_recv->get_Klass()->external_name());733tty->print(" method = ");734target->print_short_name(tty);735tty->cr();736}737#endif //PRODUCT738739if (target() == NULL) {740return NULL;741}742if (target() == root_m->get_Method()) {743return root_m;744}745if (!root_m->is_public() &&746!root_m->is_protected()) {747// If we are going to reason about inheritance, it's easiest748// if the method in question is public, protected, or private.749// If the answer is not root_m, it is conservatively correct750// to return NULL, even if the CHA encountered irrelevant751// methods in other packages.752// %%% TO DO: Work out logic for package-private methods753// with the same name but different vtable indexes.754return NULL;755}756return CURRENT_THREAD_ENV->get_method(target());757}758759// ------------------------------------------------------------------760// ciMethod::can_be_statically_bound761//762// Tries to determine whether a method can be statically bound in some context.763bool ciMethod::can_be_statically_bound(ciInstanceKlass* context) const {764return (holder() == context) && can_be_statically_bound();765}766767// ------------------------------------------------------------------768// ciMethod::resolve_invoke769//770// Given a known receiver klass, find the target for the call.771// Return NULL if the call has no target or the target is abstract.772ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, bool check_access, bool allow_abstract) {773check_is_loaded();774VM_ENTRY_MARK;775776Klass* caller_klass = caller->get_Klass();777Klass* recv = exact_receiver->get_Klass();778Klass* resolved = holder()->get_Klass();779Symbol* h_name = name()->get_symbol();780Symbol* h_signature = signature()->get_symbol();781782LinkInfo link_info(resolved, h_name, h_signature, caller_klass,783check_access ? LinkInfo::AccessCheck::required : LinkInfo::AccessCheck::skip,784check_access ? LinkInfo::LoaderConstraintCheck::required : LinkInfo::LoaderConstraintCheck::skip);785Method* m = NULL;786// Only do exact lookup if receiver klass has been linked. Otherwise,787// the vtable has not been setup, and the LinkResolver will fail.788if (recv->is_array_klass()789||790(InstanceKlass::cast(recv)->is_linked() && !exact_receiver->is_interface())) {791if (holder()->is_interface()) {792m = LinkResolver::resolve_interface_call_or_null(recv, link_info);793} else {794m = LinkResolver::resolve_virtual_call_or_null(recv, link_info);795}796}797798if (m == NULL) {799// Return NULL only if there was a problem with lookup (uninitialized class, etc.)800return NULL;801}802803ciMethod* result = this;804if (m != get_Method()) {805result = CURRENT_THREAD_ENV->get_method(m);806}807808if (result->is_abstract() && !allow_abstract) {809// Don't return abstract methods because they aren't optimizable or interesting.810return NULL;811}812return result;813}814815// ------------------------------------------------------------------816// ciMethod::resolve_vtable_index817//818// Given a known receiver klass, find the vtable index for the call.819// Return Method::invalid_vtable_index if the vtable_index is unknown.820int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) {821check_is_loaded();822823int vtable_index = Method::invalid_vtable_index;824// Only do lookup if receiver klass has been linked. Otherwise,825// the vtable has not been setup, and the LinkResolver will fail.826if (!receiver->is_interface()827&& (!receiver->is_instance_klass() ||828receiver->as_instance_klass()->is_linked())) {829VM_ENTRY_MARK;830831Klass* caller_klass = caller->get_Klass();832Klass* recv = receiver->get_Klass();833Symbol* h_name = name()->get_symbol();834Symbol* h_signature = signature()->get_symbol();835836LinkInfo link_info(recv, h_name, h_signature, caller_klass);837vtable_index = LinkResolver::resolve_virtual_vtable_index(recv, link_info);838if (vtable_index == Method::nonvirtual_vtable_index) {839// A statically bound method. Return "no such index".840vtable_index = Method::invalid_vtable_index;841}842}843844return vtable_index;845}846847// ------------------------------------------------------------------848// ciMethod::get_field_at_bci849ciField* ciMethod::get_field_at_bci(int bci, bool &will_link) {850ciBytecodeStream iter(this);851iter.reset_to_bci(bci);852iter.next();853return iter.get_field(will_link);854}855856// ------------------------------------------------------------------857// ciMethod::get_method_at_bci858ciMethod* ciMethod::get_method_at_bci(int bci, bool &will_link, ciSignature* *declared_signature) {859ciBytecodeStream iter(this);860iter.reset_to_bci(bci);861iter.next();862return iter.get_method(will_link, declared_signature);863}864865// ------------------------------------------------------------------866ciKlass* ciMethod::get_declared_method_holder_at_bci(int bci) {867ciBytecodeStream iter(this);868iter.reset_to_bci(bci);869iter.next();870return iter.get_declared_method_holder();871}872873// ------------------------------------------------------------------874// Adjust a CounterData count to be commensurate with875// interpreter_invocation_count. If the MDO exists for876// only 25% of the time the method exists, then the877// counts in the MDO should be scaled by 4X, so that878// they can be usefully and stably compared against the879// invocation counts in methods.880int ciMethod::scale_count(int count, float prof_factor) {881if (count > 0 && method_data() != NULL) {882int counter_life;883int method_life = interpreter_invocation_count();884// In tiered the MDO's life is measured directly, so just use the snapshotted counters885counter_life = MAX2(method_data()->invocation_count(), method_data()->backedge_count());886887// counter_life due to backedge_counter could be > method_life888if (counter_life > method_life)889counter_life = method_life;890if (0 < counter_life && counter_life <= method_life) {891count = (int)((double)count * prof_factor * method_life / counter_life + 0.5);892count = (count > 0) ? count : 1;893}894}895return count;896}897898899// ------------------------------------------------------------------900// ciMethod::is_special_get_caller_class_method901//902bool ciMethod::is_ignored_by_security_stack_walk() const {903check_is_loaded();904VM_ENTRY_MARK;905return get_Method()->is_ignored_by_security_stack_walk();906}907908// ------------------------------------------------------------------909// ciMethod::needs_clinit_barrier910//911bool ciMethod::needs_clinit_barrier() const {912check_is_loaded();913return is_static() && !holder()->is_initialized();914}915916// ------------------------------------------------------------------917// invokedynamic support918919// ------------------------------------------------------------------920// ciMethod::is_method_handle_intrinsic921//922// Return true if the method is an instance of the JVM-generated923// signature-polymorphic MethodHandle methods, _invokeBasic, _linkToVirtual, etc.924bool ciMethod::is_method_handle_intrinsic() const {925vmIntrinsics::ID iid = _intrinsic_id; // do not check if loaded926return (MethodHandles::is_signature_polymorphic(iid) &&927MethodHandles::is_signature_polymorphic_intrinsic(iid));928}929930// ------------------------------------------------------------------931// ciMethod::is_compiled_lambda_form932//933// Return true if the method is a generated MethodHandle adapter.934// These are built by Java code.935bool ciMethod::is_compiled_lambda_form() const {936vmIntrinsics::ID iid = _intrinsic_id; // do not check if loaded937return iid == vmIntrinsics::_compiledLambdaForm;938}939940// ------------------------------------------------------------------941// ciMethod::is_object_initializer942//943bool ciMethod::is_object_initializer() const {944return name() == ciSymbols::object_initializer_name();945}946947// ------------------------------------------------------------------948// ciMethod::has_member_arg949//950// Return true if the method is a linker intrinsic like _linkToVirtual.951// These are built by the JVM.952bool ciMethod::has_member_arg() const {953vmIntrinsics::ID iid = _intrinsic_id; // do not check if loaded954return (MethodHandles::is_signature_polymorphic(iid) &&955MethodHandles::has_member_arg(iid));956}957958// ------------------------------------------------------------------959// ciMethod::ensure_method_data960//961// Generate new MethodData* objects at compile time.962// Return true if allocation was successful or no MDO is required.963bool ciMethod::ensure_method_data(const methodHandle& h_m) {964EXCEPTION_CONTEXT;965if (is_native() || is_abstract() || h_m()->is_accessor()) {966return true;967}968if (h_m()->method_data() == NULL) {969Method::build_interpreter_method_data(h_m, THREAD);970if (HAS_PENDING_EXCEPTION) {971CLEAR_PENDING_EXCEPTION;972}973}974if (h_m()->method_data() != NULL) {975_method_data = CURRENT_ENV->get_method_data(h_m()->method_data());976return _method_data->load_data();977} else {978_method_data = CURRENT_ENV->get_empty_methodData();979return false;980}981}982983// public, retroactive version984bool ciMethod::ensure_method_data() {985bool result = true;986if (_method_data == NULL || _method_data->is_empty()) {987GUARDED_VM_ENTRY({988methodHandle mh(Thread::current(), get_Method());989result = ensure_method_data(mh);990});991}992return result;993}994995996// ------------------------------------------------------------------997// ciMethod::method_data998//999ciMethodData* ciMethod::method_data() {1000if (_method_data != NULL) {1001return _method_data;1002}1003VM_ENTRY_MARK;1004ciEnv* env = CURRENT_ENV;1005Thread* my_thread = JavaThread::current();1006methodHandle h_m(my_thread, get_Method());10071008if (h_m()->method_data() != NULL) {1009_method_data = CURRENT_ENV->get_method_data(h_m()->method_data());1010_method_data->load_data();1011} else {1012_method_data = CURRENT_ENV->get_empty_methodData();1013}1014return _method_data;10151016}10171018// ------------------------------------------------------------------1019// ciMethod::method_data_or_null1020// Returns a pointer to ciMethodData if MDO exists on the VM side,1021// NULL otherwise.1022ciMethodData* ciMethod::method_data_or_null() {1023ciMethodData *md = method_data();1024if (md->is_empty()) {1025return NULL;1026}1027return md;1028}10291030// ------------------------------------------------------------------1031// ciMethod::ensure_method_counters1032//1033MethodCounters* ciMethod::ensure_method_counters() {1034check_is_loaded();1035VM_ENTRY_MARK;1036methodHandle mh(THREAD, get_Method());1037MethodCounters* method_counters = mh->get_method_counters(CHECK_NULL);1038return method_counters;1039}10401041// ------------------------------------------------------------------1042// ciMethod::has_option1043//1044bool ciMethod::has_option(enum CompileCommand option) {1045check_is_loaded();1046VM_ENTRY_MARK;1047methodHandle mh(THREAD, get_Method());1048return CompilerOracle::has_option(mh, option);1049}10501051// ------------------------------------------------------------------1052// ciMethod::has_option_value1053//1054bool ciMethod::has_option_value(enum CompileCommand option, double& value) {1055check_is_loaded();1056VM_ENTRY_MARK;1057methodHandle mh(THREAD, get_Method());1058return CompilerOracle::has_option_value(mh, option, value);1059}1060// ------------------------------------------------------------------1061// ciMethod::can_be_compiled1062//1063// Have previous compilations of this method succeeded?1064bool ciMethod::can_be_compiled() {1065check_is_loaded();1066ciEnv* env = CURRENT_ENV;1067if (is_c1_compile(env->comp_level())) {1068return _is_c1_compilable;1069}1070return _is_c2_compilable;1071}10721073// ------------------------------------------------------------------1074// ciMethod::has_compiled_code1075bool ciMethod::has_compiled_code() {1076return instructions_size() > 0;1077}10781079int ciMethod::highest_osr_comp_level() {1080check_is_loaded();1081VM_ENTRY_MARK;1082return get_Method()->highest_osr_comp_level();1083}10841085// ------------------------------------------------------------------1086// ciMethod::code_size_for_inlining1087//1088// Code size for inlining decisions. This method returns a code1089// size of 1 for methods which has the ForceInline annotation.1090int ciMethod::code_size_for_inlining() {1091check_is_loaded();1092if (get_Method()->force_inline()) {1093return 1;1094}1095return code_size();1096}10971098// ------------------------------------------------------------------1099// ciMethod::instructions_size1100//1101// This is a rough metric for "fat" methods, compared before inlining1102// with InlineSmallCode. The CodeBlob::code_size accessor includes1103// junk like exception handler, stubs, and constant table, which are1104// not highly relevant to an inlined method. So we use the more1105// specific accessor nmethod::insts_size.1106int ciMethod::instructions_size() {1107if (_instructions_size == -1) {1108GUARDED_VM_ENTRY(1109CompiledMethod* code = get_Method()->code();1110if (code != NULL && (code->comp_level() == CompLevel_full_optimization)) {1111_instructions_size = code->insts_end() - code->verified_entry_point();1112} else {1113_instructions_size = 0;1114}1115);1116}1117return _instructions_size;1118}11191120// ------------------------------------------------------------------1121// ciMethod::log_nmethod_identity1122void ciMethod::log_nmethod_identity(xmlStream* log) {1123GUARDED_VM_ENTRY(1124CompiledMethod* code = get_Method()->code();1125if (code != NULL) {1126code->log_identity(log);1127}1128)1129}11301131// ------------------------------------------------------------------1132// ciMethod::is_not_reached1133bool ciMethod::is_not_reached(int bci) {1134check_is_loaded();1135VM_ENTRY_MARK;1136return Interpreter::is_not_reached(1137methodHandle(THREAD, get_Method()), bci);1138}11391140// ------------------------------------------------------------------1141// ciMethod::was_never_executed1142bool ciMethod::was_executed_more_than(int times) {1143VM_ENTRY_MARK;1144return get_Method()->was_executed_more_than(times);1145}11461147// ------------------------------------------------------------------1148// ciMethod::has_unloaded_classes_in_signature1149bool ciMethod::has_unloaded_classes_in_signature() {1150VM_ENTRY_MARK;1151{1152ExceptionMark em(THREAD);1153methodHandle m(THREAD, get_Method());1154bool has_unloaded = Method::has_unloaded_classes_in_signature(m, thread);1155if( HAS_PENDING_EXCEPTION ) {1156CLEAR_PENDING_EXCEPTION;1157return true; // Declare that we may have unloaded classes1158}1159return has_unloaded;1160}1161}11621163// ------------------------------------------------------------------1164// ciMethod::is_klass_loaded1165bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const {1166VM_ENTRY_MARK;1167return get_Method()->is_klass_loaded(refinfo_index, must_be_resolved);1168}11691170// ------------------------------------------------------------------1171// ciMethod::check_call1172bool ciMethod::check_call(int refinfo_index, bool is_static) const {1173// This method is used only in C2 from InlineTree::ok_to_inline,1174// and is only used under -Xcomp.1175// It appears to fail when applied to an invokeinterface call site.1176// FIXME: Remove this method and resolve_method_statically; refactor to use the other LinkResolver entry points.1177VM_ENTRY_MARK;1178{1179ExceptionMark em(THREAD);1180HandleMark hm(THREAD);1181constantPoolHandle pool (THREAD, get_Method()->constants());1182Bytecodes::Code code = (is_static ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual);1183Method* spec_method = LinkResolver::resolve_method_statically(code, pool, refinfo_index, THREAD);1184if (HAS_PENDING_EXCEPTION) {1185CLEAR_PENDING_EXCEPTION;1186return false;1187} else {1188return (spec_method->is_static() == is_static);1189}1190}1191return false;1192}11931194// ------------------------------------------------------------------1195// ciMethod::profile_aging1196//1197// Should the method be compiled with an age counter?1198bool ciMethod::profile_aging() const {1199return UseCodeAging && (!MethodCounters::is_nmethod_hot(nmethod_age()) &&1200!MethodCounters::is_nmethod_age_unset(nmethod_age()));1201}1202// ------------------------------------------------------------------1203// ciMethod::print_codes1204//1205// Print the bytecodes for this method.1206void ciMethod::print_codes_on(outputStream* st) {1207check_is_loaded();1208GUARDED_VM_ENTRY(get_Method()->print_codes_on(st);)1209}121012111212#define FETCH_FLAG_FROM_VM(flag_accessor) { \1213check_is_loaded(); \1214VM_ENTRY_MARK; \1215return get_Method()->flag_accessor(); \1216}12171218bool ciMethod::has_loops () const { FETCH_FLAG_FROM_VM(has_loops); }1219bool ciMethod::has_jsrs () const { FETCH_FLAG_FROM_VM(has_jsrs); }1220bool ciMethod::is_getter () const { FETCH_FLAG_FROM_VM(is_getter); }1221bool ciMethod::is_setter () const { FETCH_FLAG_FROM_VM(is_setter); }1222bool ciMethod::is_accessor () const { FETCH_FLAG_FROM_VM(is_accessor); }1223bool ciMethod::is_initializer () const { FETCH_FLAG_FROM_VM(is_initializer); }1224bool ciMethod::is_empty () const { FETCH_FLAG_FROM_VM(is_empty_method); }12251226bool ciMethod::is_boxing_method() const {1227if (intrinsic_id() != vmIntrinsics::_none && holder()->is_box_klass()) {1228switch (intrinsic_id()) {1229case vmIntrinsics::_Boolean_valueOf:1230case vmIntrinsics::_Byte_valueOf:1231case vmIntrinsics::_Character_valueOf:1232case vmIntrinsics::_Short_valueOf:1233case vmIntrinsics::_Integer_valueOf:1234case vmIntrinsics::_Long_valueOf:1235case vmIntrinsics::_Float_valueOf:1236case vmIntrinsics::_Double_valueOf:1237return true;1238default:1239return false;1240}1241}1242return false;1243}12441245bool ciMethod::is_unboxing_method() const {1246if (intrinsic_id() != vmIntrinsics::_none && holder()->is_box_klass()) {1247switch (intrinsic_id()) {1248case vmIntrinsics::_booleanValue:1249case vmIntrinsics::_byteValue:1250case vmIntrinsics::_charValue:1251case vmIntrinsics::_shortValue:1252case vmIntrinsics::_intValue:1253case vmIntrinsics::_longValue:1254case vmIntrinsics::_floatValue:1255case vmIntrinsics::_doubleValue:1256return true;1257default:1258return false;1259}1260}1261return false;1262}12631264bool ciMethod::is_vector_method() const {1265return (holder() == ciEnv::current()->vector_VectorSupport_klass()) &&1266(intrinsic_id() != vmIntrinsics::_none);1267}12681269BCEscapeAnalyzer *ciMethod::get_bcea() {1270#ifdef COMPILER21271if (_bcea == NULL) {1272_bcea = new (CURRENT_ENV->arena()) BCEscapeAnalyzer(this, NULL);1273}1274return _bcea;1275#else // COMPILER21276ShouldNotReachHere();1277return NULL;1278#endif // COMPILER21279}12801281ciMethodBlocks *ciMethod::get_method_blocks() {1282if (_method_blocks == NULL) {1283Arena *arena = CURRENT_ENV->arena();1284_method_blocks = new (arena) ciMethodBlocks(arena, this);1285}1286return _method_blocks;1287}12881289#undef FETCH_FLAG_FROM_VM12901291void ciMethod::dump_name_as_ascii(outputStream* st) {1292Method* method = get_Method();1293st->print("%s %s %s",1294method->klass_name()->as_quoted_ascii(),1295method->name()->as_quoted_ascii(),1296method->signature()->as_quoted_ascii());1297}12981299void ciMethod::dump_replay_data(outputStream* st) {1300ResourceMark rm;1301Method* method = get_Method();1302MethodCounters* mcs = method->method_counters();1303st->print("ciMethod ");1304dump_name_as_ascii(st);1305st->print_cr(" %d %d %d %d %d",1306mcs == NULL ? 0 : mcs->invocation_counter()->raw_counter(),1307mcs == NULL ? 0 : mcs->backedge_counter()->raw_counter(),1308interpreter_invocation_count(),1309interpreter_throwout_count(),1310_instructions_size);1311}13121313// ------------------------------------------------------------------1314// ciMethod::print_codes1315//1316// Print a range of the bytecodes for this method.1317void ciMethod::print_codes_on(int from, int to, outputStream* st) {1318check_is_loaded();1319GUARDED_VM_ENTRY(get_Method()->print_codes_on(from, to, st);)1320}13211322// ------------------------------------------------------------------1323// ciMethod::print_name1324//1325// Print the name of this method, including signature and some flags.1326void ciMethod::print_name(outputStream* st) {1327check_is_loaded();1328GUARDED_VM_ENTRY(get_Method()->print_name(st);)1329}13301331// ------------------------------------------------------------------1332// ciMethod::print_short_name1333//1334// Print the name of this method, without signature.1335void ciMethod::print_short_name(outputStream* st) {1336if (is_loaded()) {1337GUARDED_VM_ENTRY(get_Method()->print_short_name(st););1338} else {1339// Fall back if method is not loaded.1340holder()->print_name_on(st);1341st->print("::");1342name()->print_symbol_on(st);1343if (WizardMode)1344signature()->as_symbol()->print_symbol_on(st);1345}1346}13471348// ------------------------------------------------------------------1349// ciMethod::print_impl1350//1351// Implementation of the print method.1352void ciMethod::print_impl(outputStream* st) {1353ciMetadata::print_impl(st);1354st->print(" name=");1355name()->print_symbol_on(st);1356st->print(" holder=");1357holder()->print_name_on(st);1358st->print(" signature=");1359signature()->as_symbol()->print_symbol_on(st);1360if (is_loaded()) {1361st->print(" loaded=true");1362st->print(" arg_size=%d", arg_size());1363st->print(" flags=");1364flags().print_member_flags(st);1365} else {1366st->print(" loaded=false");1367}1368}13691370// ------------------------------------------------------------------13711372static BasicType erase_to_word_type(BasicType bt) {1373if (is_subword_type(bt)) return T_INT;1374if (is_reference_type(bt)) return T_OBJECT;1375return bt;1376}13771378static bool basic_types_match(ciType* t1, ciType* t2) {1379if (t1 == t2) return true;1380return erase_to_word_type(t1->basic_type()) == erase_to_word_type(t2->basic_type());1381}13821383bool ciMethod::is_consistent_info(ciMethod* declared_method, ciMethod* resolved_method) {1384bool invoke_through_mh_intrinsic = declared_method->is_method_handle_intrinsic() &&1385!resolved_method->is_method_handle_intrinsic();13861387if (!invoke_through_mh_intrinsic) {1388// Method name & descriptor should stay the same.1389// Signatures may reference unloaded types and thus they may be not strictly equal.1390ciSymbol* declared_signature = declared_method->signature()->as_symbol();1391ciSymbol* resolved_signature = resolved_method->signature()->as_symbol();13921393return (declared_method->name()->equals(resolved_method->name())) &&1394(declared_signature->equals(resolved_signature));1395}13961397ciMethod* linker = declared_method;1398ciMethod* target = resolved_method;1399// Linkers have appendix argument which is not passed to callee.1400int has_appendix = MethodHandles::has_member_arg(linker->intrinsic_id()) ? 1 : 0;1401if (linker->arg_size() != (target->arg_size() + has_appendix)) {1402return false; // argument slot count mismatch1403}14041405ciSignature* linker_sig = linker->signature();1406ciSignature* target_sig = target->signature();14071408if (linker_sig->count() + (linker->is_static() ? 0 : 1) !=1409target_sig->count() + (target->is_static() ? 0 : 1) + has_appendix) {1410return false; // argument count mismatch1411}14121413int sbase = 0, rbase = 0;1414switch (linker->intrinsic_id()) {1415case vmIntrinsics::_linkToVirtual:1416case vmIntrinsics::_linkToInterface:1417case vmIntrinsics::_linkToSpecial: {1418if (target->is_static()) {1419return false;1420}1421if (linker_sig->type_at(0)->is_primitive_type()) {1422return false; // receiver should be an oop1423}1424sbase = 1; // skip receiver1425break;1426}1427case vmIntrinsics::_linkToStatic: {1428if (!target->is_static()) {1429return false;1430}1431break;1432}1433case vmIntrinsics::_invokeBasic: {1434if (target->is_static()) {1435if (target_sig->type_at(0)->is_primitive_type()) {1436return false; // receiver should be an oop1437}1438rbase = 1; // skip receiver1439}1440break;1441}1442default:1443break;1444}1445assert(target_sig->count() - rbase == linker_sig->count() - sbase - has_appendix, "argument count mismatch");1446int arg_count = target_sig->count() - rbase;1447for (int i = 0; i < arg_count; i++) {1448if (!basic_types_match(linker_sig->type_at(sbase + i), target_sig->type_at(rbase + i))) {1449return false;1450}1451}1452// Only check the return type if the symbolic info has non-void return type.1453// I.e. the return value of the resolved method can be dropped.1454if (!linker->return_type()->is_void() &&1455!basic_types_match(linker->return_type(), target->return_type())) {1456return false;1457}1458return true; // no mismatch found1459}14601461// ------------------------------------------------------------------146214631464