1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/oops/methodDataOop.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,1341 @@ 1.4 +/* 1.5 + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +class BytecodeStream; 1.29 + 1.30 +// The MethodData object collects counts and other profile information 1.31 +// during zeroth-tier (interpretive) and first-tier execution. 1.32 +// The profile is used later by compilation heuristics. Some heuristics 1.33 +// enable use of aggressive (or "heroic") optimizations. An aggressive 1.34 +// optimization often has a down-side, a corner case that it handles 1.35 +// poorly, but which is thought to be rare. The profile provides 1.36 +// evidence of this rarity for a given method or even BCI. It allows 1.37 +// the compiler to back out of the optimization at places where it 1.38 +// has historically been a poor choice. Other heuristics try to use 1.39 +// specific information gathered about types observed at a given site. 1.40 +// 1.41 +// All data in the profile is approximate. It is expected to be accurate 1.42 +// on the whole, but the system expects occasional inaccuraces, due to 1.43 +// counter overflow, multiprocessor races during data collection, space 1.44 +// limitations, missing MDO blocks, etc. Bad or missing data will degrade 1.45 +// optimization quality but will not affect correctness. Also, each MDO 1.46 +// is marked with its birth-date ("creation_mileage") which can be used 1.47 +// to assess the quality ("maturity") of its data. 1.48 +// 1.49 +// Short (<32-bit) counters are designed to overflow to a known "saturated" 1.50 +// state. Also, certain recorded per-BCI events are given one-bit counters 1.51 +// which overflow to a saturated state which applied to all counters at 1.52 +// that BCI. In other words, there is a small lattice which approximates 1.53 +// the ideal of an infinite-precision counter for each event at each BCI, 1.54 +// and the lattice quickly "bottoms out" in a state where all counters 1.55 +// are taken to be indefinitely large. 1.56 +// 1.57 +// The reader will find many data races in profile gathering code, starting 1.58 +// with invocation counter incrementation. None of these races harm correct 1.59 +// execution of the compiled code. 1.60 + 1.61 +// DataLayout 1.62 +// 1.63 +// Overlay for generic profiling data. 1.64 +class DataLayout VALUE_OBJ_CLASS_SPEC { 1.65 +private: 1.66 + // Every data layout begins with a header. This header 1.67 + // contains a tag, which is used to indicate the size/layout 1.68 + // of the data, 4 bits of flags, which can be used in any way, 1.69 + // 4 bits of trap history (none/one reason/many reasons), 1.70 + // and a bci, which is used to tie this piece of data to a 1.71 + // specific bci in the bytecodes. 1.72 + union { 1.73 + intptr_t _bits; 1.74 + struct { 1.75 + u1 _tag; 1.76 + u1 _flags; 1.77 + u2 _bci; 1.78 + } _struct; 1.79 + } _header; 1.80 + 1.81 + // The data layout has an arbitrary number of cells, each sized 1.82 + // to accomodate a pointer or an integer. 1.83 + intptr_t _cells[1]; 1.84 + 1.85 + // Some types of data layouts need a length field. 1.86 + static bool needs_array_len(u1 tag); 1.87 + 1.88 +public: 1.89 + enum { 1.90 + counter_increment = 1 1.91 + }; 1.92 + 1.93 + enum { 1.94 + cell_size = sizeof(intptr_t) 1.95 + }; 1.96 + 1.97 + // Tag values 1.98 + enum { 1.99 + no_tag, 1.100 + bit_data_tag, 1.101 + counter_data_tag, 1.102 + jump_data_tag, 1.103 + receiver_type_data_tag, 1.104 + virtual_call_data_tag, 1.105 + ret_data_tag, 1.106 + branch_data_tag, 1.107 + multi_branch_data_tag 1.108 + }; 1.109 + 1.110 + enum { 1.111 + // The _struct._flags word is formatted as [trap_state:4 | flags:4]. 1.112 + // The trap state breaks down further as [recompile:1 | reason:3]. 1.113 + // This further breakdown is defined in deoptimization.cpp. 1.114 + // See Deoptimization::trap_state_reason for an assert that 1.115 + // trap_bits is big enough to hold reasons < Reason_RECORDED_LIMIT. 1.116 + // 1.117 + // The trap_state is collected only if ProfileTraps is true. 1.118 + trap_bits = 1+3, // 3: enough to distinguish [0..Reason_RECORDED_LIMIT]. 1.119 + trap_shift = BitsPerByte - trap_bits, 1.120 + trap_mask = right_n_bits(trap_bits), 1.121 + trap_mask_in_place = (trap_mask << trap_shift), 1.122 + flag_limit = trap_shift, 1.123 + flag_mask = right_n_bits(flag_limit), 1.124 + first_flag = 0 1.125 + }; 1.126 + 1.127 + // Size computation 1.128 + static int header_size_in_bytes() { 1.129 + return cell_size; 1.130 + } 1.131 + static int header_size_in_cells() { 1.132 + return 1; 1.133 + } 1.134 + 1.135 + static int compute_size_in_bytes(int cell_count) { 1.136 + return header_size_in_bytes() + cell_count * cell_size; 1.137 + } 1.138 + 1.139 + // Initialization 1.140 + void initialize(u1 tag, u2 bci, int cell_count); 1.141 + 1.142 + // Accessors 1.143 + u1 tag() { 1.144 + return _header._struct._tag; 1.145 + } 1.146 + 1.147 + // Return a few bits of trap state. Range is [0..trap_mask]. 1.148 + // The state tells if traps with zero, one, or many reasons have occurred. 1.149 + // It also tells whether zero or many recompilations have occurred. 1.150 + // The associated trap histogram in the MDO itself tells whether 1.151 + // traps are common or not. If a BCI shows that a trap X has 1.152 + // occurred, and the MDO shows N occurrences of X, we make the 1.153 + // simplifying assumption that all N occurrences can be blamed 1.154 + // on that BCI. 1.155 + int trap_state() { 1.156 + return ((_header._struct._flags >> trap_shift) & trap_mask); 1.157 + } 1.158 + 1.159 + void set_trap_state(int new_state) { 1.160 + assert(ProfileTraps, "used only under +ProfileTraps"); 1.161 + uint old_flags = (_header._struct._flags & flag_mask); 1.162 + _header._struct._flags = (new_state << trap_shift) | old_flags; 1.163 + assert(trap_state() == new_state, "sanity"); 1.164 + } 1.165 + 1.166 + u1 flags() { 1.167 + return _header._struct._flags; 1.168 + } 1.169 + 1.170 + u2 bci() { 1.171 + return _header._struct._bci; 1.172 + } 1.173 + 1.174 + void set_header(intptr_t value) { 1.175 + _header._bits = value; 1.176 + } 1.177 + void release_set_header(intptr_t value) { 1.178 + OrderAccess::release_store_ptr(&_header._bits, value); 1.179 + } 1.180 + intptr_t header() { 1.181 + return _header._bits; 1.182 + } 1.183 + void set_cell_at(int index, intptr_t value) { 1.184 + _cells[index] = value; 1.185 + } 1.186 + void release_set_cell_at(int index, intptr_t value) { 1.187 + OrderAccess::release_store_ptr(&_cells[index], value); 1.188 + } 1.189 + intptr_t cell_at(int index) { 1.190 + return _cells[index]; 1.191 + } 1.192 + intptr_t* adr_cell_at(int index) { 1.193 + return &_cells[index]; 1.194 + } 1.195 + oop* adr_oop_at(int index) { 1.196 + return (oop*)&(_cells[index]); 1.197 + } 1.198 + 1.199 + void set_flag_at(int flag_number) { 1.200 + assert(flag_number < flag_limit, "oob"); 1.201 + _header._struct._flags |= (0x1 << flag_number); 1.202 + } 1.203 + bool flag_at(int flag_number) { 1.204 + assert(flag_number < flag_limit, "oob"); 1.205 + return (_header._struct._flags & (0x1 << flag_number)) != 0; 1.206 + } 1.207 + 1.208 + // Low-level support for code generation. 1.209 + static ByteSize header_offset() { 1.210 + return byte_offset_of(DataLayout, _header); 1.211 + } 1.212 + static ByteSize tag_offset() { 1.213 + return byte_offset_of(DataLayout, _header._struct._tag); 1.214 + } 1.215 + static ByteSize flags_offset() { 1.216 + return byte_offset_of(DataLayout, _header._struct._flags); 1.217 + } 1.218 + static ByteSize bci_offset() { 1.219 + return byte_offset_of(DataLayout, _header._struct._bci); 1.220 + } 1.221 + static ByteSize cell_offset(int index) { 1.222 + return byte_offset_of(DataLayout, _cells[index]); 1.223 + } 1.224 + // Return a value which, when or-ed as a byte into _flags, sets the flag. 1.225 + static int flag_number_to_byte_constant(int flag_number) { 1.226 + assert(0 <= flag_number && flag_number < flag_limit, "oob"); 1.227 + DataLayout temp; temp.set_header(0); 1.228 + temp.set_flag_at(flag_number); 1.229 + return temp._header._struct._flags; 1.230 + } 1.231 + // Return a value which, when or-ed as a word into _header, sets the flag. 1.232 + static intptr_t flag_mask_to_header_mask(int byte_constant) { 1.233 + DataLayout temp; temp.set_header(0); 1.234 + temp._header._struct._flags = byte_constant; 1.235 + return temp._header._bits; 1.236 + } 1.237 +}; 1.238 + 1.239 + 1.240 +// ProfileData class hierarchy 1.241 +class ProfileData; 1.242 +class BitData; 1.243 +class CounterData; 1.244 +class ReceiverTypeData; 1.245 +class VirtualCallData; 1.246 +class RetData; 1.247 +class JumpData; 1.248 +class BranchData; 1.249 +class ArrayData; 1.250 +class MultiBranchData; 1.251 + 1.252 + 1.253 +// ProfileData 1.254 +// 1.255 +// A ProfileData object is created to refer to a section of profiling 1.256 +// data in a structured way. 1.257 +class ProfileData : public ResourceObj { 1.258 +private: 1.259 +#ifndef PRODUCT 1.260 + enum { 1.261 + tab_width_one = 16, 1.262 + tab_width_two = 36 1.263 + }; 1.264 +#endif // !PRODUCT 1.265 + 1.266 + // This is a pointer to a section of profiling data. 1.267 + DataLayout* _data; 1.268 + 1.269 +protected: 1.270 + DataLayout* data() { return _data; } 1.271 + 1.272 + enum { 1.273 + cell_size = DataLayout::cell_size 1.274 + }; 1.275 + 1.276 +public: 1.277 + // How many cells are in this? 1.278 + virtual int cell_count() { 1.279 + ShouldNotReachHere(); 1.280 + return -1; 1.281 + } 1.282 + 1.283 + // Return the size of this data. 1.284 + int size_in_bytes() { 1.285 + return DataLayout::compute_size_in_bytes(cell_count()); 1.286 + } 1.287 + 1.288 +protected: 1.289 + // Low-level accessors for underlying data 1.290 + void set_intptr_at(int index, intptr_t value) { 1.291 + assert(0 <= index && index < cell_count(), "oob"); 1.292 + data()->set_cell_at(index, value); 1.293 + } 1.294 + void release_set_intptr_at(int index, intptr_t value) { 1.295 + assert(0 <= index && index < cell_count(), "oob"); 1.296 + data()->release_set_cell_at(index, value); 1.297 + } 1.298 + intptr_t intptr_at(int index) { 1.299 + assert(0 <= index && index < cell_count(), "oob"); 1.300 + return data()->cell_at(index); 1.301 + } 1.302 + void set_uint_at(int index, uint value) { 1.303 + set_intptr_at(index, (intptr_t) value); 1.304 + } 1.305 + void release_set_uint_at(int index, uint value) { 1.306 + release_set_intptr_at(index, (intptr_t) value); 1.307 + } 1.308 + uint uint_at(int index) { 1.309 + return (uint)intptr_at(index); 1.310 + } 1.311 + void set_int_at(int index, int value) { 1.312 + set_intptr_at(index, (intptr_t) value); 1.313 + } 1.314 + void release_set_int_at(int index, int value) { 1.315 + release_set_intptr_at(index, (intptr_t) value); 1.316 + } 1.317 + int int_at(int index) { 1.318 + return (int)intptr_at(index); 1.319 + } 1.320 + int int_at_unchecked(int index) { 1.321 + return (int)data()->cell_at(index); 1.322 + } 1.323 + void set_oop_at(int index, oop value) { 1.324 + set_intptr_at(index, (intptr_t) value); 1.325 + } 1.326 + oop oop_at(int index) { 1.327 + return (oop)intptr_at(index); 1.328 + } 1.329 + oop* adr_oop_at(int index) { 1.330 + assert(0 <= index && index < cell_count(), "oob"); 1.331 + return data()->adr_oop_at(index); 1.332 + } 1.333 + 1.334 + void set_flag_at(int flag_number) { 1.335 + data()->set_flag_at(flag_number); 1.336 + } 1.337 + bool flag_at(int flag_number) { 1.338 + return data()->flag_at(flag_number); 1.339 + } 1.340 + 1.341 + // two convenient imports for use by subclasses: 1.342 + static ByteSize cell_offset(int index) { 1.343 + return DataLayout::cell_offset(index); 1.344 + } 1.345 + static int flag_number_to_byte_constant(int flag_number) { 1.346 + return DataLayout::flag_number_to_byte_constant(flag_number); 1.347 + } 1.348 + 1.349 + ProfileData(DataLayout* data) { 1.350 + _data = data; 1.351 + } 1.352 + 1.353 +public: 1.354 + // Constructor for invalid ProfileData. 1.355 + ProfileData(); 1.356 + 1.357 + u2 bci() { 1.358 + return data()->bci(); 1.359 + } 1.360 + 1.361 + address dp() { 1.362 + return (address)_data; 1.363 + } 1.364 + 1.365 + int trap_state() { 1.366 + return data()->trap_state(); 1.367 + } 1.368 + void set_trap_state(int new_state) { 1.369 + data()->set_trap_state(new_state); 1.370 + } 1.371 + 1.372 + // Type checking 1.373 + virtual bool is_BitData() { return false; } 1.374 + virtual bool is_CounterData() { return false; } 1.375 + virtual bool is_JumpData() { return false; } 1.376 + virtual bool is_ReceiverTypeData(){ return false; } 1.377 + virtual bool is_VirtualCallData() { return false; } 1.378 + virtual bool is_RetData() { return false; } 1.379 + virtual bool is_BranchData() { return false; } 1.380 + virtual bool is_ArrayData() { return false; } 1.381 + virtual bool is_MultiBranchData() { return false; } 1.382 + 1.383 + BitData* as_BitData() { 1.384 + assert(is_BitData(), "wrong type"); 1.385 + return is_BitData() ? (BitData*) this : NULL; 1.386 + } 1.387 + CounterData* as_CounterData() { 1.388 + assert(is_CounterData(), "wrong type"); 1.389 + return is_CounterData() ? (CounterData*) this : NULL; 1.390 + } 1.391 + JumpData* as_JumpData() { 1.392 + assert(is_JumpData(), "wrong type"); 1.393 + return is_JumpData() ? (JumpData*) this : NULL; 1.394 + } 1.395 + ReceiverTypeData* as_ReceiverTypeData() { 1.396 + assert(is_ReceiverTypeData(), "wrong type"); 1.397 + return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL; 1.398 + } 1.399 + VirtualCallData* as_VirtualCallData() { 1.400 + assert(is_VirtualCallData(), "wrong type"); 1.401 + return is_VirtualCallData() ? (VirtualCallData*)this : NULL; 1.402 + } 1.403 + RetData* as_RetData() { 1.404 + assert(is_RetData(), "wrong type"); 1.405 + return is_RetData() ? (RetData*) this : NULL; 1.406 + } 1.407 + BranchData* as_BranchData() { 1.408 + assert(is_BranchData(), "wrong type"); 1.409 + return is_BranchData() ? (BranchData*) this : NULL; 1.410 + } 1.411 + ArrayData* as_ArrayData() { 1.412 + assert(is_ArrayData(), "wrong type"); 1.413 + return is_ArrayData() ? (ArrayData*) this : NULL; 1.414 + } 1.415 + MultiBranchData* as_MultiBranchData() { 1.416 + assert(is_MultiBranchData(), "wrong type"); 1.417 + return is_MultiBranchData() ? (MultiBranchData*)this : NULL; 1.418 + } 1.419 + 1.420 + 1.421 + // Subclass specific initialization 1.422 + virtual void post_initialize(BytecodeStream* stream, methodDataOop mdo) {} 1.423 + 1.424 + // GC support 1.425 + virtual void follow_contents() {} 1.426 + virtual void oop_iterate(OopClosure* blk) {} 1.427 + virtual void oop_iterate_m(OopClosure* blk, MemRegion mr) {} 1.428 + virtual void adjust_pointers() {} 1.429 + 1.430 +#ifndef SERIALGC 1.431 + // Parallel old support 1.432 + virtual void follow_contents(ParCompactionManager* cm) {} 1.433 + virtual void update_pointers() {} 1.434 + virtual void update_pointers(HeapWord* beg_addr, HeapWord* end_addr) {} 1.435 +#endif // SERIALGC 1.436 + 1.437 + // CI translation: ProfileData can represent both MethodDataOop data 1.438 + // as well as CIMethodData data. This function is provided for translating 1.439 + // an oop in a ProfileData to the ci equivalent. Generally speaking, 1.440 + // most ProfileData don't require any translation, so we provide the null 1.441 + // translation here, and the required translators are in the ci subclasses. 1.442 + virtual void translate_from(ProfileData* data) {} 1.443 + 1.444 + virtual void print_data_on(outputStream* st) { 1.445 + ShouldNotReachHere(); 1.446 + } 1.447 + 1.448 +#ifndef PRODUCT 1.449 + void print_shared(outputStream* st, const char* name); 1.450 + void tab(outputStream* st); 1.451 +#endif 1.452 +}; 1.453 + 1.454 +// BitData 1.455 +// 1.456 +// A BitData holds a flag or two in its header. 1.457 +class BitData : public ProfileData { 1.458 +protected: 1.459 + enum { 1.460 + // null_seen: 1.461 + // saw a null operand (cast/aastore/instanceof) 1.462 + null_seen_flag = DataLayout::first_flag + 0 1.463 + }; 1.464 + enum { bit_cell_count = 0 }; // no additional data fields needed. 1.465 +public: 1.466 + BitData(DataLayout* layout) : ProfileData(layout) { 1.467 + } 1.468 + 1.469 + virtual bool is_BitData() { return true; } 1.470 + 1.471 + static int static_cell_count() { 1.472 + return bit_cell_count; 1.473 + } 1.474 + 1.475 + virtual int cell_count() { 1.476 + return static_cell_count(); 1.477 + } 1.478 + 1.479 + // Accessor 1.480 + 1.481 + // The null_seen flag bit is specially known to the interpreter. 1.482 + // Consulting it allows the compiler to avoid setting up null_check traps. 1.483 + bool null_seen() { return flag_at(null_seen_flag); } 1.484 + void set_null_seen() { set_flag_at(null_seen_flag); } 1.485 + 1.486 + 1.487 + // Code generation support 1.488 + static int null_seen_byte_constant() { 1.489 + return flag_number_to_byte_constant(null_seen_flag); 1.490 + } 1.491 + 1.492 + static ByteSize bit_data_size() { 1.493 + return cell_offset(bit_cell_count); 1.494 + } 1.495 + 1.496 +#ifndef PRODUCT 1.497 + void print_data_on(outputStream* st); 1.498 +#endif 1.499 +}; 1.500 + 1.501 +// CounterData 1.502 +// 1.503 +// A CounterData corresponds to a simple counter. 1.504 +class CounterData : public BitData { 1.505 +protected: 1.506 + enum { 1.507 + count_off, 1.508 + counter_cell_count 1.509 + }; 1.510 +public: 1.511 + CounterData(DataLayout* layout) : BitData(layout) {} 1.512 + 1.513 + virtual bool is_CounterData() { return true; } 1.514 + 1.515 + static int static_cell_count() { 1.516 + return counter_cell_count; 1.517 + } 1.518 + 1.519 + virtual int cell_count() { 1.520 + return static_cell_count(); 1.521 + } 1.522 + 1.523 + // Direct accessor 1.524 + uint count() { 1.525 + return uint_at(count_off); 1.526 + } 1.527 + 1.528 + // Code generation support 1.529 + static ByteSize count_offset() { 1.530 + return cell_offset(count_off); 1.531 + } 1.532 + static ByteSize counter_data_size() { 1.533 + return cell_offset(counter_cell_count); 1.534 + } 1.535 + 1.536 +#ifndef PRODUCT 1.537 + void print_data_on(outputStream* st); 1.538 +#endif 1.539 +}; 1.540 + 1.541 +// JumpData 1.542 +// 1.543 +// A JumpData is used to access profiling information for a direct 1.544 +// branch. It is a counter, used for counting the number of branches, 1.545 +// plus a data displacement, used for realigning the data pointer to 1.546 +// the corresponding target bci. 1.547 +class JumpData : public ProfileData { 1.548 +protected: 1.549 + enum { 1.550 + taken_off_set, 1.551 + displacement_off_set, 1.552 + jump_cell_count 1.553 + }; 1.554 + 1.555 + void set_displacement(int displacement) { 1.556 + set_int_at(displacement_off_set, displacement); 1.557 + } 1.558 + 1.559 +public: 1.560 + JumpData(DataLayout* layout) : ProfileData(layout) { 1.561 + assert(layout->tag() == DataLayout::jump_data_tag || 1.562 + layout->tag() == DataLayout::branch_data_tag, "wrong type"); 1.563 + } 1.564 + 1.565 + virtual bool is_JumpData() { return true; } 1.566 + 1.567 + static int static_cell_count() { 1.568 + return jump_cell_count; 1.569 + } 1.570 + 1.571 + virtual int cell_count() { 1.572 + return static_cell_count(); 1.573 + } 1.574 + 1.575 + // Direct accessor 1.576 + uint taken() { 1.577 + return uint_at(taken_off_set); 1.578 + } 1.579 + // Saturating counter 1.580 + uint inc_taken() { 1.581 + uint cnt = taken() + 1; 1.582 + // Did we wrap? Will compiler screw us?? 1.583 + if (cnt == 0) cnt--; 1.584 + set_uint_at(taken_off_set, cnt); 1.585 + return cnt; 1.586 + } 1.587 + 1.588 + int displacement() { 1.589 + return int_at(displacement_off_set); 1.590 + } 1.591 + 1.592 + // Code generation support 1.593 + static ByteSize taken_offset() { 1.594 + return cell_offset(taken_off_set); 1.595 + } 1.596 + 1.597 + static ByteSize displacement_offset() { 1.598 + return cell_offset(displacement_off_set); 1.599 + } 1.600 + 1.601 + // Specific initialization. 1.602 + void post_initialize(BytecodeStream* stream, methodDataOop mdo); 1.603 + 1.604 +#ifndef PRODUCT 1.605 + void print_data_on(outputStream* st); 1.606 +#endif 1.607 +}; 1.608 + 1.609 +// ReceiverTypeData 1.610 +// 1.611 +// A ReceiverTypeData is used to access profiling information about a 1.612 +// dynamic type check. It consists of a counter which counts the total times 1.613 +// that the check is reached, and a series of (klassOop, count) pairs 1.614 +// which are used to store a type profile for the receiver of the check. 1.615 +class ReceiverTypeData : public CounterData { 1.616 +protected: 1.617 + enum { 1.618 + receiver0_offset = counter_cell_count, 1.619 + count0_offset, 1.620 + receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset 1.621 + }; 1.622 + 1.623 +public: 1.624 + ReceiverTypeData(DataLayout* layout) : CounterData(layout) { 1.625 + assert(layout->tag() == DataLayout::receiver_type_data_tag || 1.626 + layout->tag() == DataLayout::virtual_call_data_tag, "wrong type"); 1.627 + } 1.628 + 1.629 + virtual bool is_ReceiverTypeData() { return true; } 1.630 + 1.631 + static int static_cell_count() { 1.632 + return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count; 1.633 + } 1.634 + 1.635 + virtual int cell_count() { 1.636 + return static_cell_count(); 1.637 + } 1.638 + 1.639 + // Direct accessors 1.640 + static uint row_limit() { 1.641 + return TypeProfileWidth; 1.642 + } 1.643 + static int receiver_cell_index(uint row) { 1.644 + return receiver0_offset + row * receiver_type_row_cell_count; 1.645 + } 1.646 + static int receiver_count_cell_index(uint row) { 1.647 + return count0_offset + row * receiver_type_row_cell_count; 1.648 + } 1.649 + 1.650 + // Get the receiver at row. The 'unchecked' version is needed by parallel old 1.651 + // gc; it does not assert the receiver is a klass. During compaction of the 1.652 + // perm gen, the klass may already have moved, so the is_klass() predicate 1.653 + // would fail. The 'normal' version should be used whenever possible. 1.654 + klassOop receiver_unchecked(uint row) { 1.655 + assert(row < row_limit(), "oob"); 1.656 + oop recv = oop_at(receiver_cell_index(row)); 1.657 + return (klassOop)recv; 1.658 + } 1.659 + 1.660 + klassOop receiver(uint row) { 1.661 + klassOop recv = receiver_unchecked(row); 1.662 + assert(recv == NULL || ((oop)recv)->is_klass(), "wrong type"); 1.663 + return recv; 1.664 + } 1.665 + 1.666 + uint receiver_count(uint row) { 1.667 + assert(row < row_limit(), "oob"); 1.668 + return uint_at(receiver_count_cell_index(row)); 1.669 + } 1.670 + 1.671 + // Code generation support 1.672 + static ByteSize receiver_offset(uint row) { 1.673 + return cell_offset(receiver_cell_index(row)); 1.674 + } 1.675 + static ByteSize receiver_count_offset(uint row) { 1.676 + return cell_offset(receiver_count_cell_index(row)); 1.677 + } 1.678 + static ByteSize receiver_type_data_size() { 1.679 + return cell_offset(static_cell_count()); 1.680 + } 1.681 + 1.682 + // GC support 1.683 + virtual void follow_contents(); 1.684 + virtual void oop_iterate(OopClosure* blk); 1.685 + virtual void oop_iterate_m(OopClosure* blk, MemRegion mr); 1.686 + virtual void adjust_pointers(); 1.687 + 1.688 +#ifndef SERIALGC 1.689 + // Parallel old support 1.690 + virtual void follow_contents(ParCompactionManager* cm); 1.691 + virtual void update_pointers(); 1.692 + virtual void update_pointers(HeapWord* beg_addr, HeapWord* end_addr); 1.693 +#endif // SERIALGC 1.694 + 1.695 + oop* adr_receiver(uint row) { 1.696 + return adr_oop_at(receiver_cell_index(row)); 1.697 + } 1.698 + 1.699 +#ifndef PRODUCT 1.700 + void print_receiver_data_on(outputStream* st); 1.701 + void print_data_on(outputStream* st); 1.702 +#endif 1.703 +}; 1.704 + 1.705 +// VirtualCallData 1.706 +// 1.707 +// A VirtualCallData is used to access profiling information about a 1.708 +// virtual call. For now, it has nothing more than a ReceiverTypeData. 1.709 +class VirtualCallData : public ReceiverTypeData { 1.710 +public: 1.711 + VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) { 1.712 + assert(layout->tag() == DataLayout::virtual_call_data_tag, "wrong type"); 1.713 + } 1.714 + 1.715 + virtual bool is_VirtualCallData() { return true; } 1.716 + 1.717 + static int static_cell_count() { 1.718 + // At this point we could add more profile state, e.g., for arguments. 1.719 + // But for now it's the same size as the base record type. 1.720 + return ReceiverTypeData::static_cell_count(); 1.721 + } 1.722 + 1.723 + virtual int cell_count() { 1.724 + return static_cell_count(); 1.725 + } 1.726 + 1.727 + // Direct accessors 1.728 + static ByteSize virtual_call_data_size() { 1.729 + return cell_offset(static_cell_count()); 1.730 + } 1.731 + 1.732 +#ifndef PRODUCT 1.733 + void print_data_on(outputStream* st); 1.734 +#endif 1.735 +}; 1.736 + 1.737 +// RetData 1.738 +// 1.739 +// A RetData is used to access profiling information for a ret bytecode. 1.740 +// It is composed of a count of the number of times that the ret has 1.741 +// been executed, followed by a series of triples of the form 1.742 +// (bci, count, di) which count the number of times that some bci was the 1.743 +// target of the ret and cache a corresponding data displacement. 1.744 +class RetData : public CounterData { 1.745 +protected: 1.746 + enum { 1.747 + bci0_offset = counter_cell_count, 1.748 + count0_offset, 1.749 + displacement0_offset, 1.750 + ret_row_cell_count = (displacement0_offset + 1) - bci0_offset 1.751 + }; 1.752 + 1.753 + void set_bci(uint row, int bci) { 1.754 + assert((uint)row < row_limit(), "oob"); 1.755 + set_int_at(bci0_offset + row * ret_row_cell_count, bci); 1.756 + } 1.757 + void release_set_bci(uint row, int bci) { 1.758 + assert((uint)row < row_limit(), "oob"); 1.759 + // 'release' when setting the bci acts as a valid flag for other 1.760 + // threads wrt bci_count and bci_displacement. 1.761 + release_set_int_at(bci0_offset + row * ret_row_cell_count, bci); 1.762 + } 1.763 + void set_bci_count(uint row, uint count) { 1.764 + assert((uint)row < row_limit(), "oob"); 1.765 + set_uint_at(count0_offset + row * ret_row_cell_count, count); 1.766 + } 1.767 + void set_bci_displacement(uint row, int disp) { 1.768 + set_int_at(displacement0_offset + row * ret_row_cell_count, disp); 1.769 + } 1.770 + 1.771 +public: 1.772 + RetData(DataLayout* layout) : CounterData(layout) { 1.773 + assert(layout->tag() == DataLayout::ret_data_tag, "wrong type"); 1.774 + } 1.775 + 1.776 + virtual bool is_RetData() { return true; } 1.777 + 1.778 + enum { 1.779 + no_bci = -1 // value of bci when bci1/2 are not in use. 1.780 + }; 1.781 + 1.782 + static int static_cell_count() { 1.783 + return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count; 1.784 + } 1.785 + 1.786 + virtual int cell_count() { 1.787 + return static_cell_count(); 1.788 + } 1.789 + 1.790 + static uint row_limit() { 1.791 + return BciProfileWidth; 1.792 + } 1.793 + static int bci_cell_index(uint row) { 1.794 + return bci0_offset + row * ret_row_cell_count; 1.795 + } 1.796 + static int bci_count_cell_index(uint row) { 1.797 + return count0_offset + row * ret_row_cell_count; 1.798 + } 1.799 + static int bci_displacement_cell_index(uint row) { 1.800 + return displacement0_offset + row * ret_row_cell_count; 1.801 + } 1.802 + 1.803 + // Direct accessors 1.804 + int bci(uint row) { 1.805 + return int_at(bci_cell_index(row)); 1.806 + } 1.807 + uint bci_count(uint row) { 1.808 + return uint_at(bci_count_cell_index(row)); 1.809 + } 1.810 + int bci_displacement(uint row) { 1.811 + return int_at(bci_displacement_cell_index(row)); 1.812 + } 1.813 + 1.814 + // Interpreter Runtime support 1.815 + address fixup_ret(int return_bci, methodDataHandle mdo); 1.816 + 1.817 + // Code generation support 1.818 + static ByteSize bci_offset(uint row) { 1.819 + return cell_offset(bci_cell_index(row)); 1.820 + } 1.821 + static ByteSize bci_count_offset(uint row) { 1.822 + return cell_offset(bci_count_cell_index(row)); 1.823 + } 1.824 + static ByteSize bci_displacement_offset(uint row) { 1.825 + return cell_offset(bci_displacement_cell_index(row)); 1.826 + } 1.827 + 1.828 + // Specific initialization. 1.829 + void post_initialize(BytecodeStream* stream, methodDataOop mdo); 1.830 + 1.831 +#ifndef PRODUCT 1.832 + void print_data_on(outputStream* st); 1.833 +#endif 1.834 +}; 1.835 + 1.836 +// BranchData 1.837 +// 1.838 +// A BranchData is used to access profiling data for a two-way branch. 1.839 +// It consists of taken and not_taken counts as well as a data displacement 1.840 +// for the taken case. 1.841 +class BranchData : public JumpData { 1.842 +protected: 1.843 + enum { 1.844 + not_taken_off_set = jump_cell_count, 1.845 + branch_cell_count 1.846 + }; 1.847 + 1.848 + void set_displacement(int displacement) { 1.849 + set_int_at(displacement_off_set, displacement); 1.850 + } 1.851 + 1.852 +public: 1.853 + BranchData(DataLayout* layout) : JumpData(layout) { 1.854 + assert(layout->tag() == DataLayout::branch_data_tag, "wrong type"); 1.855 + } 1.856 + 1.857 + virtual bool is_BranchData() { return true; } 1.858 + 1.859 + static int static_cell_count() { 1.860 + return branch_cell_count; 1.861 + } 1.862 + 1.863 + virtual int cell_count() { 1.864 + return static_cell_count(); 1.865 + } 1.866 + 1.867 + // Direct accessor 1.868 + uint not_taken() { 1.869 + return uint_at(not_taken_off_set); 1.870 + } 1.871 + 1.872 + uint inc_not_taken() { 1.873 + uint cnt = not_taken() + 1; 1.874 + // Did we wrap? Will compiler screw us?? 1.875 + if (cnt == 0) cnt--; 1.876 + set_uint_at(not_taken_off_set, cnt); 1.877 + return cnt; 1.878 + } 1.879 + 1.880 + // Code generation support 1.881 + static ByteSize not_taken_offset() { 1.882 + return cell_offset(not_taken_off_set); 1.883 + } 1.884 + static ByteSize branch_data_size() { 1.885 + return cell_offset(branch_cell_count); 1.886 + } 1.887 + 1.888 + // Specific initialization. 1.889 + void post_initialize(BytecodeStream* stream, methodDataOop mdo); 1.890 + 1.891 +#ifndef PRODUCT 1.892 + void print_data_on(outputStream* st); 1.893 +#endif 1.894 +}; 1.895 + 1.896 +// ArrayData 1.897 +// 1.898 +// A ArrayData is a base class for accessing profiling data which does 1.899 +// not have a statically known size. It consists of an array length 1.900 +// and an array start. 1.901 +class ArrayData : public ProfileData { 1.902 +protected: 1.903 + friend class DataLayout; 1.904 + 1.905 + enum { 1.906 + array_len_off_set, 1.907 + array_start_off_set 1.908 + }; 1.909 + 1.910 + uint array_uint_at(int index) { 1.911 + int aindex = index + array_start_off_set; 1.912 + return uint_at(aindex); 1.913 + } 1.914 + int array_int_at(int index) { 1.915 + int aindex = index + array_start_off_set; 1.916 + return int_at(aindex); 1.917 + } 1.918 + oop array_oop_at(int index) { 1.919 + int aindex = index + array_start_off_set; 1.920 + return oop_at(aindex); 1.921 + } 1.922 + void array_set_int_at(int index, int value) { 1.923 + int aindex = index + array_start_off_set; 1.924 + set_int_at(aindex, value); 1.925 + } 1.926 + 1.927 + // Code generation support for subclasses. 1.928 + static ByteSize array_element_offset(int index) { 1.929 + return cell_offset(array_start_off_set + index); 1.930 + } 1.931 + 1.932 +public: 1.933 + ArrayData(DataLayout* layout) : ProfileData(layout) {} 1.934 + 1.935 + virtual bool is_ArrayData() { return true; } 1.936 + 1.937 + static int static_cell_count() { 1.938 + return -1; 1.939 + } 1.940 + 1.941 + int array_len() { 1.942 + return int_at_unchecked(array_len_off_set); 1.943 + } 1.944 + 1.945 + virtual int cell_count() { 1.946 + return array_len() + 1; 1.947 + } 1.948 + 1.949 + // Code generation support 1.950 + static ByteSize array_len_offset() { 1.951 + return cell_offset(array_len_off_set); 1.952 + } 1.953 + static ByteSize array_start_offset() { 1.954 + return cell_offset(array_start_off_set); 1.955 + } 1.956 +}; 1.957 + 1.958 +// MultiBranchData 1.959 +// 1.960 +// A MultiBranchData is used to access profiling information for 1.961 +// a multi-way branch (*switch bytecodes). It consists of a series 1.962 +// of (count, displacement) pairs, which count the number of times each 1.963 +// case was taken and specify the data displacment for each branch target. 1.964 +class MultiBranchData : public ArrayData { 1.965 +protected: 1.966 + enum { 1.967 + default_count_off_set, 1.968 + default_disaplacement_off_set, 1.969 + case_array_start 1.970 + }; 1.971 + enum { 1.972 + relative_count_off_set, 1.973 + relative_displacement_off_set, 1.974 + per_case_cell_count 1.975 + }; 1.976 + 1.977 + void set_default_displacement(int displacement) { 1.978 + array_set_int_at(default_disaplacement_off_set, displacement); 1.979 + } 1.980 + void set_displacement_at(int index, int displacement) { 1.981 + array_set_int_at(case_array_start + 1.982 + index * per_case_cell_count + 1.983 + relative_displacement_off_set, 1.984 + displacement); 1.985 + } 1.986 + 1.987 +public: 1.988 + MultiBranchData(DataLayout* layout) : ArrayData(layout) { 1.989 + assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type"); 1.990 + } 1.991 + 1.992 + virtual bool is_MultiBranchData() { return true; } 1.993 + 1.994 + static int compute_cell_count(BytecodeStream* stream); 1.995 + 1.996 + int number_of_cases() { 1.997 + int alen = array_len() - 2; // get rid of default case here. 1.998 + assert(alen % per_case_cell_count == 0, "must be even"); 1.999 + return (alen / per_case_cell_count); 1.1000 + } 1.1001 + 1.1002 + uint default_count() { 1.1003 + return array_uint_at(default_count_off_set); 1.1004 + } 1.1005 + int default_displacement() { 1.1006 + return array_int_at(default_disaplacement_off_set); 1.1007 + } 1.1008 + 1.1009 + uint count_at(int index) { 1.1010 + return array_uint_at(case_array_start + 1.1011 + index * per_case_cell_count + 1.1012 + relative_count_off_set); 1.1013 + } 1.1014 + int displacement_at(int index) { 1.1015 + return array_int_at(case_array_start + 1.1016 + index * per_case_cell_count + 1.1017 + relative_displacement_off_set); 1.1018 + } 1.1019 + 1.1020 + // Code generation support 1.1021 + static ByteSize default_count_offset() { 1.1022 + return array_element_offset(default_count_off_set); 1.1023 + } 1.1024 + static ByteSize default_displacement_offset() { 1.1025 + return array_element_offset(default_disaplacement_off_set); 1.1026 + } 1.1027 + static ByteSize case_count_offset(int index) { 1.1028 + return case_array_offset() + 1.1029 + (per_case_size() * index) + 1.1030 + relative_count_offset(); 1.1031 + } 1.1032 + static ByteSize case_array_offset() { 1.1033 + return array_element_offset(case_array_start); 1.1034 + } 1.1035 + static ByteSize per_case_size() { 1.1036 + return in_ByteSize(per_case_cell_count) * cell_size; 1.1037 + } 1.1038 + static ByteSize relative_count_offset() { 1.1039 + return in_ByteSize(relative_count_off_set) * cell_size; 1.1040 + } 1.1041 + static ByteSize relative_displacement_offset() { 1.1042 + return in_ByteSize(relative_displacement_off_set) * cell_size; 1.1043 + } 1.1044 + 1.1045 + // Specific initialization. 1.1046 + void post_initialize(BytecodeStream* stream, methodDataOop mdo); 1.1047 + 1.1048 +#ifndef PRODUCT 1.1049 + void print_data_on(outputStream* st); 1.1050 +#endif 1.1051 +}; 1.1052 + 1.1053 +// methodDataOop 1.1054 +// 1.1055 +// A methodDataOop holds information which has been collected about 1.1056 +// a method. Its layout looks like this: 1.1057 +// 1.1058 +// ----------------------------- 1.1059 +// | header | 1.1060 +// | klass | 1.1061 +// ----------------------------- 1.1062 +// | method | 1.1063 +// | size of the methodDataOop | 1.1064 +// ----------------------------- 1.1065 +// | Data entries... | 1.1066 +// | (variable size) | 1.1067 +// | | 1.1068 +// . . 1.1069 +// . . 1.1070 +// . . 1.1071 +// | | 1.1072 +// ----------------------------- 1.1073 +// 1.1074 +// The data entry area is a heterogeneous array of DataLayouts. Each 1.1075 +// DataLayout in the array corresponds to a specific bytecode in the 1.1076 +// method. The entries in the array are sorted by the corresponding 1.1077 +// bytecode. Access to the data is via resource-allocated ProfileData, 1.1078 +// which point to the underlying blocks of DataLayout structures. 1.1079 +// 1.1080 +// During interpretation, if profiling in enabled, the interpreter 1.1081 +// maintains a method data pointer (mdp), which points at the entry 1.1082 +// in the array corresponding to the current bci. In the course of 1.1083 +// intepretation, when a bytecode is encountered that has profile data 1.1084 +// associated with it, the entry pointed to by mdp is updated, then the 1.1085 +// mdp is adjusted to point to the next appropriate DataLayout. If mdp 1.1086 +// is NULL to begin with, the interpreter assumes that the current method 1.1087 +// is not (yet) being profiled. 1.1088 +// 1.1089 +// In methodDataOop parlance, "dp" is a "data pointer", the actual address 1.1090 +// of a DataLayout element. A "di" is a "data index", the offset in bytes 1.1091 +// from the base of the data entry array. A "displacement" is the byte offset 1.1092 +// in certain ProfileData objects that indicate the amount the mdp must be 1.1093 +// adjusted in the event of a change in control flow. 1.1094 +// 1.1095 + 1.1096 +class methodDataOopDesc : public oopDesc { 1.1097 + friend class VMStructs; 1.1098 +private: 1.1099 + friend class ProfileData; 1.1100 + 1.1101 + // Back pointer to the methodOop 1.1102 + methodOop _method; 1.1103 + 1.1104 + // Size of this oop in bytes 1.1105 + int _size; 1.1106 + 1.1107 + // Cached hint for bci_to_dp and bci_to_data 1.1108 + int _hint_di; 1.1109 + 1.1110 + // Whole-method sticky bits and flags 1.1111 +public: 1.1112 + enum { 1.1113 + _trap_hist_limit = 16, // decoupled from Deoptimization::Reason_LIMIT 1.1114 + _trap_hist_mask = max_jubyte, 1.1115 + _extra_data_count = 4 // extra DataLayout headers, for trap history 1.1116 + }; // Public flag values 1.1117 +private: 1.1118 + uint _nof_decompiles; // count of all nmethod removals 1.1119 + uint _nof_overflow_recompiles; // recompile count, excluding recomp. bits 1.1120 + uint _nof_overflow_traps; // trap count, excluding _trap_hist 1.1121 + union { 1.1122 + intptr_t _align; 1.1123 + u1 _array[_trap_hist_limit]; 1.1124 + } _trap_hist; 1.1125 + 1.1126 + // Support for interprocedural escape analysis, from Thomas Kotzmann. 1.1127 + intx _eflags; // flags on escape information 1.1128 + intx _arg_local; // bit set of non-escaping arguments 1.1129 + intx _arg_stack; // bit set of stack-allocatable arguments 1.1130 + intx _arg_returned; // bit set of returned arguments 1.1131 + 1.1132 + int _creation_mileage; // method mileage at MDO creation 1.1133 + 1.1134 + // Size of _data array in bytes. (Excludes header and extra_data fields.) 1.1135 + int _data_size; 1.1136 + 1.1137 + // Beginning of the data entries 1.1138 + intptr_t _data[1]; 1.1139 + 1.1140 + // Helper for size computation 1.1141 + static int compute_data_size(BytecodeStream* stream); 1.1142 + static int bytecode_cell_count(Bytecodes::Code code); 1.1143 + enum { no_profile_data = -1, variable_cell_count = -2 }; 1.1144 + 1.1145 + // Helper for initialization 1.1146 + DataLayout* data_layout_at(int data_index) { 1.1147 + assert(data_index % sizeof(intptr_t) == 0, "unaligned"); 1.1148 + return (DataLayout*) (((address)_data) + data_index); 1.1149 + } 1.1150 + 1.1151 + // Initialize an individual data segment. Returns the size of 1.1152 + // the segment in bytes. 1.1153 + int initialize_data(BytecodeStream* stream, int data_index); 1.1154 + 1.1155 + // Helper for data_at 1.1156 + DataLayout* limit_data_position() { 1.1157 + return (DataLayout*)((address)data_base() + _data_size); 1.1158 + } 1.1159 + bool out_of_bounds(int data_index) { 1.1160 + return data_index >= data_size(); 1.1161 + } 1.1162 + 1.1163 + // Give each of the data entries a chance to perform specific 1.1164 + // data initialization. 1.1165 + void post_initialize(BytecodeStream* stream); 1.1166 + 1.1167 + // hint accessors 1.1168 + int hint_di() const { return _hint_di; } 1.1169 + void set_hint_di(int di) { 1.1170 + assert(!out_of_bounds(di), "hint_di out of bounds"); 1.1171 + _hint_di = di; 1.1172 + } 1.1173 + ProfileData* data_before(int bci) { 1.1174 + // avoid SEGV on this edge case 1.1175 + if (data_size() == 0) 1.1176 + return NULL; 1.1177 + int hint = hint_di(); 1.1178 + if (data_layout_at(hint)->bci() <= bci) 1.1179 + return data_at(hint); 1.1180 + return first_data(); 1.1181 + } 1.1182 + 1.1183 + // What is the index of the first data entry? 1.1184 + int first_di() { return 0; } 1.1185 + 1.1186 + // Find or create an extra ProfileData: 1.1187 + ProfileData* bci_to_extra_data(int bci, bool create_if_missing); 1.1188 + 1.1189 +public: 1.1190 + static int header_size() { 1.1191 + return sizeof(methodDataOopDesc)/wordSize; 1.1192 + } 1.1193 + 1.1194 + // Compute the size of a methodDataOop before it is created. 1.1195 + static int compute_allocation_size_in_bytes(methodHandle method); 1.1196 + static int compute_allocation_size_in_words(methodHandle method); 1.1197 + static int compute_extra_data_count(int data_size, int empty_bc_count); 1.1198 + 1.1199 + // Determine if a given bytecode can have profile information. 1.1200 + static bool bytecode_has_profile(Bytecodes::Code code) { 1.1201 + return bytecode_cell_count(code) != no_profile_data; 1.1202 + } 1.1203 + 1.1204 + // Perform initialization of a new methodDataOop 1.1205 + void initialize(methodHandle method); 1.1206 + 1.1207 + // My size 1.1208 + int object_size_in_bytes() { return _size; } 1.1209 + int object_size() { 1.1210 + return align_object_size(align_size_up(_size, BytesPerWord)/BytesPerWord); 1.1211 + } 1.1212 + 1.1213 + int creation_mileage() const { return _creation_mileage; } 1.1214 + void set_creation_mileage(int x) { _creation_mileage = x; } 1.1215 + bool is_mature() const; // consult mileage and ProfileMaturityPercentage 1.1216 + static int mileage_of(methodOop m); 1.1217 + 1.1218 + // Support for interprocedural escape analysis, from Thomas Kotzmann. 1.1219 + enum EscapeFlag { 1.1220 + estimated = 1 << 0, 1.1221 + return_local = 1 << 1 1.1222 + }; 1.1223 + 1.1224 + intx eflags() { return _eflags; } 1.1225 + intx arg_local() { return _arg_local; } 1.1226 + intx arg_stack() { return _arg_stack; } 1.1227 + intx arg_returned() { return _arg_returned; } 1.1228 + 1.1229 + void set_eflags(intx v) { _eflags = v; } 1.1230 + void set_arg_local(intx v) { _arg_local = v; } 1.1231 + void set_arg_stack(intx v) { _arg_stack = v; } 1.1232 + void set_arg_returned(intx v) { _arg_returned = v; } 1.1233 + 1.1234 + void clear_escape_info() { _eflags = _arg_local = _arg_stack = _arg_returned = 0; } 1.1235 + 1.1236 + // Location and size of data area 1.1237 + address data_base() const { 1.1238 + return (address) _data; 1.1239 + } 1.1240 + int data_size() { 1.1241 + return _data_size; 1.1242 + } 1.1243 + 1.1244 + // Accessors 1.1245 + methodOop method() { return _method; } 1.1246 + 1.1247 + // Get the data at an arbitrary (sort of) data index. 1.1248 + ProfileData* data_at(int data_index); 1.1249 + 1.1250 + // Walk through the data in order. 1.1251 + ProfileData* first_data() { return data_at(first_di()); } 1.1252 + ProfileData* next_data(ProfileData* current); 1.1253 + bool is_valid(ProfileData* current) { return current != NULL; } 1.1254 + 1.1255 + // Convert a dp (data pointer) to a di (data index). 1.1256 + int dp_to_di(address dp) { 1.1257 + return dp - ((address)_data); 1.1258 + } 1.1259 + 1.1260 + address di_to_dp(int di) { 1.1261 + return (address)data_layout_at(di); 1.1262 + } 1.1263 + 1.1264 + // bci to di/dp conversion. 1.1265 + address bci_to_dp(int bci); 1.1266 + int bci_to_di(int bci) { 1.1267 + return dp_to_di(bci_to_dp(bci)); 1.1268 + } 1.1269 + 1.1270 + // Get the data at an arbitrary bci, or NULL if there is none. 1.1271 + ProfileData* bci_to_data(int bci); 1.1272 + 1.1273 + // Same, but try to create an extra_data record if one is needed: 1.1274 + ProfileData* allocate_bci_to_data(int bci) { 1.1275 + ProfileData* data = bci_to_data(bci); 1.1276 + return (data != NULL) ? data : bci_to_extra_data(bci, true); 1.1277 + } 1.1278 + 1.1279 + // Add a handful of extra data records, for trap tracking. 1.1280 + DataLayout* extra_data_base() { return limit_data_position(); } 1.1281 + DataLayout* extra_data_limit() { return (DataLayout*)((address)this + object_size_in_bytes()); } 1.1282 + int extra_data_size() { return (address)extra_data_limit() 1.1283 + - (address)extra_data_base(); } 1.1284 + static DataLayout* next_extra(DataLayout* dp) { return (DataLayout*)((address)dp + in_bytes(DataLayout::cell_offset(0))); } 1.1285 + 1.1286 + // Return (uint)-1 for overflow. 1.1287 + uint trap_count(int reason) const { 1.1288 + assert((uint)reason < _trap_hist_limit, "oob"); 1.1289 + return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1; 1.1290 + } 1.1291 + // For loops: 1.1292 + static uint trap_reason_limit() { return _trap_hist_limit; } 1.1293 + static uint trap_count_limit() { return _trap_hist_mask; } 1.1294 + uint inc_trap_count(int reason) { 1.1295 + // Count another trap, anywhere in this method. 1.1296 + assert(reason >= 0, "must be single trap"); 1.1297 + if ((uint)reason < _trap_hist_limit) { 1.1298 + uint cnt1 = 1 + _trap_hist._array[reason]; 1.1299 + if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow... 1.1300 + _trap_hist._array[reason] = cnt1; 1.1301 + return cnt1; 1.1302 + } else { 1.1303 + return _trap_hist_mask + (++_nof_overflow_traps); 1.1304 + } 1.1305 + } else { 1.1306 + // Could not represent the count in the histogram. 1.1307 + return (++_nof_overflow_traps); 1.1308 + } 1.1309 + } 1.1310 + 1.1311 + uint overflow_trap_count() const { 1.1312 + return _nof_overflow_traps; 1.1313 + } 1.1314 + uint overflow_recompile_count() const { 1.1315 + return _nof_overflow_recompiles; 1.1316 + } 1.1317 + void inc_overflow_recompile_count() { 1.1318 + _nof_overflow_recompiles += 1; 1.1319 + } 1.1320 + uint decompile_count() const { 1.1321 + return _nof_decompiles; 1.1322 + } 1.1323 + void inc_decompile_count() { 1.1324 + _nof_decompiles += 1; 1.1325 + } 1.1326 + 1.1327 + // Support for code generation 1.1328 + static ByteSize data_offset() { 1.1329 + return byte_offset_of(methodDataOopDesc, _data[0]); 1.1330 + } 1.1331 + 1.1332 + // GC support 1.1333 + oop* adr_method() const { return (oop*)&_method; } 1.1334 + bool object_is_parsable() const { return _size != 0; } 1.1335 + void set_object_is_parsable(int object_size_in_bytes) { _size = object_size_in_bytes; } 1.1336 + 1.1337 +#ifndef PRODUCT 1.1338 + // printing support for method data 1.1339 + void print_data_on(outputStream* st); 1.1340 +#endif 1.1341 + 1.1342 + // verification 1.1343 + void verify_data_on(outputStream* st); 1.1344 +};