Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/oops/methodData.hpp
32285 views
/*1* Copyright (c) 2000, 2013, 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#ifndef SHARE_VM_OOPS_METHODDATAOOP_HPP25#define SHARE_VM_OOPS_METHODDATAOOP_HPP2627#include "interpreter/bytecodes.hpp"28#include "memory/universe.hpp"29#include "oops/method.hpp"30#include "oops/oop.hpp"31#include "runtime/orderAccess.hpp"3233class BytecodeStream;34class KlassSizeStats;3536// The MethodData object collects counts and other profile information37// during zeroth-tier (interpretive) and first-tier execution.38// The profile is used later by compilation heuristics. Some heuristics39// enable use of aggressive (or "heroic") optimizations. An aggressive40// optimization often has a down-side, a corner case that it handles41// poorly, but which is thought to be rare. The profile provides42// evidence of this rarity for a given method or even BCI. It allows43// the compiler to back out of the optimization at places where it44// has historically been a poor choice. Other heuristics try to use45// specific information gathered about types observed at a given site.46//47// All data in the profile is approximate. It is expected to be accurate48// on the whole, but the system expects occasional inaccuraces, due to49// counter overflow, multiprocessor races during data collection, space50// limitations, missing MDO blocks, etc. Bad or missing data will degrade51// optimization quality but will not affect correctness. Also, each MDO52// is marked with its birth-date ("creation_mileage") which can be used53// to assess the quality ("maturity") of its data.54//55// Short (<32-bit) counters are designed to overflow to a known "saturated"56// state. Also, certain recorded per-BCI events are given one-bit counters57// which overflow to a saturated state which applied to all counters at58// that BCI. In other words, there is a small lattice which approximates59// the ideal of an infinite-precision counter for each event at each BCI,60// and the lattice quickly "bottoms out" in a state where all counters61// are taken to be indefinitely large.62//63// The reader will find many data races in profile gathering code, starting64// with invocation counter incrementation. None of these races harm correct65// execution of the compiled code.6667// forward decl68class ProfileData;6970// DataLayout71//72// Overlay for generic profiling data.73class DataLayout VALUE_OBJ_CLASS_SPEC {74friend class VMStructs;7576private:77// Every data layout begins with a header. This header78// contains a tag, which is used to indicate the size/layout79// of the data, 4 bits of flags, which can be used in any way,80// 4 bits of trap history (none/one reason/many reasons),81// and a bci, which is used to tie this piece of data to a82// specific bci in the bytecodes.83union {84intptr_t _bits;85struct {86u1 _tag;87u1 _flags;88u2 _bci;89} _struct;90} _header;9192// The data layout has an arbitrary number of cells, each sized93// to accomodate a pointer or an integer.94intptr_t _cells[1];9596// Some types of data layouts need a length field.97static bool needs_array_len(u1 tag);9899public:100enum {101counter_increment = 1102};103104enum {105cell_size = sizeof(intptr_t)106};107108// Tag values109enum {110no_tag,111bit_data_tag,112counter_data_tag,113jump_data_tag,114receiver_type_data_tag,115virtual_call_data_tag,116ret_data_tag,117branch_data_tag,118multi_branch_data_tag,119arg_info_data_tag,120call_type_data_tag,121virtual_call_type_data_tag,122parameters_type_data_tag,123speculative_trap_data_tag124};125126enum {127// The _struct._flags word is formatted as [trap_state:4 | flags:4].128// The trap state breaks down further as [recompile:1 | reason:3].129// This further breakdown is defined in deoptimization.cpp.130// See Deoptimization::trap_state_reason for an assert that131// trap_bits is big enough to hold reasons < Reason_RECORDED_LIMIT.132//133// The trap_state is collected only if ProfileTraps is true.134trap_bits = 1+3, // 3: enough to distinguish [0..Reason_RECORDED_LIMIT].135trap_shift = BitsPerByte - trap_bits,136trap_mask = right_n_bits(trap_bits),137trap_mask_in_place = (trap_mask << trap_shift),138flag_limit = trap_shift,139flag_mask = right_n_bits(flag_limit),140first_flag = 0141};142143// Size computation144static int header_size_in_bytes() {145return cell_size;146}147static int header_size_in_cells() {148return 1;149}150151static int compute_size_in_bytes(int cell_count) {152return header_size_in_bytes() + cell_count * cell_size;153}154155// Initialization156void initialize(u1 tag, u2 bci, int cell_count);157158// Accessors159u1 tag() {160return _header._struct._tag;161}162163// Return a few bits of trap state. Range is [0..trap_mask].164// The state tells if traps with zero, one, or many reasons have occurred.165// It also tells whether zero or many recompilations have occurred.166// The associated trap histogram in the MDO itself tells whether167// traps are common or not. If a BCI shows that a trap X has168// occurred, and the MDO shows N occurrences of X, we make the169// simplifying assumption that all N occurrences can be blamed170// on that BCI.171int trap_state() const {172return ((_header._struct._flags >> trap_shift) & trap_mask);173}174175void set_trap_state(int new_state) {176assert(ProfileTraps, "used only under +ProfileTraps");177uint old_flags = (_header._struct._flags & flag_mask);178_header._struct._flags = (new_state << trap_shift) | old_flags;179}180181u1 flags() const {182return _header._struct._flags;183}184185u2 bci() const {186return _header._struct._bci;187}188189void set_header(intptr_t value) {190_header._bits = value;191}192intptr_t header() {193return _header._bits;194}195void set_cell_at(int index, intptr_t value) {196_cells[index] = value;197}198void release_set_cell_at(int index, intptr_t value) {199OrderAccess::release_store_ptr(&_cells[index], value);200}201intptr_t cell_at(int index) const {202return _cells[index];203}204205void set_flag_at(int flag_number) {206assert(flag_number < flag_limit, "oob");207_header._struct._flags |= (0x1 << flag_number);208}209bool flag_at(int flag_number) const {210assert(flag_number < flag_limit, "oob");211return (_header._struct._flags & (0x1 << flag_number)) != 0;212}213214// Low-level support for code generation.215static ByteSize header_offset() {216return byte_offset_of(DataLayout, _header);217}218static ByteSize tag_offset() {219return byte_offset_of(DataLayout, _header._struct._tag);220}221static ByteSize flags_offset() {222return byte_offset_of(DataLayout, _header._struct._flags);223}224static ByteSize bci_offset() {225return byte_offset_of(DataLayout, _header._struct._bci);226}227static ByteSize cell_offset(int index) {228return byte_offset_of(DataLayout, _cells) + in_ByteSize(index * cell_size);229}230#ifdef CC_INTERP231static int cell_offset_in_bytes(int index) {232return (int)offset_of(DataLayout, _cells[index]);233}234#endif // CC_INTERP235// Return a value which, when or-ed as a byte into _flags, sets the flag.236static int flag_number_to_byte_constant(int flag_number) {237assert(0 <= flag_number && flag_number < flag_limit, "oob");238DataLayout temp; temp.set_header(0);239temp.set_flag_at(flag_number);240return temp._header._struct._flags;241}242// Return a value which, when or-ed as a word into _header, sets the flag.243static intptr_t flag_mask_to_header_mask(int byte_constant) {244DataLayout temp; temp.set_header(0);245temp._header._struct._flags = byte_constant;246return temp._header._bits;247}248249ProfileData* data_in();250251// GC support252void clean_weak_klass_links(BoolObjectClosure* cl);253254// Redefinition support255void clean_weak_method_links();256};257258259// ProfileData class hierarchy260class ProfileData;261class BitData;262class CounterData;263class ReceiverTypeData;264class VirtualCallData;265class VirtualCallTypeData;266class RetData;267class CallTypeData;268class JumpData;269class BranchData;270class ArrayData;271class MultiBranchData;272class ArgInfoData;273class ParametersTypeData;274class SpeculativeTrapData;275276// ProfileData277//278// A ProfileData object is created to refer to a section of profiling279// data in a structured way.280class ProfileData : public ResourceObj {281friend class TypeEntries;282friend class ReturnTypeEntry;283friend class TypeStackSlotEntries;284private:285#ifndef PRODUCT286enum {287tab_width_one = 16,288tab_width_two = 36289};290#endif // !PRODUCT291292// This is a pointer to a section of profiling data.293DataLayout* _data;294295char* print_data_on_helper(const MethodData* md) const;296297protected:298DataLayout* data() { return _data; }299const DataLayout* data() const { return _data; }300301enum {302cell_size = DataLayout::cell_size303};304305public:306// How many cells are in this?307virtual int cell_count() const {308ShouldNotReachHere();309return -1;310}311312// Return the size of this data.313int size_in_bytes() {314return DataLayout::compute_size_in_bytes(cell_count());315}316317protected:318// Low-level accessors for underlying data319void set_intptr_at(int index, intptr_t value) {320assert(0 <= index && index < cell_count(), "oob");321data()->set_cell_at(index, value);322}323void release_set_intptr_at(int index, intptr_t value) {324assert(0 <= index && index < cell_count(), "oob");325data()->release_set_cell_at(index, value);326}327intptr_t intptr_at(int index) const {328assert(0 <= index && index < cell_count(), "oob");329return data()->cell_at(index);330}331void set_uint_at(int index, uint value) {332set_intptr_at(index, (intptr_t) value);333}334void release_set_uint_at(int index, uint value) {335release_set_intptr_at(index, (intptr_t) value);336}337uint uint_at(int index) const {338return (uint)intptr_at(index);339}340void set_int_at(int index, int value) {341set_intptr_at(index, (intptr_t) value);342}343void release_set_int_at(int index, int value) {344release_set_intptr_at(index, (intptr_t) value);345}346int int_at(int index) const {347return (int)intptr_at(index);348}349int int_at_unchecked(int index) const {350return (int)data()->cell_at(index);351}352void set_oop_at(int index, oop value) {353set_intptr_at(index, cast_from_oop<intptr_t>(value));354}355oop oop_at(int index) const {356return cast_to_oop(intptr_at(index));357}358359void set_flag_at(int flag_number) {360data()->set_flag_at(flag_number);361}362bool flag_at(int flag_number) const {363return data()->flag_at(flag_number);364}365366// two convenient imports for use by subclasses:367static ByteSize cell_offset(int index) {368return DataLayout::cell_offset(index);369}370static int flag_number_to_byte_constant(int flag_number) {371return DataLayout::flag_number_to_byte_constant(flag_number);372}373374ProfileData(DataLayout* data) {375_data = data;376}377378#ifdef CC_INTERP379// Static low level accessors for DataLayout with ProfileData's semantics.380381static int cell_offset_in_bytes(int index) {382return DataLayout::cell_offset_in_bytes(index);383}384385static void increment_uint_at_no_overflow(DataLayout* layout, int index,386int inc = DataLayout::counter_increment) {387uint count = ((uint)layout->cell_at(index)) + inc;388if (count == 0) return;389layout->set_cell_at(index, (intptr_t) count);390}391392static int int_at(DataLayout* layout, int index) {393return (int)layout->cell_at(index);394}395396static int uint_at(DataLayout* layout, int index) {397return (uint)layout->cell_at(index);398}399400static oop oop_at(DataLayout* layout, int index) {401return cast_to_oop(layout->cell_at(index));402}403404static void set_intptr_at(DataLayout* layout, int index, intptr_t value) {405layout->set_cell_at(index, (intptr_t) value);406}407408static void set_flag_at(DataLayout* layout, int flag_number) {409layout->set_flag_at(flag_number);410}411#endif // CC_INTERP412413public:414// Constructor for invalid ProfileData.415ProfileData();416417u2 bci() const {418return data()->bci();419}420421address dp() {422return (address)_data;423}424425int trap_state() const {426return data()->trap_state();427}428void set_trap_state(int new_state) {429data()->set_trap_state(new_state);430}431432// Type checking433virtual bool is_BitData() const { return false; }434virtual bool is_CounterData() const { return false; }435virtual bool is_JumpData() const { return false; }436virtual bool is_ReceiverTypeData()const { return false; }437virtual bool is_VirtualCallData() const { return false; }438virtual bool is_RetData() const { return false; }439virtual bool is_BranchData() const { return false; }440virtual bool is_ArrayData() const { return false; }441virtual bool is_MultiBranchData() const { return false; }442virtual bool is_ArgInfoData() const { return false; }443virtual bool is_CallTypeData() const { return false; }444virtual bool is_VirtualCallTypeData()const { return false; }445virtual bool is_ParametersTypeData() const { return false; }446virtual bool is_SpeculativeTrapData()const { return false; }447448449BitData* as_BitData() const {450assert(is_BitData(), "wrong type");451return is_BitData() ? (BitData*) this : NULL;452}453CounterData* as_CounterData() const {454assert(is_CounterData(), "wrong type");455return is_CounterData() ? (CounterData*) this : NULL;456}457JumpData* as_JumpData() const {458assert(is_JumpData(), "wrong type");459return is_JumpData() ? (JumpData*) this : NULL;460}461ReceiverTypeData* as_ReceiverTypeData() const {462assert(is_ReceiverTypeData(), "wrong type");463return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL;464}465VirtualCallData* as_VirtualCallData() const {466assert(is_VirtualCallData(), "wrong type");467return is_VirtualCallData() ? (VirtualCallData*)this : NULL;468}469RetData* as_RetData() const {470assert(is_RetData(), "wrong type");471return is_RetData() ? (RetData*) this : NULL;472}473BranchData* as_BranchData() const {474assert(is_BranchData(), "wrong type");475return is_BranchData() ? (BranchData*) this : NULL;476}477ArrayData* as_ArrayData() const {478assert(is_ArrayData(), "wrong type");479return is_ArrayData() ? (ArrayData*) this : NULL;480}481MultiBranchData* as_MultiBranchData() const {482assert(is_MultiBranchData(), "wrong type");483return is_MultiBranchData() ? (MultiBranchData*)this : NULL;484}485ArgInfoData* as_ArgInfoData() const {486assert(is_ArgInfoData(), "wrong type");487return is_ArgInfoData() ? (ArgInfoData*)this : NULL;488}489CallTypeData* as_CallTypeData() const {490assert(is_CallTypeData(), "wrong type");491return is_CallTypeData() ? (CallTypeData*)this : NULL;492}493VirtualCallTypeData* as_VirtualCallTypeData() const {494assert(is_VirtualCallTypeData(), "wrong type");495return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL;496}497ParametersTypeData* as_ParametersTypeData() const {498assert(is_ParametersTypeData(), "wrong type");499return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL;500}501SpeculativeTrapData* as_SpeculativeTrapData() const {502assert(is_SpeculativeTrapData(), "wrong type");503return is_SpeculativeTrapData() ? (SpeculativeTrapData*)this : NULL;504}505506507// Subclass specific initialization508virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {}509510// GC support511virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {}512513// Redefinition support514virtual void clean_weak_method_links() {}515516// CI translation: ProfileData can represent both MethodDataOop data517// as well as CIMethodData data. This function is provided for translating518// an oop in a ProfileData to the ci equivalent. Generally speaking,519// most ProfileData don't require any translation, so we provide the null520// translation here, and the required translators are in the ci subclasses.521virtual void translate_from(const ProfileData* data) {}522523virtual void print_data_on(outputStream* st, const char* extra = NULL) const {524ShouldNotReachHere();525}526527void print_data_on(outputStream* st, const MethodData* md) const;528529#ifndef PRODUCT530void print_shared(outputStream* st, const char* name, const char* extra) const;531void tab(outputStream* st, bool first = false) const;532#endif533};534535// BitData536//537// A BitData holds a flag or two in its header.538class BitData : public ProfileData {539protected:540enum {541// null_seen:542// saw a null operand (cast/aastore/instanceof)543null_seen_flag = DataLayout::first_flag + 0544};545enum { bit_cell_count = 0 }; // no additional data fields needed.546public:547BitData(DataLayout* layout) : ProfileData(layout) {548}549550virtual bool is_BitData() const { return true; }551552static int static_cell_count() {553return bit_cell_count;554}555556virtual int cell_count() const {557return static_cell_count();558}559560// Accessor561562// The null_seen flag bit is specially known to the interpreter.563// Consulting it allows the compiler to avoid setting up null_check traps.564bool null_seen() { return flag_at(null_seen_flag); }565void set_null_seen() { set_flag_at(null_seen_flag); }566567568// Code generation support569static int null_seen_byte_constant() {570return flag_number_to_byte_constant(null_seen_flag);571}572573static ByteSize bit_data_size() {574return cell_offset(bit_cell_count);575}576577#ifdef CC_INTERP578static int bit_data_size_in_bytes() {579return cell_offset_in_bytes(bit_cell_count);580}581582static void set_null_seen(DataLayout* layout) {583set_flag_at(layout, null_seen_flag);584}585586static DataLayout* advance(DataLayout* layout) {587return (DataLayout*) (((address)layout) + (ssize_t)BitData::bit_data_size_in_bytes());588}589#endif // CC_INTERP590591#ifndef PRODUCT592void print_data_on(outputStream* st, const char* extra = NULL) const;593#endif594};595596// CounterData597//598// A CounterData corresponds to a simple counter.599class CounterData : public BitData {600protected:601enum {602count_off,603counter_cell_count604};605public:606CounterData(DataLayout* layout) : BitData(layout) {}607608virtual bool is_CounterData() const { return true; }609610static int static_cell_count() {611return counter_cell_count;612}613614virtual int cell_count() const {615return static_cell_count();616}617618// Direct accessor619uint count() const {620return uint_at(count_off);621}622623// Code generation support624static ByteSize count_offset() {625return cell_offset(count_off);626}627static ByteSize counter_data_size() {628return cell_offset(counter_cell_count);629}630631void set_count(uint count) {632set_uint_at(count_off, count);633}634635#ifdef CC_INTERP636static int counter_data_size_in_bytes() {637return cell_offset_in_bytes(counter_cell_count);638}639640static void increment_count_no_overflow(DataLayout* layout) {641increment_uint_at_no_overflow(layout, count_off);642}643644// Support counter decrementation at checkcast / subtype check failed.645static void decrement_count(DataLayout* layout) {646increment_uint_at_no_overflow(layout, count_off, -1);647}648649static DataLayout* advance(DataLayout* layout) {650return (DataLayout*) (((address)layout) + (ssize_t)CounterData::counter_data_size_in_bytes());651}652#endif // CC_INTERP653654#ifndef PRODUCT655void print_data_on(outputStream* st, const char* extra = NULL) const;656#endif657};658659// JumpData660//661// A JumpData is used to access profiling information for a direct662// branch. It is a counter, used for counting the number of branches,663// plus a data displacement, used for realigning the data pointer to664// the corresponding target bci.665class JumpData : public ProfileData {666protected:667enum {668taken_off_set,669displacement_off_set,670jump_cell_count671};672673void set_displacement(int displacement) {674set_int_at(displacement_off_set, displacement);675}676677public:678JumpData(DataLayout* layout) : ProfileData(layout) {679assert(layout->tag() == DataLayout::jump_data_tag ||680layout->tag() == DataLayout::branch_data_tag, "wrong type");681}682683virtual bool is_JumpData() const { return true; }684685static int static_cell_count() {686return jump_cell_count;687}688689virtual int cell_count() const {690return static_cell_count();691}692693// Direct accessor694uint taken() const {695return uint_at(taken_off_set);696}697698void set_taken(uint cnt) {699set_uint_at(taken_off_set, cnt);700}701702// Saturating counter703uint inc_taken() {704uint cnt = taken() + 1;705// Did we wrap? Will compiler screw us??706if (cnt == 0) cnt--;707set_uint_at(taken_off_set, cnt);708return cnt;709}710711int displacement() const {712return int_at(displacement_off_set);713}714715// Code generation support716static ByteSize taken_offset() {717return cell_offset(taken_off_set);718}719720static ByteSize displacement_offset() {721return cell_offset(displacement_off_set);722}723724#ifdef CC_INTERP725static void increment_taken_count_no_overflow(DataLayout* layout) {726increment_uint_at_no_overflow(layout, taken_off_set);727}728729static DataLayout* advance_taken(DataLayout* layout) {730return (DataLayout*) (((address)layout) + (ssize_t)int_at(layout, displacement_off_set));731}732733static uint taken_count(DataLayout* layout) {734return (uint) uint_at(layout, taken_off_set);735}736#endif // CC_INTERP737738// Specific initialization.739void post_initialize(BytecodeStream* stream, MethodData* mdo);740741#ifndef PRODUCT742void print_data_on(outputStream* st, const char* extra = NULL) const;743#endif744};745746// Entries in a ProfileData object to record types: it can either be747// none (no profile), unknown (conflicting profile data) or a klass if748// a single one is seen. Whether a null reference was seen is also749// recorded. No counter is associated with the type and a single type750// is tracked (unlike VirtualCallData).751class TypeEntries {752753public:754755// A single cell is used to record information for a type:756// - the cell is initialized to 0757// - when a type is discovered it is stored in the cell758// - bit zero of the cell is used to record whether a null reference759// was encountered or not760// - bit 1 is set to record a conflict in the type information761762enum {763null_seen = 1,764type_mask = ~null_seen,765type_unknown = 2,766status_bits = null_seen | type_unknown,767type_klass_mask = ~status_bits768};769770// what to initialize a cell to771static intptr_t type_none() {772return 0;773}774775// null seen = bit 0 set?776static bool was_null_seen(intptr_t v) {777return (v & null_seen) != 0;778}779780// conflicting type information = bit 1 set?781static bool is_type_unknown(intptr_t v) {782return (v & type_unknown) != 0;783}784785// not type information yet = all bits cleared, ignoring bit 0?786static bool is_type_none(intptr_t v) {787return (v & type_mask) == 0;788}789790// recorded type: cell without bit 0 and 1791static intptr_t klass_part(intptr_t v) {792intptr_t r = v & type_klass_mask;793return r;794}795796// type recorded797static Klass* valid_klass(intptr_t k) {798if (!is_type_none(k) &&799!is_type_unknown(k)) {800Klass* res = (Klass*)klass_part(k);801assert(res != NULL, "invalid");802return res;803} else {804return NULL;805}806}807808static intptr_t with_status(intptr_t k, intptr_t in) {809return k | (in & status_bits);810}811812static intptr_t with_status(Klass* k, intptr_t in) {813return with_status((intptr_t)k, in);814}815816#ifndef PRODUCT817static void print_klass(outputStream* st, intptr_t k);818#endif819820// GC support821static bool is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p);822823protected:824// ProfileData object these entries are part of825ProfileData* _pd;826// offset within the ProfileData object where the entries start827const int _base_off;828829TypeEntries(int base_off)830: _base_off(base_off), _pd(NULL) {}831832void set_intptr_at(int index, intptr_t value) {833_pd->set_intptr_at(index, value);834}835836intptr_t intptr_at(int index) const {837return _pd->intptr_at(index);838}839840public:841void set_profile_data(ProfileData* pd) {842_pd = pd;843}844};845846// Type entries used for arguments passed at a call and parameters on847// method entry. 2 cells per entry: one for the type encoded as in848// TypeEntries and one initialized with the stack slot where the849// profiled object is to be found so that the interpreter can locate850// it quickly.851class TypeStackSlotEntries : public TypeEntries {852853private:854enum {855stack_slot_entry,856type_entry,857per_arg_cell_count858};859860// offset of cell for stack slot for entry i within ProfileData object861int stack_slot_offset(int i) const {862return _base_off + stack_slot_local_offset(i);863}864865protected:866const int _number_of_entries;867868// offset of cell for type for entry i within ProfileData object869int type_offset(int i) const {870return _base_off + type_local_offset(i);871}872873public:874875TypeStackSlotEntries(int base_off, int nb_entries)876: TypeEntries(base_off), _number_of_entries(nb_entries) {}877878static int compute_cell_count(Symbol* signature, bool include_receiver, int max);879880void post_initialize(Symbol* signature, bool has_receiver, bool include_receiver);881882// offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries883static int stack_slot_local_offset(int i) {884return i * per_arg_cell_count + stack_slot_entry;885}886887// offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries888static int type_local_offset(int i) {889return i * per_arg_cell_count + type_entry;890}891892// stack slot for entry i893uint stack_slot(int i) const {894assert(i >= 0 && i < _number_of_entries, "oob");895return _pd->uint_at(stack_slot_offset(i));896}897898// set stack slot for entry i899void set_stack_slot(int i, uint num) {900assert(i >= 0 && i < _number_of_entries, "oob");901_pd->set_uint_at(stack_slot_offset(i), num);902}903904// type for entry i905intptr_t type(int i) const {906assert(i >= 0 && i < _number_of_entries, "oob");907return _pd->intptr_at(type_offset(i));908}909910// set type for entry i911void set_type(int i, intptr_t k) {912assert(i >= 0 && i < _number_of_entries, "oob");913_pd->set_intptr_at(type_offset(i), k);914}915916static ByteSize per_arg_size() {917return in_ByteSize(per_arg_cell_count * DataLayout::cell_size);918}919920static int per_arg_count() {921return per_arg_cell_count ;922}923924// GC support925void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);926927#ifndef PRODUCT928void print_data_on(outputStream* st) const;929#endif930};931932// Type entry used for return from a call. A single cell to record the933// type.934class ReturnTypeEntry : public TypeEntries {935936private:937enum {938cell_count = 1939};940941public:942ReturnTypeEntry(int base_off)943: TypeEntries(base_off) {}944945void post_initialize() {946set_type(type_none());947}948949intptr_t type() const {950return _pd->intptr_at(_base_off);951}952953void set_type(intptr_t k) {954_pd->set_intptr_at(_base_off, k);955}956957static int static_cell_count() {958return cell_count;959}960961static ByteSize size() {962return in_ByteSize(cell_count * DataLayout::cell_size);963}964965ByteSize type_offset() {966return DataLayout::cell_offset(_base_off);967}968969// GC support970void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);971972#ifndef PRODUCT973void print_data_on(outputStream* st) const;974#endif975};976977// Entries to collect type information at a call: contains arguments978// (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a979// number of cells. Because the number of cells for the return type is980// smaller than the number of cells for the type of an arguments, the981// number of cells is used to tell how many arguments are profiled and982// whether a return value is profiled. See has_arguments() and983// has_return().984class TypeEntriesAtCall {985private:986static int stack_slot_local_offset(int i) {987return header_cell_count() + TypeStackSlotEntries::stack_slot_local_offset(i);988}989990static int argument_type_local_offset(int i) {991return header_cell_count() + TypeStackSlotEntries::type_local_offset(i);;992}993994public:995996static int header_cell_count() {997return 1;998}9991000static int cell_count_local_offset() {1001return 0;1002}10031004static int compute_cell_count(BytecodeStream* stream);10051006static void initialize(DataLayout* dl, int base, int cell_count) {1007int off = base + cell_count_local_offset();1008dl->set_cell_at(off, cell_count - base - header_cell_count());1009}10101011static bool arguments_profiling_enabled();1012static bool return_profiling_enabled();10131014// Code generation support1015static ByteSize cell_count_offset() {1016return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size);1017}10181019static ByteSize args_data_offset() {1020return in_ByteSize(header_cell_count() * DataLayout::cell_size);1021}10221023static ByteSize stack_slot_offset(int i) {1024return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size);1025}10261027static ByteSize argument_type_offset(int i) {1028return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size);1029}10301031static ByteSize return_only_size() {1032return ReturnTypeEntry::size() + in_ByteSize(header_cell_count() * DataLayout::cell_size);1033}10341035};10361037// CallTypeData1038//1039// A CallTypeData is used to access profiling information about a non1040// virtual call for which we collect type information about arguments1041// and return value.1042class CallTypeData : public CounterData {1043private:1044// entries for arguments if any1045TypeStackSlotEntries _args;1046// entry for return type if any1047ReturnTypeEntry _ret;10481049int cell_count_global_offset() const {1050return CounterData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset();1051}10521053// number of cells not counting the header1054int cell_count_no_header() const {1055return uint_at(cell_count_global_offset());1056}10571058void check_number_of_arguments(int total) {1059assert(number_of_arguments() == total, "should be set in DataLayout::initialize");1060}10611062public:1063CallTypeData(DataLayout* layout) :1064CounterData(layout),1065_args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()),1066_ret(cell_count() - ReturnTypeEntry::static_cell_count())1067{1068assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type");1069// Some compilers (VC++) don't want this passed in member initialization list1070_args.set_profile_data(this);1071_ret.set_profile_data(this);1072}10731074const TypeStackSlotEntries* args() const {1075assert(has_arguments(), "no profiling of arguments");1076return &_args;1077}10781079const ReturnTypeEntry* ret() const {1080assert(has_return(), "no profiling of return value");1081return &_ret;1082}10831084virtual bool is_CallTypeData() const { return true; }10851086static int static_cell_count() {1087return -1;1088}10891090static int compute_cell_count(BytecodeStream* stream) {1091return CounterData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream);1092}10931094static void initialize(DataLayout* dl, int cell_count) {1095TypeEntriesAtCall::initialize(dl, CounterData::static_cell_count(), cell_count);1096}10971098virtual void post_initialize(BytecodeStream* stream, MethodData* mdo);10991100virtual int cell_count() const {1101return CounterData::static_cell_count() +1102TypeEntriesAtCall::header_cell_count() +1103int_at_unchecked(cell_count_global_offset());1104}11051106int number_of_arguments() const {1107return cell_count_no_header() / TypeStackSlotEntries::per_arg_count();1108}11091110void set_argument_type(int i, Klass* k) {1111assert(has_arguments(), "no arguments!");1112intptr_t current = _args.type(i);1113_args.set_type(i, TypeEntries::with_status(k, current));1114}11151116void set_return_type(Klass* k) {1117assert(has_return(), "no return!");1118intptr_t current = _ret.type();1119_ret.set_type(TypeEntries::with_status(k, current));1120}11211122// An entry for a return value takes less space than an entry for an1123// argument so if the number of cells exceeds the number of cells1124// needed for an argument, this object contains type information for1125// at least one argument.1126bool has_arguments() const {1127bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();1128assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");1129return res;1130}11311132// An entry for a return value takes less space than an entry for an1133// argument, so if the remainder of the number of cells divided by1134// the number of cells for an argument is not null, a return value1135// is profiled in this object.1136bool has_return() const {1137bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0;1138assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values");1139return res;1140}11411142// Code generation support1143static ByteSize args_data_offset() {1144return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();1145}11461147// GC support1148virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {1149if (has_arguments()) {1150_args.clean_weak_klass_links(is_alive_closure);1151}1152if (has_return()) {1153_ret.clean_weak_klass_links(is_alive_closure);1154}1155}11561157#ifndef PRODUCT1158virtual void print_data_on(outputStream* st, const char* extra = NULL) const;1159#endif1160};11611162// ReceiverTypeData1163//1164// A ReceiverTypeData is used to access profiling information about a1165// dynamic type check. It consists of a counter which counts the total times1166// that the check is reached, and a series of (Klass*, count) pairs1167// which are used to store a type profile for the receiver of the check.1168class ReceiverTypeData : public CounterData {1169protected:1170enum {1171receiver0_offset = counter_cell_count,1172count0_offset,1173receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset1174};11751176public:1177ReceiverTypeData(DataLayout* layout) : CounterData(layout) {1178assert(layout->tag() == DataLayout::receiver_type_data_tag ||1179layout->tag() == DataLayout::virtual_call_data_tag ||1180layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");1181}11821183virtual bool is_ReceiverTypeData() const { return true; }11841185static int static_cell_count() {1186return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count;1187}11881189virtual int cell_count() const {1190return static_cell_count();1191}11921193// Direct accessors1194static uint row_limit() {1195return TypeProfileWidth;1196}1197static int receiver_cell_index(uint row) {1198return receiver0_offset + row * receiver_type_row_cell_count;1199}1200static int receiver_count_cell_index(uint row) {1201return count0_offset + row * receiver_type_row_cell_count;1202}12031204Klass* receiver(uint row) const {1205assert(row < row_limit(), "oob");12061207Klass* recv = (Klass*)intptr_at(receiver_cell_index(row));1208assert(recv == NULL || recv->is_klass(), "wrong type");1209return recv;1210}12111212void set_receiver(uint row, Klass* k) {1213assert((uint)row < row_limit(), "oob");1214set_intptr_at(receiver_cell_index(row), (uintptr_t)k);1215}12161217uint receiver_count(uint row) const {1218assert(row < row_limit(), "oob");1219return uint_at(receiver_count_cell_index(row));1220}12211222void set_receiver_count(uint row, uint count) {1223assert(row < row_limit(), "oob");1224set_uint_at(receiver_count_cell_index(row), count);1225}12261227void clear_row(uint row) {1228assert(row < row_limit(), "oob");1229// Clear total count - indicator of polymorphic call site.1230// The site may look like as monomorphic after that but1231// it allow to have more accurate profiling information because1232// there was execution phase change since klasses were unloaded.1233// If the site is still polymorphic then MDO will be updated1234// to reflect it. But it could be the case that the site becomes1235// only bimorphic. Then keeping total count not 0 will be wrong.1236// Even if we use monomorphic (when it is not) for compilation1237// we will only have trap, deoptimization and recompile again1238// with updated MDO after executing method in Interpreter.1239// An additional receiver will be recorded in the cleaned row1240// during next call execution.1241//1242// Note: our profiling logic works with empty rows in any slot.1243// We do sorting a profiling info (ciCallProfile) for compilation.1244//1245set_count(0);1246set_receiver(row, NULL);1247set_receiver_count(row, 0);1248}12491250// Code generation support1251static ByteSize receiver_offset(uint row) {1252return cell_offset(receiver_cell_index(row));1253}1254static ByteSize receiver_count_offset(uint row) {1255return cell_offset(receiver_count_cell_index(row));1256}1257static ByteSize receiver_type_data_size() {1258return cell_offset(static_cell_count());1259}12601261// GC support1262virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);12631264#ifdef CC_INTERP1265static int receiver_type_data_size_in_bytes() {1266return cell_offset_in_bytes(static_cell_count());1267}12681269static Klass *receiver_unchecked(DataLayout* layout, uint row) {1270Klass* recv = (Klass*)layout->cell_at(receiver_cell_index(row));1271return recv;1272}12731274static void increment_receiver_count_no_overflow(DataLayout* layout, Klass *rcvr) {1275const int num_rows = row_limit();1276// Receiver already exists?1277for (int row = 0; row < num_rows; row++) {1278if (receiver_unchecked(layout, row) == rcvr) {1279increment_uint_at_no_overflow(layout, receiver_count_cell_index(row));1280return;1281}1282}1283// New receiver, find a free slot.1284for (int row = 0; row < num_rows; row++) {1285if (receiver_unchecked(layout, row) == NULL) {1286set_intptr_at(layout, receiver_cell_index(row), (intptr_t)rcvr);1287increment_uint_at_no_overflow(layout, receiver_count_cell_index(row));1288return;1289}1290}1291// Receiver did not match any saved receiver and there is no empty row for it.1292// Increment total counter to indicate polymorphic case.1293increment_count_no_overflow(layout);1294}12951296static DataLayout* advance(DataLayout* layout) {1297return (DataLayout*) (((address)layout) + (ssize_t)ReceiverTypeData::receiver_type_data_size_in_bytes());1298}1299#endif // CC_INTERP13001301#ifndef PRODUCT1302void print_receiver_data_on(outputStream* st) const;1303void print_data_on(outputStream* st, const char* extra = NULL) const;1304#endif1305};13061307// VirtualCallData1308//1309// A VirtualCallData is used to access profiling information about a1310// virtual call. For now, it has nothing more than a ReceiverTypeData.1311class VirtualCallData : public ReceiverTypeData {1312public:1313VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) {1314assert(layout->tag() == DataLayout::virtual_call_data_tag ||1315layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");1316}13171318virtual bool is_VirtualCallData() const { return true; }13191320static int static_cell_count() {1321// At this point we could add more profile state, e.g., for arguments.1322// But for now it's the same size as the base record type.1323return ReceiverTypeData::static_cell_count();1324}13251326virtual int cell_count() const {1327return static_cell_count();1328}13291330// Direct accessors1331static ByteSize virtual_call_data_size() {1332return cell_offset(static_cell_count());1333}13341335#ifdef CC_INTERP1336static int virtual_call_data_size_in_bytes() {1337return cell_offset_in_bytes(static_cell_count());1338}13391340static DataLayout* advance(DataLayout* layout) {1341return (DataLayout*) (((address)layout) + (ssize_t)VirtualCallData::virtual_call_data_size_in_bytes());1342}1343#endif // CC_INTERP13441345#ifndef PRODUCT1346void print_data_on(outputStream* st, const char* extra = NULL) const;1347#endif1348};13491350// VirtualCallTypeData1351//1352// A VirtualCallTypeData is used to access profiling information about1353// a virtual call for which we collect type information about1354// arguments and return value.1355class VirtualCallTypeData : public VirtualCallData {1356private:1357// entries for arguments if any1358TypeStackSlotEntries _args;1359// entry for return type if any1360ReturnTypeEntry _ret;13611362int cell_count_global_offset() const {1363return VirtualCallData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset();1364}13651366// number of cells not counting the header1367int cell_count_no_header() const {1368return uint_at(cell_count_global_offset());1369}13701371void check_number_of_arguments(int total) {1372assert(number_of_arguments() == total, "should be set in DataLayout::initialize");1373}13741375public:1376VirtualCallTypeData(DataLayout* layout) :1377VirtualCallData(layout),1378_args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()),1379_ret(cell_count() - ReturnTypeEntry::static_cell_count())1380{1381assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");1382// Some compilers (VC++) don't want this passed in member initialization list1383_args.set_profile_data(this);1384_ret.set_profile_data(this);1385}13861387const TypeStackSlotEntries* args() const {1388assert(has_arguments(), "no profiling of arguments");1389return &_args;1390}13911392const ReturnTypeEntry* ret() const {1393assert(has_return(), "no profiling of return value");1394return &_ret;1395}13961397virtual bool is_VirtualCallTypeData() const { return true; }13981399static int static_cell_count() {1400return -1;1401}14021403static int compute_cell_count(BytecodeStream* stream) {1404return VirtualCallData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream);1405}14061407static void initialize(DataLayout* dl, int cell_count) {1408TypeEntriesAtCall::initialize(dl, VirtualCallData::static_cell_count(), cell_count);1409}14101411virtual void post_initialize(BytecodeStream* stream, MethodData* mdo);14121413virtual int cell_count() const {1414return VirtualCallData::static_cell_count() +1415TypeEntriesAtCall::header_cell_count() +1416int_at_unchecked(cell_count_global_offset());1417}14181419int number_of_arguments() const {1420return cell_count_no_header() / TypeStackSlotEntries::per_arg_count();1421}14221423void set_argument_type(int i, Klass* k) {1424assert(has_arguments(), "no arguments!");1425intptr_t current = _args.type(i);1426_args.set_type(i, TypeEntries::with_status(k, current));1427}14281429void set_return_type(Klass* k) {1430assert(has_return(), "no return!");1431intptr_t current = _ret.type();1432_ret.set_type(TypeEntries::with_status(k, current));1433}14341435// An entry for a return value takes less space than an entry for an1436// argument, so if the remainder of the number of cells divided by1437// the number of cells for an argument is not null, a return value1438// is profiled in this object.1439bool has_return() const {1440bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0;1441assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values");1442return res;1443}14441445// An entry for a return value takes less space than an entry for an1446// argument so if the number of cells exceeds the number of cells1447// needed for an argument, this object contains type information for1448// at least one argument.1449bool has_arguments() const {1450bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();1451assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");1452return res;1453}14541455// Code generation support1456static ByteSize args_data_offset() {1457return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();1458}14591460// GC support1461virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {1462ReceiverTypeData::clean_weak_klass_links(is_alive_closure);1463if (has_arguments()) {1464_args.clean_weak_klass_links(is_alive_closure);1465}1466if (has_return()) {1467_ret.clean_weak_klass_links(is_alive_closure);1468}1469}14701471#ifndef PRODUCT1472virtual void print_data_on(outputStream* st, const char* extra = NULL) const;1473#endif1474};14751476// RetData1477//1478// A RetData is used to access profiling information for a ret bytecode.1479// It is composed of a count of the number of times that the ret has1480// been executed, followed by a series of triples of the form1481// (bci, count, di) which count the number of times that some bci was the1482// target of the ret and cache a corresponding data displacement.1483class RetData : public CounterData {1484protected:1485enum {1486bci0_offset = counter_cell_count,1487count0_offset,1488displacement0_offset,1489ret_row_cell_count = (displacement0_offset + 1) - bci0_offset1490};14911492void set_bci(uint row, int bci) {1493assert((uint)row < row_limit(), "oob");1494set_int_at(bci0_offset + row * ret_row_cell_count, bci);1495}1496void release_set_bci(uint row, int bci) {1497assert((uint)row < row_limit(), "oob");1498// 'release' when setting the bci acts as a valid flag for other1499// threads wrt bci_count and bci_displacement.1500release_set_int_at(bci0_offset + row * ret_row_cell_count, bci);1501}1502void set_bci_count(uint row, uint count) {1503assert((uint)row < row_limit(), "oob");1504set_uint_at(count0_offset + row * ret_row_cell_count, count);1505}1506void set_bci_displacement(uint row, int disp) {1507set_int_at(displacement0_offset + row * ret_row_cell_count, disp);1508}15091510public:1511RetData(DataLayout* layout) : CounterData(layout) {1512assert(layout->tag() == DataLayout::ret_data_tag, "wrong type");1513}15141515virtual bool is_RetData() const { return true; }15161517enum {1518no_bci = -1 // value of bci when bci1/2 are not in use.1519};15201521static int static_cell_count() {1522return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count;1523}15241525virtual int cell_count() const {1526return static_cell_count();1527}15281529static uint row_limit() {1530return BciProfileWidth;1531}1532static int bci_cell_index(uint row) {1533return bci0_offset + row * ret_row_cell_count;1534}1535static int bci_count_cell_index(uint row) {1536return count0_offset + row * ret_row_cell_count;1537}1538static int bci_displacement_cell_index(uint row) {1539return displacement0_offset + row * ret_row_cell_count;1540}15411542// Direct accessors1543int bci(uint row) const {1544return int_at(bci_cell_index(row));1545}1546uint bci_count(uint row) const {1547return uint_at(bci_count_cell_index(row));1548}1549int bci_displacement(uint row) const {1550return int_at(bci_displacement_cell_index(row));1551}15521553// Interpreter Runtime support1554address fixup_ret(int return_bci, MethodData* mdo);15551556// Code generation support1557static ByteSize bci_offset(uint row) {1558return cell_offset(bci_cell_index(row));1559}1560static ByteSize bci_count_offset(uint row) {1561return cell_offset(bci_count_cell_index(row));1562}1563static ByteSize bci_displacement_offset(uint row) {1564return cell_offset(bci_displacement_cell_index(row));1565}15661567#ifdef CC_INTERP1568static DataLayout* advance(MethodData *md, int bci);1569#endif // CC_INTERP15701571// Specific initialization.1572void post_initialize(BytecodeStream* stream, MethodData* mdo);15731574#ifndef PRODUCT1575void print_data_on(outputStream* st, const char* extra = NULL) const;1576#endif1577};15781579// BranchData1580//1581// A BranchData is used to access profiling data for a two-way branch.1582// It consists of taken and not_taken counts as well as a data displacement1583// for the taken case.1584class BranchData : public JumpData {1585protected:1586enum {1587not_taken_off_set = jump_cell_count,1588branch_cell_count1589};15901591void set_displacement(int displacement) {1592set_int_at(displacement_off_set, displacement);1593}15941595public:1596BranchData(DataLayout* layout) : JumpData(layout) {1597assert(layout->tag() == DataLayout::branch_data_tag, "wrong type");1598}15991600virtual bool is_BranchData() const { return true; }16011602static int static_cell_count() {1603return branch_cell_count;1604}16051606virtual int cell_count() const {1607return static_cell_count();1608}16091610// Direct accessor1611uint not_taken() const {1612return uint_at(not_taken_off_set);1613}16141615void set_not_taken(uint cnt) {1616set_uint_at(not_taken_off_set, cnt);1617}16181619uint inc_not_taken() {1620uint cnt = not_taken() + 1;1621// Did we wrap? Will compiler screw us??1622if (cnt == 0) cnt--;1623set_uint_at(not_taken_off_set, cnt);1624return cnt;1625}16261627// Code generation support1628static ByteSize not_taken_offset() {1629return cell_offset(not_taken_off_set);1630}1631static ByteSize branch_data_size() {1632return cell_offset(branch_cell_count);1633}16341635#ifdef CC_INTERP1636static int branch_data_size_in_bytes() {1637return cell_offset_in_bytes(branch_cell_count);1638}16391640static void increment_not_taken_count_no_overflow(DataLayout* layout) {1641increment_uint_at_no_overflow(layout, not_taken_off_set);1642}16431644static DataLayout* advance_not_taken(DataLayout* layout) {1645return (DataLayout*) (((address)layout) + (ssize_t)BranchData::branch_data_size_in_bytes());1646}1647#endif // CC_INTERP16481649// Specific initialization.1650void post_initialize(BytecodeStream* stream, MethodData* mdo);16511652#ifndef PRODUCT1653void print_data_on(outputStream* st, const char* extra = NULL) const;1654#endif1655};16561657// ArrayData1658//1659// A ArrayData is a base class for accessing profiling data which does1660// not have a statically known size. It consists of an array length1661// and an array start.1662class ArrayData : public ProfileData {1663protected:1664friend class DataLayout;16651666enum {1667array_len_off_set,1668array_start_off_set1669};16701671uint array_uint_at(int index) const {1672int aindex = index + array_start_off_set;1673return uint_at(aindex);1674}1675int array_int_at(int index) const {1676int aindex = index + array_start_off_set;1677return int_at(aindex);1678}1679oop array_oop_at(int index) const {1680int aindex = index + array_start_off_set;1681return oop_at(aindex);1682}1683void array_set_int_at(int index, int value) {1684int aindex = index + array_start_off_set;1685set_int_at(aindex, value);1686}16871688#ifdef CC_INTERP1689// Static low level accessors for DataLayout with ArrayData's semantics.16901691static void increment_array_uint_at_no_overflow(DataLayout* layout, int index) {1692int aindex = index + array_start_off_set;1693increment_uint_at_no_overflow(layout, aindex);1694}16951696static int array_int_at(DataLayout* layout, int index) {1697int aindex = index + array_start_off_set;1698return int_at(layout, aindex);1699}1700#endif // CC_INTERP17011702// Code generation support for subclasses.1703static ByteSize array_element_offset(int index) {1704return cell_offset(array_start_off_set + index);1705}17061707public:1708ArrayData(DataLayout* layout) : ProfileData(layout) {}17091710virtual bool is_ArrayData() const { return true; }17111712static int static_cell_count() {1713return -1;1714}17151716int array_len() const {1717return int_at_unchecked(array_len_off_set);1718}17191720virtual int cell_count() const {1721return array_len() + 1;1722}17231724// Code generation support1725static ByteSize array_len_offset() {1726return cell_offset(array_len_off_set);1727}1728static ByteSize array_start_offset() {1729return cell_offset(array_start_off_set);1730}1731};17321733// MultiBranchData1734//1735// A MultiBranchData is used to access profiling information for1736// a multi-way branch (*switch bytecodes). It consists of a series1737// of (count, displacement) pairs, which count the number of times each1738// case was taken and specify the data displacment for each branch target.1739class MultiBranchData : public ArrayData {1740protected:1741enum {1742default_count_off_set,1743default_disaplacement_off_set,1744case_array_start1745};1746enum {1747relative_count_off_set,1748relative_displacement_off_set,1749per_case_cell_count1750};17511752void set_default_displacement(int displacement) {1753array_set_int_at(default_disaplacement_off_set, displacement);1754}1755void set_displacement_at(int index, int displacement) {1756array_set_int_at(case_array_start +1757index * per_case_cell_count +1758relative_displacement_off_set,1759displacement);1760}17611762public:1763MultiBranchData(DataLayout* layout) : ArrayData(layout) {1764assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type");1765}17661767virtual bool is_MultiBranchData() const { return true; }17681769static int compute_cell_count(BytecodeStream* stream);17701771int number_of_cases() const {1772int alen = array_len() - 2; // get rid of default case here.1773assert(alen % per_case_cell_count == 0, "must be even");1774return (alen / per_case_cell_count);1775}17761777uint default_count() const {1778return array_uint_at(default_count_off_set);1779}1780int default_displacement() const {1781return array_int_at(default_disaplacement_off_set);1782}17831784uint count_at(int index) const {1785return array_uint_at(case_array_start +1786index * per_case_cell_count +1787relative_count_off_set);1788}1789int displacement_at(int index) const {1790return array_int_at(case_array_start +1791index * per_case_cell_count +1792relative_displacement_off_set);1793}17941795// Code generation support1796static ByteSize default_count_offset() {1797return array_element_offset(default_count_off_set);1798}1799static ByteSize default_displacement_offset() {1800return array_element_offset(default_disaplacement_off_set);1801}1802static ByteSize case_count_offset(int index) {1803return case_array_offset() +1804(per_case_size() * index) +1805relative_count_offset();1806}1807static ByteSize case_array_offset() {1808return array_element_offset(case_array_start);1809}1810static ByteSize per_case_size() {1811return in_ByteSize(per_case_cell_count) * cell_size;1812}1813static ByteSize relative_count_offset() {1814return in_ByteSize(relative_count_off_set) * cell_size;1815}1816static ByteSize relative_displacement_offset() {1817return in_ByteSize(relative_displacement_off_set) * cell_size;1818}18191820#ifdef CC_INTERP1821static void increment_count_no_overflow(DataLayout* layout, int index) {1822if (index == -1) {1823increment_array_uint_at_no_overflow(layout, default_count_off_set);1824} else {1825increment_array_uint_at_no_overflow(layout, case_array_start +1826index * per_case_cell_count +1827relative_count_off_set);1828}1829}18301831static DataLayout* advance(DataLayout* layout, int index) {1832if (index == -1) {1833return (DataLayout*) (((address)layout) + (ssize_t)array_int_at(layout, default_disaplacement_off_set));1834} else {1835return (DataLayout*) (((address)layout) + (ssize_t)array_int_at(layout, case_array_start +1836index * per_case_cell_count +1837relative_displacement_off_set));1838}1839}1840#endif // CC_INTERP18411842// Specific initialization.1843void post_initialize(BytecodeStream* stream, MethodData* mdo);18441845#ifndef PRODUCT1846void print_data_on(outputStream* st, const char* extra = NULL) const;1847#endif1848};18491850class ArgInfoData : public ArrayData {18511852public:1853ArgInfoData(DataLayout* layout) : ArrayData(layout) {1854assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type");1855}18561857virtual bool is_ArgInfoData() const { return true; }185818591860int number_of_args() const {1861return array_len();1862}18631864uint arg_modified(int arg) const {1865return array_uint_at(arg);1866}18671868void set_arg_modified(int arg, uint val) {1869array_set_int_at(arg, val);1870}18711872#ifndef PRODUCT1873void print_data_on(outputStream* st, const char* extra = NULL) const;1874#endif1875};18761877// ParametersTypeData1878//1879// A ParametersTypeData is used to access profiling information about1880// types of parameters to a method1881class ParametersTypeData : public ArrayData {18821883private:1884TypeStackSlotEntries _parameters;18851886static int stack_slot_local_offset(int i) {1887assert_profiling_enabled();1888return array_start_off_set + TypeStackSlotEntries::stack_slot_local_offset(i);1889}18901891static int type_local_offset(int i) {1892assert_profiling_enabled();1893return array_start_off_set + TypeStackSlotEntries::type_local_offset(i);1894}18951896static bool profiling_enabled();1897static void assert_profiling_enabled() {1898assert(profiling_enabled(), "method parameters profiling should be on");1899}19001901public:1902ParametersTypeData(DataLayout* layout) : ArrayData(layout), _parameters(1, number_of_parameters()) {1903assert(layout->tag() == DataLayout::parameters_type_data_tag, "wrong type");1904// Some compilers (VC++) don't want this passed in member initialization list1905_parameters.set_profile_data(this);1906}19071908static int compute_cell_count(Method* m);19091910virtual bool is_ParametersTypeData() const { return true; }19111912virtual void post_initialize(BytecodeStream* stream, MethodData* mdo);19131914int number_of_parameters() const {1915return array_len() / TypeStackSlotEntries::per_arg_count();1916}19171918const TypeStackSlotEntries* parameters() const { return &_parameters; }19191920uint stack_slot(int i) const {1921return _parameters.stack_slot(i);1922}19231924void set_type(int i, Klass* k) {1925intptr_t current = _parameters.type(i);1926_parameters.set_type(i, TypeEntries::with_status((intptr_t)k, current));1927}19281929virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {1930_parameters.clean_weak_klass_links(is_alive_closure);1931}19321933#ifndef PRODUCT1934virtual void print_data_on(outputStream* st, const char* extra = NULL) const;1935#endif19361937static ByteSize stack_slot_offset(int i) {1938return cell_offset(stack_slot_local_offset(i));1939}19401941static ByteSize type_offset(int i) {1942return cell_offset(type_local_offset(i));1943}1944};19451946// SpeculativeTrapData1947//1948// A SpeculativeTrapData is used to record traps due to type1949// speculation. It records the root of the compilation: that type1950// speculation is wrong in the context of one compilation (for1951// method1) doesn't mean it's wrong in the context of another one (for1952// method2). Type speculation could have more/different data in the1953// context of the compilation of method2 and it's worthwhile to try an1954// optimization that failed for compilation of method1 in the context1955// of compilation of method2.1956// Space for SpeculativeTrapData entries is allocated from the extra1957// data space in the MDO. If we run out of space, the trap data for1958// the ProfileData at that bci is updated.1959class SpeculativeTrapData : public ProfileData {1960protected:1961enum {1962method_offset,1963speculative_trap_cell_count1964};1965public:1966SpeculativeTrapData(DataLayout* layout) : ProfileData(layout) {1967assert(layout->tag() == DataLayout::speculative_trap_data_tag, "wrong type");1968}19691970virtual bool is_SpeculativeTrapData() const { return true; }19711972static int static_cell_count() {1973return speculative_trap_cell_count;1974}19751976virtual int cell_count() const {1977return static_cell_count();1978}19791980// Direct accessor1981Method* method() const {1982return (Method*)intptr_at(method_offset);1983}19841985void set_method(Method* m) {1986set_intptr_at(method_offset, (intptr_t)m);1987}19881989#ifndef PRODUCT1990virtual void print_data_on(outputStream* st, const char* extra = NULL) const;1991#endif1992};19931994// MethodData*1995//1996// A MethodData* holds information which has been collected about1997// a method. Its layout looks like this:1998//1999// -----------------------------2000// | header |2001// | klass |2002// -----------------------------2003// | method |2004// | size of the MethodData* |2005// -----------------------------2006// | Data entries... |2007// | (variable size) |2008// | |2009// . .2010// . .2011// . .2012// | |2013// -----------------------------2014//2015// The data entry area is a heterogeneous array of DataLayouts. Each2016// DataLayout in the array corresponds to a specific bytecode in the2017// method. The entries in the array are sorted by the corresponding2018// bytecode. Access to the data is via resource-allocated ProfileData,2019// which point to the underlying blocks of DataLayout structures.2020//2021// During interpretation, if profiling in enabled, the interpreter2022// maintains a method data pointer (mdp), which points at the entry2023// in the array corresponding to the current bci. In the course of2024// intepretation, when a bytecode is encountered that has profile data2025// associated with it, the entry pointed to by mdp is updated, then the2026// mdp is adjusted to point to the next appropriate DataLayout. If mdp2027// is NULL to begin with, the interpreter assumes that the current method2028// is not (yet) being profiled.2029//2030// In MethodData* parlance, "dp" is a "data pointer", the actual address2031// of a DataLayout element. A "di" is a "data index", the offset in bytes2032// from the base of the data entry array. A "displacement" is the byte offset2033// in certain ProfileData objects that indicate the amount the mdp must be2034// adjusted in the event of a change in control flow.2035//20362037CC_INTERP_ONLY(class BytecodeInterpreter;)2038class CleanExtraDataClosure;20392040class MethodData : public Metadata {2041friend class VMStructs;2042CC_INTERP_ONLY(friend class BytecodeInterpreter;)2043private:2044friend class ProfileData;20452046// Back pointer to the Method*2047Method* _method;20482049// Size of this oop in bytes2050int _size;20512052// Cached hint for bci_to_dp and bci_to_data2053int _hint_di;20542055Mutex _extra_data_lock;20562057MethodData(methodHandle method, int size, TRAPS);2058public:2059static MethodData* allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS);2060MethodData() : _extra_data_lock(Monitor::leaf, "MDO extra data lock") {}; // For ciMethodData20612062bool is_methodData() const volatile { return true; }20632064// Whole-method sticky bits and flags2065enum {2066_trap_hist_limit = 20, // decoupled from Deoptimization::Reason_LIMIT2067_trap_hist_mask = max_jubyte,2068_extra_data_count = 4 // extra DataLayout headers, for trap history2069}; // Public flag values2070private:2071uint _nof_decompiles; // count of all nmethod removals2072uint _nof_overflow_recompiles; // recompile count, excluding recomp. bits2073uint _nof_overflow_traps; // trap count, excluding _trap_hist2074union {2075intptr_t _align;2076u1 _array[_trap_hist_limit];2077} _trap_hist;20782079// Support for interprocedural escape analysis, from Thomas Kotzmann.2080intx _eflags; // flags on escape information2081intx _arg_local; // bit set of non-escaping arguments2082intx _arg_stack; // bit set of stack-allocatable arguments2083intx _arg_returned; // bit set of returned arguments20842085int _creation_mileage; // method mileage at MDO creation20862087// How many invocations has this MDO seen?2088// These counters are used to determine the exact age of MDO.2089// We need those because in tiered a method can be concurrently2090// executed at different levels.2091InvocationCounter _invocation_counter;2092// Same for backedges.2093InvocationCounter _backedge_counter;2094// Counter values at the time profiling started.2095int _invocation_counter_start;2096int _backedge_counter_start;20972098#if INCLUDE_RTM_OPT2099// State of RTM code generation during compilation of the method2100int _rtm_state;2101#endif21022103// Number of loops and blocks is computed when compiling the first2104// time with C1. It is used to determine if method is trivial.2105short _num_loops;2106short _num_blocks;2107// Does this method contain anything worth profiling?2108enum WouldProfile {unknown, no_profile, profile};2109WouldProfile _would_profile;21102111// Size of _data array in bytes. (Excludes header and extra_data fields.)2112int _data_size;21132114// data index for the area dedicated to parameters. -1 if no2115// parameter profiling.2116int _parameters_type_data_di;21172118// Beginning of the data entries2119intptr_t _data[1];21202121// Helper for size computation2122static int compute_data_size(BytecodeStream* stream);2123static int bytecode_cell_count(Bytecodes::Code code);2124static bool is_speculative_trap_bytecode(Bytecodes::Code code);2125enum { no_profile_data = -1, variable_cell_count = -2 };21262127// Helper for initialization2128DataLayout* data_layout_at(int data_index) const {2129assert(data_index % sizeof(intptr_t) == 0, "unaligned");2130return (DataLayout*) (((address)_data) + data_index);2131}21322133// Initialize an individual data segment. Returns the size of2134// the segment in bytes.2135int initialize_data(BytecodeStream* stream, int data_index);21362137// Helper for data_at2138DataLayout* limit_data_position() const {2139return (DataLayout*)((address)data_base() + _data_size);2140}2141bool out_of_bounds(int data_index) const {2142return data_index >= data_size();2143}21442145// Give each of the data entries a chance to perform specific2146// data initialization.2147void post_initialize(BytecodeStream* stream);21482149// hint accessors2150int hint_di() const { return _hint_di; }2151void set_hint_di(int di) {2152assert(!out_of_bounds(di), "hint_di out of bounds");2153_hint_di = di;2154}2155ProfileData* data_before(int bci) {2156// avoid SEGV on this edge case2157if (data_size() == 0)2158return NULL;2159int hint = hint_di();2160if (data_layout_at(hint)->bci() <= bci)2161return data_at(hint);2162return first_data();2163}21642165// What is the index of the first data entry?2166int first_di() const { return 0; }21672168ProfileData* bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp, bool concurrent);2169// Find or create an extra ProfileData:2170ProfileData* bci_to_extra_data(int bci, Method* m, bool create_if_missing);21712172// return the argument info cell2173ArgInfoData *arg_info();21742175enum {2176no_type_profile = 0,2177type_profile_jsr292 = 1,2178type_profile_all = 22179};21802181static bool profile_jsr292(methodHandle m, int bci);2182static int profile_arguments_flag();2183static bool profile_all_arguments();2184static bool profile_arguments_for_invoke(methodHandle m, int bci);2185static int profile_return_flag();2186static bool profile_all_return();2187static bool profile_return_for_invoke(methodHandle m, int bci);2188static int profile_parameters_flag();2189static bool profile_parameters_jsr292_only();2190static bool profile_all_parameters();21912192void clean_extra_data(CleanExtraDataClosure* cl);2193void clean_extra_data_helper(DataLayout* dp, int shift, bool reset = false);2194void verify_extra_data_clean(CleanExtraDataClosure* cl);21952196public:2197static int header_size() {2198return sizeof(MethodData)/wordSize;2199}22002201// Compute the size of a MethodData* before it is created.2202static int compute_allocation_size_in_bytes(methodHandle method);2203static int compute_allocation_size_in_words(methodHandle method);2204static int compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps);22052206// Determine if a given bytecode can have profile information.2207static bool bytecode_has_profile(Bytecodes::Code code) {2208return bytecode_cell_count(code) != no_profile_data;2209}22102211// reset into original state2212void init();22132214// My size2215int size_in_bytes() const { return _size; }2216int size() const { return align_object_size(align_size_up(_size, BytesPerWord)/BytesPerWord); }2217#if INCLUDE_SERVICES2218void collect_statistics(KlassSizeStats *sz) const;2219#endif22202221int creation_mileage() const { return _creation_mileage; }2222void set_creation_mileage(int x) { _creation_mileage = x; }22232224int invocation_count() {2225if (invocation_counter()->carry()) {2226return InvocationCounter::count_limit;2227}2228return invocation_counter()->count();2229}2230int backedge_count() {2231if (backedge_counter()->carry()) {2232return InvocationCounter::count_limit;2233}2234return backedge_counter()->count();2235}22362237int invocation_count_start() {2238if (invocation_counter()->carry()) {2239return 0;2240}2241return _invocation_counter_start;2242}22432244int backedge_count_start() {2245if (backedge_counter()->carry()) {2246return 0;2247}2248return _backedge_counter_start;2249}22502251int invocation_count_delta() { return invocation_count() - invocation_count_start(); }2252int backedge_count_delta() { return backedge_count() - backedge_count_start(); }22532254void reset_start_counters() {2255_invocation_counter_start = invocation_count();2256_backedge_counter_start = backedge_count();2257}22582259InvocationCounter* invocation_counter() { return &_invocation_counter; }2260InvocationCounter* backedge_counter() { return &_backedge_counter; }22612262#if INCLUDE_RTM_OPT2263int rtm_state() const {2264return _rtm_state;2265}2266void set_rtm_state(RTMState rstate) {2267_rtm_state = (int)rstate;2268}2269void atomic_set_rtm_state(RTMState rstate) {2270Atomic::store((int)rstate, &_rtm_state);2271}22722273static int rtm_state_offset_in_bytes() {2274return offset_of(MethodData, _rtm_state);2275}2276#endif22772278void set_would_profile(bool p) { _would_profile = p ? profile : no_profile; }2279bool would_profile() const { return _would_profile != no_profile; }22802281int num_loops() const { return _num_loops; }2282void set_num_loops(int n) { _num_loops = n; }2283int num_blocks() const { return _num_blocks; }2284void set_num_blocks(int n) { _num_blocks = n; }22852286bool is_mature() const; // consult mileage and ProfileMaturityPercentage2287static int mileage_of(Method* m);22882289// Support for interprocedural escape analysis, from Thomas Kotzmann.2290enum EscapeFlag {2291estimated = 1 << 0,2292return_local = 1 << 1,2293return_allocated = 1 << 2,2294allocated_escapes = 1 << 3,2295unknown_modified = 1 << 42296};22972298intx eflags() { return _eflags; }2299intx arg_local() { return _arg_local; }2300intx arg_stack() { return _arg_stack; }2301intx arg_returned() { return _arg_returned; }2302uint arg_modified(int a) { ArgInfoData *aid = arg_info();2303assert(aid != NULL, "arg_info must be not null");2304assert(a >= 0 && a < aid->number_of_args(), "valid argument number");2305return aid->arg_modified(a); }23062307void set_eflags(intx v) { _eflags = v; }2308void set_arg_local(intx v) { _arg_local = v; }2309void set_arg_stack(intx v) { _arg_stack = v; }2310void set_arg_returned(intx v) { _arg_returned = v; }2311void set_arg_modified(int a, uint v) { ArgInfoData *aid = arg_info();2312assert(aid != NULL, "arg_info must be not null");2313assert(a >= 0 && a < aid->number_of_args(), "valid argument number");2314aid->set_arg_modified(a, v); }23152316void clear_escape_info() { _eflags = _arg_local = _arg_stack = _arg_returned = 0; }23172318// Location and size of data area2319address data_base() const {2320return (address) _data;2321}2322int data_size() const {2323return _data_size;2324}23252326// Accessors2327Method* method() const { return _method; }23282329// Get the data at an arbitrary (sort of) data index.2330ProfileData* data_at(int data_index) const;23312332// Walk through the data in order.2333ProfileData* first_data() const { return data_at(first_di()); }2334ProfileData* next_data(ProfileData* current) const;2335bool is_valid(ProfileData* current) const { return current != NULL; }23362337// Convert a dp (data pointer) to a di (data index).2338int dp_to_di(address dp) const {2339return dp - ((address)_data);2340}23412342address di_to_dp(int di) {2343return (address)data_layout_at(di);2344}23452346// bci to di/dp conversion.2347address bci_to_dp(int bci);2348int bci_to_di(int bci) {2349return dp_to_di(bci_to_dp(bci));2350}23512352// Get the data at an arbitrary bci, or NULL if there is none.2353ProfileData* bci_to_data(int bci);23542355// Same, but try to create an extra_data record if one is needed:2356ProfileData* allocate_bci_to_data(int bci, Method* m) {2357ProfileData* data = NULL;2358// If m not NULL, try to allocate a SpeculativeTrapData entry2359if (m == NULL) {2360data = bci_to_data(bci);2361}2362if (data != NULL) {2363return data;2364}2365data = bci_to_extra_data(bci, m, true);2366if (data != NULL) {2367return data;2368}2369// If SpeculativeTrapData allocation fails try to allocate a2370// regular entry2371data = bci_to_data(bci);2372if (data != NULL) {2373return data;2374}2375return bci_to_extra_data(bci, NULL, true);2376}23772378// Add a handful of extra data records, for trap tracking.2379DataLayout* extra_data_base() const { return limit_data_position(); }2380DataLayout* extra_data_limit() const { return (DataLayout*)((address)this + size_in_bytes()); }2381int extra_data_size() const { return (address)extra_data_limit()2382- (address)extra_data_base(); }2383static DataLayout* next_extra(DataLayout* dp);23842385// Return (uint)-1 for overflow.2386uint trap_count(int reason) const {2387assert((uint)reason < _trap_hist_limit, "oob");2388return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1;2389}2390// For loops:2391static uint trap_reason_limit() { return _trap_hist_limit; }2392static uint trap_count_limit() { return _trap_hist_mask; }2393uint inc_trap_count(int reason) {2394// Count another trap, anywhere in this method.2395assert(reason >= 0, "must be single trap");2396if ((uint)reason < _trap_hist_limit) {2397uint cnt1 = 1 + _trap_hist._array[reason];2398if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow...2399_trap_hist._array[reason] = cnt1;2400return cnt1;2401} else {2402return _trap_hist_mask + (++_nof_overflow_traps);2403}2404} else {2405// Could not represent the count in the histogram.2406return (++_nof_overflow_traps);2407}2408}24092410uint overflow_trap_count() const {2411return _nof_overflow_traps;2412}2413uint overflow_recompile_count() const {2414return _nof_overflow_recompiles;2415}2416void inc_overflow_recompile_count() {2417_nof_overflow_recompiles += 1;2418}2419uint decompile_count() const {2420return _nof_decompiles;2421}2422void inc_decompile_count() {2423_nof_decompiles += 1;2424if (decompile_count() > (uint)PerMethodRecompilationCutoff) {2425method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff");2426}2427}24282429// Return pointer to area dedicated to parameters in MDO2430ParametersTypeData* parameters_type_data() const {2431return _parameters_type_data_di != -1 ? data_layout_at(_parameters_type_data_di)->data_in()->as_ParametersTypeData() : NULL;2432}24332434int parameters_type_data_di() const {2435assert(_parameters_type_data_di != -1, "no args type data");2436return _parameters_type_data_di;2437}24382439// Support for code generation2440static ByteSize data_offset() {2441return byte_offset_of(MethodData, _data[0]);2442}24432444static ByteSize invocation_counter_offset() {2445return byte_offset_of(MethodData, _invocation_counter);2446}2447static ByteSize backedge_counter_offset() {2448return byte_offset_of(MethodData, _backedge_counter);2449}24502451static ByteSize parameters_type_data_di_offset() {2452return byte_offset_of(MethodData, _parameters_type_data_di);2453}24542455// Deallocation support - no pointer fields to deallocate2456void deallocate_contents(ClassLoaderData* loader_data) {}24572458// GC support2459void set_size(int object_size_in_bytes) { _size = object_size_in_bytes; }24602461// Printing2462#ifndef PRODUCT2463void print_on (outputStream* st) const;2464#endif2465void print_value_on(outputStream* st) const;24662467#ifndef PRODUCT2468// printing support for method data2469void print_data_on(outputStream* st) const;2470#endif24712472const char* internal_name() const { return "{method data}"; }24732474// verification2475void verify_on(outputStream* st);2476void verify_data_on(outputStream* st);24772478static bool profile_parameters_for_method(methodHandle m);2479static bool profile_arguments();2480static bool profile_arguments_jsr292_only();2481static bool profile_return();2482static bool profile_parameters();2483static bool profile_return_jsr292_only();24842485void clean_method_data(BoolObjectClosure* is_alive);24862487void clean_weak_method_links();2488};24892490#endif // SHARE_VM_OOPS_METHODDATAOOP_HPP249124922493