Mercurial > hg > truffle
comparison src/share/vm/oops/methodData.hpp @ 14422:2b8e28fdf503
Merge
author | kvn |
---|---|
date | Tue, 05 Nov 2013 17:38:04 -0800 |
parents | abe03600372a 5ccbab1c69f3 |
children | 018b357638aa |
comparison
equal
deleted
inserted
replaced
14421:3068270ba476 | 14422:2b8e28fdf503 |
---|---|
70 | 70 |
71 // DataLayout | 71 // DataLayout |
72 // | 72 // |
73 // Overlay for generic profiling data. | 73 // Overlay for generic profiling data. |
74 class DataLayout VALUE_OBJ_CLASS_SPEC { | 74 class DataLayout VALUE_OBJ_CLASS_SPEC { |
75 friend class VMStructs; | |
76 | |
75 private: | 77 private: |
76 // Every data layout begins with a header. This header | 78 // Every data layout begins with a header. This header |
77 // contains a tag, which is used to indicate the size/layout | 79 // contains a tag, which is used to indicate the size/layout |
78 // of the data, 4 bits of flags, which can be used in any way, | 80 // of the data, 4 bits of flags, which can be used in any way, |
79 // 4 bits of trap history (none/one reason/many reasons), | 81 // 4 bits of trap history (none/one reason/many reasons), |
113 receiver_type_data_tag, | 115 receiver_type_data_tag, |
114 virtual_call_data_tag, | 116 virtual_call_data_tag, |
115 ret_data_tag, | 117 ret_data_tag, |
116 branch_data_tag, | 118 branch_data_tag, |
117 multi_branch_data_tag, | 119 multi_branch_data_tag, |
118 arg_info_data_tag | 120 arg_info_data_tag, |
121 call_type_data_tag, | |
122 virtual_call_type_data_tag, | |
123 parameters_type_data_tag | |
119 }; | 124 }; |
120 | 125 |
121 enum { | 126 enum { |
122 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. | 127 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. |
123 // The trap state breaks down further as [recompile:1 | reason:3]. | 128 // The trap state breaks down further as [recompile:1 | reason:3]. |
161 // The associated trap histogram in the MDO itself tells whether | 166 // The associated trap histogram in the MDO itself tells whether |
162 // traps are common or not. If a BCI shows that a trap X has | 167 // traps are common or not. If a BCI shows that a trap X has |
163 // occurred, and the MDO shows N occurrences of X, we make the | 168 // occurred, and the MDO shows N occurrences of X, we make the |
164 // simplifying assumption that all N occurrences can be blamed | 169 // simplifying assumption that all N occurrences can be blamed |
165 // on that BCI. | 170 // on that BCI. |
166 int trap_state() { | 171 int trap_state() const { |
167 return ((_header._struct._flags >> trap_shift) & trap_mask); | 172 return ((_header._struct._flags >> trap_shift) & trap_mask); |
168 } | 173 } |
169 | 174 |
170 void set_trap_state(int new_state) { | 175 void set_trap_state(int new_state) { |
171 assert(ProfileTraps, "used only under +ProfileTraps"); | 176 assert(ProfileTraps, "used only under +ProfileTraps"); |
172 uint old_flags = (_header._struct._flags & flag_mask); | 177 uint old_flags = (_header._struct._flags & flag_mask); |
173 _header._struct._flags = (new_state << trap_shift) | old_flags; | 178 _header._struct._flags = (new_state << trap_shift) | old_flags; |
174 } | 179 } |
175 | 180 |
176 u1 flags() { | 181 u1 flags() const { |
177 return _header._struct._flags; | 182 return _header._struct._flags; |
178 } | 183 } |
179 | 184 |
180 u2 bci() { | 185 u2 bci() const { |
181 return _header._struct._bci; | 186 return _header._struct._bci; |
182 } | 187 } |
183 | 188 |
184 void set_header(intptr_t value) { | 189 void set_header(intptr_t value) { |
185 _header._bits = value; | 190 _header._bits = value; |
194 _cells[index] = value; | 199 _cells[index] = value; |
195 } | 200 } |
196 void release_set_cell_at(int index, intptr_t value) { | 201 void release_set_cell_at(int index, intptr_t value) { |
197 OrderAccess::release_store_ptr(&_cells[index], value); | 202 OrderAccess::release_store_ptr(&_cells[index], value); |
198 } | 203 } |
199 intptr_t cell_at(int index) { | 204 intptr_t cell_at(int index) const { |
200 return _cells[index]; | 205 return _cells[index]; |
201 } | 206 } |
202 | 207 |
203 void set_flag_at(int flag_number) { | 208 void set_flag_at(int flag_number) { |
204 assert(flag_number < flag_limit, "oob"); | 209 assert(flag_number < flag_limit, "oob"); |
205 _header._struct._flags |= (0x1 << flag_number); | 210 _header._struct._flags |= (0x1 << flag_number); |
206 } | 211 } |
207 bool flag_at(int flag_number) { | 212 bool flag_at(int flag_number) const { |
208 assert(flag_number < flag_limit, "oob"); | 213 assert(flag_number < flag_limit, "oob"); |
209 return (_header._struct._flags & (0x1 << flag_number)) != 0; | 214 return (_header._struct._flags & (0x1 << flag_number)) != 0; |
210 } | 215 } |
211 | 216 |
212 // Low-level support for code generation. | 217 // Low-level support for code generation. |
255 class ProfileData; | 260 class ProfileData; |
256 class BitData; | 261 class BitData; |
257 class CounterData; | 262 class CounterData; |
258 class ReceiverTypeData; | 263 class ReceiverTypeData; |
259 class VirtualCallData; | 264 class VirtualCallData; |
265 class VirtualCallTypeData; | |
260 class RetData; | 266 class RetData; |
267 class CallTypeData; | |
261 class JumpData; | 268 class JumpData; |
262 class BranchData; | 269 class BranchData; |
263 class ArrayData; | 270 class ArrayData; |
264 class MultiBranchData; | 271 class MultiBranchData; |
265 class ArgInfoData; | 272 class ArgInfoData; |
266 | 273 class ParametersTypeData; |
267 | 274 |
268 // ProfileData | 275 // ProfileData |
269 // | 276 // |
270 // A ProfileData object is created to refer to a section of profiling | 277 // A ProfileData object is created to refer to a section of profiling |
271 // data in a structured way. | 278 // data in a structured way. |
272 class ProfileData : public ResourceObj { | 279 class ProfileData : public ResourceObj { |
280 friend class TypeEntries; | |
281 friend class ReturnTypeEntry; | |
282 friend class TypeStackSlotEntries; | |
273 private: | 283 private: |
274 #ifndef PRODUCT | 284 #ifndef PRODUCT |
275 enum { | 285 enum { |
276 tab_width_one = 16, | 286 tab_width_one = 16, |
277 tab_width_two = 36 | 287 tab_width_two = 36 |
281 // This is a pointer to a section of profiling data. | 291 // This is a pointer to a section of profiling data. |
282 DataLayout* _data; | 292 DataLayout* _data; |
283 | 293 |
284 protected: | 294 protected: |
285 DataLayout* data() { return _data; } | 295 DataLayout* data() { return _data; } |
296 const DataLayout* data() const { return _data; } | |
286 | 297 |
287 enum { | 298 enum { |
288 cell_size = DataLayout::cell_size | 299 cell_size = DataLayout::cell_size |
289 }; | 300 }; |
290 | 301 |
291 public: | 302 public: |
292 // How many cells are in this? | 303 // How many cells are in this? |
293 virtual int cell_count() { | 304 virtual int cell_count() const { |
294 ShouldNotReachHere(); | 305 ShouldNotReachHere(); |
295 return -1; | 306 return -1; |
296 } | 307 } |
297 | 308 |
298 // Return the size of this data. | 309 // Return the size of this data. |
308 } | 319 } |
309 void release_set_intptr_at(int index, intptr_t value) { | 320 void release_set_intptr_at(int index, intptr_t value) { |
310 assert(0 <= index && index < cell_count(), "oob"); | 321 assert(0 <= index && index < cell_count(), "oob"); |
311 data()->release_set_cell_at(index, value); | 322 data()->release_set_cell_at(index, value); |
312 } | 323 } |
313 intptr_t intptr_at(int index) { | 324 intptr_t intptr_at(int index) const { |
314 assert(0 <= index && index < cell_count(), "oob"); | 325 assert(0 <= index && index < cell_count(), "oob"); |
315 return data()->cell_at(index); | 326 return data()->cell_at(index); |
316 } | 327 } |
317 void set_uint_at(int index, uint value) { | 328 void set_uint_at(int index, uint value) { |
318 set_intptr_at(index, (intptr_t) value); | 329 set_intptr_at(index, (intptr_t) value); |
319 } | 330 } |
320 void release_set_uint_at(int index, uint value) { | 331 void release_set_uint_at(int index, uint value) { |
321 release_set_intptr_at(index, (intptr_t) value); | 332 release_set_intptr_at(index, (intptr_t) value); |
322 } | 333 } |
323 uint uint_at(int index) { | 334 uint uint_at(int index) const { |
324 return (uint)intptr_at(index); | 335 return (uint)intptr_at(index); |
325 } | 336 } |
326 void set_int_at(int index, int value) { | 337 void set_int_at(int index, int value) { |
327 set_intptr_at(index, (intptr_t) value); | 338 set_intptr_at(index, (intptr_t) value); |
328 } | 339 } |
329 void release_set_int_at(int index, int value) { | 340 void release_set_int_at(int index, int value) { |
330 release_set_intptr_at(index, (intptr_t) value); | 341 release_set_intptr_at(index, (intptr_t) value); |
331 } | 342 } |
332 int int_at(int index) { | 343 int int_at(int index) const { |
333 return (int)intptr_at(index); | 344 return (int)intptr_at(index); |
334 } | 345 } |
335 int int_at_unchecked(int index) { | 346 int int_at_unchecked(int index) const { |
336 return (int)data()->cell_at(index); | 347 return (int)data()->cell_at(index); |
337 } | 348 } |
338 void set_oop_at(int index, oop value) { | 349 void set_oop_at(int index, oop value) { |
339 set_intptr_at(index, (intptr_t) value); | 350 set_intptr_at(index, cast_from_oop<intptr_t>(value)); |
340 } | 351 } |
341 oop oop_at(int index) { | 352 oop oop_at(int index) const { |
342 return (oop)intptr_at(index); | 353 return cast_to_oop(intptr_at(index)); |
343 } | 354 } |
344 | 355 |
345 void set_flag_at(int flag_number) { | 356 void set_flag_at(int flag_number) { |
346 data()->set_flag_at(flag_number); | 357 data()->set_flag_at(flag_number); |
347 } | 358 } |
348 bool flag_at(int flag_number) { | 359 bool flag_at(int flag_number) const { |
349 return data()->flag_at(flag_number); | 360 return data()->flag_at(flag_number); |
350 } | 361 } |
351 | 362 |
352 // two convenient imports for use by subclasses: | 363 // two convenient imports for use by subclasses: |
353 static ByteSize cell_offset(int index) { | 364 static ByteSize cell_offset(int index) { |
398 | 409 |
399 public: | 410 public: |
400 // Constructor for invalid ProfileData. | 411 // Constructor for invalid ProfileData. |
401 ProfileData(); | 412 ProfileData(); |
402 | 413 |
403 u2 bci() { | 414 u2 bci() const { |
404 return data()->bci(); | 415 return data()->bci(); |
405 } | 416 } |
406 | 417 |
407 address dp() { | 418 address dp() { |
408 return (address)_data; | 419 return (address)_data; |
409 } | 420 } |
410 | 421 |
411 int trap_state() { | 422 int trap_state() const { |
412 return data()->trap_state(); | 423 return data()->trap_state(); |
413 } | 424 } |
414 void set_trap_state(int new_state) { | 425 void set_trap_state(int new_state) { |
415 data()->set_trap_state(new_state); | 426 data()->set_trap_state(new_state); |
416 } | 427 } |
417 | 428 |
418 // Type checking | 429 // Type checking |
419 virtual bool is_BitData() { return false; } | 430 virtual bool is_BitData() const { return false; } |
420 virtual bool is_CounterData() { return false; } | 431 virtual bool is_CounterData() const { return false; } |
421 virtual bool is_JumpData() { return false; } | 432 virtual bool is_JumpData() const { return false; } |
422 virtual bool is_ReceiverTypeData(){ return false; } | 433 virtual bool is_ReceiverTypeData()const { return false; } |
423 virtual bool is_VirtualCallData() { return false; } | 434 virtual bool is_VirtualCallData() const { return false; } |
424 virtual bool is_RetData() { return false; } | 435 virtual bool is_RetData() const { return false; } |
425 virtual bool is_BranchData() { return false; } | 436 virtual bool is_BranchData() const { return false; } |
426 virtual bool is_ArrayData() { return false; } | 437 virtual bool is_ArrayData() const { return false; } |
427 virtual bool is_MultiBranchData() { return false; } | 438 virtual bool is_MultiBranchData() const { return false; } |
428 virtual bool is_ArgInfoData() { return false; } | 439 virtual bool is_ArgInfoData() const { return false; } |
429 | 440 virtual bool is_CallTypeData() const { return false; } |
430 | 441 virtual bool is_VirtualCallTypeData()const { return false; } |
431 BitData* as_BitData() { | 442 virtual bool is_ParametersTypeData() const { return false; } |
443 | |
444 | |
445 BitData* as_BitData() const { | |
432 assert(is_BitData(), "wrong type"); | 446 assert(is_BitData(), "wrong type"); |
433 return is_BitData() ? (BitData*) this : NULL; | 447 return is_BitData() ? (BitData*) this : NULL; |
434 } | 448 } |
435 CounterData* as_CounterData() { | 449 CounterData* as_CounterData() const { |
436 assert(is_CounterData(), "wrong type"); | 450 assert(is_CounterData(), "wrong type"); |
437 return is_CounterData() ? (CounterData*) this : NULL; | 451 return is_CounterData() ? (CounterData*) this : NULL; |
438 } | 452 } |
439 JumpData* as_JumpData() { | 453 JumpData* as_JumpData() const { |
440 assert(is_JumpData(), "wrong type"); | 454 assert(is_JumpData(), "wrong type"); |
441 return is_JumpData() ? (JumpData*) this : NULL; | 455 return is_JumpData() ? (JumpData*) this : NULL; |
442 } | 456 } |
443 ReceiverTypeData* as_ReceiverTypeData() { | 457 ReceiverTypeData* as_ReceiverTypeData() const { |
444 assert(is_ReceiverTypeData(), "wrong type"); | 458 assert(is_ReceiverTypeData(), "wrong type"); |
445 return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL; | 459 return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL; |
446 } | 460 } |
447 VirtualCallData* as_VirtualCallData() { | 461 VirtualCallData* as_VirtualCallData() const { |
448 assert(is_VirtualCallData(), "wrong type"); | 462 assert(is_VirtualCallData(), "wrong type"); |
449 return is_VirtualCallData() ? (VirtualCallData*)this : NULL; | 463 return is_VirtualCallData() ? (VirtualCallData*)this : NULL; |
450 } | 464 } |
451 RetData* as_RetData() { | 465 RetData* as_RetData() const { |
452 assert(is_RetData(), "wrong type"); | 466 assert(is_RetData(), "wrong type"); |
453 return is_RetData() ? (RetData*) this : NULL; | 467 return is_RetData() ? (RetData*) this : NULL; |
454 } | 468 } |
455 BranchData* as_BranchData() { | 469 BranchData* as_BranchData() const { |
456 assert(is_BranchData(), "wrong type"); | 470 assert(is_BranchData(), "wrong type"); |
457 return is_BranchData() ? (BranchData*) this : NULL; | 471 return is_BranchData() ? (BranchData*) this : NULL; |
458 } | 472 } |
459 ArrayData* as_ArrayData() { | 473 ArrayData* as_ArrayData() const { |
460 assert(is_ArrayData(), "wrong type"); | 474 assert(is_ArrayData(), "wrong type"); |
461 return is_ArrayData() ? (ArrayData*) this : NULL; | 475 return is_ArrayData() ? (ArrayData*) this : NULL; |
462 } | 476 } |
463 MultiBranchData* as_MultiBranchData() { | 477 MultiBranchData* as_MultiBranchData() const { |
464 assert(is_MultiBranchData(), "wrong type"); | 478 assert(is_MultiBranchData(), "wrong type"); |
465 return is_MultiBranchData() ? (MultiBranchData*)this : NULL; | 479 return is_MultiBranchData() ? (MultiBranchData*)this : NULL; |
466 } | 480 } |
467 ArgInfoData* as_ArgInfoData() { | 481 ArgInfoData* as_ArgInfoData() const { |
468 assert(is_ArgInfoData(), "wrong type"); | 482 assert(is_ArgInfoData(), "wrong type"); |
469 return is_ArgInfoData() ? (ArgInfoData*)this : NULL; | 483 return is_ArgInfoData() ? (ArgInfoData*)this : NULL; |
484 } | |
485 CallTypeData* as_CallTypeData() const { | |
486 assert(is_CallTypeData(), "wrong type"); | |
487 return is_CallTypeData() ? (CallTypeData*)this : NULL; | |
488 } | |
489 VirtualCallTypeData* as_VirtualCallTypeData() const { | |
490 assert(is_VirtualCallTypeData(), "wrong type"); | |
491 return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL; | |
492 } | |
493 ParametersTypeData* as_ParametersTypeData() const { | |
494 assert(is_ParametersTypeData(), "wrong type"); | |
495 return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL; | |
470 } | 496 } |
471 | 497 |
472 | 498 |
473 // Subclass specific initialization | 499 // Subclass specific initialization |
474 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} | 500 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} |
479 // CI translation: ProfileData can represent both MethodDataOop data | 505 // CI translation: ProfileData can represent both MethodDataOop data |
480 // as well as CIMethodData data. This function is provided for translating | 506 // as well as CIMethodData data. This function is provided for translating |
481 // an oop in a ProfileData to the ci equivalent. Generally speaking, | 507 // an oop in a ProfileData to the ci equivalent. Generally speaking, |
482 // most ProfileData don't require any translation, so we provide the null | 508 // most ProfileData don't require any translation, so we provide the null |
483 // translation here, and the required translators are in the ci subclasses. | 509 // translation here, and the required translators are in the ci subclasses. |
484 virtual void translate_from(ProfileData* data) {} | 510 virtual void translate_from(const ProfileData* data) {} |
485 | 511 |
486 virtual void print_data_on(outputStream* st) { | 512 virtual void print_data_on(outputStream* st) const { |
487 ShouldNotReachHere(); | 513 ShouldNotReachHere(); |
488 } | 514 } |
489 | 515 |
490 #ifndef PRODUCT | 516 #ifndef PRODUCT |
491 void print_shared(outputStream* st, const char* name); | 517 void print_shared(outputStream* st, const char* name) const; |
492 void tab(outputStream* st); | 518 void tab(outputStream* st, bool first = false) const; |
493 #endif | 519 #endif |
494 }; | 520 }; |
495 | 521 |
496 // BitData | 522 // BitData |
497 // | 523 // |
506 enum { bit_cell_count = 0 }; // no additional data fields needed. | 532 enum { bit_cell_count = 0 }; // no additional data fields needed. |
507 public: | 533 public: |
508 BitData(DataLayout* layout) : ProfileData(layout) { | 534 BitData(DataLayout* layout) : ProfileData(layout) { |
509 } | 535 } |
510 | 536 |
511 virtual bool is_BitData() { return true; } | 537 virtual bool is_BitData() const { return true; } |
512 | 538 |
513 static int static_cell_count() { | 539 static int static_cell_count() { |
514 return bit_cell_count; | 540 return bit_cell_count; |
515 } | 541 } |
516 | 542 |
517 virtual int cell_count() { | 543 virtual int cell_count() const { |
518 return static_cell_count(); | 544 return static_cell_count(); |
519 } | 545 } |
520 | 546 |
521 // Accessor | 547 // Accessor |
522 | 548 |
548 return (DataLayout*) (((address)layout) + (ssize_t)BitData::bit_data_size_in_bytes()); | 574 return (DataLayout*) (((address)layout) + (ssize_t)BitData::bit_data_size_in_bytes()); |
549 } | 575 } |
550 #endif // CC_INTERP | 576 #endif // CC_INTERP |
551 | 577 |
552 #ifndef PRODUCT | 578 #ifndef PRODUCT |
553 void print_data_on(outputStream* st); | 579 void print_data_on(outputStream* st) const; |
554 #endif | 580 #endif |
555 }; | 581 }; |
556 | 582 |
557 // CounterData | 583 // CounterData |
558 // | 584 // |
564 counter_cell_count | 590 counter_cell_count |
565 }; | 591 }; |
566 public: | 592 public: |
567 CounterData(DataLayout* layout) : BitData(layout) {} | 593 CounterData(DataLayout* layout) : BitData(layout) {} |
568 | 594 |
569 virtual bool is_CounterData() { return true; } | 595 virtual bool is_CounterData() const { return true; } |
570 | 596 |
571 static int static_cell_count() { | 597 static int static_cell_count() { |
572 return counter_cell_count; | 598 return counter_cell_count; |
573 } | 599 } |
574 | 600 |
575 virtual int cell_count() { | 601 virtual int cell_count() const { |
576 return static_cell_count(); | 602 return static_cell_count(); |
577 } | 603 } |
578 | 604 |
579 // Direct accessor | 605 // Direct accessor |
580 uint count() { | 606 uint count() const { |
581 return uint_at(count_off); | 607 return uint_at(count_off); |
582 } | 608 } |
583 | 609 |
584 // Code generation support | 610 // Code generation support |
585 static ByteSize count_offset() { | 611 static ByteSize count_offset() { |
611 return (DataLayout*) (((address)layout) + (ssize_t)CounterData::counter_data_size_in_bytes()); | 637 return (DataLayout*) (((address)layout) + (ssize_t)CounterData::counter_data_size_in_bytes()); |
612 } | 638 } |
613 #endif // CC_INTERP | 639 #endif // CC_INTERP |
614 | 640 |
615 #ifndef PRODUCT | 641 #ifndef PRODUCT |
616 void print_data_on(outputStream* st); | 642 void print_data_on(outputStream* st) const; |
617 #endif | 643 #endif |
618 }; | 644 }; |
619 | 645 |
620 // JumpData | 646 // JumpData |
621 // | 647 // |
639 JumpData(DataLayout* layout) : ProfileData(layout) { | 665 JumpData(DataLayout* layout) : ProfileData(layout) { |
640 assert(layout->tag() == DataLayout::jump_data_tag || | 666 assert(layout->tag() == DataLayout::jump_data_tag || |
641 layout->tag() == DataLayout::branch_data_tag, "wrong type"); | 667 layout->tag() == DataLayout::branch_data_tag, "wrong type"); |
642 } | 668 } |
643 | 669 |
644 virtual bool is_JumpData() { return true; } | 670 virtual bool is_JumpData() const { return true; } |
645 | 671 |
646 static int static_cell_count() { | 672 static int static_cell_count() { |
647 return jump_cell_count; | 673 return jump_cell_count; |
648 } | 674 } |
649 | 675 |
650 virtual int cell_count() { | 676 virtual int cell_count() const { |
651 return static_cell_count(); | 677 return static_cell_count(); |
652 } | 678 } |
653 | 679 |
654 // Direct accessor | 680 // Direct accessor |
655 uint taken() { | 681 uint taken() const { |
656 return uint_at(taken_off_set); | 682 return uint_at(taken_off_set); |
657 } | 683 } |
658 | 684 |
659 void set_taken(uint cnt) { | 685 void set_taken(uint cnt) { |
660 set_uint_at(taken_off_set, cnt); | 686 set_uint_at(taken_off_set, cnt); |
667 if (cnt == 0) cnt--; | 693 if (cnt == 0) cnt--; |
668 set_uint_at(taken_off_set, cnt); | 694 set_uint_at(taken_off_set, cnt); |
669 return cnt; | 695 return cnt; |
670 } | 696 } |
671 | 697 |
672 int displacement() { | 698 int displacement() const { |
673 return int_at(displacement_off_set); | 699 return int_at(displacement_off_set); |
674 } | 700 } |
675 | 701 |
676 // Code generation support | 702 // Code generation support |
677 static ByteSize taken_offset() { | 703 static ByteSize taken_offset() { |
698 | 724 |
699 // Specific initialization. | 725 // Specific initialization. |
700 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 726 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
701 | 727 |
702 #ifndef PRODUCT | 728 #ifndef PRODUCT |
703 void print_data_on(outputStream* st); | 729 void print_data_on(outputStream* st) const; |
730 #endif | |
731 }; | |
732 | |
733 // Entries in a ProfileData object to record types: it can either be | |
734 // none (no profile), unknown (conflicting profile data) or a klass if | |
735 // a single one is seen. Whether a null reference was seen is also | |
736 // recorded. No counter is associated with the type and a single type | |
737 // is tracked (unlike VirtualCallData). | |
738 class TypeEntries { | |
739 | |
740 public: | |
741 | |
742 // A single cell is used to record information for a type: | |
743 // - the cell is initialized to 0 | |
744 // - when a type is discovered it is stored in the cell | |
745 // - bit zero of the cell is used to record whether a null reference | |
746 // was encountered or not | |
747 // - bit 1 is set to record a conflict in the type information | |
748 | |
749 enum { | |
750 null_seen = 1, | |
751 type_mask = ~null_seen, | |
752 type_unknown = 2, | |
753 status_bits = null_seen | type_unknown, | |
754 type_klass_mask = ~status_bits | |
755 }; | |
756 | |
757 // what to initialize a cell to | |
758 static intptr_t type_none() { | |
759 return 0; | |
760 } | |
761 | |
762 // null seen = bit 0 set? | |
763 static bool was_null_seen(intptr_t v) { | |
764 return (v & null_seen) != 0; | |
765 } | |
766 | |
767 // conflicting type information = bit 1 set? | |
768 static bool is_type_unknown(intptr_t v) { | |
769 return (v & type_unknown) != 0; | |
770 } | |
771 | |
772 // not type information yet = all bits cleared, ignoring bit 0? | |
773 static bool is_type_none(intptr_t v) { | |
774 return (v & type_mask) == 0; | |
775 } | |
776 | |
777 // recorded type: cell without bit 0 and 1 | |
778 static intptr_t klass_part(intptr_t v) { | |
779 intptr_t r = v & type_klass_mask; | |
780 assert (r != 0, "invalid"); | |
781 return r; | |
782 } | |
783 | |
784 // type recorded | |
785 static Klass* valid_klass(intptr_t k) { | |
786 if (!is_type_none(k) && | |
787 !is_type_unknown(k)) { | |
788 return (Klass*)klass_part(k); | |
789 } else { | |
790 return NULL; | |
791 } | |
792 } | |
793 | |
794 static intptr_t with_status(intptr_t k, intptr_t in) { | |
795 return k | (in & status_bits); | |
796 } | |
797 | |
798 static intptr_t with_status(Klass* k, intptr_t in) { | |
799 return with_status((intptr_t)k, in); | |
800 } | |
801 | |
802 #ifndef PRODUCT | |
803 static void print_klass(outputStream* st, intptr_t k); | |
804 #endif | |
805 | |
806 // GC support | |
807 static bool is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p); | |
808 | |
809 protected: | |
810 // ProfileData object these entries are part of | |
811 ProfileData* _pd; | |
812 // offset within the ProfileData object where the entries start | |
813 const int _base_off; | |
814 | |
815 TypeEntries(int base_off) | |
816 : _base_off(base_off), _pd(NULL) {} | |
817 | |
818 void set_intptr_at(int index, intptr_t value) { | |
819 _pd->set_intptr_at(index, value); | |
820 } | |
821 | |
822 intptr_t intptr_at(int index) const { | |
823 return _pd->intptr_at(index); | |
824 } | |
825 | |
826 public: | |
827 void set_profile_data(ProfileData* pd) { | |
828 _pd = pd; | |
829 } | |
830 }; | |
831 | |
832 // Type entries used for arguments passed at a call and parameters on | |
833 // method entry. 2 cells per entry: one for the type encoded as in | |
834 // TypeEntries and one initialized with the stack slot where the | |
835 // profiled object is to be found so that the interpreter can locate | |
836 // it quickly. | |
837 class TypeStackSlotEntries : public TypeEntries { | |
838 | |
839 private: | |
840 enum { | |
841 stack_slot_entry, | |
842 type_entry, | |
843 per_arg_cell_count | |
844 }; | |
845 | |
846 // offset of cell for stack slot for entry i within ProfileData object | |
847 int stack_slot_offset(int i) const { | |
848 return _base_off + stack_slot_local_offset(i); | |
849 } | |
850 | |
851 protected: | |
852 const int _number_of_entries; | |
853 | |
854 // offset of cell for type for entry i within ProfileData object | |
855 int type_offset(int i) const { | |
856 return _base_off + type_local_offset(i); | |
857 } | |
858 | |
859 public: | |
860 | |
861 TypeStackSlotEntries(int base_off, int nb_entries) | |
862 : TypeEntries(base_off), _number_of_entries(nb_entries) {} | |
863 | |
864 static int compute_cell_count(Symbol* signature, bool include_receiver, int max); | |
865 | |
866 void post_initialize(Symbol* signature, bool has_receiver, bool include_receiver); | |
867 | |
868 // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries | |
869 static int stack_slot_local_offset(int i) { | |
870 return i * per_arg_cell_count + stack_slot_entry; | |
871 } | |
872 | |
873 // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries | |
874 static int type_local_offset(int i) { | |
875 return i * per_arg_cell_count + type_entry; | |
876 } | |
877 | |
878 // stack slot for entry i | |
879 uint stack_slot(int i) const { | |
880 assert(i >= 0 && i < _number_of_entries, "oob"); | |
881 return _pd->uint_at(stack_slot_offset(i)); | |
882 } | |
883 | |
884 // set stack slot for entry i | |
885 void set_stack_slot(int i, uint num) { | |
886 assert(i >= 0 && i < _number_of_entries, "oob"); | |
887 _pd->set_uint_at(stack_slot_offset(i), num); | |
888 } | |
889 | |
890 // type for entry i | |
891 intptr_t type(int i) const { | |
892 assert(i >= 0 && i < _number_of_entries, "oob"); | |
893 return _pd->intptr_at(type_offset(i)); | |
894 } | |
895 | |
896 // set type for entry i | |
897 void set_type(int i, intptr_t k) { | |
898 assert(i >= 0 && i < _number_of_entries, "oob"); | |
899 _pd->set_intptr_at(type_offset(i), k); | |
900 } | |
901 | |
902 static ByteSize per_arg_size() { | |
903 return in_ByteSize(per_arg_cell_count * DataLayout::cell_size); | |
904 } | |
905 | |
906 static int per_arg_count() { | |
907 return per_arg_cell_count ; | |
908 } | |
909 | |
910 // GC support | |
911 void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); | |
912 | |
913 #ifndef PRODUCT | |
914 void print_data_on(outputStream* st) const; | |
915 #endif | |
916 }; | |
917 | |
918 // Type entry used for return from a call. A single cell to record the | |
919 // type. | |
920 class ReturnTypeEntry : public TypeEntries { | |
921 | |
922 private: | |
923 enum { | |
924 cell_count = 1 | |
925 }; | |
926 | |
927 public: | |
928 ReturnTypeEntry(int base_off) | |
929 : TypeEntries(base_off) {} | |
930 | |
931 void post_initialize() { | |
932 set_type(type_none()); | |
933 } | |
934 | |
935 intptr_t type() const { | |
936 return _pd->intptr_at(_base_off); | |
937 } | |
938 | |
939 void set_type(intptr_t k) { | |
940 _pd->set_intptr_at(_base_off, k); | |
941 } | |
942 | |
943 static int static_cell_count() { | |
944 return cell_count; | |
945 } | |
946 | |
947 static ByteSize size() { | |
948 return in_ByteSize(cell_count * DataLayout::cell_size); | |
949 } | |
950 | |
951 ByteSize type_offset() { | |
952 return DataLayout::cell_offset(_base_off); | |
953 } | |
954 | |
955 // GC support | |
956 void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); | |
957 | |
958 #ifndef PRODUCT | |
959 void print_data_on(outputStream* st) const; | |
960 #endif | |
961 }; | |
962 | |
963 // Entries to collect type information at a call: contains arguments | |
964 // (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a | |
965 // number of cells. Because the number of cells for the return type is | |
966 // smaller than the number of cells for the type of an arguments, the | |
967 // number of cells is used to tell how many arguments are profiled and | |
968 // whether a return value is profiled. See has_arguments() and | |
969 // has_return(). | |
970 class TypeEntriesAtCall { | |
971 private: | |
972 static int stack_slot_local_offset(int i) { | |
973 return header_cell_count() + TypeStackSlotEntries::stack_slot_local_offset(i); | |
974 } | |
975 | |
976 static int argument_type_local_offset(int i) { | |
977 return header_cell_count() + TypeStackSlotEntries::type_local_offset(i);; | |
978 } | |
979 | |
980 public: | |
981 | |
982 static int header_cell_count() { | |
983 return 1; | |
984 } | |
985 | |
986 static int cell_count_local_offset() { | |
987 return 0; | |
988 } | |
989 | |
990 static int compute_cell_count(BytecodeStream* stream); | |
991 | |
992 static void initialize(DataLayout* dl, int base, int cell_count) { | |
993 int off = base + cell_count_local_offset(); | |
994 dl->set_cell_at(off, cell_count - base - header_cell_count()); | |
995 } | |
996 | |
997 static bool arguments_profiling_enabled(); | |
998 static bool return_profiling_enabled(); | |
999 | |
1000 // Code generation support | |
1001 static ByteSize cell_count_offset() { | |
1002 return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size); | |
1003 } | |
1004 | |
1005 static ByteSize args_data_offset() { | |
1006 return in_ByteSize(header_cell_count() * DataLayout::cell_size); | |
1007 } | |
1008 | |
1009 static ByteSize stack_slot_offset(int i) { | |
1010 return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size); | |
1011 } | |
1012 | |
1013 static ByteSize argument_type_offset(int i) { | |
1014 return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size); | |
1015 } | |
1016 }; | |
1017 | |
1018 // CallTypeData | |
1019 // | |
1020 // A CallTypeData is used to access profiling information about a non | |
1021 // virtual call for which we collect type information about arguments | |
1022 // and return value. | |
1023 class CallTypeData : public CounterData { | |
1024 private: | |
1025 // entries for arguments if any | |
1026 TypeStackSlotEntries _args; | |
1027 // entry for return type if any | |
1028 ReturnTypeEntry _ret; | |
1029 | |
1030 int cell_count_global_offset() const { | |
1031 return CounterData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset(); | |
1032 } | |
1033 | |
1034 // number of cells not counting the header | |
1035 int cell_count_no_header() const { | |
1036 return uint_at(cell_count_global_offset()); | |
1037 } | |
1038 | |
1039 void check_number_of_arguments(int total) { | |
1040 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); | |
1041 } | |
1042 | |
1043 public: | |
1044 CallTypeData(DataLayout* layout) : | |
1045 CounterData(layout), | |
1046 _args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), | |
1047 _ret(cell_count() - ReturnTypeEntry::static_cell_count()) | |
1048 { | |
1049 assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type"); | |
1050 // Some compilers (VC++) don't want this passed in member initialization list | |
1051 _args.set_profile_data(this); | |
1052 _ret.set_profile_data(this); | |
1053 } | |
1054 | |
1055 const TypeStackSlotEntries* args() const { | |
1056 assert(has_arguments(), "no profiling of arguments"); | |
1057 return &_args; | |
1058 } | |
1059 | |
1060 const ReturnTypeEntry* ret() const { | |
1061 assert(has_return(), "no profiling of return value"); | |
1062 return &_ret; | |
1063 } | |
1064 | |
1065 virtual bool is_CallTypeData() const { return true; } | |
1066 | |
1067 static int static_cell_count() { | |
1068 return -1; | |
1069 } | |
1070 | |
1071 static int compute_cell_count(BytecodeStream* stream) { | |
1072 return CounterData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream); | |
1073 } | |
1074 | |
1075 static void initialize(DataLayout* dl, int cell_count) { | |
1076 TypeEntriesAtCall::initialize(dl, CounterData::static_cell_count(), cell_count); | |
1077 } | |
1078 | |
1079 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); | |
1080 | |
1081 virtual int cell_count() const { | |
1082 return CounterData::static_cell_count() + | |
1083 TypeEntriesAtCall::header_cell_count() + | |
1084 int_at_unchecked(cell_count_global_offset()); | |
1085 } | |
1086 | |
1087 int number_of_arguments() const { | |
1088 return cell_count_no_header() / TypeStackSlotEntries::per_arg_count(); | |
1089 } | |
1090 | |
1091 void set_argument_type(int i, Klass* k) { | |
1092 assert(has_arguments(), "no arguments!"); | |
1093 intptr_t current = _args.type(i); | |
1094 _args.set_type(i, TypeEntries::with_status(k, current)); | |
1095 } | |
1096 | |
1097 void set_return_type(Klass* k) { | |
1098 assert(has_return(), "no return!"); | |
1099 intptr_t current = _ret.type(); | |
1100 _ret.set_type(TypeEntries::with_status(k, current)); | |
1101 } | |
1102 | |
1103 // An entry for a return value takes less space than an entry for an | |
1104 // argument so if the number of cells exceeds the number of cells | |
1105 // needed for an argument, this object contains type information for | |
1106 // at least one argument. | |
1107 bool has_arguments() const { | |
1108 bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); | |
1109 assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); | |
1110 return res; | |
1111 } | |
1112 | |
1113 // An entry for a return value takes less space than an entry for an | |
1114 // argument, so if the remainder of the number of cells divided by | |
1115 // the number of cells for an argument is not null, a return value | |
1116 // is profiled in this object. | |
1117 bool has_return() const { | |
1118 bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; | |
1119 assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); | |
1120 return res; | |
1121 } | |
1122 | |
1123 // Code generation support | |
1124 static ByteSize args_data_offset() { | |
1125 return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); | |
1126 } | |
1127 | |
1128 // GC support | |
1129 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { | |
1130 if (has_arguments()) { | |
1131 _args.clean_weak_klass_links(is_alive_closure); | |
1132 } | |
1133 if (has_return()) { | |
1134 _ret.clean_weak_klass_links(is_alive_closure); | |
1135 } | |
1136 } | |
1137 | |
1138 #ifndef PRODUCT | |
1139 virtual void print_data_on(outputStream* st) const; | |
704 #endif | 1140 #endif |
705 }; | 1141 }; |
706 | 1142 |
707 // ReceiverTypeData | 1143 // ReceiverTypeData |
708 // | 1144 // |
719 }; | 1155 }; |
720 | 1156 |
721 public: | 1157 public: |
722 ReceiverTypeData(DataLayout* layout) : CounterData(layout) { | 1158 ReceiverTypeData(DataLayout* layout) : CounterData(layout) { |
723 assert(layout->tag() == DataLayout::receiver_type_data_tag || | 1159 assert(layout->tag() == DataLayout::receiver_type_data_tag || |
724 layout->tag() == DataLayout::virtual_call_data_tag, "wrong type"); | 1160 layout->tag() == DataLayout::virtual_call_data_tag || |
725 } | 1161 layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); |
726 | 1162 } |
727 virtual bool is_ReceiverTypeData() { return true; } | 1163 |
1164 virtual bool is_ReceiverTypeData() const { return true; } | |
728 | 1165 |
729 static int static_cell_count() { | 1166 static int static_cell_count() { |
730 return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count; | 1167 return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count; |
731 } | 1168 } |
732 | 1169 |
733 virtual int cell_count() { | 1170 virtual int cell_count() const { |
734 return static_cell_count(); | 1171 return static_cell_count(); |
735 } | 1172 } |
736 | 1173 |
737 // Direct accessors | 1174 // Direct accessors |
738 static uint row_limit() { | 1175 static uint row_limit() { |
743 } | 1180 } |
744 static int receiver_count_cell_index(uint row) { | 1181 static int receiver_count_cell_index(uint row) { |
745 return count0_offset + row * receiver_type_row_cell_count; | 1182 return count0_offset + row * receiver_type_row_cell_count; |
746 } | 1183 } |
747 | 1184 |
748 Klass* receiver(uint row) { | 1185 Klass* receiver(uint row) const { |
749 assert(row < row_limit(), "oob"); | 1186 assert(row < row_limit(), "oob"); |
750 | 1187 |
751 Klass* recv = (Klass*)intptr_at(receiver_cell_index(row)); | 1188 Klass* recv = (Klass*)intptr_at(receiver_cell_index(row)); |
752 assert(recv == NULL || recv->is_klass(), "wrong type"); | 1189 assert(recv == NULL || recv->is_klass(), "wrong type"); |
753 return recv; | 1190 return recv; |
756 void set_receiver(uint row, Klass* k) { | 1193 void set_receiver(uint row, Klass* k) { |
757 assert((uint)row < row_limit(), "oob"); | 1194 assert((uint)row < row_limit(), "oob"); |
758 set_intptr_at(receiver_cell_index(row), (uintptr_t)k); | 1195 set_intptr_at(receiver_cell_index(row), (uintptr_t)k); |
759 } | 1196 } |
760 | 1197 |
761 uint receiver_count(uint row) { | 1198 uint receiver_count(uint row) const { |
762 assert(row < row_limit(), "oob"); | 1199 assert(row < row_limit(), "oob"); |
763 return uint_at(receiver_count_cell_index(row)); | 1200 return uint_at(receiver_count_cell_index(row)); |
764 } | 1201 } |
765 | 1202 |
766 void set_receiver_count(uint row, uint count) { | 1203 void set_receiver_count(uint row, uint count) { |
841 return (DataLayout*) (((address)layout) + (ssize_t)ReceiverTypeData::receiver_type_data_size_in_bytes()); | 1278 return (DataLayout*) (((address)layout) + (ssize_t)ReceiverTypeData::receiver_type_data_size_in_bytes()); |
842 } | 1279 } |
843 #endif // CC_INTERP | 1280 #endif // CC_INTERP |
844 | 1281 |
845 #ifndef PRODUCT | 1282 #ifndef PRODUCT |
846 void print_receiver_data_on(outputStream* st); | 1283 void print_receiver_data_on(outputStream* st) const; |
847 void print_data_on(outputStream* st); | 1284 void print_data_on(outputStream* st) const; |
848 #endif | 1285 #endif |
849 }; | 1286 }; |
850 | 1287 |
851 // VirtualCallData | 1288 // VirtualCallData |
852 // | 1289 // |
853 // A VirtualCallData is used to access profiling information about a | 1290 // A VirtualCallData is used to access profiling information about a |
854 // virtual call. For now, it has nothing more than a ReceiverTypeData. | 1291 // virtual call. For now, it has nothing more than a ReceiverTypeData. |
855 class VirtualCallData : public ReceiverTypeData { | 1292 class VirtualCallData : public ReceiverTypeData { |
856 public: | 1293 public: |
857 VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) { | 1294 VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) { |
858 assert(layout->tag() == DataLayout::virtual_call_data_tag, "wrong type"); | 1295 assert(layout->tag() == DataLayout::virtual_call_data_tag || |
859 } | 1296 layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); |
860 | 1297 } |
861 virtual bool is_VirtualCallData() { return true; } | 1298 |
1299 virtual bool is_VirtualCallData() const { return true; } | |
862 | 1300 |
863 static int static_cell_count() { | 1301 static int static_cell_count() { |
864 // At this point we could add more profile state, e.g., for arguments. | 1302 // At this point we could add more profile state, e.g., for arguments. |
865 // But for now it's the same size as the base record type. | 1303 // But for now it's the same size as the base record type. |
866 return ReceiverTypeData::static_cell_count(); | 1304 return ReceiverTypeData::static_cell_count(); |
867 } | 1305 } |
868 | 1306 |
869 virtual int cell_count() { | 1307 virtual int cell_count() const { |
870 return static_cell_count(); | 1308 return static_cell_count(); |
871 } | 1309 } |
872 | 1310 |
873 // Direct accessors | 1311 // Direct accessors |
874 static ByteSize virtual_call_data_size() { | 1312 static ByteSize virtual_call_data_size() { |
884 return (DataLayout*) (((address)layout) + (ssize_t)VirtualCallData::virtual_call_data_size_in_bytes()); | 1322 return (DataLayout*) (((address)layout) + (ssize_t)VirtualCallData::virtual_call_data_size_in_bytes()); |
885 } | 1323 } |
886 #endif // CC_INTERP | 1324 #endif // CC_INTERP |
887 | 1325 |
888 #ifndef PRODUCT | 1326 #ifndef PRODUCT |
889 void print_data_on(outputStream* st); | 1327 void print_data_on(outputStream* st) const; |
1328 #endif | |
1329 }; | |
1330 | |
1331 // VirtualCallTypeData | |
1332 // | |
1333 // A VirtualCallTypeData is used to access profiling information about | |
1334 // a virtual call for which we collect type information about | |
1335 // arguments and return value. | |
1336 class VirtualCallTypeData : public VirtualCallData { | |
1337 private: | |
1338 // entries for arguments if any | |
1339 TypeStackSlotEntries _args; | |
1340 // entry for return type if any | |
1341 ReturnTypeEntry _ret; | |
1342 | |
1343 int cell_count_global_offset() const { | |
1344 return VirtualCallData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset(); | |
1345 } | |
1346 | |
1347 // number of cells not counting the header | |
1348 int cell_count_no_header() const { | |
1349 return uint_at(cell_count_global_offset()); | |
1350 } | |
1351 | |
1352 void check_number_of_arguments(int total) { | |
1353 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); | |
1354 } | |
1355 | |
1356 public: | |
1357 VirtualCallTypeData(DataLayout* layout) : | |
1358 VirtualCallData(layout), | |
1359 _args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), | |
1360 _ret(cell_count() - ReturnTypeEntry::static_cell_count()) | |
1361 { | |
1362 assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); | |
1363 // Some compilers (VC++) don't want this passed in member initialization list | |
1364 _args.set_profile_data(this); | |
1365 _ret.set_profile_data(this); | |
1366 } | |
1367 | |
1368 const TypeStackSlotEntries* args() const { | |
1369 assert(has_arguments(), "no profiling of arguments"); | |
1370 return &_args; | |
1371 } | |
1372 | |
1373 const ReturnTypeEntry* ret() const { | |
1374 assert(has_return(), "no profiling of return value"); | |
1375 return &_ret; | |
1376 } | |
1377 | |
1378 virtual bool is_VirtualCallTypeData() const { return true; } | |
1379 | |
1380 static int static_cell_count() { | |
1381 return -1; | |
1382 } | |
1383 | |
1384 static int compute_cell_count(BytecodeStream* stream) { | |
1385 return VirtualCallData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream); | |
1386 } | |
1387 | |
1388 static void initialize(DataLayout* dl, int cell_count) { | |
1389 TypeEntriesAtCall::initialize(dl, VirtualCallData::static_cell_count(), cell_count); | |
1390 } | |
1391 | |
1392 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); | |
1393 | |
1394 virtual int cell_count() const { | |
1395 return VirtualCallData::static_cell_count() + | |
1396 TypeEntriesAtCall::header_cell_count() + | |
1397 int_at_unchecked(cell_count_global_offset()); | |
1398 } | |
1399 | |
1400 int number_of_arguments() const { | |
1401 return cell_count_no_header() / TypeStackSlotEntries::per_arg_count(); | |
1402 } | |
1403 | |
1404 void set_argument_type(int i, Klass* k) { | |
1405 assert(has_arguments(), "no arguments!"); | |
1406 intptr_t current = _args.type(i); | |
1407 _args.set_type(i, TypeEntries::with_status(k, current)); | |
1408 } | |
1409 | |
1410 void set_return_type(Klass* k) { | |
1411 assert(has_return(), "no return!"); | |
1412 intptr_t current = _ret.type(); | |
1413 _ret.set_type(TypeEntries::with_status(k, current)); | |
1414 } | |
1415 | |
1416 // An entry for a return value takes less space than an entry for an | |
1417 // argument, so if the remainder of the number of cells divided by | |
1418 // the number of cells for an argument is not null, a return value | |
1419 // is profiled in this object. | |
1420 bool has_return() const { | |
1421 bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; | |
1422 assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); | |
1423 return res; | |
1424 } | |
1425 | |
1426 // An entry for a return value takes less space than an entry for an | |
1427 // argument so if the number of cells exceeds the number of cells | |
1428 // needed for an argument, this object contains type information for | |
1429 // at least one argument. | |
1430 bool has_arguments() const { | |
1431 bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); | |
1432 assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); | |
1433 return res; | |
1434 } | |
1435 | |
1436 // Code generation support | |
1437 static ByteSize args_data_offset() { | |
1438 return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); | |
1439 } | |
1440 | |
1441 // GC support | |
1442 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { | |
1443 ReceiverTypeData::clean_weak_klass_links(is_alive_closure); | |
1444 if (has_arguments()) { | |
1445 _args.clean_weak_klass_links(is_alive_closure); | |
1446 } | |
1447 if (has_return()) { | |
1448 _ret.clean_weak_klass_links(is_alive_closure); | |
1449 } | |
1450 } | |
1451 | |
1452 #ifndef PRODUCT | |
1453 virtual void print_data_on(outputStream* st) const; | |
890 #endif | 1454 #endif |
891 }; | 1455 }; |
892 | 1456 |
893 // RetData | 1457 // RetData |
894 // | 1458 // |
927 public: | 1491 public: |
928 RetData(DataLayout* layout) : CounterData(layout) { | 1492 RetData(DataLayout* layout) : CounterData(layout) { |
929 assert(layout->tag() == DataLayout::ret_data_tag, "wrong type"); | 1493 assert(layout->tag() == DataLayout::ret_data_tag, "wrong type"); |
930 } | 1494 } |
931 | 1495 |
932 virtual bool is_RetData() { return true; } | 1496 virtual bool is_RetData() const { return true; } |
933 | 1497 |
934 enum { | 1498 enum { |
935 no_bci = -1 // value of bci when bci1/2 are not in use. | 1499 no_bci = -1 // value of bci when bci1/2 are not in use. |
936 }; | 1500 }; |
937 | 1501 |
938 static int static_cell_count() { | 1502 static int static_cell_count() { |
939 return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count; | 1503 return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count; |
940 } | 1504 } |
941 | 1505 |
942 virtual int cell_count() { | 1506 virtual int cell_count() const { |
943 return static_cell_count(); | 1507 return static_cell_count(); |
944 } | 1508 } |
945 | 1509 |
946 static uint row_limit() { | 1510 static uint row_limit() { |
947 return BciProfileWidth; | 1511 return BciProfileWidth; |
955 static int bci_displacement_cell_index(uint row) { | 1519 static int bci_displacement_cell_index(uint row) { |
956 return displacement0_offset + row * ret_row_cell_count; | 1520 return displacement0_offset + row * ret_row_cell_count; |
957 } | 1521 } |
958 | 1522 |
959 // Direct accessors | 1523 // Direct accessors |
960 int bci(uint row) { | 1524 int bci(uint row) const { |
961 return int_at(bci_cell_index(row)); | 1525 return int_at(bci_cell_index(row)); |
962 } | 1526 } |
963 uint bci_count(uint row) { | 1527 uint bci_count(uint row) const { |
964 return uint_at(bci_count_cell_index(row)); | 1528 return uint_at(bci_count_cell_index(row)); |
965 } | 1529 } |
966 int bci_displacement(uint row) { | 1530 int bci_displacement(uint row) const { |
967 return int_at(bci_displacement_cell_index(row)); | 1531 return int_at(bci_displacement_cell_index(row)); |
968 } | 1532 } |
969 | 1533 |
970 // Interpreter Runtime support | 1534 // Interpreter Runtime support |
971 address fixup_ret(int return_bci, MethodData* mdo); | 1535 address fixup_ret(int return_bci, MethodData* mdo); |
987 | 1551 |
988 // Specific initialization. | 1552 // Specific initialization. |
989 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1553 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
990 | 1554 |
991 #ifndef PRODUCT | 1555 #ifndef PRODUCT |
992 void print_data_on(outputStream* st); | 1556 void print_data_on(outputStream* st) const; |
993 #endif | 1557 #endif |
994 }; | 1558 }; |
995 | 1559 |
996 // BranchData | 1560 // BranchData |
997 // | 1561 // |
1012 public: | 1576 public: |
1013 BranchData(DataLayout* layout) : JumpData(layout) { | 1577 BranchData(DataLayout* layout) : JumpData(layout) { |
1014 assert(layout->tag() == DataLayout::branch_data_tag, "wrong type"); | 1578 assert(layout->tag() == DataLayout::branch_data_tag, "wrong type"); |
1015 } | 1579 } |
1016 | 1580 |
1017 virtual bool is_BranchData() { return true; } | 1581 virtual bool is_BranchData() const { return true; } |
1018 | 1582 |
1019 static int static_cell_count() { | 1583 static int static_cell_count() { |
1020 return branch_cell_count; | 1584 return branch_cell_count; |
1021 } | 1585 } |
1022 | 1586 |
1023 virtual int cell_count() { | 1587 virtual int cell_count() const { |
1024 return static_cell_count(); | 1588 return static_cell_count(); |
1025 } | 1589 } |
1026 | 1590 |
1027 // Direct accessor | 1591 // Direct accessor |
1028 uint not_taken() { | 1592 uint not_taken() const { |
1029 return uint_at(not_taken_off_set); | 1593 return uint_at(not_taken_off_set); |
1030 } | 1594 } |
1031 | 1595 |
1032 void set_not_taken(uint cnt) { | 1596 void set_not_taken(uint cnt) { |
1033 set_uint_at(not_taken_off_set, cnt); | 1597 set_uint_at(not_taken_off_set, cnt); |
1065 | 1629 |
1066 // Specific initialization. | 1630 // Specific initialization. |
1067 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1631 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1068 | 1632 |
1069 #ifndef PRODUCT | 1633 #ifndef PRODUCT |
1070 void print_data_on(outputStream* st); | 1634 void print_data_on(outputStream* st) const; |
1071 #endif | 1635 #endif |
1072 }; | 1636 }; |
1073 | 1637 |
1074 // ArrayData | 1638 // ArrayData |
1075 // | 1639 // |
1083 enum { | 1647 enum { |
1084 array_len_off_set, | 1648 array_len_off_set, |
1085 array_start_off_set | 1649 array_start_off_set |
1086 }; | 1650 }; |
1087 | 1651 |
1088 uint array_uint_at(int index) { | 1652 uint array_uint_at(int index) const { |
1089 int aindex = index + array_start_off_set; | 1653 int aindex = index + array_start_off_set; |
1090 return uint_at(aindex); | 1654 return uint_at(aindex); |
1091 } | 1655 } |
1092 int array_int_at(int index) { | 1656 int array_int_at(int index) const { |
1093 int aindex = index + array_start_off_set; | 1657 int aindex = index + array_start_off_set; |
1094 return int_at(aindex); | 1658 return int_at(aindex); |
1095 } | 1659 } |
1096 oop array_oop_at(int index) { | 1660 oop array_oop_at(int index) const { |
1097 int aindex = index + array_start_off_set; | 1661 int aindex = index + array_start_off_set; |
1098 return oop_at(aindex); | 1662 return oop_at(aindex); |
1099 } | 1663 } |
1100 void array_set_int_at(int index, int value) { | 1664 void array_set_int_at(int index, int value) { |
1101 int aindex = index + array_start_off_set; | 1665 int aindex = index + array_start_off_set; |
1122 } | 1686 } |
1123 | 1687 |
1124 public: | 1688 public: |
1125 ArrayData(DataLayout* layout) : ProfileData(layout) {} | 1689 ArrayData(DataLayout* layout) : ProfileData(layout) {} |
1126 | 1690 |
1127 virtual bool is_ArrayData() { return true; } | 1691 virtual bool is_ArrayData() const { return true; } |
1128 | 1692 |
1129 static int static_cell_count() { | 1693 static int static_cell_count() { |
1130 return -1; | 1694 return -1; |
1131 } | 1695 } |
1132 | 1696 |
1133 int array_len() { | 1697 int array_len() const { |
1134 return int_at_unchecked(array_len_off_set); | 1698 return int_at_unchecked(array_len_off_set); |
1135 } | 1699 } |
1136 | 1700 |
1137 virtual int cell_count() { | 1701 virtual int cell_count() const { |
1138 return array_len() + 1; | 1702 return array_len() + 1; |
1139 } | 1703 } |
1140 | 1704 |
1141 // Code generation support | 1705 // Code generation support |
1142 static ByteSize array_len_offset() { | 1706 static ByteSize array_len_offset() { |
1179 public: | 1743 public: |
1180 MultiBranchData(DataLayout* layout) : ArrayData(layout) { | 1744 MultiBranchData(DataLayout* layout) : ArrayData(layout) { |
1181 assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type"); | 1745 assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type"); |
1182 } | 1746 } |
1183 | 1747 |
1184 virtual bool is_MultiBranchData() { return true; } | 1748 virtual bool is_MultiBranchData() const { return true; } |
1185 | 1749 |
1186 static int compute_cell_count(BytecodeStream* stream); | 1750 static int compute_cell_count(BytecodeStream* stream); |
1187 | 1751 |
1188 int number_of_cases() { | 1752 int number_of_cases() const { |
1189 int alen = array_len() - 2; // get rid of default case here. | 1753 int alen = array_len() - 2; // get rid of default case here. |
1190 assert(alen % per_case_cell_count == 0, "must be even"); | 1754 assert(alen % per_case_cell_count == 0, "must be even"); |
1191 return (alen / per_case_cell_count); | 1755 return (alen / per_case_cell_count); |
1192 } | 1756 } |
1193 | 1757 |
1194 uint default_count() { | 1758 uint default_count() const { |
1195 return array_uint_at(default_count_off_set); | 1759 return array_uint_at(default_count_off_set); |
1196 } | 1760 } |
1197 int default_displacement() { | 1761 int default_displacement() const { |
1198 return array_int_at(default_disaplacement_off_set); | 1762 return array_int_at(default_disaplacement_off_set); |
1199 } | 1763 } |
1200 | 1764 |
1201 uint count_at(int index) { | 1765 uint count_at(int index) const { |
1202 return array_uint_at(case_array_start + | 1766 return array_uint_at(case_array_start + |
1203 index * per_case_cell_count + | 1767 index * per_case_cell_count + |
1204 relative_count_off_set); | 1768 relative_count_off_set); |
1205 } | 1769 } |
1206 int displacement_at(int index) { | 1770 int displacement_at(int index) const { |
1207 return array_int_at(case_array_start + | 1771 return array_int_at(case_array_start + |
1208 index * per_case_cell_count + | 1772 index * per_case_cell_count + |
1209 relative_displacement_off_set); | 1773 relative_displacement_off_set); |
1210 } | 1774 } |
1211 | 1775 |
1258 | 1822 |
1259 // Specific initialization. | 1823 // Specific initialization. |
1260 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1824 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1261 | 1825 |
1262 #ifndef PRODUCT | 1826 #ifndef PRODUCT |
1263 void print_data_on(outputStream* st); | 1827 void print_data_on(outputStream* st) const; |
1264 #endif | 1828 #endif |
1265 }; | 1829 }; |
1266 | 1830 |
1267 class ArgInfoData : public ArrayData { | 1831 class ArgInfoData : public ArrayData { |
1268 | 1832 |
1269 public: | 1833 public: |
1270 ArgInfoData(DataLayout* layout) : ArrayData(layout) { | 1834 ArgInfoData(DataLayout* layout) : ArrayData(layout) { |
1271 assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type"); | 1835 assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type"); |
1272 } | 1836 } |
1273 | 1837 |
1274 virtual bool is_ArgInfoData() { return true; } | 1838 virtual bool is_ArgInfoData() const { return true; } |
1275 | 1839 |
1276 | 1840 |
1277 int number_of_args() { | 1841 int number_of_args() const { |
1278 return array_len(); | 1842 return array_len(); |
1279 } | 1843 } |
1280 | 1844 |
1281 uint arg_modified(int arg) { | 1845 uint arg_modified(int arg) const { |
1282 return array_uint_at(arg); | 1846 return array_uint_at(arg); |
1283 } | 1847 } |
1284 | 1848 |
1285 void set_arg_modified(int arg, uint val) { | 1849 void set_arg_modified(int arg, uint val) { |
1286 array_set_int_at(arg, val); | 1850 array_set_int_at(arg, val); |
1287 } | 1851 } |
1288 | 1852 |
1289 #ifndef PRODUCT | 1853 #ifndef PRODUCT |
1290 void print_data_on(outputStream* st); | 1854 void print_data_on(outputStream* st) const; |
1291 #endif | 1855 #endif |
1856 }; | |
1857 | |
1858 // ParametersTypeData | |
1859 // | |
1860 // A ParametersTypeData is used to access profiling information about | |
1861 // types of parameters to a method | |
1862 class ParametersTypeData : public ArrayData { | |
1863 | |
1864 private: | |
1865 TypeStackSlotEntries _parameters; | |
1866 | |
1867 static int stack_slot_local_offset(int i) { | |
1868 assert_profiling_enabled(); | |
1869 return array_start_off_set + TypeStackSlotEntries::stack_slot_local_offset(i); | |
1870 } | |
1871 | |
1872 static int type_local_offset(int i) { | |
1873 assert_profiling_enabled(); | |
1874 return array_start_off_set + TypeStackSlotEntries::type_local_offset(i); | |
1875 } | |
1876 | |
1877 static bool profiling_enabled(); | |
1878 static void assert_profiling_enabled() { | |
1879 assert(profiling_enabled(), "method parameters profiling should be on"); | |
1880 } | |
1881 | |
1882 public: | |
1883 ParametersTypeData(DataLayout* layout) : ArrayData(layout), _parameters(1, number_of_parameters()) { | |
1884 assert(layout->tag() == DataLayout::parameters_type_data_tag, "wrong type"); | |
1885 // Some compilers (VC++) don't want this passed in member initialization list | |
1886 _parameters.set_profile_data(this); | |
1887 } | |
1888 | |
1889 static int compute_cell_count(Method* m); | |
1890 | |
1891 virtual bool is_ParametersTypeData() const { return true; } | |
1892 | |
1893 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); | |
1894 | |
1895 int number_of_parameters() const { | |
1896 return array_len() / TypeStackSlotEntries::per_arg_count(); | |
1897 } | |
1898 | |
1899 const TypeStackSlotEntries* parameters() const { return &_parameters; } | |
1900 | |
1901 uint stack_slot(int i) const { | |
1902 return _parameters.stack_slot(i); | |
1903 } | |
1904 | |
1905 void set_type(int i, Klass* k) { | |
1906 intptr_t current = _parameters.type(i); | |
1907 _parameters.set_type(i, TypeEntries::with_status((intptr_t)k, current)); | |
1908 } | |
1909 | |
1910 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { | |
1911 _parameters.clean_weak_klass_links(is_alive_closure); | |
1912 } | |
1913 | |
1914 #ifndef PRODUCT | |
1915 virtual void print_data_on(outputStream* st) const; | |
1916 #endif | |
1917 | |
1918 static ByteSize stack_slot_offset(int i) { | |
1919 return cell_offset(stack_slot_local_offset(i)); | |
1920 } | |
1921 | |
1922 static ByteSize type_offset(int i) { | |
1923 return cell_offset(type_local_offset(i)); | |
1924 } | |
1292 }; | 1925 }; |
1293 | 1926 |
1294 // MethodData* | 1927 // MethodData* |
1295 // | 1928 // |
1296 // A MethodData* holds information which has been collected about | 1929 // A MethodData* holds information which has been collected about |
1403 bool _would_profile; | 2036 bool _would_profile; |
1404 | 2037 |
1405 // Size of _data array in bytes. (Excludes header and extra_data fields.) | 2038 // Size of _data array in bytes. (Excludes header and extra_data fields.) |
1406 int _data_size; | 2039 int _data_size; |
1407 | 2040 |
2041 // data index for the area dedicated to parameters. -1 if no | |
2042 // parameter profiling. | |
2043 int _parameters_type_data_di; | |
2044 | |
1408 // Beginning of the data entries | 2045 // Beginning of the data entries |
1409 intptr_t _data[1]; | 2046 intptr_t _data[1]; |
1410 | 2047 |
1411 // Helper for size computation | 2048 // Helper for size computation |
1412 static int compute_data_size(BytecodeStream* stream); | 2049 static int compute_data_size(BytecodeStream* stream); |
1457 // Find or create an extra ProfileData: | 2094 // Find or create an extra ProfileData: |
1458 ProfileData* bci_to_extra_data(int bci, bool create_if_missing); | 2095 ProfileData* bci_to_extra_data(int bci, bool create_if_missing); |
1459 | 2096 |
1460 // return the argument info cell | 2097 // return the argument info cell |
1461 ArgInfoData *arg_info(); | 2098 ArgInfoData *arg_info(); |
2099 | |
2100 enum { | |
2101 no_type_profile = 0, | |
2102 type_profile_jsr292 = 1, | |
2103 type_profile_all = 2 | |
2104 }; | |
2105 | |
2106 static bool profile_jsr292(methodHandle m, int bci); | |
2107 static int profile_arguments_flag(); | |
2108 static bool profile_arguments_jsr292_only(); | |
2109 static bool profile_all_arguments(); | |
2110 static bool profile_arguments_for_invoke(methodHandle m, int bci); | |
2111 static int profile_return_flag(); | |
2112 static bool profile_all_return(); | |
2113 static bool profile_return_for_invoke(methodHandle m, int bci); | |
2114 static int profile_parameters_flag(); | |
2115 static bool profile_parameters_jsr292_only(); | |
2116 static bool profile_all_parameters(); | |
1462 | 2117 |
1463 public: | 2118 public: |
1464 static int header_size() { | 2119 static int header_size() { |
1465 return sizeof(MethodData)/wordSize; | 2120 return sizeof(MethodData)/wordSize; |
1466 } | 2121 } |
1663 if (decompile_count() > (uint)PerMethodRecompilationCutoff) { | 2318 if (decompile_count() > (uint)PerMethodRecompilationCutoff) { |
1664 method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff"); | 2319 method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff"); |
1665 } | 2320 } |
1666 } | 2321 } |
1667 | 2322 |
2323 // Return pointer to area dedicated to parameters in MDO | |
2324 ParametersTypeData* parameters_type_data() const { | |
2325 return _parameters_type_data_di != -1 ? data_layout_at(_parameters_type_data_di)->data_in()->as_ParametersTypeData() : NULL; | |
2326 } | |
2327 | |
2328 int parameters_type_data_di() const { | |
2329 assert(_parameters_type_data_di != -1, "no args type data"); | |
2330 return _parameters_type_data_di; | |
2331 } | |
2332 | |
1668 // Support for code generation | 2333 // Support for code generation |
1669 static ByteSize data_offset() { | 2334 static ByteSize data_offset() { |
1670 return byte_offset_of(MethodData, _data[0]); | 2335 return byte_offset_of(MethodData, _data[0]); |
1671 } | 2336 } |
1672 | 2337 |
1673 static ByteSize invocation_counter_offset() { | 2338 static ByteSize invocation_counter_offset() { |
1674 return byte_offset_of(MethodData, _invocation_counter); | 2339 return byte_offset_of(MethodData, _invocation_counter); |
1675 } | 2340 } |
1676 static ByteSize backedge_counter_offset() { | 2341 static ByteSize backedge_counter_offset() { |
1677 return byte_offset_of(MethodData, _backedge_counter); | 2342 return byte_offset_of(MethodData, _backedge_counter); |
2343 } | |
2344 | |
2345 static ByteSize parameters_type_data_di_offset() { | |
2346 return byte_offset_of(MethodData, _parameters_type_data_di); | |
1678 } | 2347 } |
1679 | 2348 |
1680 // Deallocation support - no pointer fields to deallocate | 2349 // Deallocation support - no pointer fields to deallocate |
1681 void deallocate_contents(ClassLoaderData* loader_data) {} | 2350 void deallocate_contents(ClassLoaderData* loader_data) {} |
1682 | 2351 |
1697 const char* internal_name() const { return "{method data}"; } | 2366 const char* internal_name() const { return "{method data}"; } |
1698 | 2367 |
1699 // verification | 2368 // verification |
1700 void verify_on(outputStream* st); | 2369 void verify_on(outputStream* st); |
1701 void verify_data_on(outputStream* st); | 2370 void verify_data_on(outputStream* st); |
2371 | |
2372 static bool profile_parameters_for_method(methodHandle m); | |
2373 static bool profile_arguments(); | |
2374 static bool profile_return(); | |
2375 static bool profile_parameters(); | |
2376 static bool profile_return_jsr292_only(); | |
1702 }; | 2377 }; |
1703 | 2378 |
1704 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP | 2379 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP |