comparison src/share/vm/oops/methodData.hpp @ 12875:d13d7aba8c12

8023657: New type profiling points: arguments to call Summary: x86 interpreter and c1 type profiling for arguments at calls Reviewed-by: kvn, twisti
author roland
date Wed, 09 Oct 2013 16:32:21 +0200
parents 190899198332
children ce0cc25bc5e2
comparison
equal deleted inserted replaced
12874:46ef27bcacb3 12875:d13d7aba8c12
115 receiver_type_data_tag, 115 receiver_type_data_tag,
116 virtual_call_data_tag, 116 virtual_call_data_tag,
117 ret_data_tag, 117 ret_data_tag,
118 branch_data_tag, 118 branch_data_tag,
119 multi_branch_data_tag, 119 multi_branch_data_tag,
120 arg_info_data_tag 120 arg_info_data_tag,
121 call_type_data_tag,
122 virtual_call_type_data_tag
121 }; 123 };
122 124
123 enum { 125 enum {
124 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. 126 // The _struct._flags word is formatted as [trap_state:4 | flags:4].
125 // The trap state breaks down further as [recompile:1 | reason:3]. 127 // The trap state breaks down further as [recompile:1 | reason:3].
163 // The associated trap histogram in the MDO itself tells whether 165 // The associated trap histogram in the MDO itself tells whether
164 // traps are common or not. If a BCI shows that a trap X has 166 // traps are common or not. If a BCI shows that a trap X has
165 // occurred, and the MDO shows N occurrences of X, we make the 167 // occurred, and the MDO shows N occurrences of X, we make the
166 // simplifying assumption that all N occurrences can be blamed 168 // simplifying assumption that all N occurrences can be blamed
167 // on that BCI. 169 // on that BCI.
168 int trap_state() { 170 int trap_state() const {
169 return ((_header._struct._flags >> trap_shift) & trap_mask); 171 return ((_header._struct._flags >> trap_shift) & trap_mask);
170 } 172 }
171 173
172 void set_trap_state(int new_state) { 174 void set_trap_state(int new_state) {
173 assert(ProfileTraps, "used only under +ProfileTraps"); 175 assert(ProfileTraps, "used only under +ProfileTraps");
174 uint old_flags = (_header._struct._flags & flag_mask); 176 uint old_flags = (_header._struct._flags & flag_mask);
175 _header._struct._flags = (new_state << trap_shift) | old_flags; 177 _header._struct._flags = (new_state << trap_shift) | old_flags;
176 } 178 }
177 179
178 u1 flags() { 180 u1 flags() const {
179 return _header._struct._flags; 181 return _header._struct._flags;
180 } 182 }
181 183
182 u2 bci() { 184 u2 bci() const {
183 return _header._struct._bci; 185 return _header._struct._bci;
184 } 186 }
185 187
186 void set_header(intptr_t value) { 188 void set_header(intptr_t value) {
187 _header._bits = value; 189 _header._bits = value;
196 _cells[index] = value; 198 _cells[index] = value;
197 } 199 }
198 void release_set_cell_at(int index, intptr_t value) { 200 void release_set_cell_at(int index, intptr_t value) {
199 OrderAccess::release_store_ptr(&_cells[index], value); 201 OrderAccess::release_store_ptr(&_cells[index], value);
200 } 202 }
201 intptr_t cell_at(int index) { 203 intptr_t cell_at(int index) const {
202 return _cells[index]; 204 return _cells[index];
203 } 205 }
204 206
205 void set_flag_at(int flag_number) { 207 void set_flag_at(int flag_number) {
206 assert(flag_number < flag_limit, "oob"); 208 assert(flag_number < flag_limit, "oob");
207 _header._struct._flags |= (0x1 << flag_number); 209 _header._struct._flags |= (0x1 << flag_number);
208 } 210 }
209 bool flag_at(int flag_number) { 211 bool flag_at(int flag_number) const {
210 assert(flag_number < flag_limit, "oob"); 212 assert(flag_number < flag_limit, "oob");
211 return (_header._struct._flags & (0x1 << flag_number)) != 0; 213 return (_header._struct._flags & (0x1 << flag_number)) != 0;
212 } 214 }
213 215
214 // Low-level support for code generation. 216 // Low-level support for code generation.
252 class ProfileData; 254 class ProfileData;
253 class BitData; 255 class BitData;
254 class CounterData; 256 class CounterData;
255 class ReceiverTypeData; 257 class ReceiverTypeData;
256 class VirtualCallData; 258 class VirtualCallData;
259 class VirtualCallTypeData;
257 class RetData; 260 class RetData;
261 class CallTypeData;
258 class JumpData; 262 class JumpData;
259 class BranchData; 263 class BranchData;
260 class ArrayData; 264 class ArrayData;
261 class MultiBranchData; 265 class MultiBranchData;
262 class ArgInfoData; 266 class ArgInfoData;
263 267
264
265 // ProfileData 268 // ProfileData
266 // 269 //
267 // A ProfileData object is created to refer to a section of profiling 270 // A ProfileData object is created to refer to a section of profiling
268 // data in a structured way. 271 // data in a structured way.
269 class ProfileData : public ResourceObj { 272 class ProfileData : public ResourceObj {
273 friend class TypeEntries;
274 friend class TypeStackSlotEntries;
270 private: 275 private:
271 #ifndef PRODUCT 276 #ifndef PRODUCT
272 enum { 277 enum {
273 tab_width_one = 16, 278 tab_width_one = 16,
274 tab_width_two = 36 279 tab_width_two = 36
278 // This is a pointer to a section of profiling data. 283 // This is a pointer to a section of profiling data.
279 DataLayout* _data; 284 DataLayout* _data;
280 285
281 protected: 286 protected:
282 DataLayout* data() { return _data; } 287 DataLayout* data() { return _data; }
288 const DataLayout* data() const { return _data; }
283 289
284 enum { 290 enum {
285 cell_size = DataLayout::cell_size 291 cell_size = DataLayout::cell_size
286 }; 292 };
287 293
288 public: 294 public:
289 // How many cells are in this? 295 // How many cells are in this?
290 virtual int cell_count() { 296 virtual int cell_count() const {
291 ShouldNotReachHere(); 297 ShouldNotReachHere();
292 return -1; 298 return -1;
293 } 299 }
294 300
295 // Return the size of this data. 301 // Return the size of this data.
305 } 311 }
306 void release_set_intptr_at(int index, intptr_t value) { 312 void release_set_intptr_at(int index, intptr_t value) {
307 assert(0 <= index && index < cell_count(), "oob"); 313 assert(0 <= index && index < cell_count(), "oob");
308 data()->release_set_cell_at(index, value); 314 data()->release_set_cell_at(index, value);
309 } 315 }
310 intptr_t intptr_at(int index) { 316 intptr_t intptr_at(int index) const {
311 assert(0 <= index && index < cell_count(), "oob"); 317 assert(0 <= index && index < cell_count(), "oob");
312 return data()->cell_at(index); 318 return data()->cell_at(index);
313 } 319 }
314 void set_uint_at(int index, uint value) { 320 void set_uint_at(int index, uint value) {
315 set_intptr_at(index, (intptr_t) value); 321 set_intptr_at(index, (intptr_t) value);
316 } 322 }
317 void release_set_uint_at(int index, uint value) { 323 void release_set_uint_at(int index, uint value) {
318 release_set_intptr_at(index, (intptr_t) value); 324 release_set_intptr_at(index, (intptr_t) value);
319 } 325 }
320 uint uint_at(int index) { 326 uint uint_at(int index) const {
321 return (uint)intptr_at(index); 327 return (uint)intptr_at(index);
322 } 328 }
323 void set_int_at(int index, int value) { 329 void set_int_at(int index, int value) {
324 set_intptr_at(index, (intptr_t) value); 330 set_intptr_at(index, (intptr_t) value);
325 } 331 }
326 void release_set_int_at(int index, int value) { 332 void release_set_int_at(int index, int value) {
327 release_set_intptr_at(index, (intptr_t) value); 333 release_set_intptr_at(index, (intptr_t) value);
328 } 334 }
329 int int_at(int index) { 335 int int_at(int index) const {
330 return (int)intptr_at(index); 336 return (int)intptr_at(index);
331 } 337 }
332 int int_at_unchecked(int index) { 338 int int_at_unchecked(int index) const {
333 return (int)data()->cell_at(index); 339 return (int)data()->cell_at(index);
334 } 340 }
335 void set_oop_at(int index, oop value) { 341 void set_oop_at(int index, oop value) {
336 set_intptr_at(index, cast_from_oop<intptr_t>(value)); 342 set_intptr_at(index, cast_from_oop<intptr_t>(value));
337 } 343 }
338 oop oop_at(int index) { 344 oop oop_at(int index) const {
339 return cast_to_oop(intptr_at(index)); 345 return cast_to_oop(intptr_at(index));
340 } 346 }
341 347
342 void set_flag_at(int flag_number) { 348 void set_flag_at(int flag_number) {
343 data()->set_flag_at(flag_number); 349 data()->set_flag_at(flag_number);
344 } 350 }
345 bool flag_at(int flag_number) { 351 bool flag_at(int flag_number) const {
346 return data()->flag_at(flag_number); 352 return data()->flag_at(flag_number);
347 } 353 }
348 354
349 // two convenient imports for use by subclasses: 355 // two convenient imports for use by subclasses:
350 static ByteSize cell_offset(int index) { 356 static ByteSize cell_offset(int index) {
360 366
361 public: 367 public:
362 // Constructor for invalid ProfileData. 368 // Constructor for invalid ProfileData.
363 ProfileData(); 369 ProfileData();
364 370
365 u2 bci() { 371 u2 bci() const {
366 return data()->bci(); 372 return data()->bci();
367 } 373 }
368 374
369 address dp() { 375 address dp() {
370 return (address)_data; 376 return (address)_data;
371 } 377 }
372 378
373 int trap_state() { 379 int trap_state() const {
374 return data()->trap_state(); 380 return data()->trap_state();
375 } 381 }
376 void set_trap_state(int new_state) { 382 void set_trap_state(int new_state) {
377 data()->set_trap_state(new_state); 383 data()->set_trap_state(new_state);
378 } 384 }
379 385
380 // Type checking 386 // Type checking
381 virtual bool is_BitData() { return false; } 387 virtual bool is_BitData() const { return false; }
382 virtual bool is_CounterData() { return false; } 388 virtual bool is_CounterData() const { return false; }
383 virtual bool is_JumpData() { return false; } 389 virtual bool is_JumpData() const { return false; }
384 virtual bool is_ReceiverTypeData(){ return false; } 390 virtual bool is_ReceiverTypeData()const { return false; }
385 virtual bool is_VirtualCallData() { return false; } 391 virtual bool is_VirtualCallData() const { return false; }
386 virtual bool is_RetData() { return false; } 392 virtual bool is_RetData() const { return false; }
387 virtual bool is_BranchData() { return false; } 393 virtual bool is_BranchData() const { return false; }
388 virtual bool is_ArrayData() { return false; } 394 virtual bool is_ArrayData() const { return false; }
389 virtual bool is_MultiBranchData() { return false; } 395 virtual bool is_MultiBranchData() const { return false; }
390 virtual bool is_ArgInfoData() { return false; } 396 virtual bool is_ArgInfoData() const { return false; }
391 397 virtual bool is_CallTypeData() const { return false; }
392 398 virtual bool is_VirtualCallTypeData()const { return false; }
393 BitData* as_BitData() { 399
400
401 BitData* as_BitData() const {
394 assert(is_BitData(), "wrong type"); 402 assert(is_BitData(), "wrong type");
395 return is_BitData() ? (BitData*) this : NULL; 403 return is_BitData() ? (BitData*) this : NULL;
396 } 404 }
397 CounterData* as_CounterData() { 405 CounterData* as_CounterData() const {
398 assert(is_CounterData(), "wrong type"); 406 assert(is_CounterData(), "wrong type");
399 return is_CounterData() ? (CounterData*) this : NULL; 407 return is_CounterData() ? (CounterData*) this : NULL;
400 } 408 }
401 JumpData* as_JumpData() { 409 JumpData* as_JumpData() const {
402 assert(is_JumpData(), "wrong type"); 410 assert(is_JumpData(), "wrong type");
403 return is_JumpData() ? (JumpData*) this : NULL; 411 return is_JumpData() ? (JumpData*) this : NULL;
404 } 412 }
405 ReceiverTypeData* as_ReceiverTypeData() { 413 ReceiverTypeData* as_ReceiverTypeData() const {
406 assert(is_ReceiverTypeData(), "wrong type"); 414 assert(is_ReceiverTypeData(), "wrong type");
407 return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL; 415 return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL;
408 } 416 }
409 VirtualCallData* as_VirtualCallData() { 417 VirtualCallData* as_VirtualCallData() const {
410 assert(is_VirtualCallData(), "wrong type"); 418 assert(is_VirtualCallData(), "wrong type");
411 return is_VirtualCallData() ? (VirtualCallData*)this : NULL; 419 return is_VirtualCallData() ? (VirtualCallData*)this : NULL;
412 } 420 }
413 RetData* as_RetData() { 421 RetData* as_RetData() const {
414 assert(is_RetData(), "wrong type"); 422 assert(is_RetData(), "wrong type");
415 return is_RetData() ? (RetData*) this : NULL; 423 return is_RetData() ? (RetData*) this : NULL;
416 } 424 }
417 BranchData* as_BranchData() { 425 BranchData* as_BranchData() const {
418 assert(is_BranchData(), "wrong type"); 426 assert(is_BranchData(), "wrong type");
419 return is_BranchData() ? (BranchData*) this : NULL; 427 return is_BranchData() ? (BranchData*) this : NULL;
420 } 428 }
421 ArrayData* as_ArrayData() { 429 ArrayData* as_ArrayData() const {
422 assert(is_ArrayData(), "wrong type"); 430 assert(is_ArrayData(), "wrong type");
423 return is_ArrayData() ? (ArrayData*) this : NULL; 431 return is_ArrayData() ? (ArrayData*) this : NULL;
424 } 432 }
425 MultiBranchData* as_MultiBranchData() { 433 MultiBranchData* as_MultiBranchData() const {
426 assert(is_MultiBranchData(), "wrong type"); 434 assert(is_MultiBranchData(), "wrong type");
427 return is_MultiBranchData() ? (MultiBranchData*)this : NULL; 435 return is_MultiBranchData() ? (MultiBranchData*)this : NULL;
428 } 436 }
429 ArgInfoData* as_ArgInfoData() { 437 ArgInfoData* as_ArgInfoData() const {
430 assert(is_ArgInfoData(), "wrong type"); 438 assert(is_ArgInfoData(), "wrong type");
431 return is_ArgInfoData() ? (ArgInfoData*)this : NULL; 439 return is_ArgInfoData() ? (ArgInfoData*)this : NULL;
440 }
441 CallTypeData* as_CallTypeData() const {
442 assert(is_CallTypeData(), "wrong type");
443 return is_CallTypeData() ? (CallTypeData*)this : NULL;
444 }
445 VirtualCallTypeData* as_VirtualCallTypeData() const {
446 assert(is_VirtualCallTypeData(), "wrong type");
447 return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL;
432 } 448 }
433 449
434 450
435 // Subclass specific initialization 451 // Subclass specific initialization
436 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} 452 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {}
441 // CI translation: ProfileData can represent both MethodDataOop data 457 // CI translation: ProfileData can represent both MethodDataOop data
442 // as well as CIMethodData data. This function is provided for translating 458 // as well as CIMethodData data. This function is provided for translating
443 // an oop in a ProfileData to the ci equivalent. Generally speaking, 459 // an oop in a ProfileData to the ci equivalent. Generally speaking,
444 // most ProfileData don't require any translation, so we provide the null 460 // most ProfileData don't require any translation, so we provide the null
445 // translation here, and the required translators are in the ci subclasses. 461 // translation here, and the required translators are in the ci subclasses.
446 virtual void translate_from(ProfileData* data) {} 462 virtual void translate_from(const ProfileData* data) {}
447 463
448 virtual void print_data_on(outputStream* st) { 464 virtual void print_data_on(outputStream* st) const {
449 ShouldNotReachHere(); 465 ShouldNotReachHere();
450 } 466 }
451 467
452 #ifndef PRODUCT 468 #ifndef PRODUCT
453 void print_shared(outputStream* st, const char* name); 469 void print_shared(outputStream* st, const char* name) const;
454 void tab(outputStream* st); 470 void tab(outputStream* st, bool first = false) const;
455 #endif 471 #endif
456 }; 472 };
457 473
458 // BitData 474 // BitData
459 // 475 //
468 enum { bit_cell_count = 0 }; // no additional data fields needed. 484 enum { bit_cell_count = 0 }; // no additional data fields needed.
469 public: 485 public:
470 BitData(DataLayout* layout) : ProfileData(layout) { 486 BitData(DataLayout* layout) : ProfileData(layout) {
471 } 487 }
472 488
473 virtual bool is_BitData() { return true; } 489 virtual bool is_BitData() const { return true; }
474 490
475 static int static_cell_count() { 491 static int static_cell_count() {
476 return bit_cell_count; 492 return bit_cell_count;
477 } 493 }
478 494
479 virtual int cell_count() { 495 virtual int cell_count() const {
480 return static_cell_count(); 496 return static_cell_count();
481 } 497 }
482 498
483 // Accessor 499 // Accessor
484 500
496 static ByteSize bit_data_size() { 512 static ByteSize bit_data_size() {
497 return cell_offset(bit_cell_count); 513 return cell_offset(bit_cell_count);
498 } 514 }
499 515
500 #ifndef PRODUCT 516 #ifndef PRODUCT
501 void print_data_on(outputStream* st); 517 void print_data_on(outputStream* st) const;
502 #endif 518 #endif
503 }; 519 };
504 520
505 // CounterData 521 // CounterData
506 // 522 //
512 counter_cell_count 528 counter_cell_count
513 }; 529 };
514 public: 530 public:
515 CounterData(DataLayout* layout) : BitData(layout) {} 531 CounterData(DataLayout* layout) : BitData(layout) {}
516 532
517 virtual bool is_CounterData() { return true; } 533 virtual bool is_CounterData() const { return true; }
518 534
519 static int static_cell_count() { 535 static int static_cell_count() {
520 return counter_cell_count; 536 return counter_cell_count;
521 } 537 }
522 538
523 virtual int cell_count() { 539 virtual int cell_count() const {
524 return static_cell_count(); 540 return static_cell_count();
525 } 541 }
526 542
527 // Direct accessor 543 // Direct accessor
528 uint count() { 544 uint count() const {
529 return uint_at(count_off); 545 return uint_at(count_off);
530 } 546 }
531 547
532 // Code generation support 548 // Code generation support
533 static ByteSize count_offset() { 549 static ByteSize count_offset() {
540 void set_count(uint count) { 556 void set_count(uint count) {
541 set_uint_at(count_off, count); 557 set_uint_at(count_off, count);
542 } 558 }
543 559
544 #ifndef PRODUCT 560 #ifndef PRODUCT
545 void print_data_on(outputStream* st); 561 void print_data_on(outputStream* st) const;
546 #endif 562 #endif
547 }; 563 };
548 564
549 // JumpData 565 // JumpData
550 // 566 //
568 JumpData(DataLayout* layout) : ProfileData(layout) { 584 JumpData(DataLayout* layout) : ProfileData(layout) {
569 assert(layout->tag() == DataLayout::jump_data_tag || 585 assert(layout->tag() == DataLayout::jump_data_tag ||
570 layout->tag() == DataLayout::branch_data_tag, "wrong type"); 586 layout->tag() == DataLayout::branch_data_tag, "wrong type");
571 } 587 }
572 588
573 virtual bool is_JumpData() { return true; } 589 virtual bool is_JumpData() const { return true; }
574 590
575 static int static_cell_count() { 591 static int static_cell_count() {
576 return jump_cell_count; 592 return jump_cell_count;
577 } 593 }
578 594
579 virtual int cell_count() { 595 virtual int cell_count() const {
580 return static_cell_count(); 596 return static_cell_count();
581 } 597 }
582 598
583 // Direct accessor 599 // Direct accessor
584 uint taken() { 600 uint taken() const {
585 return uint_at(taken_off_set); 601 return uint_at(taken_off_set);
586 } 602 }
587 603
588 void set_taken(uint cnt) { 604 void set_taken(uint cnt) {
589 set_uint_at(taken_off_set, cnt); 605 set_uint_at(taken_off_set, cnt);
596 if (cnt == 0) cnt--; 612 if (cnt == 0) cnt--;
597 set_uint_at(taken_off_set, cnt); 613 set_uint_at(taken_off_set, cnt);
598 return cnt; 614 return cnt;
599 } 615 }
600 616
601 int displacement() { 617 int displacement() const {
602 return int_at(displacement_off_set); 618 return int_at(displacement_off_set);
603 } 619 }
604 620
605 // Code generation support 621 // Code generation support
606 static ByteSize taken_offset() { 622 static ByteSize taken_offset() {
613 629
614 // Specific initialization. 630 // Specific initialization.
615 void post_initialize(BytecodeStream* stream, MethodData* mdo); 631 void post_initialize(BytecodeStream* stream, MethodData* mdo);
616 632
617 #ifndef PRODUCT 633 #ifndef PRODUCT
618 void print_data_on(outputStream* st); 634 void print_data_on(outputStream* st) const;
635 #endif
636 };
637
638 // Entries in a ProfileData object to record types: it can either be
639 // none (no profile), unknown (conflicting profile data) or a klass if
640 // a single one is seen. Whether a null reference was seen is also
641 // recorded. No counter is associated with the type and a single type
642 // is tracked (unlike VirtualCallData).
643 class TypeEntries {
644
645 public:
646
647 // A single cell is used to record information for a type:
648 // - the cell is initialized to 0
649 // - when a type is discovered it is stored in the cell
650 // - bit zero of the cell is used to record whether a null reference
651 // was encountered or not
652 // - bit 1 is set to record a conflict in the type information
653
654 enum {
655 null_seen = 1,
656 type_mask = ~null_seen,
657 type_unknown = 2,
658 status_bits = null_seen | type_unknown,
659 type_klass_mask = ~status_bits
660 };
661
662 // what to initialize a cell to
663 static intptr_t type_none() {
664 return 0;
665 }
666
667 // null seen = bit 0 set?
668 static bool was_null_seen(intptr_t v) {
669 return (v & null_seen) != 0;
670 }
671
672 // conflicting type information = bit 1 set?
673 static bool is_type_unknown(intptr_t v) {
674 return (v & type_unknown) != 0;
675 }
676
677 // not type information yet = all bits cleared, ignoring bit 0?
678 static bool is_type_none(intptr_t v) {
679 return (v & type_mask) == 0;
680 }
681
682 // recorded type: cell without bit 0 and 1
683 static intptr_t klass_part(intptr_t v) {
684 intptr_t r = v & type_klass_mask;
685 assert (r != 0, "invalid");
686 return r;
687 }
688
689 // type recorded
690 static Klass* valid_klass(intptr_t k) {
691 if (!is_type_none(k) &&
692 !is_type_unknown(k)) {
693 return (Klass*)klass_part(k);
694 } else {
695 return NULL;
696 }
697 }
698
699 static intptr_t with_status(intptr_t k, intptr_t in) {
700 return k | (in & status_bits);
701 }
702
703 static intptr_t with_status(Klass* k, intptr_t in) {
704 return with_status((intptr_t)k, in);
705 }
706
707 #ifndef PRODUCT
708 static void print_klass(outputStream* st, intptr_t k);
709 #endif
710
711 // GC support
712 static bool is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p);
713
714 protected:
715 // ProfileData object these entries are part of
716 ProfileData* _pd;
717 // offset within the ProfileData object where the entries start
718 const int _base_off;
719
720 TypeEntries(int base_off)
721 : _base_off(base_off), _pd(NULL) {}
722
723 void set_intptr_at(int index, intptr_t value) {
724 _pd->set_intptr_at(index, value);
725 }
726
727 intptr_t intptr_at(int index) const {
728 return _pd->intptr_at(index);
729 }
730
731 public:
732 void set_profile_data(ProfileData* pd) {
733 _pd = pd;
734 }
735 };
736
737 // Type entries used for arguments passed at a call and parameters on
738 // method entry. 2 cells per entry: one for the type encoded as in
739 // TypeEntries and one initialized with the stack slot where the
740 // profiled object is to be found so that the interpreter can locate
741 // it quickly.
742 class TypeStackSlotEntries : public TypeEntries {
743
744 private:
745 enum {
746 stack_slot_entry,
747 type_entry,
748 per_arg_cell_count
749 };
750
751 // Start with a header if needed. It stores the number of cells used
752 // for this call type information. Unless we collect only profiling
753 // for a single argument the number of cells is unknown statically.
754 static int header_cell_count() {
755 return (TypeProfileArgsLimit > 1) ? 1 : 0;
756 }
757
758 static int cell_count_local_offset() {
759 assert(arguments_profiling_enabled() && TypeProfileArgsLimit > 1, "no cell count");
760 return 0;
761 }
762
763 int cell_count_global_offset() const {
764 return _base_off + cell_count_local_offset();
765 }
766
767 // offset of cell for stack slot for entry i within ProfileData object
768 int stack_slot_global_offset(int i) const {
769 return _base_off + stack_slot_local_offset(i);
770 }
771
772 void check_number_of_arguments(int total) {
773 assert(number_of_arguments() == total, "should be set in DataLayout::initialize");
774 }
775
776 // number of cells not counting the header
777 int cell_count_no_header() const {
778 return _pd->uint_at(cell_count_global_offset());
779 }
780
781 static bool arguments_profiling_enabled();
782 static void assert_arguments_profiling_enabled() {
783 assert(arguments_profiling_enabled(), "args profiling should be on");
784 }
785
786 protected:
787
788 // offset of cell for type for entry i within ProfileData object
789 int type_global_offset(int i) const {
790 return _base_off + type_local_offset(i);
791 }
792
793 public:
794
795 TypeStackSlotEntries(int base_off)
796 : TypeEntries(base_off) {}
797
798 static int compute_cell_count(BytecodeStream* stream);
799
800 static void initialize(DataLayout* dl, int base, int cell_count) {
801 if (TypeProfileArgsLimit > 1) {
802 int off = base + cell_count_local_offset();
803 dl->set_cell_at(off, cell_count - base - header_cell_count());
804 }
805 }
806
807 void post_initialize(BytecodeStream* stream);
808
809 int number_of_arguments() const {
810 assert_arguments_profiling_enabled();
811 if (TypeProfileArgsLimit > 1) {
812 int cell_count = cell_count_no_header();
813 int nb = cell_count / TypeStackSlotEntries::per_arg_count();
814 assert(nb > 0 && nb <= TypeProfileArgsLimit , "only when we profile args");
815 return nb;
816 } else {
817 assert(TypeProfileArgsLimit == 1, "at least one arg");
818 return 1;
819 }
820 }
821
822 int cell_count() const {
823 assert_arguments_profiling_enabled();
824 if (TypeProfileArgsLimit > 1) {
825 return _base_off + header_cell_count() + _pd->int_at_unchecked(cell_count_global_offset());
826 } else {
827 return _base_off + TypeStackSlotEntries::per_arg_count();
828 }
829 }
830
831 // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries
832 static int stack_slot_local_offset(int i) {
833 assert_arguments_profiling_enabled();
834 return header_cell_count() + i * per_arg_cell_count + stack_slot_entry;
835 }
836
837 // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries
838 static int type_local_offset(int i) {
839 return header_cell_count() + i * per_arg_cell_count + type_entry;
840 }
841
842 // stack slot for entry i
843 uint stack_slot(int i) const {
844 assert(i >= 0 && i < number_of_arguments(), "oob");
845 return _pd->uint_at(stack_slot_global_offset(i));
846 }
847
848 // set stack slot for entry i
849 void set_stack_slot(int i, uint num) {
850 assert(i >= 0 && i < number_of_arguments(), "oob");
851 _pd->set_uint_at(stack_slot_global_offset(i), num);
852 }
853
854 // type for entry i
855 intptr_t type(int i) const {
856 assert(i >= 0 && i < number_of_arguments(), "oob");
857 return _pd->intptr_at(type_global_offset(i));
858 }
859
860 // set type for entry i
861 void set_type(int i, intptr_t k) {
862 assert(i >= 0 && i < number_of_arguments(), "oob");
863 _pd->set_intptr_at(type_global_offset(i), k);
864 }
865
866 static ByteSize per_arg_size() {
867 return in_ByteSize(per_arg_cell_count * DataLayout::cell_size);
868 }
869
870 static int per_arg_count() {
871 return per_arg_cell_count ;
872 }
873
874 // Code generation support
875 static ByteSize cell_count_offset() {
876 return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size);
877 }
878
879 static ByteSize args_data_offset() {
880 return in_ByteSize(header_cell_count() * DataLayout::cell_size);
881 }
882
883 static ByteSize stack_slot_offset(int i) {
884 return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size);
885 }
886
887 static ByteSize type_offset(int i) {
888 return in_ByteSize(type_local_offset(i) * DataLayout::cell_size);
889 }
890
891 // GC support
892 void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
893
894 #ifndef PRODUCT
895 void print_data_on(outputStream* st) const;
896 #endif
897 };
898
899 // CallTypeData
900 //
901 // A CallTypeData is used to access profiling information about a non
902 // virtual call for which we collect type information about arguments.
903 class CallTypeData : public CounterData {
904 private:
905 TypeStackSlotEntries _args;
906
907 public:
908 CallTypeData(DataLayout* layout) :
909 CounterData(layout), _args(CounterData::static_cell_count()) {
910 assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type");
911 // Some compilers (VC++) don't want this passed in member initialization list
912 _args.set_profile_data(this);
913 }
914
915 const TypeStackSlotEntries* args() const { return &_args; }
916
917 virtual bool is_CallTypeData() const { return true; }
918
919 static int static_cell_count() {
920 return -1;
921 }
922
923 static int compute_cell_count(BytecodeStream* stream) {
924 return CounterData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream);
925 }
926
927 static void initialize(DataLayout* dl, int cell_count) {
928 TypeStackSlotEntries::initialize(dl, CounterData::static_cell_count(), cell_count);
929 }
930
931 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {
932 _args.post_initialize(stream);
933 }
934
935 virtual int cell_count() const {
936 return _args.cell_count();
937 }
938
939 uint number_of_arguments() const {
940 return args()->number_of_arguments();
941 }
942
943 void set_argument_type(int i, Klass* k) {
944 intptr_t current = _args.type(i);
945 _args.set_type(i, TypeEntries::with_status(k, current));
946 }
947
948 // Code generation support
949 static ByteSize args_data_offset() {
950 return cell_offset(CounterData::static_cell_count()) + TypeStackSlotEntries::args_data_offset();
951 }
952
953 // GC support
954 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
955 _args.clean_weak_klass_links(is_alive_closure);
956 }
957
958 #ifndef PRODUCT
959 virtual void print_data_on(outputStream* st) const;
619 #endif 960 #endif
620 }; 961 };
621 962
622 // ReceiverTypeData 963 // ReceiverTypeData
623 // 964 //
634 }; 975 };
635 976
636 public: 977 public:
637 ReceiverTypeData(DataLayout* layout) : CounterData(layout) { 978 ReceiverTypeData(DataLayout* layout) : CounterData(layout) {
638 assert(layout->tag() == DataLayout::receiver_type_data_tag || 979 assert(layout->tag() == DataLayout::receiver_type_data_tag ||
639 layout->tag() == DataLayout::virtual_call_data_tag, "wrong type"); 980 layout->tag() == DataLayout::virtual_call_data_tag ||
640 } 981 layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");
641 982 }
642 virtual bool is_ReceiverTypeData() { return true; } 983
984 virtual bool is_ReceiverTypeData() const { return true; }
643 985
644 static int static_cell_count() { 986 static int static_cell_count() {
645 return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count; 987 return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count;
646 } 988 }
647 989
648 virtual int cell_count() { 990 virtual int cell_count() const {
649 return static_cell_count(); 991 return static_cell_count();
650 } 992 }
651 993
652 // Direct accessors 994 // Direct accessors
653 static uint row_limit() { 995 static uint row_limit() {
658 } 1000 }
659 static int receiver_count_cell_index(uint row) { 1001 static int receiver_count_cell_index(uint row) {
660 return count0_offset + row * receiver_type_row_cell_count; 1002 return count0_offset + row * receiver_type_row_cell_count;
661 } 1003 }
662 1004
663 Klass* receiver(uint row) { 1005 Klass* receiver(uint row) const {
664 assert(row < row_limit(), "oob"); 1006 assert(row < row_limit(), "oob");
665 1007
666 Klass* recv = (Klass*)intptr_at(receiver_cell_index(row)); 1008 Klass* recv = (Klass*)intptr_at(receiver_cell_index(row));
667 assert(recv == NULL || recv->is_klass(), "wrong type"); 1009 assert(recv == NULL || recv->is_klass(), "wrong type");
668 return recv; 1010 return recv;
671 void set_receiver(uint row, Klass* k) { 1013 void set_receiver(uint row, Klass* k) {
672 assert((uint)row < row_limit(), "oob"); 1014 assert((uint)row < row_limit(), "oob");
673 set_intptr_at(receiver_cell_index(row), (uintptr_t)k); 1015 set_intptr_at(receiver_cell_index(row), (uintptr_t)k);
674 } 1016 }
675 1017
676 uint receiver_count(uint row) { 1018 uint receiver_count(uint row) const {
677 assert(row < row_limit(), "oob"); 1019 assert(row < row_limit(), "oob");
678 return uint_at(receiver_count_cell_index(row)); 1020 return uint_at(receiver_count_cell_index(row));
679 } 1021 }
680 1022
681 void set_receiver_count(uint row, uint count) { 1023 void set_receiver_count(uint row, uint count) {
719 1061
720 // GC support 1062 // GC support
721 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); 1063 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
722 1064
723 #ifndef PRODUCT 1065 #ifndef PRODUCT
724 void print_receiver_data_on(outputStream* st); 1066 void print_receiver_data_on(outputStream* st) const;
725 void print_data_on(outputStream* st); 1067 void print_data_on(outputStream* st) const;
726 #endif 1068 #endif
727 }; 1069 };
728 1070
729 // VirtualCallData 1071 // VirtualCallData
730 // 1072 //
731 // A VirtualCallData is used to access profiling information about a 1073 // A VirtualCallData is used to access profiling information about a
732 // virtual call. For now, it has nothing more than a ReceiverTypeData. 1074 // virtual call. For now, it has nothing more than a ReceiverTypeData.
733 class VirtualCallData : public ReceiverTypeData { 1075 class VirtualCallData : public ReceiverTypeData {
734 public: 1076 public:
735 VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) { 1077 VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) {
736 assert(layout->tag() == DataLayout::virtual_call_data_tag, "wrong type"); 1078 assert(layout->tag() == DataLayout::virtual_call_data_tag ||
737 } 1079 layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");
738 1080 }
739 virtual bool is_VirtualCallData() { return true; } 1081
1082 virtual bool is_VirtualCallData() const { return true; }
740 1083
741 static int static_cell_count() { 1084 static int static_cell_count() {
742 // At this point we could add more profile state, e.g., for arguments. 1085 // At this point we could add more profile state, e.g., for arguments.
743 // But for now it's the same size as the base record type. 1086 // But for now it's the same size as the base record type.
744 return ReceiverTypeData::static_cell_count(); 1087 return ReceiverTypeData::static_cell_count();
745 } 1088 }
746 1089
747 virtual int cell_count() { 1090 virtual int cell_count() const {
748 return static_cell_count(); 1091 return static_cell_count();
749 } 1092 }
750 1093
751 // Direct accessors 1094 // Direct accessors
752 static ByteSize virtual_call_data_size() { 1095 static ByteSize virtual_call_data_size() {
753 return cell_offset(static_cell_count()); 1096 return cell_offset(static_cell_count());
754 } 1097 }
755 1098
756 #ifndef PRODUCT 1099 #ifndef PRODUCT
757 void print_data_on(outputStream* st); 1100 void print_data_on(outputStream* st) const;
1101 #endif
1102 };
1103
1104 // VirtualCallTypeData
1105 //
1106 // A VirtualCallTypeData is used to access profiling information about
1107 // a virtual call for which we collect type information about
1108 // arguments.
1109 class VirtualCallTypeData : public VirtualCallData {
1110 private:
1111 TypeStackSlotEntries _args;
1112
1113 public:
1114 VirtualCallTypeData(DataLayout* layout) :
1115 VirtualCallData(layout), _args(VirtualCallData::static_cell_count()) {
1116 assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");
1117 // Some compilers (VC++) don't want this passed in member initialization list
1118 _args.set_profile_data(this);
1119 }
1120
1121 const TypeStackSlotEntries* args() const { return &_args; }
1122
1123 virtual bool is_VirtualCallTypeData() const { return true; }
1124
1125 static int static_cell_count() {
1126 return -1;
1127 }
1128
1129 static int compute_cell_count(BytecodeStream* stream) {
1130 return VirtualCallData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream);
1131 }
1132
1133 static void initialize(DataLayout* dl, int cell_count) {
1134 TypeStackSlotEntries::initialize(dl, VirtualCallData::static_cell_count(), cell_count);
1135 }
1136
1137 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {
1138 _args.post_initialize(stream);
1139 }
1140
1141 virtual int cell_count() const {
1142 return _args.cell_count();
1143 }
1144
1145 uint number_of_arguments() const {
1146 return args()->number_of_arguments();
1147 }
1148
1149 void set_argument_type(int i, Klass* k) {
1150 intptr_t current = _args.type(i);
1151 _args.set_type(i, TypeEntries::with_status(k, current));
1152 }
1153
1154 // Code generation support
1155 static ByteSize args_data_offset() {
1156 return cell_offset(VirtualCallData::static_cell_count()) + TypeStackSlotEntries::args_data_offset();
1157 }
1158
1159 // GC support
1160 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
1161 ReceiverTypeData::clean_weak_klass_links(is_alive_closure);
1162 _args.clean_weak_klass_links(is_alive_closure);
1163 }
1164
1165 #ifndef PRODUCT
1166 virtual void print_data_on(outputStream* st) const;
758 #endif 1167 #endif
759 }; 1168 };
760 1169
761 // RetData 1170 // RetData
762 // 1171 //
795 public: 1204 public:
796 RetData(DataLayout* layout) : CounterData(layout) { 1205 RetData(DataLayout* layout) : CounterData(layout) {
797 assert(layout->tag() == DataLayout::ret_data_tag, "wrong type"); 1206 assert(layout->tag() == DataLayout::ret_data_tag, "wrong type");
798 } 1207 }
799 1208
800 virtual bool is_RetData() { return true; } 1209 virtual bool is_RetData() const { return true; }
801 1210
802 enum { 1211 enum {
803 no_bci = -1 // value of bci when bci1/2 are not in use. 1212 no_bci = -1 // value of bci when bci1/2 are not in use.
804 }; 1213 };
805 1214
806 static int static_cell_count() { 1215 static int static_cell_count() {
807 return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count; 1216 return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count;
808 } 1217 }
809 1218
810 virtual int cell_count() { 1219 virtual int cell_count() const {
811 return static_cell_count(); 1220 return static_cell_count();
812 } 1221 }
813 1222
814 static uint row_limit() { 1223 static uint row_limit() {
815 return BciProfileWidth; 1224 return BciProfileWidth;
823 static int bci_displacement_cell_index(uint row) { 1232 static int bci_displacement_cell_index(uint row) {
824 return displacement0_offset + row * ret_row_cell_count; 1233 return displacement0_offset + row * ret_row_cell_count;
825 } 1234 }
826 1235
827 // Direct accessors 1236 // Direct accessors
828 int bci(uint row) { 1237 int bci(uint row) const {
829 return int_at(bci_cell_index(row)); 1238 return int_at(bci_cell_index(row));
830 } 1239 }
831 uint bci_count(uint row) { 1240 uint bci_count(uint row) const {
832 return uint_at(bci_count_cell_index(row)); 1241 return uint_at(bci_count_cell_index(row));
833 } 1242 }
834 int bci_displacement(uint row) { 1243 int bci_displacement(uint row) const {
835 return int_at(bci_displacement_cell_index(row)); 1244 return int_at(bci_displacement_cell_index(row));
836 } 1245 }
837 1246
838 // Interpreter Runtime support 1247 // Interpreter Runtime support
839 address fixup_ret(int return_bci, MethodData* mdo); 1248 address fixup_ret(int return_bci, MethodData* mdo);
851 1260
852 // Specific initialization. 1261 // Specific initialization.
853 void post_initialize(BytecodeStream* stream, MethodData* mdo); 1262 void post_initialize(BytecodeStream* stream, MethodData* mdo);
854 1263
855 #ifndef PRODUCT 1264 #ifndef PRODUCT
856 void print_data_on(outputStream* st); 1265 void print_data_on(outputStream* st) const;
857 #endif 1266 #endif
858 }; 1267 };
859 1268
860 // BranchData 1269 // BranchData
861 // 1270 //
876 public: 1285 public:
877 BranchData(DataLayout* layout) : JumpData(layout) { 1286 BranchData(DataLayout* layout) : JumpData(layout) {
878 assert(layout->tag() == DataLayout::branch_data_tag, "wrong type"); 1287 assert(layout->tag() == DataLayout::branch_data_tag, "wrong type");
879 } 1288 }
880 1289
881 virtual bool is_BranchData() { return true; } 1290 virtual bool is_BranchData() const { return true; }
882 1291
883 static int static_cell_count() { 1292 static int static_cell_count() {
884 return branch_cell_count; 1293 return branch_cell_count;
885 } 1294 }
886 1295
887 virtual int cell_count() { 1296 virtual int cell_count() const {
888 return static_cell_count(); 1297 return static_cell_count();
889 } 1298 }
890 1299
891 // Direct accessor 1300 // Direct accessor
892 uint not_taken() { 1301 uint not_taken() const {
893 return uint_at(not_taken_off_set); 1302 return uint_at(not_taken_off_set);
894 } 1303 }
895 1304
896 void set_not_taken(uint cnt) { 1305 void set_not_taken(uint cnt) {
897 set_uint_at(not_taken_off_set, cnt); 1306 set_uint_at(not_taken_off_set, cnt);
915 1324
916 // Specific initialization. 1325 // Specific initialization.
917 void post_initialize(BytecodeStream* stream, MethodData* mdo); 1326 void post_initialize(BytecodeStream* stream, MethodData* mdo);
918 1327
919 #ifndef PRODUCT 1328 #ifndef PRODUCT
920 void print_data_on(outputStream* st); 1329 void print_data_on(outputStream* st) const;
921 #endif 1330 #endif
922 }; 1331 };
923 1332
924 // ArrayData 1333 // ArrayData
925 // 1334 //
933 enum { 1342 enum {
934 array_len_off_set, 1343 array_len_off_set,
935 array_start_off_set 1344 array_start_off_set
936 }; 1345 };
937 1346
938 uint array_uint_at(int index) { 1347 uint array_uint_at(int index) const {
939 int aindex = index + array_start_off_set; 1348 int aindex = index + array_start_off_set;
940 return uint_at(aindex); 1349 return uint_at(aindex);
941 } 1350 }
942 int array_int_at(int index) { 1351 int array_int_at(int index) const {
943 int aindex = index + array_start_off_set; 1352 int aindex = index + array_start_off_set;
944 return int_at(aindex); 1353 return int_at(aindex);
945 } 1354 }
946 oop array_oop_at(int index) { 1355 oop array_oop_at(int index) const {
947 int aindex = index + array_start_off_set; 1356 int aindex = index + array_start_off_set;
948 return oop_at(aindex); 1357 return oop_at(aindex);
949 } 1358 }
950 void array_set_int_at(int index, int value) { 1359 void array_set_int_at(int index, int value) {
951 int aindex = index + array_start_off_set; 1360 int aindex = index + array_start_off_set;
958 } 1367 }
959 1368
960 public: 1369 public:
961 ArrayData(DataLayout* layout) : ProfileData(layout) {} 1370 ArrayData(DataLayout* layout) : ProfileData(layout) {}
962 1371
963 virtual bool is_ArrayData() { return true; } 1372 virtual bool is_ArrayData() const { return true; }
964 1373
965 static int static_cell_count() { 1374 static int static_cell_count() {
966 return -1; 1375 return -1;
967 } 1376 }
968 1377
969 int array_len() { 1378 int array_len() const {
970 return int_at_unchecked(array_len_off_set); 1379 return int_at_unchecked(array_len_off_set);
971 } 1380 }
972 1381
973 virtual int cell_count() { 1382 virtual int cell_count() const {
974 return array_len() + 1; 1383 return array_len() + 1;
975 } 1384 }
976 1385
977 // Code generation support 1386 // Code generation support
978 static ByteSize array_len_offset() { 1387 static ByteSize array_len_offset() {
1015 public: 1424 public:
1016 MultiBranchData(DataLayout* layout) : ArrayData(layout) { 1425 MultiBranchData(DataLayout* layout) : ArrayData(layout) {
1017 assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type"); 1426 assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type");
1018 } 1427 }
1019 1428
1020 virtual bool is_MultiBranchData() { return true; } 1429 virtual bool is_MultiBranchData() const { return true; }
1021 1430
1022 static int compute_cell_count(BytecodeStream* stream); 1431 static int compute_cell_count(BytecodeStream* stream);
1023 1432
1024 int number_of_cases() { 1433 int number_of_cases() const {
1025 int alen = array_len() - 2; // get rid of default case here. 1434 int alen = array_len() - 2; // get rid of default case here.
1026 assert(alen % per_case_cell_count == 0, "must be even"); 1435 assert(alen % per_case_cell_count == 0, "must be even");
1027 return (alen / per_case_cell_count); 1436 return (alen / per_case_cell_count);
1028 } 1437 }
1029 1438
1030 uint default_count() { 1439 uint default_count() const {
1031 return array_uint_at(default_count_off_set); 1440 return array_uint_at(default_count_off_set);
1032 } 1441 }
1033 int default_displacement() { 1442 int default_displacement() const {
1034 return array_int_at(default_disaplacement_off_set); 1443 return array_int_at(default_disaplacement_off_set);
1035 } 1444 }
1036 1445
1037 uint count_at(int index) { 1446 uint count_at(int index) const {
1038 return array_uint_at(case_array_start + 1447 return array_uint_at(case_array_start +
1039 index * per_case_cell_count + 1448 index * per_case_cell_count +
1040 relative_count_off_set); 1449 relative_count_off_set);
1041 } 1450 }
1042 int displacement_at(int index) { 1451 int displacement_at(int index) const {
1043 return array_int_at(case_array_start + 1452 return array_int_at(case_array_start +
1044 index * per_case_cell_count + 1453 index * per_case_cell_count +
1045 relative_displacement_off_set); 1454 relative_displacement_off_set);
1046 } 1455 }
1047 1456
1072 1481
1073 // Specific initialization. 1482 // Specific initialization.
1074 void post_initialize(BytecodeStream* stream, MethodData* mdo); 1483 void post_initialize(BytecodeStream* stream, MethodData* mdo);
1075 1484
1076 #ifndef PRODUCT 1485 #ifndef PRODUCT
1077 void print_data_on(outputStream* st); 1486 void print_data_on(outputStream* st) const;
1078 #endif 1487 #endif
1079 }; 1488 };
1080 1489
1081 class ArgInfoData : public ArrayData { 1490 class ArgInfoData : public ArrayData {
1082 1491
1083 public: 1492 public:
1084 ArgInfoData(DataLayout* layout) : ArrayData(layout) { 1493 ArgInfoData(DataLayout* layout) : ArrayData(layout) {
1085 assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type"); 1494 assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type");
1086 } 1495 }
1087 1496
1088 virtual bool is_ArgInfoData() { return true; } 1497 virtual bool is_ArgInfoData() const { return true; }
1089 1498
1090 1499
1091 int number_of_args() { 1500 int number_of_args() const {
1092 return array_len(); 1501 return array_len();
1093 } 1502 }
1094 1503
1095 uint arg_modified(int arg) { 1504 uint arg_modified(int arg) const {
1096 return array_uint_at(arg); 1505 return array_uint_at(arg);
1097 } 1506 }
1098 1507
1099 void set_arg_modified(int arg, uint val) { 1508 void set_arg_modified(int arg, uint val) {
1100 array_set_int_at(arg, val); 1509 array_set_int_at(arg, val);
1101 } 1510 }
1102 1511
1103 #ifndef PRODUCT 1512 #ifndef PRODUCT
1104 void print_data_on(outputStream* st); 1513 void print_data_on(outputStream* st) const;
1105 #endif 1514 #endif
1106 }; 1515 };
1107 1516
1108 // MethodData* 1517 // MethodData*
1109 // 1518 //
1269 ProfileData* bci_to_extra_data(int bci, bool create_if_missing); 1678 ProfileData* bci_to_extra_data(int bci, bool create_if_missing);
1270 1679
1271 // return the argument info cell 1680 // return the argument info cell
1272 ArgInfoData *arg_info(); 1681 ArgInfoData *arg_info();
1273 1682
1683 enum {
1684 no_type_profile = 0,
1685 type_profile_jsr292 = 1,
1686 type_profile_all = 2
1687 };
1688
1689 static bool profile_jsr292(methodHandle m, int bci);
1690 static int profile_arguments_flag();
1691 static bool profile_arguments_jsr292_only();
1692 static bool profile_all_arguments();
1693 static bool profile_arguments_for_invoke(methodHandle m, int bci);
1694
1274 public: 1695 public:
1275 static int header_size() { 1696 static int header_size() {
1276 return sizeof(MethodData)/wordSize; 1697 return sizeof(MethodData)/wordSize;
1277 } 1698 }
1278 1699
1508 const char* internal_name() const { return "{method data}"; } 1929 const char* internal_name() const { return "{method data}"; }
1509 1930
1510 // verification 1931 // verification
1511 void verify_on(outputStream* st); 1932 void verify_on(outputStream* st);
1512 void verify_data_on(outputStream* st); 1933 void verify_data_on(outputStream* st);
1934
1935 static bool profile_arguments();
1513 }; 1936 };
1514 1937
1515 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP 1938 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP