src/share/vm/oops/methodDataOop.hpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2615
f767174aac14
child 2877
bad7ecd0b6ed
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

duke@435 1 /*
stefank@2534 2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #ifndef SHARE_VM_OOPS_METHODDATAOOP_HPP
stefank@2314 26 #define SHARE_VM_OOPS_METHODDATAOOP_HPP
stefank@2314 27
stefank@2314 28 #include "interpreter/bytecodes.hpp"
stefank@2314 29 #include "memory/universe.hpp"
stefank@2314 30 #include "oops/methodOop.hpp"
stefank@2314 31 #include "oops/oop.hpp"
stefank@2314 32 #include "runtime/orderAccess.hpp"
stefank@2314 33
duke@435 34 class BytecodeStream;
duke@435 35
duke@435 36 // The MethodData object collects counts and other profile information
duke@435 37 // during zeroth-tier (interpretive) and first-tier execution.
duke@435 38 // The profile is used later by compilation heuristics. Some heuristics
duke@435 39 // enable use of aggressive (or "heroic") optimizations. An aggressive
duke@435 40 // optimization often has a down-side, a corner case that it handles
duke@435 41 // poorly, but which is thought to be rare. The profile provides
duke@435 42 // evidence of this rarity for a given method or even BCI. It allows
duke@435 43 // the compiler to back out of the optimization at places where it
duke@435 44 // has historically been a poor choice. Other heuristics try to use
duke@435 45 // specific information gathered about types observed at a given site.
duke@435 46 //
duke@435 47 // All data in the profile is approximate. It is expected to be accurate
duke@435 48 // on the whole, but the system expects occasional inaccuraces, due to
duke@435 49 // counter overflow, multiprocessor races during data collection, space
duke@435 50 // limitations, missing MDO blocks, etc. Bad or missing data will degrade
duke@435 51 // optimization quality but will not affect correctness. Also, each MDO
duke@435 52 // is marked with its birth-date ("creation_mileage") which can be used
duke@435 53 // to assess the quality ("maturity") of its data.
duke@435 54 //
duke@435 55 // Short (<32-bit) counters are designed to overflow to a known "saturated"
duke@435 56 // state. Also, certain recorded per-BCI events are given one-bit counters
duke@435 57 // which overflow to a saturated state which applied to all counters at
duke@435 58 // that BCI. In other words, there is a small lattice which approximates
duke@435 59 // the ideal of an infinite-precision counter for each event at each BCI,
duke@435 60 // and the lattice quickly "bottoms out" in a state where all counters
duke@435 61 // are taken to be indefinitely large.
duke@435 62 //
duke@435 63 // The reader will find many data races in profile gathering code, starting
duke@435 64 // with invocation counter incrementation. None of these races harm correct
duke@435 65 // execution of the compiled code.
duke@435 66
ysr@1376 67 // forward decl
ysr@1376 68 class ProfileData;
ysr@1376 69
duke@435 70 // DataLayout
duke@435 71 //
duke@435 72 // Overlay for generic profiling data.
duke@435 73 class DataLayout VALUE_OBJ_CLASS_SPEC {
duke@435 74 private:
duke@435 75 // Every data layout begins with a header. This header
duke@435 76 // contains a tag, which is used to indicate the size/layout
duke@435 77 // of the data, 4 bits of flags, which can be used in any way,
duke@435 78 // 4 bits of trap history (none/one reason/many reasons),
duke@435 79 // and a bci, which is used to tie this piece of data to a
duke@435 80 // specific bci in the bytecodes.
duke@435 81 union {
duke@435 82 intptr_t _bits;
duke@435 83 struct {
duke@435 84 u1 _tag;
duke@435 85 u1 _flags;
duke@435 86 u2 _bci;
duke@435 87 } _struct;
duke@435 88 } _header;
duke@435 89
duke@435 90 // The data layout has an arbitrary number of cells, each sized
duke@435 91 // to accomodate a pointer or an integer.
duke@435 92 intptr_t _cells[1];
duke@435 93
duke@435 94 // Some types of data layouts need a length field.
duke@435 95 static bool needs_array_len(u1 tag);
duke@435 96
duke@435 97 public:
duke@435 98 enum {
duke@435 99 counter_increment = 1
duke@435 100 };
duke@435 101
duke@435 102 enum {
duke@435 103 cell_size = sizeof(intptr_t)
duke@435 104 };
duke@435 105
duke@435 106 // Tag values
duke@435 107 enum {
duke@435 108 no_tag,
duke@435 109 bit_data_tag,
duke@435 110 counter_data_tag,
duke@435 111 jump_data_tag,
duke@435 112 receiver_type_data_tag,
duke@435 113 virtual_call_data_tag,
duke@435 114 ret_data_tag,
duke@435 115 branch_data_tag,
kvn@480 116 multi_branch_data_tag,
kvn@480 117 arg_info_data_tag
duke@435 118 };
duke@435 119
duke@435 120 enum {
duke@435 121 // The _struct._flags word is formatted as [trap_state:4 | flags:4].
duke@435 122 // The trap state breaks down further as [recompile:1 | reason:3].
duke@435 123 // This further breakdown is defined in deoptimization.cpp.
duke@435 124 // See Deoptimization::trap_state_reason for an assert that
duke@435 125 // trap_bits is big enough to hold reasons < Reason_RECORDED_LIMIT.
duke@435 126 //
duke@435 127 // The trap_state is collected only if ProfileTraps is true.
duke@435 128 trap_bits = 1+3, // 3: enough to distinguish [0..Reason_RECORDED_LIMIT].
duke@435 129 trap_shift = BitsPerByte - trap_bits,
duke@435 130 trap_mask = right_n_bits(trap_bits),
duke@435 131 trap_mask_in_place = (trap_mask << trap_shift),
duke@435 132 flag_limit = trap_shift,
duke@435 133 flag_mask = right_n_bits(flag_limit),
duke@435 134 first_flag = 0
duke@435 135 };
duke@435 136
duke@435 137 // Size computation
duke@435 138 static int header_size_in_bytes() {
duke@435 139 return cell_size;
duke@435 140 }
duke@435 141 static int header_size_in_cells() {
duke@435 142 return 1;
duke@435 143 }
duke@435 144
duke@435 145 static int compute_size_in_bytes(int cell_count) {
duke@435 146 return header_size_in_bytes() + cell_count * cell_size;
duke@435 147 }
duke@435 148
duke@435 149 // Initialization
duke@435 150 void initialize(u1 tag, u2 bci, int cell_count);
duke@435 151
duke@435 152 // Accessors
duke@435 153 u1 tag() {
duke@435 154 return _header._struct._tag;
duke@435 155 }
duke@435 156
duke@435 157 // Return a few bits of trap state. Range is [0..trap_mask].
duke@435 158 // The state tells if traps with zero, one, or many reasons have occurred.
duke@435 159 // It also tells whether zero or many recompilations have occurred.
duke@435 160 // The associated trap histogram in the MDO itself tells whether
duke@435 161 // traps are common or not. If a BCI shows that a trap X has
duke@435 162 // occurred, and the MDO shows N occurrences of X, we make the
duke@435 163 // simplifying assumption that all N occurrences can be blamed
duke@435 164 // on that BCI.
duke@435 165 int trap_state() {
duke@435 166 return ((_header._struct._flags >> trap_shift) & trap_mask);
duke@435 167 }
duke@435 168
duke@435 169 void set_trap_state(int new_state) {
duke@435 170 assert(ProfileTraps, "used only under +ProfileTraps");
duke@435 171 uint old_flags = (_header._struct._flags & flag_mask);
duke@435 172 _header._struct._flags = (new_state << trap_shift) | old_flags;
duke@435 173 }
duke@435 174
duke@435 175 u1 flags() {
duke@435 176 return _header._struct._flags;
duke@435 177 }
duke@435 178
duke@435 179 u2 bci() {
duke@435 180 return _header._struct._bci;
duke@435 181 }
duke@435 182
duke@435 183 void set_header(intptr_t value) {
duke@435 184 _header._bits = value;
duke@435 185 }
duke@435 186 void release_set_header(intptr_t value) {
duke@435 187 OrderAccess::release_store_ptr(&_header._bits, value);
duke@435 188 }
duke@435 189 intptr_t header() {
duke@435 190 return _header._bits;
duke@435 191 }
duke@435 192 void set_cell_at(int index, intptr_t value) {
duke@435 193 _cells[index] = value;
duke@435 194 }
duke@435 195 void release_set_cell_at(int index, intptr_t value) {
duke@435 196 OrderAccess::release_store_ptr(&_cells[index], value);
duke@435 197 }
duke@435 198 intptr_t cell_at(int index) {
duke@435 199 return _cells[index];
duke@435 200 }
duke@435 201 intptr_t* adr_cell_at(int index) {
duke@435 202 return &_cells[index];
duke@435 203 }
duke@435 204 oop* adr_oop_at(int index) {
duke@435 205 return (oop*)&(_cells[index]);
duke@435 206 }
duke@435 207
duke@435 208 void set_flag_at(int flag_number) {
duke@435 209 assert(flag_number < flag_limit, "oob");
duke@435 210 _header._struct._flags |= (0x1 << flag_number);
duke@435 211 }
duke@435 212 bool flag_at(int flag_number) {
duke@435 213 assert(flag_number < flag_limit, "oob");
duke@435 214 return (_header._struct._flags & (0x1 << flag_number)) != 0;
duke@435 215 }
duke@435 216
duke@435 217 // Low-level support for code generation.
duke@435 218 static ByteSize header_offset() {
duke@435 219 return byte_offset_of(DataLayout, _header);
duke@435 220 }
duke@435 221 static ByteSize tag_offset() {
duke@435 222 return byte_offset_of(DataLayout, _header._struct._tag);
duke@435 223 }
duke@435 224 static ByteSize flags_offset() {
duke@435 225 return byte_offset_of(DataLayout, _header._struct._flags);
duke@435 226 }
duke@435 227 static ByteSize bci_offset() {
duke@435 228 return byte_offset_of(DataLayout, _header._struct._bci);
duke@435 229 }
duke@435 230 static ByteSize cell_offset(int index) {
coleenp@2615 231 return byte_offset_of(DataLayout, _cells) + in_ByteSize(index * cell_size);
duke@435 232 }
duke@435 233 // Return a value which, when or-ed as a byte into _flags, sets the flag.
duke@435 234 static int flag_number_to_byte_constant(int flag_number) {
duke@435 235 assert(0 <= flag_number && flag_number < flag_limit, "oob");
duke@435 236 DataLayout temp; temp.set_header(0);
duke@435 237 temp.set_flag_at(flag_number);
duke@435 238 return temp._header._struct._flags;
duke@435 239 }
duke@435 240 // Return a value which, when or-ed as a word into _header, sets the flag.
duke@435 241 static intptr_t flag_mask_to_header_mask(int byte_constant) {
duke@435 242 DataLayout temp; temp.set_header(0);
duke@435 243 temp._header._struct._flags = byte_constant;
duke@435 244 return temp._header._bits;
duke@435 245 }
ysr@1376 246
ysr@1376 247 // GC support
ysr@1376 248 ProfileData* data_in();
ysr@1376 249 void follow_weak_refs(BoolObjectClosure* cl);
duke@435 250 };
duke@435 251
duke@435 252
duke@435 253 // ProfileData class hierarchy
duke@435 254 class ProfileData;
duke@435 255 class BitData;
duke@435 256 class CounterData;
duke@435 257 class ReceiverTypeData;
duke@435 258 class VirtualCallData;
duke@435 259 class RetData;
duke@435 260 class JumpData;
duke@435 261 class BranchData;
duke@435 262 class ArrayData;
duke@435 263 class MultiBranchData;
kvn@480 264 class ArgInfoData;
duke@435 265
duke@435 266
duke@435 267 // ProfileData
duke@435 268 //
duke@435 269 // A ProfileData object is created to refer to a section of profiling
duke@435 270 // data in a structured way.
duke@435 271 class ProfileData : public ResourceObj {
duke@435 272 private:
duke@435 273 #ifndef PRODUCT
duke@435 274 enum {
duke@435 275 tab_width_one = 16,
duke@435 276 tab_width_two = 36
duke@435 277 };
duke@435 278 #endif // !PRODUCT
duke@435 279
duke@435 280 // This is a pointer to a section of profiling data.
duke@435 281 DataLayout* _data;
duke@435 282
duke@435 283 protected:
duke@435 284 DataLayout* data() { return _data; }
duke@435 285
duke@435 286 enum {
duke@435 287 cell_size = DataLayout::cell_size
duke@435 288 };
duke@435 289
duke@435 290 public:
duke@435 291 // How many cells are in this?
duke@435 292 virtual int cell_count() {
duke@435 293 ShouldNotReachHere();
duke@435 294 return -1;
duke@435 295 }
duke@435 296
duke@435 297 // Return the size of this data.
duke@435 298 int size_in_bytes() {
duke@435 299 return DataLayout::compute_size_in_bytes(cell_count());
duke@435 300 }
duke@435 301
duke@435 302 protected:
duke@435 303 // Low-level accessors for underlying data
duke@435 304 void set_intptr_at(int index, intptr_t value) {
duke@435 305 assert(0 <= index && index < cell_count(), "oob");
duke@435 306 data()->set_cell_at(index, value);
duke@435 307 }
duke@435 308 void release_set_intptr_at(int index, intptr_t value) {
duke@435 309 assert(0 <= index && index < cell_count(), "oob");
duke@435 310 data()->release_set_cell_at(index, value);
duke@435 311 }
duke@435 312 intptr_t intptr_at(int index) {
duke@435 313 assert(0 <= index && index < cell_count(), "oob");
duke@435 314 return data()->cell_at(index);
duke@435 315 }
duke@435 316 void set_uint_at(int index, uint value) {
duke@435 317 set_intptr_at(index, (intptr_t) value);
duke@435 318 }
duke@435 319 void release_set_uint_at(int index, uint value) {
duke@435 320 release_set_intptr_at(index, (intptr_t) value);
duke@435 321 }
duke@435 322 uint uint_at(int index) {
duke@435 323 return (uint)intptr_at(index);
duke@435 324 }
duke@435 325 void set_int_at(int index, int value) {
duke@435 326 set_intptr_at(index, (intptr_t) value);
duke@435 327 }
duke@435 328 void release_set_int_at(int index, int value) {
duke@435 329 release_set_intptr_at(index, (intptr_t) value);
duke@435 330 }
duke@435 331 int int_at(int index) {
duke@435 332 return (int)intptr_at(index);
duke@435 333 }
duke@435 334 int int_at_unchecked(int index) {
duke@435 335 return (int)data()->cell_at(index);
duke@435 336 }
duke@435 337 void set_oop_at(int index, oop value) {
duke@435 338 set_intptr_at(index, (intptr_t) value);
duke@435 339 }
duke@435 340 oop oop_at(int index) {
duke@435 341 return (oop)intptr_at(index);
duke@435 342 }
duke@435 343 oop* adr_oop_at(int index) {
duke@435 344 assert(0 <= index && index < cell_count(), "oob");
duke@435 345 return data()->adr_oop_at(index);
duke@435 346 }
duke@435 347
duke@435 348 void set_flag_at(int flag_number) {
duke@435 349 data()->set_flag_at(flag_number);
duke@435 350 }
duke@435 351 bool flag_at(int flag_number) {
duke@435 352 return data()->flag_at(flag_number);
duke@435 353 }
duke@435 354
duke@435 355 // two convenient imports for use by subclasses:
duke@435 356 static ByteSize cell_offset(int index) {
duke@435 357 return DataLayout::cell_offset(index);
duke@435 358 }
duke@435 359 static int flag_number_to_byte_constant(int flag_number) {
duke@435 360 return DataLayout::flag_number_to_byte_constant(flag_number);
duke@435 361 }
duke@435 362
duke@435 363 ProfileData(DataLayout* data) {
duke@435 364 _data = data;
duke@435 365 }
duke@435 366
duke@435 367 public:
duke@435 368 // Constructor for invalid ProfileData.
duke@435 369 ProfileData();
duke@435 370
duke@435 371 u2 bci() {
duke@435 372 return data()->bci();
duke@435 373 }
duke@435 374
duke@435 375 address dp() {
duke@435 376 return (address)_data;
duke@435 377 }
duke@435 378
duke@435 379 int trap_state() {
duke@435 380 return data()->trap_state();
duke@435 381 }
duke@435 382 void set_trap_state(int new_state) {
duke@435 383 data()->set_trap_state(new_state);
duke@435 384 }
duke@435 385
duke@435 386 // Type checking
duke@435 387 virtual bool is_BitData() { return false; }
duke@435 388 virtual bool is_CounterData() { return false; }
duke@435 389 virtual bool is_JumpData() { return false; }
duke@435 390 virtual bool is_ReceiverTypeData(){ return false; }
duke@435 391 virtual bool is_VirtualCallData() { return false; }
duke@435 392 virtual bool is_RetData() { return false; }
duke@435 393 virtual bool is_BranchData() { return false; }
duke@435 394 virtual bool is_ArrayData() { return false; }
duke@435 395 virtual bool is_MultiBranchData() { return false; }
kvn@480 396 virtual bool is_ArgInfoData() { return false; }
kvn@480 397
duke@435 398
duke@435 399 BitData* as_BitData() {
duke@435 400 assert(is_BitData(), "wrong type");
duke@435 401 return is_BitData() ? (BitData*) this : NULL;
duke@435 402 }
duke@435 403 CounterData* as_CounterData() {
duke@435 404 assert(is_CounterData(), "wrong type");
duke@435 405 return is_CounterData() ? (CounterData*) this : NULL;
duke@435 406 }
duke@435 407 JumpData* as_JumpData() {
duke@435 408 assert(is_JumpData(), "wrong type");
duke@435 409 return is_JumpData() ? (JumpData*) this : NULL;
duke@435 410 }
duke@435 411 ReceiverTypeData* as_ReceiverTypeData() {
duke@435 412 assert(is_ReceiverTypeData(), "wrong type");
duke@435 413 return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL;
duke@435 414 }
duke@435 415 VirtualCallData* as_VirtualCallData() {
duke@435 416 assert(is_VirtualCallData(), "wrong type");
duke@435 417 return is_VirtualCallData() ? (VirtualCallData*)this : NULL;
duke@435 418 }
duke@435 419 RetData* as_RetData() {
duke@435 420 assert(is_RetData(), "wrong type");
duke@435 421 return is_RetData() ? (RetData*) this : NULL;
duke@435 422 }
duke@435 423 BranchData* as_BranchData() {
duke@435 424 assert(is_BranchData(), "wrong type");
duke@435 425 return is_BranchData() ? (BranchData*) this : NULL;
duke@435 426 }
duke@435 427 ArrayData* as_ArrayData() {
duke@435 428 assert(is_ArrayData(), "wrong type");
duke@435 429 return is_ArrayData() ? (ArrayData*) this : NULL;
duke@435 430 }
duke@435 431 MultiBranchData* as_MultiBranchData() {
duke@435 432 assert(is_MultiBranchData(), "wrong type");
duke@435 433 return is_MultiBranchData() ? (MultiBranchData*)this : NULL;
duke@435 434 }
kvn@480 435 ArgInfoData* as_ArgInfoData() {
kvn@480 436 assert(is_ArgInfoData(), "wrong type");
kvn@480 437 return is_ArgInfoData() ? (ArgInfoData*)this : NULL;
kvn@480 438 }
duke@435 439
duke@435 440
duke@435 441 // Subclass specific initialization
duke@435 442 virtual void post_initialize(BytecodeStream* stream, methodDataOop mdo) {}
duke@435 443
duke@435 444 // GC support
duke@435 445 virtual void follow_contents() {}
duke@435 446 virtual void oop_iterate(OopClosure* blk) {}
duke@435 447 virtual void oop_iterate_m(OopClosure* blk, MemRegion mr) {}
duke@435 448 virtual void adjust_pointers() {}
ysr@1376 449 virtual void follow_weak_refs(BoolObjectClosure* is_alive_closure) {}
duke@435 450
duke@435 451 #ifndef SERIALGC
duke@435 452 // Parallel old support
duke@435 453 virtual void follow_contents(ParCompactionManager* cm) {}
duke@435 454 virtual void update_pointers() {}
duke@435 455 #endif // SERIALGC
duke@435 456
duke@435 457 // CI translation: ProfileData can represent both MethodDataOop data
duke@435 458 // as well as CIMethodData data. This function is provided for translating
duke@435 459 // an oop in a ProfileData to the ci equivalent. Generally speaking,
duke@435 460 // most ProfileData don't require any translation, so we provide the null
duke@435 461 // translation here, and the required translators are in the ci subclasses.
duke@435 462 virtual void translate_from(ProfileData* data) {}
duke@435 463
duke@435 464 virtual void print_data_on(outputStream* st) {
duke@435 465 ShouldNotReachHere();
duke@435 466 }
duke@435 467
duke@435 468 #ifndef PRODUCT
duke@435 469 void print_shared(outputStream* st, const char* name);
duke@435 470 void tab(outputStream* st);
duke@435 471 #endif
duke@435 472 };
duke@435 473
duke@435 474 // BitData
duke@435 475 //
duke@435 476 // A BitData holds a flag or two in its header.
duke@435 477 class BitData : public ProfileData {
duke@435 478 protected:
duke@435 479 enum {
duke@435 480 // null_seen:
duke@435 481 // saw a null operand (cast/aastore/instanceof)
duke@435 482 null_seen_flag = DataLayout::first_flag + 0
duke@435 483 };
duke@435 484 enum { bit_cell_count = 0 }; // no additional data fields needed.
duke@435 485 public:
duke@435 486 BitData(DataLayout* layout) : ProfileData(layout) {
duke@435 487 }
duke@435 488
duke@435 489 virtual bool is_BitData() { return true; }
duke@435 490
duke@435 491 static int static_cell_count() {
duke@435 492 return bit_cell_count;
duke@435 493 }
duke@435 494
duke@435 495 virtual int cell_count() {
duke@435 496 return static_cell_count();
duke@435 497 }
duke@435 498
duke@435 499 // Accessor
duke@435 500
duke@435 501 // The null_seen flag bit is specially known to the interpreter.
duke@435 502 // Consulting it allows the compiler to avoid setting up null_check traps.
duke@435 503 bool null_seen() { return flag_at(null_seen_flag); }
duke@435 504 void set_null_seen() { set_flag_at(null_seen_flag); }
duke@435 505
duke@435 506
duke@435 507 // Code generation support
duke@435 508 static int null_seen_byte_constant() {
duke@435 509 return flag_number_to_byte_constant(null_seen_flag);
duke@435 510 }
duke@435 511
duke@435 512 static ByteSize bit_data_size() {
duke@435 513 return cell_offset(bit_cell_count);
duke@435 514 }
duke@435 515
duke@435 516 #ifndef PRODUCT
duke@435 517 void print_data_on(outputStream* st);
duke@435 518 #endif
duke@435 519 };
duke@435 520
duke@435 521 // CounterData
duke@435 522 //
duke@435 523 // A CounterData corresponds to a simple counter.
duke@435 524 class CounterData : public BitData {
duke@435 525 protected:
duke@435 526 enum {
duke@435 527 count_off,
duke@435 528 counter_cell_count
duke@435 529 };
duke@435 530 public:
duke@435 531 CounterData(DataLayout* layout) : BitData(layout) {}
duke@435 532
duke@435 533 virtual bool is_CounterData() { return true; }
duke@435 534
duke@435 535 static int static_cell_count() {
duke@435 536 return counter_cell_count;
duke@435 537 }
duke@435 538
duke@435 539 virtual int cell_count() {
duke@435 540 return static_cell_count();
duke@435 541 }
duke@435 542
duke@435 543 // Direct accessor
duke@435 544 uint count() {
duke@435 545 return uint_at(count_off);
duke@435 546 }
duke@435 547
duke@435 548 // Code generation support
duke@435 549 static ByteSize count_offset() {
duke@435 550 return cell_offset(count_off);
duke@435 551 }
duke@435 552 static ByteSize counter_data_size() {
duke@435 553 return cell_offset(counter_cell_count);
duke@435 554 }
duke@435 555
kvn@1686 556 void set_count(uint count) {
kvn@1686 557 set_uint_at(count_off, count);
kvn@1686 558 }
kvn@1686 559
duke@435 560 #ifndef PRODUCT
duke@435 561 void print_data_on(outputStream* st);
duke@435 562 #endif
duke@435 563 };
duke@435 564
duke@435 565 // JumpData
duke@435 566 //
duke@435 567 // A JumpData is used to access profiling information for a direct
duke@435 568 // branch. It is a counter, used for counting the number of branches,
duke@435 569 // plus a data displacement, used for realigning the data pointer to
duke@435 570 // the corresponding target bci.
duke@435 571 class JumpData : public ProfileData {
duke@435 572 protected:
duke@435 573 enum {
duke@435 574 taken_off_set,
duke@435 575 displacement_off_set,
duke@435 576 jump_cell_count
duke@435 577 };
duke@435 578
duke@435 579 void set_displacement(int displacement) {
duke@435 580 set_int_at(displacement_off_set, displacement);
duke@435 581 }
duke@435 582
duke@435 583 public:
duke@435 584 JumpData(DataLayout* layout) : ProfileData(layout) {
duke@435 585 assert(layout->tag() == DataLayout::jump_data_tag ||
duke@435 586 layout->tag() == DataLayout::branch_data_tag, "wrong type");
duke@435 587 }
duke@435 588
duke@435 589 virtual bool is_JumpData() { return true; }
duke@435 590
duke@435 591 static int static_cell_count() {
duke@435 592 return jump_cell_count;
duke@435 593 }
duke@435 594
duke@435 595 virtual int cell_count() {
duke@435 596 return static_cell_count();
duke@435 597 }
duke@435 598
duke@435 599 // Direct accessor
duke@435 600 uint taken() {
duke@435 601 return uint_at(taken_off_set);
duke@435 602 }
duke@435 603 // Saturating counter
duke@435 604 uint inc_taken() {
duke@435 605 uint cnt = taken() + 1;
duke@435 606 // Did we wrap? Will compiler screw us??
duke@435 607 if (cnt == 0) cnt--;
duke@435 608 set_uint_at(taken_off_set, cnt);
duke@435 609 return cnt;
duke@435 610 }
duke@435 611
duke@435 612 int displacement() {
duke@435 613 return int_at(displacement_off_set);
duke@435 614 }
duke@435 615
duke@435 616 // Code generation support
duke@435 617 static ByteSize taken_offset() {
duke@435 618 return cell_offset(taken_off_set);
duke@435 619 }
duke@435 620
duke@435 621 static ByteSize displacement_offset() {
duke@435 622 return cell_offset(displacement_off_set);
duke@435 623 }
duke@435 624
duke@435 625 // Specific initialization.
duke@435 626 void post_initialize(BytecodeStream* stream, methodDataOop mdo);
duke@435 627
duke@435 628 #ifndef PRODUCT
duke@435 629 void print_data_on(outputStream* st);
duke@435 630 #endif
duke@435 631 };
duke@435 632
duke@435 633 // ReceiverTypeData
duke@435 634 //
duke@435 635 // A ReceiverTypeData is used to access profiling information about a
duke@435 636 // dynamic type check. It consists of a counter which counts the total times
duke@435 637 // that the check is reached, and a series of (klassOop, count) pairs
duke@435 638 // which are used to store a type profile for the receiver of the check.
duke@435 639 class ReceiverTypeData : public CounterData {
duke@435 640 protected:
duke@435 641 enum {
duke@435 642 receiver0_offset = counter_cell_count,
duke@435 643 count0_offset,
duke@435 644 receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset
duke@435 645 };
duke@435 646
duke@435 647 public:
duke@435 648 ReceiverTypeData(DataLayout* layout) : CounterData(layout) {
duke@435 649 assert(layout->tag() == DataLayout::receiver_type_data_tag ||
duke@435 650 layout->tag() == DataLayout::virtual_call_data_tag, "wrong type");
duke@435 651 }
duke@435 652
duke@435 653 virtual bool is_ReceiverTypeData() { return true; }
duke@435 654
duke@435 655 static int static_cell_count() {
duke@435 656 return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count;
duke@435 657 }
duke@435 658
duke@435 659 virtual int cell_count() {
duke@435 660 return static_cell_count();
duke@435 661 }
duke@435 662
duke@435 663 // Direct accessors
duke@435 664 static uint row_limit() {
duke@435 665 return TypeProfileWidth;
duke@435 666 }
duke@435 667 static int receiver_cell_index(uint row) {
duke@435 668 return receiver0_offset + row * receiver_type_row_cell_count;
duke@435 669 }
duke@435 670 static int receiver_count_cell_index(uint row) {
duke@435 671 return count0_offset + row * receiver_type_row_cell_count;
duke@435 672 }
duke@435 673
duke@435 674 // Get the receiver at row. The 'unchecked' version is needed by parallel old
duke@435 675 // gc; it does not assert the receiver is a klass. During compaction of the
duke@435 676 // perm gen, the klass may already have moved, so the is_klass() predicate
duke@435 677 // would fail. The 'normal' version should be used whenever possible.
duke@435 678 klassOop receiver_unchecked(uint row) {
duke@435 679 assert(row < row_limit(), "oob");
duke@435 680 oop recv = oop_at(receiver_cell_index(row));
duke@435 681 return (klassOop)recv;
duke@435 682 }
duke@435 683
duke@435 684 klassOop receiver(uint row) {
duke@435 685 klassOop recv = receiver_unchecked(row);
duke@435 686 assert(recv == NULL || ((oop)recv)->is_klass(), "wrong type");
duke@435 687 return recv;
duke@435 688 }
duke@435 689
ysr@1376 690 void set_receiver(uint row, oop p) {
ysr@1376 691 assert((uint)row < row_limit(), "oob");
ysr@1376 692 set_oop_at(receiver_cell_index(row), p);
ysr@1376 693 }
ysr@1376 694
duke@435 695 uint receiver_count(uint row) {
duke@435 696 assert(row < row_limit(), "oob");
duke@435 697 return uint_at(receiver_count_cell_index(row));
duke@435 698 }
duke@435 699
ysr@1376 700 void set_receiver_count(uint row, uint count) {
ysr@1376 701 assert(row < row_limit(), "oob");
ysr@1376 702 set_uint_at(receiver_count_cell_index(row), count);
ysr@1376 703 }
ysr@1376 704
ysr@1376 705 void clear_row(uint row) {
ysr@1376 706 assert(row < row_limit(), "oob");
kvn@1686 707 // Clear total count - indicator of polymorphic call site.
kvn@1686 708 // The site may look like as monomorphic after that but
kvn@1686 709 // it allow to have more accurate profiling information because
kvn@1686 710 // there was execution phase change since klasses were unloaded.
kvn@1686 711 // If the site is still polymorphic then MDO will be updated
kvn@1686 712 // to reflect it. But it could be the case that the site becomes
kvn@1686 713 // only bimorphic. Then keeping total count not 0 will be wrong.
kvn@1686 714 // Even if we use monomorphic (when it is not) for compilation
kvn@1686 715 // we will only have trap, deoptimization and recompile again
kvn@1686 716 // with updated MDO after executing method in Interpreter.
kvn@1686 717 // An additional receiver will be recorded in the cleaned row
kvn@1686 718 // during next call execution.
kvn@1686 719 //
kvn@1686 720 // Note: our profiling logic works with empty rows in any slot.
kvn@1686 721 // We do sorting a profiling info (ciCallProfile) for compilation.
kvn@1686 722 //
kvn@1686 723 set_count(0);
ysr@1376 724 set_receiver(row, NULL);
ysr@1376 725 set_receiver_count(row, 0);
ysr@1376 726 }
ysr@1376 727
duke@435 728 // Code generation support
duke@435 729 static ByteSize receiver_offset(uint row) {
duke@435 730 return cell_offset(receiver_cell_index(row));
duke@435 731 }
duke@435 732 static ByteSize receiver_count_offset(uint row) {
duke@435 733 return cell_offset(receiver_count_cell_index(row));
duke@435 734 }
duke@435 735 static ByteSize receiver_type_data_size() {
duke@435 736 return cell_offset(static_cell_count());
duke@435 737 }
duke@435 738
duke@435 739 // GC support
duke@435 740 virtual void follow_contents();
duke@435 741 virtual void oop_iterate(OopClosure* blk);
duke@435 742 virtual void oop_iterate_m(OopClosure* blk, MemRegion mr);
duke@435 743 virtual void adjust_pointers();
ysr@1376 744 virtual void follow_weak_refs(BoolObjectClosure* is_alive_closure);
duke@435 745
duke@435 746 #ifndef SERIALGC
duke@435 747 // Parallel old support
duke@435 748 virtual void follow_contents(ParCompactionManager* cm);
duke@435 749 virtual void update_pointers();
duke@435 750 #endif // SERIALGC
duke@435 751
duke@435 752 oop* adr_receiver(uint row) {
duke@435 753 return adr_oop_at(receiver_cell_index(row));
duke@435 754 }
duke@435 755
duke@435 756 #ifndef PRODUCT
duke@435 757 void print_receiver_data_on(outputStream* st);
duke@435 758 void print_data_on(outputStream* st);
duke@435 759 #endif
duke@435 760 };
duke@435 761
duke@435 762 // VirtualCallData
duke@435 763 //
duke@435 764 // A VirtualCallData is used to access profiling information about a
duke@435 765 // virtual call. For now, it has nothing more than a ReceiverTypeData.
duke@435 766 class VirtualCallData : public ReceiverTypeData {
duke@435 767 public:
duke@435 768 VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) {
duke@435 769 assert(layout->tag() == DataLayout::virtual_call_data_tag, "wrong type");
duke@435 770 }
duke@435 771
duke@435 772 virtual bool is_VirtualCallData() { return true; }
duke@435 773
duke@435 774 static int static_cell_count() {
duke@435 775 // At this point we could add more profile state, e.g., for arguments.
duke@435 776 // But for now it's the same size as the base record type.
duke@435 777 return ReceiverTypeData::static_cell_count();
duke@435 778 }
duke@435 779
duke@435 780 virtual int cell_count() {
duke@435 781 return static_cell_count();
duke@435 782 }
duke@435 783
duke@435 784 // Direct accessors
duke@435 785 static ByteSize virtual_call_data_size() {
duke@435 786 return cell_offset(static_cell_count());
duke@435 787 }
duke@435 788
duke@435 789 #ifndef PRODUCT
duke@435 790 void print_data_on(outputStream* st);
duke@435 791 #endif
duke@435 792 };
duke@435 793
duke@435 794 // RetData
duke@435 795 //
duke@435 796 // A RetData is used to access profiling information for a ret bytecode.
duke@435 797 // It is composed of a count of the number of times that the ret has
duke@435 798 // been executed, followed by a series of triples of the form
duke@435 799 // (bci, count, di) which count the number of times that some bci was the
duke@435 800 // target of the ret and cache a corresponding data displacement.
duke@435 801 class RetData : public CounterData {
duke@435 802 protected:
duke@435 803 enum {
duke@435 804 bci0_offset = counter_cell_count,
duke@435 805 count0_offset,
duke@435 806 displacement0_offset,
duke@435 807 ret_row_cell_count = (displacement0_offset + 1) - bci0_offset
duke@435 808 };
duke@435 809
duke@435 810 void set_bci(uint row, int bci) {
duke@435 811 assert((uint)row < row_limit(), "oob");
duke@435 812 set_int_at(bci0_offset + row * ret_row_cell_count, bci);
duke@435 813 }
duke@435 814 void release_set_bci(uint row, int bci) {
duke@435 815 assert((uint)row < row_limit(), "oob");
duke@435 816 // 'release' when setting the bci acts as a valid flag for other
duke@435 817 // threads wrt bci_count and bci_displacement.
duke@435 818 release_set_int_at(bci0_offset + row * ret_row_cell_count, bci);
duke@435 819 }
duke@435 820 void set_bci_count(uint row, uint count) {
duke@435 821 assert((uint)row < row_limit(), "oob");
duke@435 822 set_uint_at(count0_offset + row * ret_row_cell_count, count);
duke@435 823 }
duke@435 824 void set_bci_displacement(uint row, int disp) {
duke@435 825 set_int_at(displacement0_offset + row * ret_row_cell_count, disp);
duke@435 826 }
duke@435 827
duke@435 828 public:
duke@435 829 RetData(DataLayout* layout) : CounterData(layout) {
duke@435 830 assert(layout->tag() == DataLayout::ret_data_tag, "wrong type");
duke@435 831 }
duke@435 832
duke@435 833 virtual bool is_RetData() { return true; }
duke@435 834
duke@435 835 enum {
duke@435 836 no_bci = -1 // value of bci when bci1/2 are not in use.
duke@435 837 };
duke@435 838
duke@435 839 static int static_cell_count() {
duke@435 840 return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count;
duke@435 841 }
duke@435 842
duke@435 843 virtual int cell_count() {
duke@435 844 return static_cell_count();
duke@435 845 }
duke@435 846
duke@435 847 static uint row_limit() {
duke@435 848 return BciProfileWidth;
duke@435 849 }
duke@435 850 static int bci_cell_index(uint row) {
duke@435 851 return bci0_offset + row * ret_row_cell_count;
duke@435 852 }
duke@435 853 static int bci_count_cell_index(uint row) {
duke@435 854 return count0_offset + row * ret_row_cell_count;
duke@435 855 }
duke@435 856 static int bci_displacement_cell_index(uint row) {
duke@435 857 return displacement0_offset + row * ret_row_cell_count;
duke@435 858 }
duke@435 859
duke@435 860 // Direct accessors
duke@435 861 int bci(uint row) {
duke@435 862 return int_at(bci_cell_index(row));
duke@435 863 }
duke@435 864 uint bci_count(uint row) {
duke@435 865 return uint_at(bci_count_cell_index(row));
duke@435 866 }
duke@435 867 int bci_displacement(uint row) {
duke@435 868 return int_at(bci_displacement_cell_index(row));
duke@435 869 }
duke@435 870
duke@435 871 // Interpreter Runtime support
duke@435 872 address fixup_ret(int return_bci, methodDataHandle mdo);
duke@435 873
duke@435 874 // Code generation support
duke@435 875 static ByteSize bci_offset(uint row) {
duke@435 876 return cell_offset(bci_cell_index(row));
duke@435 877 }
duke@435 878 static ByteSize bci_count_offset(uint row) {
duke@435 879 return cell_offset(bci_count_cell_index(row));
duke@435 880 }
duke@435 881 static ByteSize bci_displacement_offset(uint row) {
duke@435 882 return cell_offset(bci_displacement_cell_index(row));
duke@435 883 }
duke@435 884
duke@435 885 // Specific initialization.
duke@435 886 void post_initialize(BytecodeStream* stream, methodDataOop mdo);
duke@435 887
duke@435 888 #ifndef PRODUCT
duke@435 889 void print_data_on(outputStream* st);
duke@435 890 #endif
duke@435 891 };
duke@435 892
duke@435 893 // BranchData
duke@435 894 //
duke@435 895 // A BranchData is used to access profiling data for a two-way branch.
duke@435 896 // It consists of taken and not_taken counts as well as a data displacement
duke@435 897 // for the taken case.
duke@435 898 class BranchData : public JumpData {
duke@435 899 protected:
duke@435 900 enum {
duke@435 901 not_taken_off_set = jump_cell_count,
duke@435 902 branch_cell_count
duke@435 903 };
duke@435 904
duke@435 905 void set_displacement(int displacement) {
duke@435 906 set_int_at(displacement_off_set, displacement);
duke@435 907 }
duke@435 908
duke@435 909 public:
duke@435 910 BranchData(DataLayout* layout) : JumpData(layout) {
duke@435 911 assert(layout->tag() == DataLayout::branch_data_tag, "wrong type");
duke@435 912 }
duke@435 913
duke@435 914 virtual bool is_BranchData() { return true; }
duke@435 915
duke@435 916 static int static_cell_count() {
duke@435 917 return branch_cell_count;
duke@435 918 }
duke@435 919
duke@435 920 virtual int cell_count() {
duke@435 921 return static_cell_count();
duke@435 922 }
duke@435 923
duke@435 924 // Direct accessor
duke@435 925 uint not_taken() {
duke@435 926 return uint_at(not_taken_off_set);
duke@435 927 }
duke@435 928
duke@435 929 uint inc_not_taken() {
duke@435 930 uint cnt = not_taken() + 1;
duke@435 931 // Did we wrap? Will compiler screw us??
duke@435 932 if (cnt == 0) cnt--;
duke@435 933 set_uint_at(not_taken_off_set, cnt);
duke@435 934 return cnt;
duke@435 935 }
duke@435 936
duke@435 937 // Code generation support
duke@435 938 static ByteSize not_taken_offset() {
duke@435 939 return cell_offset(not_taken_off_set);
duke@435 940 }
duke@435 941 static ByteSize branch_data_size() {
duke@435 942 return cell_offset(branch_cell_count);
duke@435 943 }
duke@435 944
duke@435 945 // Specific initialization.
duke@435 946 void post_initialize(BytecodeStream* stream, methodDataOop mdo);
duke@435 947
duke@435 948 #ifndef PRODUCT
duke@435 949 void print_data_on(outputStream* st);
duke@435 950 #endif
duke@435 951 };
duke@435 952
duke@435 953 // ArrayData
duke@435 954 //
duke@435 955 // A ArrayData is a base class for accessing profiling data which does
duke@435 956 // not have a statically known size. It consists of an array length
duke@435 957 // and an array start.
duke@435 958 class ArrayData : public ProfileData {
duke@435 959 protected:
duke@435 960 friend class DataLayout;
duke@435 961
duke@435 962 enum {
duke@435 963 array_len_off_set,
duke@435 964 array_start_off_set
duke@435 965 };
duke@435 966
duke@435 967 uint array_uint_at(int index) {
duke@435 968 int aindex = index + array_start_off_set;
duke@435 969 return uint_at(aindex);
duke@435 970 }
duke@435 971 int array_int_at(int index) {
duke@435 972 int aindex = index + array_start_off_set;
duke@435 973 return int_at(aindex);
duke@435 974 }
duke@435 975 oop array_oop_at(int index) {
duke@435 976 int aindex = index + array_start_off_set;
duke@435 977 return oop_at(aindex);
duke@435 978 }
duke@435 979 void array_set_int_at(int index, int value) {
duke@435 980 int aindex = index + array_start_off_set;
duke@435 981 set_int_at(aindex, value);
duke@435 982 }
duke@435 983
duke@435 984 // Code generation support for subclasses.
duke@435 985 static ByteSize array_element_offset(int index) {
duke@435 986 return cell_offset(array_start_off_set + index);
duke@435 987 }
duke@435 988
duke@435 989 public:
duke@435 990 ArrayData(DataLayout* layout) : ProfileData(layout) {}
duke@435 991
duke@435 992 virtual bool is_ArrayData() { return true; }
duke@435 993
duke@435 994 static int static_cell_count() {
duke@435 995 return -1;
duke@435 996 }
duke@435 997
duke@435 998 int array_len() {
duke@435 999 return int_at_unchecked(array_len_off_set);
duke@435 1000 }
duke@435 1001
duke@435 1002 virtual int cell_count() {
duke@435 1003 return array_len() + 1;
duke@435 1004 }
duke@435 1005
duke@435 1006 // Code generation support
duke@435 1007 static ByteSize array_len_offset() {
duke@435 1008 return cell_offset(array_len_off_set);
duke@435 1009 }
duke@435 1010 static ByteSize array_start_offset() {
duke@435 1011 return cell_offset(array_start_off_set);
duke@435 1012 }
duke@435 1013 };
duke@435 1014
duke@435 1015 // MultiBranchData
duke@435 1016 //
duke@435 1017 // A MultiBranchData is used to access profiling information for
duke@435 1018 // a multi-way branch (*switch bytecodes). It consists of a series
duke@435 1019 // of (count, displacement) pairs, which count the number of times each
duke@435 1020 // case was taken and specify the data displacment for each branch target.
duke@435 1021 class MultiBranchData : public ArrayData {
duke@435 1022 protected:
duke@435 1023 enum {
duke@435 1024 default_count_off_set,
duke@435 1025 default_disaplacement_off_set,
duke@435 1026 case_array_start
duke@435 1027 };
duke@435 1028 enum {
duke@435 1029 relative_count_off_set,
duke@435 1030 relative_displacement_off_set,
duke@435 1031 per_case_cell_count
duke@435 1032 };
duke@435 1033
duke@435 1034 void set_default_displacement(int displacement) {
duke@435 1035 array_set_int_at(default_disaplacement_off_set, displacement);
duke@435 1036 }
duke@435 1037 void set_displacement_at(int index, int displacement) {
duke@435 1038 array_set_int_at(case_array_start +
duke@435 1039 index * per_case_cell_count +
duke@435 1040 relative_displacement_off_set,
duke@435 1041 displacement);
duke@435 1042 }
duke@435 1043
duke@435 1044 public:
duke@435 1045 MultiBranchData(DataLayout* layout) : ArrayData(layout) {
duke@435 1046 assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type");
duke@435 1047 }
duke@435 1048
duke@435 1049 virtual bool is_MultiBranchData() { return true; }
duke@435 1050
duke@435 1051 static int compute_cell_count(BytecodeStream* stream);
duke@435 1052
duke@435 1053 int number_of_cases() {
duke@435 1054 int alen = array_len() - 2; // get rid of default case here.
duke@435 1055 assert(alen % per_case_cell_count == 0, "must be even");
duke@435 1056 return (alen / per_case_cell_count);
duke@435 1057 }
duke@435 1058
duke@435 1059 uint default_count() {
duke@435 1060 return array_uint_at(default_count_off_set);
duke@435 1061 }
duke@435 1062 int default_displacement() {
duke@435 1063 return array_int_at(default_disaplacement_off_set);
duke@435 1064 }
duke@435 1065
duke@435 1066 uint count_at(int index) {
duke@435 1067 return array_uint_at(case_array_start +
duke@435 1068 index * per_case_cell_count +
duke@435 1069 relative_count_off_set);
duke@435 1070 }
duke@435 1071 int displacement_at(int index) {
duke@435 1072 return array_int_at(case_array_start +
duke@435 1073 index * per_case_cell_count +
duke@435 1074 relative_displacement_off_set);
duke@435 1075 }
duke@435 1076
duke@435 1077 // Code generation support
duke@435 1078 static ByteSize default_count_offset() {
duke@435 1079 return array_element_offset(default_count_off_set);
duke@435 1080 }
duke@435 1081 static ByteSize default_displacement_offset() {
duke@435 1082 return array_element_offset(default_disaplacement_off_set);
duke@435 1083 }
duke@435 1084 static ByteSize case_count_offset(int index) {
duke@435 1085 return case_array_offset() +
duke@435 1086 (per_case_size() * index) +
duke@435 1087 relative_count_offset();
duke@435 1088 }
duke@435 1089 static ByteSize case_array_offset() {
duke@435 1090 return array_element_offset(case_array_start);
duke@435 1091 }
duke@435 1092 static ByteSize per_case_size() {
duke@435 1093 return in_ByteSize(per_case_cell_count) * cell_size;
duke@435 1094 }
duke@435 1095 static ByteSize relative_count_offset() {
duke@435 1096 return in_ByteSize(relative_count_off_set) * cell_size;
duke@435 1097 }
duke@435 1098 static ByteSize relative_displacement_offset() {
duke@435 1099 return in_ByteSize(relative_displacement_off_set) * cell_size;
duke@435 1100 }
duke@435 1101
duke@435 1102 // Specific initialization.
duke@435 1103 void post_initialize(BytecodeStream* stream, methodDataOop mdo);
duke@435 1104
duke@435 1105 #ifndef PRODUCT
duke@435 1106 void print_data_on(outputStream* st);
duke@435 1107 #endif
duke@435 1108 };
duke@435 1109
kvn@480 1110 class ArgInfoData : public ArrayData {
kvn@480 1111
kvn@480 1112 public:
kvn@480 1113 ArgInfoData(DataLayout* layout) : ArrayData(layout) {
kvn@480 1114 assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type");
kvn@480 1115 }
kvn@480 1116
kvn@480 1117 virtual bool is_ArgInfoData() { return true; }
kvn@480 1118
kvn@480 1119
kvn@480 1120 int number_of_args() {
kvn@480 1121 return array_len();
kvn@480 1122 }
kvn@480 1123
kvn@480 1124 uint arg_modified(int arg) {
kvn@480 1125 return array_uint_at(arg);
kvn@480 1126 }
kvn@480 1127
kvn@480 1128 void set_arg_modified(int arg, uint val) {
kvn@480 1129 array_set_int_at(arg, val);
kvn@480 1130 }
kvn@480 1131
kvn@480 1132 #ifndef PRODUCT
kvn@480 1133 void print_data_on(outputStream* st);
kvn@480 1134 #endif
kvn@480 1135 };
kvn@480 1136
duke@435 1137 // methodDataOop
duke@435 1138 //
duke@435 1139 // A methodDataOop holds information which has been collected about
duke@435 1140 // a method. Its layout looks like this:
duke@435 1141 //
duke@435 1142 // -----------------------------
duke@435 1143 // | header |
duke@435 1144 // | klass |
duke@435 1145 // -----------------------------
duke@435 1146 // | method |
duke@435 1147 // | size of the methodDataOop |
duke@435 1148 // -----------------------------
duke@435 1149 // | Data entries... |
duke@435 1150 // | (variable size) |
duke@435 1151 // | |
duke@435 1152 // . .
duke@435 1153 // . .
duke@435 1154 // . .
duke@435 1155 // | |
duke@435 1156 // -----------------------------
duke@435 1157 //
duke@435 1158 // The data entry area is a heterogeneous array of DataLayouts. Each
duke@435 1159 // DataLayout in the array corresponds to a specific bytecode in the
duke@435 1160 // method. The entries in the array are sorted by the corresponding
duke@435 1161 // bytecode. Access to the data is via resource-allocated ProfileData,
duke@435 1162 // which point to the underlying blocks of DataLayout structures.
duke@435 1163 //
duke@435 1164 // During interpretation, if profiling in enabled, the interpreter
duke@435 1165 // maintains a method data pointer (mdp), which points at the entry
duke@435 1166 // in the array corresponding to the current bci. In the course of
duke@435 1167 // intepretation, when a bytecode is encountered that has profile data
duke@435 1168 // associated with it, the entry pointed to by mdp is updated, then the
duke@435 1169 // mdp is adjusted to point to the next appropriate DataLayout. If mdp
duke@435 1170 // is NULL to begin with, the interpreter assumes that the current method
duke@435 1171 // is not (yet) being profiled.
duke@435 1172 //
duke@435 1173 // In methodDataOop parlance, "dp" is a "data pointer", the actual address
duke@435 1174 // of a DataLayout element. A "di" is a "data index", the offset in bytes
duke@435 1175 // from the base of the data entry array. A "displacement" is the byte offset
duke@435 1176 // in certain ProfileData objects that indicate the amount the mdp must be
duke@435 1177 // adjusted in the event of a change in control flow.
duke@435 1178 //
duke@435 1179
duke@435 1180 class methodDataOopDesc : public oopDesc {
duke@435 1181 friend class VMStructs;
duke@435 1182 private:
duke@435 1183 friend class ProfileData;
duke@435 1184
duke@435 1185 // Back pointer to the methodOop
duke@435 1186 methodOop _method;
duke@435 1187
duke@435 1188 // Size of this oop in bytes
duke@435 1189 int _size;
duke@435 1190
duke@435 1191 // Cached hint for bci_to_dp and bci_to_data
duke@435 1192 int _hint_di;
duke@435 1193
duke@435 1194 // Whole-method sticky bits and flags
duke@435 1195 public:
duke@435 1196 enum {
duke@435 1197 _trap_hist_limit = 16, // decoupled from Deoptimization::Reason_LIMIT
duke@435 1198 _trap_hist_mask = max_jubyte,
duke@435 1199 _extra_data_count = 4 // extra DataLayout headers, for trap history
duke@435 1200 }; // Public flag values
duke@435 1201 private:
duke@435 1202 uint _nof_decompiles; // count of all nmethod removals
duke@435 1203 uint _nof_overflow_recompiles; // recompile count, excluding recomp. bits
duke@435 1204 uint _nof_overflow_traps; // trap count, excluding _trap_hist
duke@435 1205 union {
duke@435 1206 intptr_t _align;
duke@435 1207 u1 _array[_trap_hist_limit];
duke@435 1208 } _trap_hist;
duke@435 1209
duke@435 1210 // Support for interprocedural escape analysis, from Thomas Kotzmann.
duke@435 1211 intx _eflags; // flags on escape information
duke@435 1212 intx _arg_local; // bit set of non-escaping arguments
duke@435 1213 intx _arg_stack; // bit set of stack-allocatable arguments
duke@435 1214 intx _arg_returned; // bit set of returned arguments
duke@435 1215
iveresov@2138 1216 int _creation_mileage; // method mileage at MDO creation
iveresov@2138 1217
iveresov@2138 1218 // How many invocations has this MDO seen?
iveresov@2138 1219 // These counters are used to determine the exact age of MDO.
iveresov@2138 1220 // We need those because in tiered a method can be concurrently
iveresov@2138 1221 // executed at different levels.
iveresov@2138 1222 InvocationCounter _invocation_counter;
iveresov@2138 1223 // Same for backedges.
iveresov@2138 1224 InvocationCounter _backedge_counter;
iveresov@2559 1225 // Counter values at the time profiling started.
iveresov@2559 1226 int _invocation_counter_start;
iveresov@2559 1227 int _backedge_counter_start;
iveresov@2138 1228 // Number of loops and blocks is computed when compiling the first
iveresov@2138 1229 // time with C1. It is used to determine if method is trivial.
iveresov@2138 1230 short _num_loops;
iveresov@2138 1231 short _num_blocks;
iveresov@2138 1232 // Highest compile level this method has ever seen.
iveresov@2138 1233 u1 _highest_comp_level;
iveresov@2138 1234 // Same for OSR level
iveresov@2138 1235 u1 _highest_osr_comp_level;
iveresov@2138 1236 // Does this method contain anything worth profiling?
iveresov@2138 1237 bool _would_profile;
duke@435 1238
duke@435 1239 // Size of _data array in bytes. (Excludes header and extra_data fields.)
duke@435 1240 int _data_size;
duke@435 1241
duke@435 1242 // Beginning of the data entries
duke@435 1243 intptr_t _data[1];
duke@435 1244
duke@435 1245 // Helper for size computation
duke@435 1246 static int compute_data_size(BytecodeStream* stream);
duke@435 1247 static int bytecode_cell_count(Bytecodes::Code code);
duke@435 1248 enum { no_profile_data = -1, variable_cell_count = -2 };
duke@435 1249
duke@435 1250 // Helper for initialization
duke@435 1251 DataLayout* data_layout_at(int data_index) {
duke@435 1252 assert(data_index % sizeof(intptr_t) == 0, "unaligned");
duke@435 1253 return (DataLayout*) (((address)_data) + data_index);
duke@435 1254 }
duke@435 1255
duke@435 1256 // Initialize an individual data segment. Returns the size of
duke@435 1257 // the segment in bytes.
duke@435 1258 int initialize_data(BytecodeStream* stream, int data_index);
duke@435 1259
duke@435 1260 // Helper for data_at
duke@435 1261 DataLayout* limit_data_position() {
duke@435 1262 return (DataLayout*)((address)data_base() + _data_size);
duke@435 1263 }
duke@435 1264 bool out_of_bounds(int data_index) {
duke@435 1265 return data_index >= data_size();
duke@435 1266 }
duke@435 1267
duke@435 1268 // Give each of the data entries a chance to perform specific
duke@435 1269 // data initialization.
duke@435 1270 void post_initialize(BytecodeStream* stream);
duke@435 1271
duke@435 1272 // hint accessors
duke@435 1273 int hint_di() const { return _hint_di; }
duke@435 1274 void set_hint_di(int di) {
duke@435 1275 assert(!out_of_bounds(di), "hint_di out of bounds");
duke@435 1276 _hint_di = di;
duke@435 1277 }
duke@435 1278 ProfileData* data_before(int bci) {
duke@435 1279 // avoid SEGV on this edge case
duke@435 1280 if (data_size() == 0)
duke@435 1281 return NULL;
duke@435 1282 int hint = hint_di();
duke@435 1283 if (data_layout_at(hint)->bci() <= bci)
duke@435 1284 return data_at(hint);
duke@435 1285 return first_data();
duke@435 1286 }
duke@435 1287
duke@435 1288 // What is the index of the first data entry?
duke@435 1289 int first_di() { return 0; }
duke@435 1290
duke@435 1291 // Find or create an extra ProfileData:
duke@435 1292 ProfileData* bci_to_extra_data(int bci, bool create_if_missing);
duke@435 1293
kvn@480 1294 // return the argument info cell
kvn@480 1295 ArgInfoData *arg_info();
kvn@480 1296
duke@435 1297 public:
duke@435 1298 static int header_size() {
duke@435 1299 return sizeof(methodDataOopDesc)/wordSize;
duke@435 1300 }
duke@435 1301
duke@435 1302 // Compute the size of a methodDataOop before it is created.
duke@435 1303 static int compute_allocation_size_in_bytes(methodHandle method);
duke@435 1304 static int compute_allocation_size_in_words(methodHandle method);
duke@435 1305 static int compute_extra_data_count(int data_size, int empty_bc_count);
duke@435 1306
duke@435 1307 // Determine if a given bytecode can have profile information.
duke@435 1308 static bool bytecode_has_profile(Bytecodes::Code code) {
duke@435 1309 return bytecode_cell_count(code) != no_profile_data;
duke@435 1310 }
duke@435 1311
duke@435 1312 // Perform initialization of a new methodDataOop
duke@435 1313 void initialize(methodHandle method);
duke@435 1314
duke@435 1315 // My size
duke@435 1316 int object_size_in_bytes() { return _size; }
duke@435 1317 int object_size() {
duke@435 1318 return align_object_size(align_size_up(_size, BytesPerWord)/BytesPerWord);
duke@435 1319 }
duke@435 1320
duke@435 1321 int creation_mileage() const { return _creation_mileage; }
duke@435 1322 void set_creation_mileage(int x) { _creation_mileage = x; }
iveresov@2138 1323
iveresov@2138 1324 int invocation_count() {
iveresov@2138 1325 if (invocation_counter()->carry()) {
iveresov@2138 1326 return InvocationCounter::count_limit;
iveresov@2138 1327 }
iveresov@2138 1328 return invocation_counter()->count();
iveresov@2138 1329 }
iveresov@2138 1330 int backedge_count() {
iveresov@2138 1331 if (backedge_counter()->carry()) {
iveresov@2138 1332 return InvocationCounter::count_limit;
iveresov@2138 1333 }
iveresov@2138 1334 return backedge_counter()->count();
iveresov@2138 1335 }
iveresov@2138 1336
iveresov@2559 1337 int invocation_count_start() {
iveresov@2559 1338 if (invocation_counter()->carry()) {
iveresov@2559 1339 return 0;
iveresov@2559 1340 }
iveresov@2559 1341 return _invocation_counter_start;
iveresov@2559 1342 }
iveresov@2559 1343
iveresov@2559 1344 int backedge_count_start() {
iveresov@2559 1345 if (backedge_counter()->carry()) {
iveresov@2559 1346 return 0;
iveresov@2559 1347 }
iveresov@2559 1348 return _backedge_counter_start;
iveresov@2559 1349 }
iveresov@2559 1350
iveresov@2559 1351 int invocation_count_delta() { return invocation_count() - invocation_count_start(); }
iveresov@2559 1352 int backedge_count_delta() { return backedge_count() - backedge_count_start(); }
iveresov@2559 1353
iveresov@2559 1354 void reset_start_counters() {
iveresov@2559 1355 _invocation_counter_start = invocation_count();
iveresov@2559 1356 _backedge_counter_start = backedge_count();
iveresov@2559 1357 }
iveresov@2559 1358
iveresov@2138 1359 InvocationCounter* invocation_counter() { return &_invocation_counter; }
iveresov@2138 1360 InvocationCounter* backedge_counter() { return &_backedge_counter; }
iveresov@2138 1361
iveresov@2138 1362 void set_would_profile(bool p) { _would_profile = p; }
iveresov@2138 1363 bool would_profile() const { return _would_profile; }
iveresov@2138 1364
iveresov@2138 1365 int highest_comp_level() { return _highest_comp_level; }
iveresov@2138 1366 void set_highest_comp_level(int level) { _highest_comp_level = level; }
iveresov@2138 1367 int highest_osr_comp_level() { return _highest_osr_comp_level; }
iveresov@2138 1368 void set_highest_osr_comp_level(int level) { _highest_osr_comp_level = level; }
iveresov@2138 1369
iveresov@2138 1370 int num_loops() const { return _num_loops; }
iveresov@2138 1371 void set_num_loops(int n) { _num_loops = n; }
iveresov@2138 1372 int num_blocks() const { return _num_blocks; }
iveresov@2138 1373 void set_num_blocks(int n) { _num_blocks = n; }
iveresov@2138 1374
duke@435 1375 bool is_mature() const; // consult mileage and ProfileMaturityPercentage
duke@435 1376 static int mileage_of(methodOop m);
duke@435 1377
duke@435 1378 // Support for interprocedural escape analysis, from Thomas Kotzmann.
duke@435 1379 enum EscapeFlag {
duke@435 1380 estimated = 1 << 0,
kvn@513 1381 return_local = 1 << 1,
kvn@513 1382 return_allocated = 1 << 2,
kvn@513 1383 allocated_escapes = 1 << 3,
kvn@513 1384 unknown_modified = 1 << 4
duke@435 1385 };
duke@435 1386
duke@435 1387 intx eflags() { return _eflags; }
duke@435 1388 intx arg_local() { return _arg_local; }
duke@435 1389 intx arg_stack() { return _arg_stack; }
duke@435 1390 intx arg_returned() { return _arg_returned; }
kvn@480 1391 uint arg_modified(int a) { ArgInfoData *aid = arg_info();
kvn@480 1392 assert(a >= 0 && a < aid->number_of_args(), "valid argument number");
kvn@480 1393 return aid->arg_modified(a); }
duke@435 1394
duke@435 1395 void set_eflags(intx v) { _eflags = v; }
duke@435 1396 void set_arg_local(intx v) { _arg_local = v; }
duke@435 1397 void set_arg_stack(intx v) { _arg_stack = v; }
duke@435 1398 void set_arg_returned(intx v) { _arg_returned = v; }
kvn@480 1399 void set_arg_modified(int a, uint v) { ArgInfoData *aid = arg_info();
kvn@480 1400 assert(a >= 0 && a < aid->number_of_args(), "valid argument number");
kvn@480 1401
kvn@480 1402 aid->set_arg_modified(a, v); }
duke@435 1403
duke@435 1404 void clear_escape_info() { _eflags = _arg_local = _arg_stack = _arg_returned = 0; }
duke@435 1405
duke@435 1406 // Location and size of data area
duke@435 1407 address data_base() const {
duke@435 1408 return (address) _data;
duke@435 1409 }
duke@435 1410 int data_size() {
duke@435 1411 return _data_size;
duke@435 1412 }
duke@435 1413
duke@435 1414 // Accessors
duke@435 1415 methodOop method() { return _method; }
duke@435 1416
duke@435 1417 // Get the data at an arbitrary (sort of) data index.
duke@435 1418 ProfileData* data_at(int data_index);
duke@435 1419
duke@435 1420 // Walk through the data in order.
duke@435 1421 ProfileData* first_data() { return data_at(first_di()); }
duke@435 1422 ProfileData* next_data(ProfileData* current);
duke@435 1423 bool is_valid(ProfileData* current) { return current != NULL; }
duke@435 1424
duke@435 1425 // Convert a dp (data pointer) to a di (data index).
duke@435 1426 int dp_to_di(address dp) {
duke@435 1427 return dp - ((address)_data);
duke@435 1428 }
duke@435 1429
duke@435 1430 address di_to_dp(int di) {
duke@435 1431 return (address)data_layout_at(di);
duke@435 1432 }
duke@435 1433
duke@435 1434 // bci to di/dp conversion.
duke@435 1435 address bci_to_dp(int bci);
duke@435 1436 int bci_to_di(int bci) {
duke@435 1437 return dp_to_di(bci_to_dp(bci));
duke@435 1438 }
duke@435 1439
duke@435 1440 // Get the data at an arbitrary bci, or NULL if there is none.
duke@435 1441 ProfileData* bci_to_data(int bci);
duke@435 1442
duke@435 1443 // Same, but try to create an extra_data record if one is needed:
duke@435 1444 ProfileData* allocate_bci_to_data(int bci) {
duke@435 1445 ProfileData* data = bci_to_data(bci);
duke@435 1446 return (data != NULL) ? data : bci_to_extra_data(bci, true);
duke@435 1447 }
duke@435 1448
duke@435 1449 // Add a handful of extra data records, for trap tracking.
duke@435 1450 DataLayout* extra_data_base() { return limit_data_position(); }
duke@435 1451 DataLayout* extra_data_limit() { return (DataLayout*)((address)this + object_size_in_bytes()); }
duke@435 1452 int extra_data_size() { return (address)extra_data_limit()
duke@435 1453 - (address)extra_data_base(); }
duke@435 1454 static DataLayout* next_extra(DataLayout* dp) { return (DataLayout*)((address)dp + in_bytes(DataLayout::cell_offset(0))); }
duke@435 1455
duke@435 1456 // Return (uint)-1 for overflow.
duke@435 1457 uint trap_count(int reason) const {
duke@435 1458 assert((uint)reason < _trap_hist_limit, "oob");
duke@435 1459 return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1;
duke@435 1460 }
duke@435 1461 // For loops:
duke@435 1462 static uint trap_reason_limit() { return _trap_hist_limit; }
duke@435 1463 static uint trap_count_limit() { return _trap_hist_mask; }
duke@435 1464 uint inc_trap_count(int reason) {
duke@435 1465 // Count another trap, anywhere in this method.
duke@435 1466 assert(reason >= 0, "must be single trap");
duke@435 1467 if ((uint)reason < _trap_hist_limit) {
duke@435 1468 uint cnt1 = 1 + _trap_hist._array[reason];
duke@435 1469 if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow...
duke@435 1470 _trap_hist._array[reason] = cnt1;
duke@435 1471 return cnt1;
duke@435 1472 } else {
duke@435 1473 return _trap_hist_mask + (++_nof_overflow_traps);
duke@435 1474 }
duke@435 1475 } else {
duke@435 1476 // Could not represent the count in the histogram.
duke@435 1477 return (++_nof_overflow_traps);
duke@435 1478 }
duke@435 1479 }
duke@435 1480
duke@435 1481 uint overflow_trap_count() const {
duke@435 1482 return _nof_overflow_traps;
duke@435 1483 }
duke@435 1484 uint overflow_recompile_count() const {
duke@435 1485 return _nof_overflow_recompiles;
duke@435 1486 }
duke@435 1487 void inc_overflow_recompile_count() {
duke@435 1488 _nof_overflow_recompiles += 1;
duke@435 1489 }
duke@435 1490 uint decompile_count() const {
duke@435 1491 return _nof_decompiles;
duke@435 1492 }
duke@435 1493 void inc_decompile_count() {
duke@435 1494 _nof_decompiles += 1;
kvn@1641 1495 if (decompile_count() > (uint)PerMethodRecompilationCutoff) {
iveresov@2138 1496 method()->set_not_compilable(CompLevel_full_optimization);
kvn@1641 1497 }
duke@435 1498 }
duke@435 1499
duke@435 1500 // Support for code generation
duke@435 1501 static ByteSize data_offset() {
duke@435 1502 return byte_offset_of(methodDataOopDesc, _data[0]);
duke@435 1503 }
duke@435 1504
iveresov@2138 1505 static ByteSize invocation_counter_offset() {
iveresov@2138 1506 return byte_offset_of(methodDataOopDesc, _invocation_counter);
iveresov@2138 1507 }
iveresov@2138 1508 static ByteSize backedge_counter_offset() {
iveresov@2138 1509 return byte_offset_of(methodDataOopDesc, _backedge_counter);
iveresov@2138 1510 }
iveresov@2138 1511
duke@435 1512 // GC support
duke@435 1513 oop* adr_method() const { return (oop*)&_method; }
duke@435 1514 bool object_is_parsable() const { return _size != 0; }
duke@435 1515 void set_object_is_parsable(int object_size_in_bytes) { _size = object_size_in_bytes; }
duke@435 1516
duke@435 1517 #ifndef PRODUCT
duke@435 1518 // printing support for method data
duke@435 1519 void print_data_on(outputStream* st);
duke@435 1520 #endif
duke@435 1521
duke@435 1522 // verification
duke@435 1523 void verify_data_on(outputStream* st);
duke@435 1524 };
stefank@2314 1525
stefank@2314 1526 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP

mercurial