changeset 20702 | bbe0fcde6e13 |
parent 20282 | 7f9cbdf89af2 |
child 20709 | 034be898bf04 |
20701:ef9996662fd5 | 20702:bbe0fcde6e13 |
---|---|
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 |