Mercurial > hg > graal-jvmci-8
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 |