/* * Copyright (c) 1999, 2022, 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. *
*/
class ciMethodBlocks; class MethodLiveness; class Arena; class BCEscapeAnalyzer; class InlineTree; class xmlStream;
// Whether profiling found an oop to be always, never or sometimes // null enum ProfilePtrKind {
ProfileAlwaysNull,
ProfileNeverNull,
ProfileMaybeNull
};
// ciMethod // // This class represents a Method* in the HotSpot virtual // machine. class ciMethod : public ciMetadata { friendclass CompileBroker;
CI_PACKAGE_ACCESS friendclass ciEnv; friendclass ciExceptionHandlerStream; friendclass ciBytecodeStream; friendclass ciMethodHandle; friendclass ciReplay; friendclass InlineTree;
// Code attributes. int _code_size; int _max_stack; int _max_locals;
vmIntrinsicID _intrinsic_id; int _handler_count; int _interpreter_invocation_count; int _interpreter_throwout_count; int _instructions_size; int _size_of_parameters;
// Signature information.
ciSignature* signature() const { return _signature; }
ciType* return_type() const { return _signature->return_type(); } int arg_size_no_receiver() const { return _signature->size(); } // Can only be used on loaded ciMethods int arg_size() const {
check_is_loaded(); return _signature->size() + (_flags.is_static() ? 0 : 1);
} // Report the number of elements on stack when invoking the current method. // If the method is loaded, arg_size() gives precise information about the // number of stack elements (using the method's signature and its flags). // However, if the method is not loaded, the number of stack elements must // be determined differently, as the method's flags are not yet available. // The invoke_arg_size() method assumes in that case that all bytecodes except // invokestatic and invokedynamic have a receiver that is also pushed onto the // stack by the caller of the current method. int invoke_arg_size(Bytecodes::Code code) const { if (is_loaded()) { return arg_size();
} else { int arg_size = _signature->size(); if (code != Bytecodes::_invokestatic &&
code != Bytecodes::_invokedynamic) {
arg_size++;
} return arg_size;
}
}
Method* get_Method() const {
Method* m = (Method*)_metadata;
assert(m != NULL, "illegal use of unloaded method"); return m;
}
// Method code and related information.
address code() { if (_code == NULL) load_code(); return _code; } int code_size() const { check_is_loaded(); return _code_size; } int max_stack() const { check_is_loaded(); return _max_stack; } int max_locals() const { check_is_loaded(); return _max_locals; }
vmIntrinsicID intrinsic_id() const { check_is_loaded(); return _intrinsic_id; } bool has_exception_handlers() const { check_is_loaded(); return _handler_count > 0; } int exception_table_length() const { check_is_loaded(); return _handler_count; } int interpreter_invocation_count() const { check_is_loaded(); return _interpreter_invocation_count; } int interpreter_throwout_count() const { check_is_loaded(); return _interpreter_throwout_count; } int size_of_parameters() const { check_is_loaded(); return _size_of_parameters; }
// Code size for inlining decisions. int code_size_for_inlining();
bool check_intrinsic_candidate() const { if (intrinsic_id() == vmIntrinsics::_blackhole) { // This is the intrinsic without an associated method, so no intrinsic_candidate // flag is set. The intrinsic is still correct. returntrue;
} return (CheckIntrinsics ? intrinsic_candidate() : true);
}
bool has_linenumber_table() const; // length unknown until decompression
int line_number_from_bci(int bci) const;
// Runtime information. int vtable_index();
// Analysis and profiling. // // Usage note: liveness_at_bci and init_vars should be wrapped in ResourceMarks. bool has_monitor_bytecodes() const { return _uses_monitors; } bool has_balanced_monitors();
// Returns a bitmap indicating which locals are required to be // maintained as live for deopt. raw_liveness_at_bci is always the // direct output of the liveness computation while liveness_at_bci // may mark all locals as live to improve support for debugging Java // code by maintaining the state of as many locals as possible.
MethodLivenessResult raw_liveness_at_bci(int bci);
MethodLivenessResult liveness_at_bci(int bci);
// Get the interpreters viewpoint on oop liveness. 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.
// Does type profiling provide any useful information at this point? bool argument_profiled_type(int bci, int i, ciKlass*& type, ProfilePtrKind& ptr_kind); bool parameter_profiled_type(int i, ciKlass*& type, ProfilePtrKind& ptr_kind); bool return_profiled_type(int bci, ciKlass*& type, ProfilePtrKind& ptr_kind);
// Given a certain calling environment, find the monomorphic target // for the call. Return NULL if the call is not monomorphic in // its calling environment.
ciMethod* find_monomorphic_target(ciInstanceKlass* caller,
ciInstanceKlass* callee_holder,
ciInstanceKlass* actual_receiver, bool check_access = true);
// Given a known receiver klass, find the target for the call. // Return NULL if the call has no target or is abstract.
ciMethod* resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, bool check_access = true, bool allow_abstract = false);
// Find the proper vtable index to invoke this method. int resolve_vtable_index(ciKlass* caller, ciKlass* receiver);
bool has_option(enum CompileCommand option); bool has_option_value(enum CompileCommand option, double& value); bool can_be_compiled(); bool can_be_parsed() const { return _can_be_parsed; } bool has_compiled_code(); void log_nmethod_identity(xmlStream* log); bool is_not_reached(int bci); bool was_executed_more_than(int times); bool has_unloaded_classes_in_signature(); bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const; bool check_call(int refinfo_index, bool is_static) const; bool ensure_method_data(); // make sure it exists in the VM also
MethodCounters* ensure_method_counters(); int instructions_size(); int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC
// Stack walking support bool is_ignored_by_security_stack_walk() const;
// Print the bytecodes of this method. void print_codes_on(outputStream* st); void print_codes() {
print_codes_on(tty);
} void print_codes_on(int from, int to, outputStream* st);
// Print the name of this method in various incarnations. void print_name(outputStream* st = tty); void print_short_name(outputStream* st = tty);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.