559 _implementor = impl; |
559 _implementor = impl; |
560 } |
560 } |
561 } |
561 } |
562 return impl; |
562 return impl; |
563 } |
563 } |
|
564 |
|
565 // Utility class for printing of the contents of the static fields for |
|
566 // use by compilation replay. It only prints out the information that |
|
567 // could be consumed by the compiler, so for primitive types it prints |
|
568 // out the actual value. For Strings it's the actual string value. |
|
569 // For array types it it's first level array size since that's the |
|
570 // only value which statically unchangeable. For all other reference |
|
571 // types it simply prints out the dynamic type. |
|
572 |
|
573 class StaticFinalFieldPrinter : public FieldClosure { |
|
574 outputStream* _out; |
|
575 const char* _holder; |
|
576 public: |
|
577 StaticFinalFieldPrinter(outputStream* out, const char* holder) : |
|
578 _out(out), |
|
579 _holder(holder) { |
|
580 } |
|
581 void do_field(fieldDescriptor* fd) { |
|
582 if (fd->is_final() && !fd->has_initial_value()) { |
|
583 oop mirror = fd->field_holder()->java_mirror(); |
|
584 _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii()); |
|
585 switch (fd->field_type()) { |
|
586 case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break; |
|
587 case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break; |
|
588 case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break; |
|
589 case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break; |
|
590 case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break; |
|
591 case T_LONG: _out->print_cr(INT64_FORMAT, mirror->long_field(fd->offset())); break; |
|
592 case T_FLOAT: { |
|
593 float f = mirror->float_field(fd->offset()); |
|
594 _out->print_cr("%d", *(int*)&f); |
|
595 break; |
|
596 } |
|
597 case T_DOUBLE: { |
|
598 double d = mirror->double_field(fd->offset()); |
|
599 _out->print_cr(INT64_FORMAT, *(jlong*)&d); |
|
600 break; |
|
601 } |
|
602 case T_ARRAY: { |
|
603 oop value = mirror->obj_field_acquire(fd->offset()); |
|
604 if (value == NULL) { |
|
605 _out->print_cr("null"); |
|
606 } else { |
|
607 typeArrayOop ta = (typeArrayOop)value; |
|
608 _out->print("%d", ta->length()); |
|
609 if (value->is_objArray()) { |
|
610 objArrayOop oa = (objArrayOop)value; |
|
611 const char* klass_name = value->klass()->name()->as_quoted_ascii(); |
|
612 _out->print(" %s", klass_name); |
|
613 } |
|
614 _out->cr(); |
|
615 } |
|
616 break; |
|
617 } |
|
618 case T_OBJECT: { |
|
619 oop value = mirror->obj_field_acquire(fd->offset()); |
|
620 if (value == NULL) { |
|
621 _out->print_cr("null"); |
|
622 } else if (value->is_instance()) { |
|
623 if (value->is_a(SystemDictionary::String_klass())) { |
|
624 _out->print("\""); |
|
625 _out->print_raw(java_lang_String::as_quoted_ascii(value)); |
|
626 _out->print_cr("\""); |
|
627 } else { |
|
628 const char* klass_name = value->klass()->name()->as_quoted_ascii(); |
|
629 _out->print_cr(klass_name); |
|
630 } |
|
631 } else { |
|
632 ShouldNotReachHere(); |
|
633 } |
|
634 break; |
|
635 } |
|
636 default: |
|
637 ShouldNotReachHere(); |
|
638 } |
|
639 } |
|
640 } |
|
641 }; |
|
642 |
|
643 |
|
644 void ciInstanceKlass::dump_replay_data(outputStream* out) { |
|
645 ASSERT_IN_VM; |
|
646 InstanceKlass* ik = get_instanceKlass(); |
|
647 ConstantPool* cp = ik->constants(); |
|
648 |
|
649 // Try to record related loaded classes |
|
650 Klass* sub = ik->subklass(); |
|
651 while (sub != NULL) { |
|
652 if (sub->oop_is_instance()) { |
|
653 out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii()); |
|
654 } |
|
655 sub = sub->next_sibling(); |
|
656 } |
|
657 |
|
658 // Dump out the state of the constant pool tags. During replay the |
|
659 // tags will be validated for things which shouldn't change and |
|
660 // classes will be resolved if the tags indicate that they were |
|
661 // resolved at compile time. |
|
662 out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(), |
|
663 is_linked(), is_initialized(), cp->length()); |
|
664 for (int index = 1; index < cp->length(); index++) { |
|
665 out->print(" %d", cp->tags()->at(index)); |
|
666 } |
|
667 out->cr(); |
|
668 if (is_initialized()) { |
|
669 // Dump out the static final fields in case the compilation relies |
|
670 // on their value for correct replay. |
|
671 StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii()); |
|
672 ik->do_local_static_fields(&sffp); |
|
673 } |
|
674 } |