Mercurial > hg > graal-compiler
comparison src/share/vm/oops/methodData.hpp @ 13102:f9f4503a4ab5
Merge
author | Christos Kotselidis <christos.kotselidis@oracle.com> |
---|---|
date | Thu, 21 Nov 2013 15:04:54 +0100 |
parents | 096c224171c4 |
children | d84fa69a9874 |
comparison
equal
deleted
inserted
replaced
13101:790ebab62d23 | 13102:f9f4503a4ab5 |
---|---|
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, | |
123 parameters_type_data_tag | |
121 }; | 124 }; |
122 | 125 |
123 enum { | 126 enum { |
124 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. | 127 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. |
125 // The trap state breaks down further as [recompile:1 | reason:3]. | 128 // The trap state breaks down further as [recompile:1 | reason:3]. |
163 // The associated trap histogram in the MDO itself tells whether | 166 // 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 | 167 // 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 | 168 // occurred, and the MDO shows N occurrences of X, we make the |
166 // simplifying assumption that all N occurrences can be blamed | 169 // simplifying assumption that all N occurrences can be blamed |
167 // on that BCI. | 170 // on that BCI. |
168 int trap_state() { | 171 int trap_state() const { |
169 return ((_header._struct._flags >> trap_shift) & trap_mask); | 172 return ((_header._struct._flags >> trap_shift) & trap_mask); |
170 } | 173 } |
171 | 174 |
172 void set_trap_state(int new_state) { | 175 void set_trap_state(int new_state) { |
173 assert(ProfileTraps, "used only under +ProfileTraps"); | 176 assert(ProfileTraps, "used only under +ProfileTraps"); |
174 uint old_flags = (_header._struct._flags & flag_mask); | 177 uint old_flags = (_header._struct._flags & flag_mask); |
175 _header._struct._flags = (new_state << trap_shift) | old_flags; | 178 _header._struct._flags = (new_state << trap_shift) | old_flags; |
176 } | 179 } |
177 | 180 |
178 u1 flags() { | 181 u1 flags() const { |
179 return _header._struct._flags; | 182 return _header._struct._flags; |
180 } | 183 } |
181 | 184 |
182 u2 bci() { | 185 u2 bci() const { |
183 return _header._struct._bci; | 186 return _header._struct._bci; |
184 } | 187 } |
185 | 188 |
186 void set_header(intptr_t value) { | 189 void set_header(intptr_t value) { |
187 _header._bits = value; | 190 _header._bits = value; |
196 _cells[index] = value; | 199 _cells[index] = value; |
197 } | 200 } |
198 void release_set_cell_at(int index, intptr_t value) { | 201 void release_set_cell_at(int index, intptr_t value) { |
199 OrderAccess::release_store_ptr(&_cells[index], value); | 202 OrderAccess::release_store_ptr(&_cells[index], value); |
200 } | 203 } |
201 intptr_t cell_at(int index) { | 204 intptr_t cell_at(int index) const { |
202 return _cells[index]; | 205 return _cells[index]; |
203 } | 206 } |
204 | 207 |
205 void set_flag_at(int flag_number) { | 208 void set_flag_at(int flag_number) { |
206 assert(flag_number < flag_limit, "oob"); | 209 assert(flag_number < flag_limit, "oob"); |
207 _header._struct._flags |= (0x1 << flag_number); | 210 _header._struct._flags |= (0x1 << flag_number); |
208 } | 211 } |
209 bool flag_at(int flag_number) { | 212 bool flag_at(int flag_number) const { |
210 assert(flag_number < flag_limit, "oob"); | 213 assert(flag_number < flag_limit, "oob"); |
211 return (_header._struct._flags & (0x1 << flag_number)) != 0; | 214 return (_header._struct._flags & (0x1 << flag_number)) != 0; |
212 } | 215 } |
213 | 216 |
214 // Low-level support for code generation. | 217 // Low-level support for code generation. |
252 class ProfileData; | 255 class ProfileData; |
253 class BitData; | 256 class BitData; |
254 class CounterData; | 257 class CounterData; |
255 class ReceiverTypeData; | 258 class ReceiverTypeData; |
256 class VirtualCallData; | 259 class VirtualCallData; |
260 class VirtualCallTypeData; | |
257 class RetData; | 261 class RetData; |
262 class CallTypeData; | |
258 class JumpData; | 263 class JumpData; |
259 class BranchData; | 264 class BranchData; |
260 class ArrayData; | 265 class ArrayData; |
261 class MultiBranchData; | 266 class MultiBranchData; |
262 class ArgInfoData; | 267 class ArgInfoData; |
263 | 268 class ParametersTypeData; |
264 | 269 |
265 // ProfileData | 270 // ProfileData |
266 // | 271 // |
267 // A ProfileData object is created to refer to a section of profiling | 272 // A ProfileData object is created to refer to a section of profiling |
268 // data in a structured way. | 273 // data in a structured way. |
269 class ProfileData : public ResourceObj { | 274 class ProfileData : public ResourceObj { |
275 friend class TypeEntries; | |
276 friend class ReturnTypeEntry; | |
277 friend class TypeStackSlotEntries; | |
270 private: | 278 private: |
271 #ifndef PRODUCT | 279 #ifndef PRODUCT |
272 enum { | 280 enum { |
273 tab_width_one = 16, | 281 tab_width_one = 16, |
274 tab_width_two = 36 | 282 tab_width_two = 36 |
278 // This is a pointer to a section of profiling data. | 286 // This is a pointer to a section of profiling data. |
279 DataLayout* _data; | 287 DataLayout* _data; |
280 | 288 |
281 protected: | 289 protected: |
282 DataLayout* data() { return _data; } | 290 DataLayout* data() { return _data; } |
291 const DataLayout* data() const { return _data; } | |
283 | 292 |
284 enum { | 293 enum { |
285 cell_size = DataLayout::cell_size | 294 cell_size = DataLayout::cell_size |
286 }; | 295 }; |
287 | 296 |
288 public: | 297 public: |
289 // How many cells are in this? | 298 // How many cells are in this? |
290 virtual int cell_count() { | 299 virtual int cell_count() const { |
291 ShouldNotReachHere(); | 300 ShouldNotReachHere(); |
292 return -1; | 301 return -1; |
293 } | 302 } |
294 | 303 |
295 // Return the size of this data. | 304 // Return the size of this data. |
305 } | 314 } |
306 void release_set_intptr_at(int index, intptr_t value) { | 315 void release_set_intptr_at(int index, intptr_t value) { |
307 assert(0 <= index && index < cell_count(), "oob"); | 316 assert(0 <= index && index < cell_count(), "oob"); |
308 data()->release_set_cell_at(index, value); | 317 data()->release_set_cell_at(index, value); |
309 } | 318 } |
310 intptr_t intptr_at(int index) { | 319 intptr_t intptr_at(int index) const { |
311 assert(0 <= index && index < cell_count(), "oob"); | 320 assert(0 <= index && index < cell_count(), "oob"); |
312 return data()->cell_at(index); | 321 return data()->cell_at(index); |
313 } | 322 } |
314 void set_uint_at(int index, uint value) { | 323 void set_uint_at(int index, uint value) { |
315 set_intptr_at(index, (intptr_t) value); | 324 set_intptr_at(index, (intptr_t) value); |
316 } | 325 } |
317 void release_set_uint_at(int index, uint value) { | 326 void release_set_uint_at(int index, uint value) { |
318 release_set_intptr_at(index, (intptr_t) value); | 327 release_set_intptr_at(index, (intptr_t) value); |
319 } | 328 } |
320 uint uint_at(int index) { | 329 uint uint_at(int index) const { |
321 return (uint)intptr_at(index); | 330 return (uint)intptr_at(index); |
322 } | 331 } |
323 void set_int_at(int index, int value) { | 332 void set_int_at(int index, int value) { |
324 set_intptr_at(index, (intptr_t) value); | 333 set_intptr_at(index, (intptr_t) value); |
325 } | 334 } |
326 void release_set_int_at(int index, int value) { | 335 void release_set_int_at(int index, int value) { |
327 release_set_intptr_at(index, (intptr_t) value); | 336 release_set_intptr_at(index, (intptr_t) value); |
328 } | 337 } |
329 int int_at(int index) { | 338 int int_at(int index) const { |
330 return (int)intptr_at(index); | 339 return (int)intptr_at(index); |
331 } | 340 } |
332 int int_at_unchecked(int index) { | 341 int int_at_unchecked(int index) const { |
333 return (int)data()->cell_at(index); | 342 return (int)data()->cell_at(index); |
334 } | 343 } |
335 void set_oop_at(int index, oop value) { | 344 void set_oop_at(int index, oop value) { |
336 set_intptr_at(index, cast_from_oop<intptr_t>(value)); | 345 set_intptr_at(index, cast_from_oop<intptr_t>(value)); |
337 } | 346 } |
338 oop oop_at(int index) { | 347 oop oop_at(int index) const { |
339 return cast_to_oop(intptr_at(index)); | 348 return cast_to_oop(intptr_at(index)); |
340 } | 349 } |
341 | 350 |
342 void set_flag_at(int flag_number) { | 351 void set_flag_at(int flag_number) { |
343 data()->set_flag_at(flag_number); | 352 data()->set_flag_at(flag_number); |
344 } | 353 } |
345 bool flag_at(int flag_number) { | 354 bool flag_at(int flag_number) const { |
346 return data()->flag_at(flag_number); | 355 return data()->flag_at(flag_number); |
347 } | 356 } |
348 | 357 |
349 // two convenient imports for use by subclasses: | 358 // two convenient imports for use by subclasses: |
350 static ByteSize cell_offset(int index) { | 359 static ByteSize cell_offset(int index) { |
360 | 369 |
361 public: | 370 public: |
362 // Constructor for invalid ProfileData. | 371 // Constructor for invalid ProfileData. |
363 ProfileData(); | 372 ProfileData(); |
364 | 373 |
365 u2 bci() { | 374 u2 bci() const { |
366 return data()->bci(); | 375 return data()->bci(); |
367 } | 376 } |
368 | 377 |
369 address dp() { | 378 address dp() { |
370 return (address)_data; | 379 return (address)_data; |
371 } | 380 } |
372 | 381 |
373 int trap_state() { | 382 int trap_state() const { |
374 return data()->trap_state(); | 383 return data()->trap_state(); |
375 } | 384 } |
376 void set_trap_state(int new_state) { | 385 void set_trap_state(int new_state) { |
377 data()->set_trap_state(new_state); | 386 data()->set_trap_state(new_state); |
378 } | 387 } |
379 | 388 |
380 // Type checking | 389 // Type checking |
381 virtual bool is_BitData() { return false; } | 390 virtual bool is_BitData() const { return false; } |
382 virtual bool is_CounterData() { return false; } | 391 virtual bool is_CounterData() const { return false; } |
383 virtual bool is_JumpData() { return false; } | 392 virtual bool is_JumpData() const { return false; } |
384 virtual bool is_ReceiverTypeData(){ return false; } | 393 virtual bool is_ReceiverTypeData()const { return false; } |
385 virtual bool is_VirtualCallData() { return false; } | 394 virtual bool is_VirtualCallData() const { return false; } |
386 virtual bool is_RetData() { return false; } | 395 virtual bool is_RetData() const { return false; } |
387 virtual bool is_BranchData() { return false; } | 396 virtual bool is_BranchData() const { return false; } |
388 virtual bool is_ArrayData() { return false; } | 397 virtual bool is_ArrayData() const { return false; } |
389 virtual bool is_MultiBranchData() { return false; } | 398 virtual bool is_MultiBranchData() const { return false; } |
390 virtual bool is_ArgInfoData() { return false; } | 399 virtual bool is_ArgInfoData() const { return false; } |
391 | 400 virtual bool is_CallTypeData() const { return false; } |
392 | 401 virtual bool is_VirtualCallTypeData()const { return false; } |
393 BitData* as_BitData() { | 402 virtual bool is_ParametersTypeData() const { return false; } |
403 | |
404 | |
405 BitData* as_BitData() const { | |
394 assert(is_BitData(), "wrong type"); | 406 assert(is_BitData(), "wrong type"); |
395 return is_BitData() ? (BitData*) this : NULL; | 407 return is_BitData() ? (BitData*) this : NULL; |
396 } | 408 } |
397 CounterData* as_CounterData() { | 409 CounterData* as_CounterData() const { |
398 assert(is_CounterData(), "wrong type"); | 410 assert(is_CounterData(), "wrong type"); |
399 return is_CounterData() ? (CounterData*) this : NULL; | 411 return is_CounterData() ? (CounterData*) this : NULL; |
400 } | 412 } |
401 JumpData* as_JumpData() { | 413 JumpData* as_JumpData() const { |
402 assert(is_JumpData(), "wrong type"); | 414 assert(is_JumpData(), "wrong type"); |
403 return is_JumpData() ? (JumpData*) this : NULL; | 415 return is_JumpData() ? (JumpData*) this : NULL; |
404 } | 416 } |
405 ReceiverTypeData* as_ReceiverTypeData() { | 417 ReceiverTypeData* as_ReceiverTypeData() const { |
406 assert(is_ReceiverTypeData(), "wrong type"); | 418 assert(is_ReceiverTypeData(), "wrong type"); |
407 return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL; | 419 return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL; |
408 } | 420 } |
409 VirtualCallData* as_VirtualCallData() { | 421 VirtualCallData* as_VirtualCallData() const { |
410 assert(is_VirtualCallData(), "wrong type"); | 422 assert(is_VirtualCallData(), "wrong type"); |
411 return is_VirtualCallData() ? (VirtualCallData*)this : NULL; | 423 return is_VirtualCallData() ? (VirtualCallData*)this : NULL; |
412 } | 424 } |
413 RetData* as_RetData() { | 425 RetData* as_RetData() const { |
414 assert(is_RetData(), "wrong type"); | 426 assert(is_RetData(), "wrong type"); |
415 return is_RetData() ? (RetData*) this : NULL; | 427 return is_RetData() ? (RetData*) this : NULL; |
416 } | 428 } |
417 BranchData* as_BranchData() { | 429 BranchData* as_BranchData() const { |
418 assert(is_BranchData(), "wrong type"); | 430 assert(is_BranchData(), "wrong type"); |
419 return is_BranchData() ? (BranchData*) this : NULL; | 431 return is_BranchData() ? (BranchData*) this : NULL; |
420 } | 432 } |
421 ArrayData* as_ArrayData() { | 433 ArrayData* as_ArrayData() const { |
422 assert(is_ArrayData(), "wrong type"); | 434 assert(is_ArrayData(), "wrong type"); |
423 return is_ArrayData() ? (ArrayData*) this : NULL; | 435 return is_ArrayData() ? (ArrayData*) this : NULL; |
424 } | 436 } |
425 MultiBranchData* as_MultiBranchData() { | 437 MultiBranchData* as_MultiBranchData() const { |
426 assert(is_MultiBranchData(), "wrong type"); | 438 assert(is_MultiBranchData(), "wrong type"); |
427 return is_MultiBranchData() ? (MultiBranchData*)this : NULL; | 439 return is_MultiBranchData() ? (MultiBranchData*)this : NULL; |
428 } | 440 } |
429 ArgInfoData* as_ArgInfoData() { | 441 ArgInfoData* as_ArgInfoData() const { |
430 assert(is_ArgInfoData(), "wrong type"); | 442 assert(is_ArgInfoData(), "wrong type"); |
431 return is_ArgInfoData() ? (ArgInfoData*)this : NULL; | 443 return is_ArgInfoData() ? (ArgInfoData*)this : NULL; |
444 } | |
445 CallTypeData* as_CallTypeData() const { | |
446 assert(is_CallTypeData(), "wrong type"); | |
447 return is_CallTypeData() ? (CallTypeData*)this : NULL; | |
448 } | |
449 VirtualCallTypeData* as_VirtualCallTypeData() const { | |
450 assert(is_VirtualCallTypeData(), "wrong type"); | |
451 return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL; | |
452 } | |
453 ParametersTypeData* as_ParametersTypeData() const { | |
454 assert(is_ParametersTypeData(), "wrong type"); | |
455 return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL; | |
432 } | 456 } |
433 | 457 |
434 | 458 |
435 // Subclass specific initialization | 459 // Subclass specific initialization |
436 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} | 460 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} |
441 // CI translation: ProfileData can represent both MethodDataOop data | 465 // CI translation: ProfileData can represent both MethodDataOop data |
442 // as well as CIMethodData data. This function is provided for translating | 466 // as well as CIMethodData data. This function is provided for translating |
443 // an oop in a ProfileData to the ci equivalent. Generally speaking, | 467 // an oop in a ProfileData to the ci equivalent. Generally speaking, |
444 // most ProfileData don't require any translation, so we provide the null | 468 // most ProfileData don't require any translation, so we provide the null |
445 // translation here, and the required translators are in the ci subclasses. | 469 // translation here, and the required translators are in the ci subclasses. |
446 virtual void translate_from(ProfileData* data) {} | 470 virtual void translate_from(const ProfileData* data) {} |
447 | 471 |
448 virtual void print_data_on(outputStream* st) { | 472 virtual void print_data_on(outputStream* st) const { |
449 ShouldNotReachHere(); | 473 ShouldNotReachHere(); |
450 } | 474 } |
451 | 475 |
452 #ifndef PRODUCT | 476 #ifndef PRODUCT |
453 void print_shared(outputStream* st, const char* name); | 477 void print_shared(outputStream* st, const char* name) const; |
454 void tab(outputStream* st); | 478 void tab(outputStream* st, bool first = false) const; |
455 #endif | 479 #endif |
456 }; | 480 }; |
457 | 481 |
458 // BitData | 482 // BitData |
459 // | 483 // |
472 enum { bit_cell_count = 0 }; // no additional data fields needed. | 496 enum { bit_cell_count = 0 }; // no additional data fields needed. |
473 public: | 497 public: |
474 BitData(DataLayout* layout) : ProfileData(layout) { | 498 BitData(DataLayout* layout) : ProfileData(layout) { |
475 } | 499 } |
476 | 500 |
477 virtual bool is_BitData() { return true; } | 501 virtual bool is_BitData() const { return true; } |
478 | 502 |
479 static int static_cell_count() { | 503 static int static_cell_count() { |
480 return bit_cell_count; | 504 return bit_cell_count; |
481 } | 505 } |
482 | 506 |
483 virtual int cell_count() { | 507 virtual int cell_count() const { |
484 return static_cell_count(); | 508 return static_cell_count(); |
485 } | 509 } |
486 | 510 |
487 // Accessor | 511 // Accessor |
488 | 512 |
504 static ByteSize bit_data_size() { | 528 static ByteSize bit_data_size() { |
505 return cell_offset(bit_cell_count); | 529 return cell_offset(bit_cell_count); |
506 } | 530 } |
507 | 531 |
508 #ifndef PRODUCT | 532 #ifndef PRODUCT |
509 void print_data_on(outputStream* st); | 533 void print_data_on(outputStream* st) const; |
510 #endif | 534 #endif |
511 }; | 535 }; |
512 | 536 |
513 // CounterData | 537 // CounterData |
514 // | 538 // |
520 counter_cell_count | 544 counter_cell_count |
521 }; | 545 }; |
522 public: | 546 public: |
523 CounterData(DataLayout* layout) : BitData(layout) {} | 547 CounterData(DataLayout* layout) : BitData(layout) {} |
524 | 548 |
525 virtual bool is_CounterData() { return true; } | 549 virtual bool is_CounterData() const { return true; } |
526 | 550 |
527 static int static_cell_count() { | 551 static int static_cell_count() { |
528 return counter_cell_count; | 552 return counter_cell_count; |
529 } | 553 } |
530 | 554 |
531 virtual int cell_count() { | 555 virtual int cell_count() const { |
532 return static_cell_count(); | 556 return static_cell_count(); |
533 } | 557 } |
534 | 558 |
535 // Direct accessor | 559 // Direct accessor |
536 uint count() { | 560 uint count() const { |
537 return uint_at(count_off); | 561 return uint_at(count_off); |
538 } | 562 } |
539 | 563 |
540 // Code generation support | 564 // Code generation support |
541 static ByteSize count_offset() { | 565 static ByteSize count_offset() { |
548 void set_count(uint count) { | 572 void set_count(uint count) { |
549 set_uint_at(count_off, count); | 573 set_uint_at(count_off, count); |
550 } | 574 } |
551 | 575 |
552 #ifndef PRODUCT | 576 #ifndef PRODUCT |
553 void print_data_on(outputStream* st); | 577 void print_data_on(outputStream* st) const; |
554 #endif | 578 #endif |
555 }; | 579 }; |
556 | 580 |
557 // JumpData | 581 // JumpData |
558 // | 582 // |
576 JumpData(DataLayout* layout) : ProfileData(layout) { | 600 JumpData(DataLayout* layout) : ProfileData(layout) { |
577 assert(layout->tag() == DataLayout::jump_data_tag || | 601 assert(layout->tag() == DataLayout::jump_data_tag || |
578 layout->tag() == DataLayout::branch_data_tag, "wrong type"); | 602 layout->tag() == DataLayout::branch_data_tag, "wrong type"); |
579 } | 603 } |
580 | 604 |
581 virtual bool is_JumpData() { return true; } | 605 virtual bool is_JumpData() const { return true; } |
582 | 606 |
583 static int static_cell_count() { | 607 static int static_cell_count() { |
584 return jump_cell_count; | 608 return jump_cell_count; |
585 } | 609 } |
586 | 610 |
587 virtual int cell_count() { | 611 virtual int cell_count() const { |
588 return static_cell_count(); | 612 return static_cell_count(); |
589 } | 613 } |
590 | 614 |
591 // Direct accessor | 615 // Direct accessor |
592 uint taken() { | 616 uint taken() const { |
593 return uint_at(taken_off_set); | 617 return uint_at(taken_off_set); |
594 } | 618 } |
595 | 619 |
596 void set_taken(uint cnt) { | 620 void set_taken(uint cnt) { |
597 set_uint_at(taken_off_set, cnt); | 621 set_uint_at(taken_off_set, cnt); |
604 if (cnt == 0) cnt--; | 628 if (cnt == 0) cnt--; |
605 set_uint_at(taken_off_set, cnt); | 629 set_uint_at(taken_off_set, cnt); |
606 return cnt; | 630 return cnt; |
607 } | 631 } |
608 | 632 |
609 int displacement() { | 633 int displacement() const { |
610 return int_at(displacement_off_set); | 634 return int_at(displacement_off_set); |
611 } | 635 } |
612 | 636 |
613 // Code generation support | 637 // Code generation support |
614 static ByteSize taken_offset() { | 638 static ByteSize taken_offset() { |
621 | 645 |
622 // Specific initialization. | 646 // Specific initialization. |
623 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 647 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
624 | 648 |
625 #ifndef PRODUCT | 649 #ifndef PRODUCT |
626 void print_data_on(outputStream* st); | 650 void print_data_on(outputStream* st) const; |
651 #endif | |
652 }; | |
653 | |
654 // Entries in a ProfileData object to record types: it can either be | |
655 // none (no profile), unknown (conflicting profile data) or a klass if | |
656 // a single one is seen. Whether a null reference was seen is also | |
657 // recorded. No counter is associated with the type and a single type | |
658 // is tracked (unlike VirtualCallData). | |
659 class TypeEntries { | |
660 | |
661 public: | |
662 | |
663 // A single cell is used to record information for a type: | |
664 // - the cell is initialized to 0 | |
665 // - when a type is discovered it is stored in the cell | |
666 // - bit zero of the cell is used to record whether a null reference | |
667 // was encountered or not | |
668 // - bit 1 is set to record a conflict in the type information | |
669 | |
670 enum { | |
671 null_seen = 1, | |
672 type_mask = ~null_seen, | |
673 type_unknown = 2, | |
674 status_bits = null_seen | type_unknown, | |
675 type_klass_mask = ~status_bits | |
676 }; | |
677 | |
678 // what to initialize a cell to | |
679 static intptr_t type_none() { | |
680 return 0; | |
681 } | |
682 | |
683 // null seen = bit 0 set? | |
684 static bool was_null_seen(intptr_t v) { | |
685 return (v & null_seen) != 0; | |
686 } | |
687 | |
688 // conflicting type information = bit 1 set? | |
689 static bool is_type_unknown(intptr_t v) { | |
690 return (v & type_unknown) != 0; | |
691 } | |
692 | |
693 // not type information yet = all bits cleared, ignoring bit 0? | |
694 static bool is_type_none(intptr_t v) { | |
695 return (v & type_mask) == 0; | |
696 } | |
697 | |
698 // recorded type: cell without bit 0 and 1 | |
699 static intptr_t klass_part(intptr_t v) { | |
700 intptr_t r = v & type_klass_mask; | |
701 return r; | |
702 } | |
703 | |
704 // type recorded | |
705 static Klass* valid_klass(intptr_t k) { | |
706 if (!is_type_none(k) && | |
707 !is_type_unknown(k)) { | |
708 Klass* res = (Klass*)klass_part(k); | |
709 assert(res != NULL, "invalid"); | |
710 return res; | |
711 } else { | |
712 return NULL; | |
713 } | |
714 } | |
715 | |
716 static intptr_t with_status(intptr_t k, intptr_t in) { | |
717 return k | (in & status_bits); | |
718 } | |
719 | |
720 static intptr_t with_status(Klass* k, intptr_t in) { | |
721 return with_status((intptr_t)k, in); | |
722 } | |
723 | |
724 #ifndef PRODUCT | |
725 static void print_klass(outputStream* st, intptr_t k); | |
726 #endif | |
727 | |
728 // GC support | |
729 static bool is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p); | |
730 | |
731 protected: | |
732 // ProfileData object these entries are part of | |
733 ProfileData* _pd; | |
734 // offset within the ProfileData object where the entries start | |
735 const int _base_off; | |
736 | |
737 TypeEntries(int base_off) | |
738 : _base_off(base_off), _pd(NULL) {} | |
739 | |
740 void set_intptr_at(int index, intptr_t value) { | |
741 _pd->set_intptr_at(index, value); | |
742 } | |
743 | |
744 intptr_t intptr_at(int index) const { | |
745 return _pd->intptr_at(index); | |
746 } | |
747 | |
748 public: | |
749 void set_profile_data(ProfileData* pd) { | |
750 _pd = pd; | |
751 } | |
752 }; | |
753 | |
754 // Type entries used for arguments passed at a call and parameters on | |
755 // method entry. 2 cells per entry: one for the type encoded as in | |
756 // TypeEntries and one initialized with the stack slot where the | |
757 // profiled object is to be found so that the interpreter can locate | |
758 // it quickly. | |
759 class TypeStackSlotEntries : public TypeEntries { | |
760 | |
761 private: | |
762 enum { | |
763 stack_slot_entry, | |
764 type_entry, | |
765 per_arg_cell_count | |
766 }; | |
767 | |
768 // offset of cell for stack slot for entry i within ProfileData object | |
769 int stack_slot_offset(int i) const { | |
770 return _base_off + stack_slot_local_offset(i); | |
771 } | |
772 | |
773 protected: | |
774 const int _number_of_entries; | |
775 | |
776 // offset of cell for type for entry i within ProfileData object | |
777 int type_offset(int i) const { | |
778 return _base_off + type_local_offset(i); | |
779 } | |
780 | |
781 public: | |
782 | |
783 TypeStackSlotEntries(int base_off, int nb_entries) | |
784 : TypeEntries(base_off), _number_of_entries(nb_entries) {} | |
785 | |
786 static int compute_cell_count(Symbol* signature, bool include_receiver, int max); | |
787 | |
788 void post_initialize(Symbol* signature, bool has_receiver, bool include_receiver); | |
789 | |
790 // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries | |
791 static int stack_slot_local_offset(int i) { | |
792 return i * per_arg_cell_count + stack_slot_entry; | |
793 } | |
794 | |
795 // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries | |
796 static int type_local_offset(int i) { | |
797 return i * per_arg_cell_count + type_entry; | |
798 } | |
799 | |
800 // stack slot for entry i | |
801 uint stack_slot(int i) const { | |
802 assert(i >= 0 && i < _number_of_entries, "oob"); | |
803 return _pd->uint_at(stack_slot_offset(i)); | |
804 } | |
805 | |
806 // set stack slot for entry i | |
807 void set_stack_slot(int i, uint num) { | |
808 assert(i >= 0 && i < _number_of_entries, "oob"); | |
809 _pd->set_uint_at(stack_slot_offset(i), num); | |
810 } | |
811 | |
812 // type for entry i | |
813 intptr_t type(int i) const { | |
814 assert(i >= 0 && i < _number_of_entries, "oob"); | |
815 return _pd->intptr_at(type_offset(i)); | |
816 } | |
817 | |
818 // set type for entry i | |
819 void set_type(int i, intptr_t k) { | |
820 assert(i >= 0 && i < _number_of_entries, "oob"); | |
821 _pd->set_intptr_at(type_offset(i), k); | |
822 } | |
823 | |
824 static ByteSize per_arg_size() { | |
825 return in_ByteSize(per_arg_cell_count * DataLayout::cell_size); | |
826 } | |
827 | |
828 static int per_arg_count() { | |
829 return per_arg_cell_count ; | |
830 } | |
831 | |
832 // GC support | |
833 void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); | |
834 | |
835 #ifndef PRODUCT | |
836 void print_data_on(outputStream* st) const; | |
837 #endif | |
838 }; | |
839 | |
840 // Type entry used for return from a call. A single cell to record the | |
841 // type. | |
842 class ReturnTypeEntry : public TypeEntries { | |
843 | |
844 private: | |
845 enum { | |
846 cell_count = 1 | |
847 }; | |
848 | |
849 public: | |
850 ReturnTypeEntry(int base_off) | |
851 : TypeEntries(base_off) {} | |
852 | |
853 void post_initialize() { | |
854 set_type(type_none()); | |
855 } | |
856 | |
857 intptr_t type() const { | |
858 return _pd->intptr_at(_base_off); | |
859 } | |
860 | |
861 void set_type(intptr_t k) { | |
862 _pd->set_intptr_at(_base_off, k); | |
863 } | |
864 | |
865 static int static_cell_count() { | |
866 return cell_count; | |
867 } | |
868 | |
869 static ByteSize size() { | |
870 return in_ByteSize(cell_count * DataLayout::cell_size); | |
871 } | |
872 | |
873 ByteSize type_offset() { | |
874 return DataLayout::cell_offset(_base_off); | |
875 } | |
876 | |
877 // GC support | |
878 void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); | |
879 | |
880 #ifndef PRODUCT | |
881 void print_data_on(outputStream* st) const; | |
882 #endif | |
883 }; | |
884 | |
885 // Entries to collect type information at a call: contains arguments | |
886 // (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a | |
887 // number of cells. Because the number of cells for the return type is | |
888 // smaller than the number of cells for the type of an arguments, the | |
889 // number of cells is used to tell how many arguments are profiled and | |
890 // whether a return value is profiled. See has_arguments() and | |
891 // has_return(). | |
892 class TypeEntriesAtCall { | |
893 private: | |
894 static int stack_slot_local_offset(int i) { | |
895 return header_cell_count() + TypeStackSlotEntries::stack_slot_local_offset(i); | |
896 } | |
897 | |
898 static int argument_type_local_offset(int i) { | |
899 return header_cell_count() + TypeStackSlotEntries::type_local_offset(i);; | |
900 } | |
901 | |
902 public: | |
903 | |
904 static int header_cell_count() { | |
905 return 1; | |
906 } | |
907 | |
908 static int cell_count_local_offset() { | |
909 return 0; | |
910 } | |
911 | |
912 static int compute_cell_count(BytecodeStream* stream); | |
913 | |
914 static void initialize(DataLayout* dl, int base, int cell_count) { | |
915 int off = base + cell_count_local_offset(); | |
916 dl->set_cell_at(off, cell_count - base - header_cell_count()); | |
917 } | |
918 | |
919 static bool arguments_profiling_enabled(); | |
920 static bool return_profiling_enabled(); | |
921 | |
922 // Code generation support | |
923 static ByteSize cell_count_offset() { | |
924 return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size); | |
925 } | |
926 | |
927 static ByteSize args_data_offset() { | |
928 return in_ByteSize(header_cell_count() * DataLayout::cell_size); | |
929 } | |
930 | |
931 static ByteSize stack_slot_offset(int i) { | |
932 return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size); | |
933 } | |
934 | |
935 static ByteSize argument_type_offset(int i) { | |
936 return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size); | |
937 } | |
938 }; | |
939 | |
940 // CallTypeData | |
941 // | |
942 // A CallTypeData is used to access profiling information about a non | |
943 // virtual call for which we collect type information about arguments | |
944 // and return value. | |
945 class CallTypeData : public CounterData { | |
946 private: | |
947 // entries for arguments if any | |
948 TypeStackSlotEntries _args; | |
949 // entry for return type if any | |
950 ReturnTypeEntry _ret; | |
951 | |
952 int cell_count_global_offset() const { | |
953 return CounterData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset(); | |
954 } | |
955 | |
956 // number of cells not counting the header | |
957 int cell_count_no_header() const { | |
958 return uint_at(cell_count_global_offset()); | |
959 } | |
960 | |
961 void check_number_of_arguments(int total) { | |
962 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); | |
963 } | |
964 | |
965 public: | |
966 CallTypeData(DataLayout* layout) : | |
967 CounterData(layout), | |
968 _args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), | |
969 _ret(cell_count() - ReturnTypeEntry::static_cell_count()) | |
970 { | |
971 assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type"); | |
972 // Some compilers (VC++) don't want this passed in member initialization list | |
973 _args.set_profile_data(this); | |
974 _ret.set_profile_data(this); | |
975 } | |
976 | |
977 const TypeStackSlotEntries* args() const { | |
978 assert(has_arguments(), "no profiling of arguments"); | |
979 return &_args; | |
980 } | |
981 | |
982 const ReturnTypeEntry* ret() const { | |
983 assert(has_return(), "no profiling of return value"); | |
984 return &_ret; | |
985 } | |
986 | |
987 virtual bool is_CallTypeData() const { return true; } | |
988 | |
989 static int static_cell_count() { | |
990 return -1; | |
991 } | |
992 | |
993 static int compute_cell_count(BytecodeStream* stream) { | |
994 return CounterData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream); | |
995 } | |
996 | |
997 static void initialize(DataLayout* dl, int cell_count) { | |
998 TypeEntriesAtCall::initialize(dl, CounterData::static_cell_count(), cell_count); | |
999 } | |
1000 | |
1001 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); | |
1002 | |
1003 virtual int cell_count() const { | |
1004 return CounterData::static_cell_count() + | |
1005 TypeEntriesAtCall::header_cell_count() + | |
1006 int_at_unchecked(cell_count_global_offset()); | |
1007 } | |
1008 | |
1009 int number_of_arguments() const { | |
1010 return cell_count_no_header() / TypeStackSlotEntries::per_arg_count(); | |
1011 } | |
1012 | |
1013 void set_argument_type(int i, Klass* k) { | |
1014 assert(has_arguments(), "no arguments!"); | |
1015 intptr_t current = _args.type(i); | |
1016 _args.set_type(i, TypeEntries::with_status(k, current)); | |
1017 } | |
1018 | |
1019 void set_return_type(Klass* k) { | |
1020 assert(has_return(), "no return!"); | |
1021 intptr_t current = _ret.type(); | |
1022 _ret.set_type(TypeEntries::with_status(k, current)); | |
1023 } | |
1024 | |
1025 // An entry for a return value takes less space than an entry for an | |
1026 // argument so if the number of cells exceeds the number of cells | |
1027 // needed for an argument, this object contains type information for | |
1028 // at least one argument. | |
1029 bool has_arguments() const { | |
1030 bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); | |
1031 assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); | |
1032 return res; | |
1033 } | |
1034 | |
1035 // An entry for a return value takes less space than an entry for an | |
1036 // argument, so if the remainder of the number of cells divided by | |
1037 // the number of cells for an argument is not null, a return value | |
1038 // is profiled in this object. | |
1039 bool has_return() const { | |
1040 bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; | |
1041 assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); | |
1042 return res; | |
1043 } | |
1044 | |
1045 // Code generation support | |
1046 static ByteSize args_data_offset() { | |
1047 return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); | |
1048 } | |
1049 | |
1050 // GC support | |
1051 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { | |
1052 if (has_arguments()) { | |
1053 _args.clean_weak_klass_links(is_alive_closure); | |
1054 } | |
1055 if (has_return()) { | |
1056 _ret.clean_weak_klass_links(is_alive_closure); | |
1057 } | |
1058 } | |
1059 | |
1060 #ifndef PRODUCT | |
1061 virtual void print_data_on(outputStream* st) const; | |
627 #endif | 1062 #endif |
628 }; | 1063 }; |
629 | 1064 |
630 // ReceiverTypeData | 1065 // ReceiverTypeData |
631 // | 1066 // |
657 }; | 1092 }; |
658 | 1093 |
659 public: | 1094 public: |
660 ReceiverTypeData(DataLayout* layout) : CounterData(layout) { | 1095 ReceiverTypeData(DataLayout* layout) : CounterData(layout) { |
661 assert(layout->tag() == DataLayout::receiver_type_data_tag || | 1096 assert(layout->tag() == DataLayout::receiver_type_data_tag || |
662 layout->tag() == DataLayout::virtual_call_data_tag, "wrong type"); | 1097 layout->tag() == DataLayout::virtual_call_data_tag || |
663 } | 1098 layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); |
664 | 1099 } |
665 virtual bool is_ReceiverTypeData() { return true; } | 1100 |
1101 virtual bool is_ReceiverTypeData() const { return true; } | |
666 | 1102 |
667 static int static_cell_count() { | 1103 static int static_cell_count() { |
668 return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count GRAAL_ONLY(+ 1); | 1104 return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count GRAAL_ONLY(+ 1); |
669 } | 1105 } |
670 | 1106 |
671 virtual int cell_count() { | 1107 virtual int cell_count() const { |
672 return static_cell_count(); | 1108 return static_cell_count(); |
673 } | 1109 } |
674 | 1110 |
675 // Direct accessors | 1111 // Direct accessors |
676 static uint row_limit() { | 1112 static uint row_limit() { |
681 } | 1117 } |
682 static int receiver_count_cell_index(uint row) { | 1118 static int receiver_count_cell_index(uint row) { |
683 return count0_offset + row * receiver_type_row_cell_count; | 1119 return count0_offset + row * receiver_type_row_cell_count; |
684 } | 1120 } |
685 | 1121 |
686 Klass* receiver(uint row) { | 1122 Klass* receiver(uint row) const { |
687 assert(row < row_limit(), "oob"); | 1123 assert(row < row_limit(), "oob"); |
688 | 1124 |
689 Klass* recv = (Klass*)intptr_at(receiver_cell_index(row)); | 1125 Klass* recv = (Klass*)intptr_at(receiver_cell_index(row)); |
690 assert(recv == NULL || recv->is_klass(), "wrong type"); | 1126 assert(recv == NULL || recv->is_klass(), "wrong type"); |
691 return recv; | 1127 return recv; |
694 void set_receiver(uint row, Klass* k) { | 1130 void set_receiver(uint row, Klass* k) { |
695 assert((uint)row < row_limit(), "oob"); | 1131 assert((uint)row < row_limit(), "oob"); |
696 set_intptr_at(receiver_cell_index(row), (uintptr_t)k); | 1132 set_intptr_at(receiver_cell_index(row), (uintptr_t)k); |
697 } | 1133 } |
698 | 1134 |
699 uint receiver_count(uint row) { | 1135 uint receiver_count(uint row) const { |
700 assert(row < row_limit(), "oob"); | 1136 assert(row < row_limit(), "oob"); |
701 return uint_at(receiver_count_cell_index(row)); | 1137 return uint_at(receiver_count_cell_index(row)); |
702 } | 1138 } |
703 | 1139 |
704 void set_receiver_count(uint row, uint count) { | 1140 void set_receiver_count(uint row, uint count) { |
757 | 1193 |
758 // GC support | 1194 // GC support |
759 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); | 1195 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); |
760 | 1196 |
761 #ifndef PRODUCT | 1197 #ifndef PRODUCT |
762 void print_receiver_data_on(outputStream* st); | 1198 void print_receiver_data_on(outputStream* st) const; |
763 void print_data_on(outputStream* st); | 1199 void print_data_on(outputStream* st) const; |
764 #endif | 1200 #endif |
765 }; | 1201 }; |
766 | 1202 |
767 // VirtualCallData | 1203 // VirtualCallData |
768 // | 1204 // |
769 // A VirtualCallData is used to access profiling information about a | 1205 // A VirtualCallData is used to access profiling information about a |
770 // virtual call. For now, it has nothing more than a ReceiverTypeData. | 1206 // virtual call. For now, it has nothing more than a ReceiverTypeData. |
771 class VirtualCallData : public ReceiverTypeData { | 1207 class VirtualCallData : public ReceiverTypeData { |
772 public: | 1208 public: |
773 VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) { | 1209 VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) { |
774 assert(layout->tag() == DataLayout::virtual_call_data_tag, "wrong type"); | 1210 assert(layout->tag() == DataLayout::virtual_call_data_tag || |
775 } | 1211 layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); |
776 | 1212 } |
777 virtual bool is_VirtualCallData() { return true; } | 1213 |
1214 virtual bool is_VirtualCallData() const { return true; } | |
778 | 1215 |
779 static int static_cell_count() { | 1216 static int static_cell_count() { |
780 // At this point we could add more profile state, e.g., for arguments. | 1217 // At this point we could add more profile state, e.g., for arguments. |
781 // But for now it's the same size as the base record type. | 1218 // But for now it's the same size as the base record type. |
782 return ReceiverTypeData::static_cell_count() GRAAL_ONLY(+ (uint) MethodProfileWidth * receiver_type_row_cell_count); | 1219 return ReceiverTypeData::static_cell_count() GRAAL_ONLY(+ (uint) MethodProfileWidth * receiver_type_row_cell_count); |
783 } | 1220 } |
784 | 1221 |
785 virtual int cell_count() { | 1222 virtual int cell_count() const { |
786 return static_cell_count(); | 1223 return static_cell_count(); |
787 } | 1224 } |
788 | 1225 |
789 // Direct accessors | 1226 // Direct accessors |
790 static ByteSize virtual_call_data_size() { | 1227 static ByteSize virtual_call_data_size() { |
837 // GC support | 1274 // GC support |
838 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); | 1275 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); |
839 #endif | 1276 #endif |
840 | 1277 |
841 #ifndef PRODUCT | 1278 #ifndef PRODUCT |
842 void print_data_on(outputStream* st); | 1279 void print_data_on(outputStream* st) const; |
1280 #endif | |
1281 }; | |
1282 | |
1283 // VirtualCallTypeData | |
1284 // | |
1285 // A VirtualCallTypeData is used to access profiling information about | |
1286 // a virtual call for which we collect type information about | |
1287 // arguments and return value. | |
1288 class VirtualCallTypeData : public VirtualCallData { | |
1289 private: | |
1290 // entries for arguments if any | |
1291 TypeStackSlotEntries _args; | |
1292 // entry for return type if any | |
1293 ReturnTypeEntry _ret; | |
1294 | |
1295 int cell_count_global_offset() const { | |
1296 return VirtualCallData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset(); | |
1297 } | |
1298 | |
1299 // number of cells not counting the header | |
1300 int cell_count_no_header() const { | |
1301 return uint_at(cell_count_global_offset()); | |
1302 } | |
1303 | |
1304 void check_number_of_arguments(int total) { | |
1305 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); | |
1306 } | |
1307 | |
1308 public: | |
1309 VirtualCallTypeData(DataLayout* layout) : | |
1310 VirtualCallData(layout), | |
1311 _args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), | |
1312 _ret(cell_count() - ReturnTypeEntry::static_cell_count()) | |
1313 { | |
1314 assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); | |
1315 // Some compilers (VC++) don't want this passed in member initialization list | |
1316 _args.set_profile_data(this); | |
1317 _ret.set_profile_data(this); | |
1318 } | |
1319 | |
1320 const TypeStackSlotEntries* args() const { | |
1321 assert(has_arguments(), "no profiling of arguments"); | |
1322 return &_args; | |
1323 } | |
1324 | |
1325 const ReturnTypeEntry* ret() const { | |
1326 assert(has_return(), "no profiling of return value"); | |
1327 return &_ret; | |
1328 } | |
1329 | |
1330 virtual bool is_VirtualCallTypeData() const { return true; } | |
1331 | |
1332 static int static_cell_count() { | |
1333 return -1; | |
1334 } | |
1335 | |
1336 static int compute_cell_count(BytecodeStream* stream) { | |
1337 return VirtualCallData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream); | |
1338 } | |
1339 | |
1340 static void initialize(DataLayout* dl, int cell_count) { | |
1341 TypeEntriesAtCall::initialize(dl, VirtualCallData::static_cell_count(), cell_count); | |
1342 } | |
1343 | |
1344 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); | |
1345 | |
1346 virtual int cell_count() const { | |
1347 return VirtualCallData::static_cell_count() + | |
1348 TypeEntriesAtCall::header_cell_count() + | |
1349 int_at_unchecked(cell_count_global_offset()); | |
1350 } | |
1351 | |
1352 int number_of_arguments() const { | |
1353 return cell_count_no_header() / TypeStackSlotEntries::per_arg_count(); | |
1354 } | |
1355 | |
1356 void set_argument_type(int i, Klass* k) { | |
1357 assert(has_arguments(), "no arguments!"); | |
1358 intptr_t current = _args.type(i); | |
1359 _args.set_type(i, TypeEntries::with_status(k, current)); | |
1360 } | |
1361 | |
1362 void set_return_type(Klass* k) { | |
1363 assert(has_return(), "no return!"); | |
1364 intptr_t current = _ret.type(); | |
1365 _ret.set_type(TypeEntries::with_status(k, current)); | |
1366 } | |
1367 | |
1368 // An entry for a return value takes less space than an entry for an | |
1369 // argument, so if the remainder of the number of cells divided by | |
1370 // the number of cells for an argument is not null, a return value | |
1371 // is profiled in this object. | |
1372 bool has_return() const { | |
1373 bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; | |
1374 assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); | |
1375 return res; | |
1376 } | |
1377 | |
1378 // An entry for a return value takes less space than an entry for an | |
1379 // argument so if the number of cells exceeds the number of cells | |
1380 // needed for an argument, this object contains type information for | |
1381 // at least one argument. | |
1382 bool has_arguments() const { | |
1383 bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); | |
1384 assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); | |
1385 return res; | |
1386 } | |
1387 | |
1388 // Code generation support | |
1389 static ByteSize args_data_offset() { | |
1390 return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); | |
1391 } | |
1392 | |
1393 // GC support | |
1394 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { | |
1395 ReceiverTypeData::clean_weak_klass_links(is_alive_closure); | |
1396 if (has_arguments()) { | |
1397 _args.clean_weak_klass_links(is_alive_closure); | |
1398 } | |
1399 if (has_return()) { | |
1400 _ret.clean_weak_klass_links(is_alive_closure); | |
1401 } | |
1402 } | |
1403 | |
1404 #ifndef PRODUCT | |
1405 virtual void print_data_on(outputStream* st) const; | |
843 #endif | 1406 #endif |
844 }; | 1407 }; |
845 | 1408 |
846 // RetData | 1409 // RetData |
847 // | 1410 // |
880 public: | 1443 public: |
881 RetData(DataLayout* layout) : CounterData(layout) { | 1444 RetData(DataLayout* layout) : CounterData(layout) { |
882 assert(layout->tag() == DataLayout::ret_data_tag, "wrong type"); | 1445 assert(layout->tag() == DataLayout::ret_data_tag, "wrong type"); |
883 } | 1446 } |
884 | 1447 |
885 virtual bool is_RetData() { return true; } | 1448 virtual bool is_RetData() const { return true; } |
886 | 1449 |
887 enum { | 1450 enum { |
888 no_bci = -1 // value of bci when bci1/2 are not in use. | 1451 no_bci = -1 // value of bci when bci1/2 are not in use. |
889 }; | 1452 }; |
890 | 1453 |
891 static int static_cell_count() { | 1454 static int static_cell_count() { |
892 return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count; | 1455 return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count; |
893 } | 1456 } |
894 | 1457 |
895 virtual int cell_count() { | 1458 virtual int cell_count() const { |
896 return static_cell_count(); | 1459 return static_cell_count(); |
897 } | 1460 } |
898 | 1461 |
899 static uint row_limit() { | 1462 static uint row_limit() { |
900 return BciProfileWidth; | 1463 return BciProfileWidth; |
908 static int bci_displacement_cell_index(uint row) { | 1471 static int bci_displacement_cell_index(uint row) { |
909 return displacement0_offset + row * ret_row_cell_count; | 1472 return displacement0_offset + row * ret_row_cell_count; |
910 } | 1473 } |
911 | 1474 |
912 // Direct accessors | 1475 // Direct accessors |
913 int bci(uint row) { | 1476 int bci(uint row) const { |
914 return int_at(bci_cell_index(row)); | 1477 return int_at(bci_cell_index(row)); |
915 } | 1478 } |
916 uint bci_count(uint row) { | 1479 uint bci_count(uint row) const { |
917 return uint_at(bci_count_cell_index(row)); | 1480 return uint_at(bci_count_cell_index(row)); |
918 } | 1481 } |
919 int bci_displacement(uint row) { | 1482 int bci_displacement(uint row) const { |
920 return int_at(bci_displacement_cell_index(row)); | 1483 return int_at(bci_displacement_cell_index(row)); |
921 } | 1484 } |
922 | 1485 |
923 // Interpreter Runtime support | 1486 // Interpreter Runtime support |
924 address fixup_ret(int return_bci, MethodData* mdo); | 1487 address fixup_ret(int return_bci, MethodData* mdo); |
936 | 1499 |
937 // Specific initialization. | 1500 // Specific initialization. |
938 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1501 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
939 | 1502 |
940 #ifndef PRODUCT | 1503 #ifndef PRODUCT |
941 void print_data_on(outputStream* st); | 1504 void print_data_on(outputStream* st) const; |
942 #endif | 1505 #endif |
943 }; | 1506 }; |
944 | 1507 |
945 // BranchData | 1508 // BranchData |
946 // | 1509 // |
961 public: | 1524 public: |
962 BranchData(DataLayout* layout) : JumpData(layout) { | 1525 BranchData(DataLayout* layout) : JumpData(layout) { |
963 assert(layout->tag() == DataLayout::branch_data_tag, "wrong type"); | 1526 assert(layout->tag() == DataLayout::branch_data_tag, "wrong type"); |
964 } | 1527 } |
965 | 1528 |
966 virtual bool is_BranchData() { return true; } | 1529 virtual bool is_BranchData() const { return true; } |
967 | 1530 |
968 static int static_cell_count() { | 1531 static int static_cell_count() { |
969 return branch_cell_count; | 1532 return branch_cell_count; |
970 } | 1533 } |
971 | 1534 |
972 virtual int cell_count() { | 1535 virtual int cell_count() const { |
973 return static_cell_count(); | 1536 return static_cell_count(); |
974 } | 1537 } |
975 | 1538 |
976 // Direct accessor | 1539 // Direct accessor |
977 uint not_taken() { | 1540 uint not_taken() const { |
978 return uint_at(not_taken_off_set); | 1541 return uint_at(not_taken_off_set); |
979 } | 1542 } |
980 | 1543 |
981 void set_not_taken(uint cnt) { | 1544 void set_not_taken(uint cnt) { |
982 set_uint_at(not_taken_off_set, cnt); | 1545 set_uint_at(not_taken_off_set, cnt); |
1000 | 1563 |
1001 // Specific initialization. | 1564 // Specific initialization. |
1002 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1565 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1003 | 1566 |
1004 #ifndef PRODUCT | 1567 #ifndef PRODUCT |
1005 void print_data_on(outputStream* st); | 1568 void print_data_on(outputStream* st) const; |
1006 #endif | 1569 #endif |
1007 }; | 1570 }; |
1008 | 1571 |
1009 // ArrayData | 1572 // ArrayData |
1010 // | 1573 // |
1018 enum { | 1581 enum { |
1019 array_len_off_set, | 1582 array_len_off_set, |
1020 array_start_off_set | 1583 array_start_off_set |
1021 }; | 1584 }; |
1022 | 1585 |
1023 uint array_uint_at(int index) { | 1586 uint array_uint_at(int index) const { |
1024 int aindex = index + array_start_off_set; | 1587 int aindex = index + array_start_off_set; |
1025 return uint_at(aindex); | 1588 return uint_at(aindex); |
1026 } | 1589 } |
1027 int array_int_at(int index) { | 1590 int array_int_at(int index) const { |
1028 int aindex = index + array_start_off_set; | 1591 int aindex = index + array_start_off_set; |
1029 return int_at(aindex); | 1592 return int_at(aindex); |
1030 } | 1593 } |
1031 oop array_oop_at(int index) { | 1594 oop array_oop_at(int index) const { |
1032 int aindex = index + array_start_off_set; | 1595 int aindex = index + array_start_off_set; |
1033 return oop_at(aindex); | 1596 return oop_at(aindex); |
1034 } | 1597 } |
1035 void array_set_int_at(int index, int value) { | 1598 void array_set_int_at(int index, int value) { |
1036 int aindex = index + array_start_off_set; | 1599 int aindex = index + array_start_off_set; |
1043 } | 1606 } |
1044 | 1607 |
1045 public: | 1608 public: |
1046 ArrayData(DataLayout* layout) : ProfileData(layout) {} | 1609 ArrayData(DataLayout* layout) : ProfileData(layout) {} |
1047 | 1610 |
1048 virtual bool is_ArrayData() { return true; } | 1611 virtual bool is_ArrayData() const { return true; } |
1049 | 1612 |
1050 static int static_cell_count() { | 1613 static int static_cell_count() { |
1051 return -1; | 1614 return -1; |
1052 } | 1615 } |
1053 | 1616 |
1054 int array_len() { | 1617 int array_len() const { |
1055 return int_at_unchecked(array_len_off_set); | 1618 return int_at_unchecked(array_len_off_set); |
1056 } | 1619 } |
1057 | 1620 |
1058 virtual int cell_count() { | 1621 virtual int cell_count() const { |
1059 return array_len() + 1; | 1622 return array_len() + 1; |
1060 } | 1623 } |
1061 | 1624 |
1062 // Code generation support | 1625 // Code generation support |
1063 static ByteSize array_len_offset() { | 1626 static ByteSize array_len_offset() { |
1100 public: | 1663 public: |
1101 MultiBranchData(DataLayout* layout) : ArrayData(layout) { | 1664 MultiBranchData(DataLayout* layout) : ArrayData(layout) { |
1102 assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type"); | 1665 assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type"); |
1103 } | 1666 } |
1104 | 1667 |
1105 virtual bool is_MultiBranchData() { return true; } | 1668 virtual bool is_MultiBranchData() const { return true; } |
1106 | 1669 |
1107 static int compute_cell_count(BytecodeStream* stream); | 1670 static int compute_cell_count(BytecodeStream* stream); |
1108 | 1671 |
1109 int number_of_cases() { | 1672 int number_of_cases() const { |
1110 int alen = array_len() - 2; // get rid of default case here. | 1673 int alen = array_len() - 2; // get rid of default case here. |
1111 assert(alen % per_case_cell_count == 0, "must be even"); | 1674 assert(alen % per_case_cell_count == 0, "must be even"); |
1112 return (alen / per_case_cell_count); | 1675 return (alen / per_case_cell_count); |
1113 } | 1676 } |
1114 | 1677 |
1115 uint default_count() { | 1678 uint default_count() const { |
1116 return array_uint_at(default_count_off_set); | 1679 return array_uint_at(default_count_off_set); |
1117 } | 1680 } |
1118 int default_displacement() { | 1681 int default_displacement() const { |
1119 return array_int_at(default_disaplacement_off_set); | 1682 return array_int_at(default_disaplacement_off_set); |
1120 } | 1683 } |
1121 | 1684 |
1122 uint count_at(int index) { | 1685 uint count_at(int index) const { |
1123 return array_uint_at(case_array_start + | 1686 return array_uint_at(case_array_start + |
1124 index * per_case_cell_count + | 1687 index * per_case_cell_count + |
1125 relative_count_off_set); | 1688 relative_count_off_set); |
1126 } | 1689 } |
1127 int displacement_at(int index) { | 1690 int displacement_at(int index) const { |
1128 return array_int_at(case_array_start + | 1691 return array_int_at(case_array_start + |
1129 index * per_case_cell_count + | 1692 index * per_case_cell_count + |
1130 relative_displacement_off_set); | 1693 relative_displacement_off_set); |
1131 } | 1694 } |
1132 | 1695 |
1157 | 1720 |
1158 // Specific initialization. | 1721 // Specific initialization. |
1159 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1722 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1160 | 1723 |
1161 #ifndef PRODUCT | 1724 #ifndef PRODUCT |
1162 void print_data_on(outputStream* st); | 1725 void print_data_on(outputStream* st) const; |
1163 #endif | 1726 #endif |
1164 }; | 1727 }; |
1165 | 1728 |
1166 class ArgInfoData : public ArrayData { | 1729 class ArgInfoData : public ArrayData { |
1167 | 1730 |
1168 public: | 1731 public: |
1169 ArgInfoData(DataLayout* layout) : ArrayData(layout) { | 1732 ArgInfoData(DataLayout* layout) : ArrayData(layout) { |
1170 assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type"); | 1733 assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type"); |
1171 } | 1734 } |
1172 | 1735 |
1173 virtual bool is_ArgInfoData() { return true; } | 1736 virtual bool is_ArgInfoData() const { return true; } |
1174 | 1737 |
1175 | 1738 |
1176 int number_of_args() { | 1739 int number_of_args() const { |
1177 return array_len(); | 1740 return array_len(); |
1178 } | 1741 } |
1179 | 1742 |
1180 uint arg_modified(int arg) { | 1743 uint arg_modified(int arg) const { |
1181 return array_uint_at(arg); | 1744 return array_uint_at(arg); |
1182 } | 1745 } |
1183 | 1746 |
1184 void set_arg_modified(int arg, uint val) { | 1747 void set_arg_modified(int arg, uint val) { |
1185 array_set_int_at(arg, val); | 1748 array_set_int_at(arg, val); |
1186 } | 1749 } |
1187 | 1750 |
1188 #ifndef PRODUCT | 1751 #ifndef PRODUCT |
1189 void print_data_on(outputStream* st); | 1752 void print_data_on(outputStream* st) const; |
1190 #endif | 1753 #endif |
1754 }; | |
1755 | |
1756 // ParametersTypeData | |
1757 // | |
1758 // A ParametersTypeData is used to access profiling information about | |
1759 // types of parameters to a method | |
1760 class ParametersTypeData : public ArrayData { | |
1761 | |
1762 private: | |
1763 TypeStackSlotEntries _parameters; | |
1764 | |
1765 static int stack_slot_local_offset(int i) { | |
1766 assert_profiling_enabled(); | |
1767 return array_start_off_set + TypeStackSlotEntries::stack_slot_local_offset(i); | |
1768 } | |
1769 | |
1770 static int type_local_offset(int i) { | |
1771 assert_profiling_enabled(); | |
1772 return array_start_off_set + TypeStackSlotEntries::type_local_offset(i); | |
1773 } | |
1774 | |
1775 static bool profiling_enabled(); | |
1776 static void assert_profiling_enabled() { | |
1777 assert(profiling_enabled(), "method parameters profiling should be on"); | |
1778 } | |
1779 | |
1780 public: | |
1781 ParametersTypeData(DataLayout* layout) : ArrayData(layout), _parameters(1, number_of_parameters()) { | |
1782 assert(layout->tag() == DataLayout::parameters_type_data_tag, "wrong type"); | |
1783 // Some compilers (VC++) don't want this passed in member initialization list | |
1784 _parameters.set_profile_data(this); | |
1785 } | |
1786 | |
1787 static int compute_cell_count(Method* m); | |
1788 | |
1789 virtual bool is_ParametersTypeData() const { return true; } | |
1790 | |
1791 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); | |
1792 | |
1793 int number_of_parameters() const { | |
1794 return array_len() / TypeStackSlotEntries::per_arg_count(); | |
1795 } | |
1796 | |
1797 const TypeStackSlotEntries* parameters() const { return &_parameters; } | |
1798 | |
1799 uint stack_slot(int i) const { | |
1800 return _parameters.stack_slot(i); | |
1801 } | |
1802 | |
1803 void set_type(int i, Klass* k) { | |
1804 intptr_t current = _parameters.type(i); | |
1805 _parameters.set_type(i, TypeEntries::with_status((intptr_t)k, current)); | |
1806 } | |
1807 | |
1808 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { | |
1809 _parameters.clean_weak_klass_links(is_alive_closure); | |
1810 } | |
1811 | |
1812 #ifndef PRODUCT | |
1813 virtual void print_data_on(outputStream* st) const; | |
1814 #endif | |
1815 | |
1816 static ByteSize stack_slot_offset(int i) { | |
1817 return cell_offset(stack_slot_local_offset(i)); | |
1818 } | |
1819 | |
1820 static ByteSize type_offset(int i) { | |
1821 return cell_offset(type_local_offset(i)); | |
1822 } | |
1191 }; | 1823 }; |
1192 | 1824 |
1193 // MethodData* | 1825 // MethodData* |
1194 // | 1826 // |
1195 // A MethodData* holds information which has been collected about | 1827 // A MethodData* holds information which has been collected about |
1300 bool _would_profile; | 1932 bool _would_profile; |
1301 | 1933 |
1302 // Size of _data array in bytes. (Excludes header and extra_data fields.) | 1934 // Size of _data array in bytes. (Excludes header and extra_data fields.) |
1303 int _data_size; | 1935 int _data_size; |
1304 | 1936 |
1937 // data index for the area dedicated to parameters. -1 if no | |
1938 // parameter profiling. | |
1939 int _parameters_type_data_di; | |
1940 | |
1305 // Beginning of the data entries | 1941 // Beginning of the data entries |
1306 intptr_t _data[1]; | 1942 intptr_t _data[1]; |
1307 | 1943 |
1308 // Helper for size computation | 1944 // Helper for size computation |
1309 static int compute_data_size(BytecodeStream* stream); | 1945 static int compute_data_size(BytecodeStream* stream); |
1354 // Find or create an extra ProfileData: | 1990 // Find or create an extra ProfileData: |
1355 ProfileData* bci_to_extra_data(int bci, bool create_if_missing); | 1991 ProfileData* bci_to_extra_data(int bci, bool create_if_missing); |
1356 | 1992 |
1357 // return the argument info cell | 1993 // return the argument info cell |
1358 ArgInfoData *arg_info(); | 1994 ArgInfoData *arg_info(); |
1995 | |
1996 enum { | |
1997 no_type_profile = 0, | |
1998 type_profile_jsr292 = 1, | |
1999 type_profile_all = 2 | |
2000 }; | |
2001 | |
2002 static bool profile_jsr292(methodHandle m, int bci); | |
2003 static int profile_arguments_flag(); | |
2004 static bool profile_arguments_jsr292_only(); | |
2005 static bool profile_all_arguments(); | |
2006 static bool profile_arguments_for_invoke(methodHandle m, int bci); | |
2007 static int profile_return_flag(); | |
2008 static bool profile_all_return(); | |
2009 static bool profile_return_for_invoke(methodHandle m, int bci); | |
2010 static int profile_parameters_flag(); | |
2011 static bool profile_parameters_jsr292_only(); | |
2012 static bool profile_all_parameters(); | |
1359 | 2013 |
1360 public: | 2014 public: |
1361 static int header_size() { | 2015 static int header_size() { |
1362 return sizeof(MethodData)/wordSize; | 2016 return sizeof(MethodData)/wordSize; |
1363 } | 2017 } |
1557 if (decompile_count() > (uint)PerMethodRecompilationCutoff) { | 2211 if (decompile_count() > (uint)PerMethodRecompilationCutoff) { |
1558 method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff"); | 2212 method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff"); |
1559 } | 2213 } |
1560 } | 2214 } |
1561 | 2215 |
2216 // Return pointer to area dedicated to parameters in MDO | |
2217 ParametersTypeData* parameters_type_data() const { | |
2218 return _parameters_type_data_di != -1 ? data_layout_at(_parameters_type_data_di)->data_in()->as_ParametersTypeData() : NULL; | |
2219 } | |
2220 | |
2221 int parameters_type_data_di() const { | |
2222 assert(_parameters_type_data_di != -1, "no args type data"); | |
2223 return _parameters_type_data_di; | |
2224 } | |
2225 | |
1562 // Support for code generation | 2226 // Support for code generation |
1563 static ByteSize data_offset() { | 2227 static ByteSize data_offset() { |
1564 return byte_offset_of(MethodData, _data[0]); | 2228 return byte_offset_of(MethodData, _data[0]); |
1565 } | 2229 } |
1566 | 2230 |
1573 } | 2237 } |
1574 static ByteSize backedge_counter_offset() { | 2238 static ByteSize backedge_counter_offset() { |
1575 return byte_offset_of(MethodData, _backedge_counter); | 2239 return byte_offset_of(MethodData, _backedge_counter); |
1576 } | 2240 } |
1577 | 2241 |
2242 static ByteSize parameters_type_data_di_offset() { | |
2243 return byte_offset_of(MethodData, _parameters_type_data_di); | |
2244 } | |
2245 | |
1578 // Deallocation support - no pointer fields to deallocate | 2246 // Deallocation support - no pointer fields to deallocate |
1579 void deallocate_contents(ClassLoaderData* loader_data) {} | 2247 void deallocate_contents(ClassLoaderData* loader_data) {} |
1580 | 2248 |
1581 // GC support | 2249 // GC support |
1582 void set_size(int object_size_in_bytes) { _size = object_size_in_bytes; } | 2250 void set_size(int object_size_in_bytes) { _size = object_size_in_bytes; } |
1595 const char* internal_name() const { return "{method data}"; } | 2263 const char* internal_name() const { return "{method data}"; } |
1596 | 2264 |
1597 // verification | 2265 // verification |
1598 void verify_on(outputStream* st); | 2266 void verify_on(outputStream* st); |
1599 void verify_data_on(outputStream* st); | 2267 void verify_data_on(outputStream* st); |
2268 | |
2269 static bool profile_parameters_for_method(methodHandle m); | |
2270 static bool profile_arguments(); | |
2271 static bool profile_return(); | |
2272 static bool profile_parameters(); | |
2273 static bool profile_return_jsr292_only(); | |
1600 }; | 2274 }; |
1601 | 2275 |
1602 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP | 2276 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP |