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