16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "ci/ciField.hpp"
27 #include "ci/ciInstance.hpp"
28 #include "ci/ciInstanceKlass.hpp"
29 #include "ci/ciUtilities.hpp"
30 #include "ci/ciValueKlass.hpp"
31 #include "classfile/systemDictionary.hpp"
32 #include "memory/allocation.hpp"
33 #include "memory/allocation.inline.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "oops/fieldStreams.hpp"
36 #include "runtime/fieldDescriptor.hpp"
37
38 // ciInstanceKlass
39 //
40 // This class represents a Klass* in the HotSpot virtual machine
41 // whose Klass part in an InstanceKlass.
42
43 // ------------------------------------------------------------------
44 // ciInstanceKlass::ciInstanceKlass
45 //
46 // Loaded instance klass.
47 ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
48 ciKlass(h_k)
49 {
50 assert(get_Klass()->is_instance_klass(), "wrong type");
51 assert(get_instanceKlass()->is_loaded(), "must be at least loaded");
52 InstanceKlass* ik = get_instanceKlass();
53
54 AccessFlags access_flags = ik->access_flags();
55 _flags = ciFlags(access_flags);
638 impl = CURRENT_THREAD_ENV->get_instance_klass(k);
639 }
640 }
641 }
642 // Memoize this result.
643 if (!is_shared()) {
644 _implementor = impl;
645 }
646 }
647 return impl;
648 }
649
650 // Utility class for printing of the contents of the static fields for
651 // use by compilation replay. It only prints out the information that
652 // could be consumed by the compiler, so for primitive types it prints
653 // out the actual value. For Strings it's the actual string value.
654 // For array types it it's first level array size since that's the
655 // only value which statically unchangeable. For all other reference
656 // types it simply prints out the dynamic type.
657
658 class StaticFinalFieldPrinter : public FieldClosure {
659 outputStream* _out;
660 const char* _holder;
661 public:
662 StaticFinalFieldPrinter(outputStream* out, const char* holder) :
663 _out(out),
664 _holder(holder) {
665 }
666 void do_field(fieldDescriptor* fd) {
667 if (fd->is_final() && !fd->has_initial_value()) {
668 ResourceMark rm;
669 oop mirror = fd->field_holder()->java_mirror();
670 _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
671 switch (fd->field_type()) {
672 case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break;
673 case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break;
674 case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break;
675 case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break;
676 case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break;
677 case T_LONG: _out->print_cr(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break;
678 case T_FLOAT: {
679 float f = mirror->float_field(fd->offset());
680 _out->print_cr("%d", *(int*)&f);
681 break;
682 }
683 case T_DOUBLE: {
684 double d = mirror->double_field(fd->offset());
685 _out->print_cr(INT64_FORMAT, *(int64_t*)&d);
686 break;
687 }
688 case T_ARRAY: {
689 oop value = mirror->obj_field_acquire(fd->offset());
690 if (value == NULL) {
691 _out->print_cr("null");
692 } else {
693 typeArrayOop ta = (typeArrayOop)value;
694 _out->print("%d", ta->length());
695 if (value->is_objArray()) {
696 objArrayOop oa = (objArrayOop)value;
697 const char* klass_name = value->klass()->name()->as_quoted_ascii();
698 _out->print(" %s", klass_name);
699 }
700 _out->cr();
701 }
702 break;
703 }
704 case T_OBJECT: {
705 oop value = mirror->obj_field_acquire(fd->offset());
706 if (value == NULL) {
707 _out->print_cr("null");
708 } else if (value->is_instance()) {
709 if (value->is_a(SystemDictionary::String_klass())) {
710 _out->print("\"");
711 _out->print_raw(java_lang_String::as_quoted_ascii(value));
712 _out->print_cr("\"");
713 } else {
714 const char* klass_name = value->klass()->name()->as_quoted_ascii();
715 _out->print_cr("%s", klass_name);
716 }
717 } else {
718 ShouldNotReachHere();
719 }
720 break;
721 }
722 default:
723 ShouldNotReachHere();
724 }
725 }
726 }
727 };
728
729
730 void ciInstanceKlass::dump_replay_data(outputStream* out) {
731 ResourceMark rm;
732
733 InstanceKlass* ik = get_instanceKlass();
734 ConstantPool* cp = ik->constants();
735
736 // Try to record related loaded classes
737 Klass* sub = ik->subklass();
738 while (sub != NULL) {
739 if (sub->is_instance_klass()) {
740 out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());
741 }
742 sub = sub->next_sibling();
743 }
744
745 // Dump out the state of the constant pool tags. During replay the
746 // tags will be validated for things which shouldn't change and
747 // classes will be resolved if the tags indicate that they were
748 // resolved at compile time.
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "ci/ciField.hpp"
27 #include "ci/ciInstance.hpp"
28 #include "ci/ciInstanceKlass.hpp"
29 #include "ci/ciUtilities.hpp"
30 #include "ci/ciValueKlass.hpp"
31 #include "classfile/systemDictionary.hpp"
32 #include "memory/allocation.hpp"
33 #include "memory/allocation.inline.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "oops/fieldStreams.hpp"
36 #include "oops/valueKlass.hpp"
37 #include "runtime/fieldDescriptor.hpp"
38
39 // ciInstanceKlass
40 //
41 // This class represents a Klass* in the HotSpot virtual machine
42 // whose Klass part in an InstanceKlass.
43
44 // ------------------------------------------------------------------
45 // ciInstanceKlass::ciInstanceKlass
46 //
47 // Loaded instance klass.
48 ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
49 ciKlass(h_k)
50 {
51 assert(get_Klass()->is_instance_klass(), "wrong type");
52 assert(get_instanceKlass()->is_loaded(), "must be at least loaded");
53 InstanceKlass* ik = get_instanceKlass();
54
55 AccessFlags access_flags = ik->access_flags();
56 _flags = ciFlags(access_flags);
639 impl = CURRENT_THREAD_ENV->get_instance_klass(k);
640 }
641 }
642 }
643 // Memoize this result.
644 if (!is_shared()) {
645 _implementor = impl;
646 }
647 }
648 return impl;
649 }
650
651 // Utility class for printing of the contents of the static fields for
652 // use by compilation replay. It only prints out the information that
653 // could be consumed by the compiler, so for primitive types it prints
654 // out the actual value. For Strings it's the actual string value.
655 // For array types it it's first level array size since that's the
656 // only value which statically unchangeable. For all other reference
657 // types it simply prints out the dynamic type.
658
659 class StaticFieldPrinter : public FieldClosure {
660 protected:
661 outputStream* _out;
662 public:
663 StaticFieldPrinter(outputStream* out) :
664 _out(out) {
665 }
666 void do_field_helper(fieldDescriptor* fd, oop obj, bool flattened);
667 };
668
669 class StaticFinalFieldPrinter : public StaticFieldPrinter {
670 const char* _holder;
671 public:
672 StaticFinalFieldPrinter(outputStream* out, const char* holder) :
673 StaticFieldPrinter(out), _holder(holder) {
674 }
675 void do_field(fieldDescriptor* fd) {
676 if (fd->is_final() && !fd->has_initial_value()) {
677 ResourceMark rm;
678 InstanceKlass* holder = fd->field_holder();
679 oop mirror = holder->java_mirror();
680 _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
681 do_field_helper(fd, mirror, false);
682 _out->cr();
683 }
684 }
685 };
686
687 class ValueTypeFieldPrinter : public StaticFieldPrinter {
688 oop _obj;
689 public:
690 ValueTypeFieldPrinter(outputStream* out, oop obj) :
691 StaticFieldPrinter(out), _obj(obj) {
692 }
693 void do_field(fieldDescriptor* fd) {
694 do_field_helper(fd, _obj, true);
695 _out->print(" ");
696 }
697 };
698
699 void StaticFieldPrinter::do_field_helper(fieldDescriptor* fd, oop mirror, bool flattened) {
700 switch (fd->field_type()) {
701 case T_BYTE: _out->print("%d", mirror->byte_field(fd->offset())); break;
702 case T_BOOLEAN: _out->print("%d", mirror->bool_field(fd->offset())); break;
703 case T_SHORT: _out->print("%d", mirror->short_field(fd->offset())); break;
704 case T_CHAR: _out->print("%d", mirror->char_field(fd->offset())); break;
705 case T_INT: _out->print("%d", mirror->int_field(fd->offset())); break;
706 case T_LONG: _out->print(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break;
707 case T_FLOAT: {
708 float f = mirror->float_field(fd->offset());
709 _out->print("%d", *(int*)&f);
710 break;
711 }
712 case T_DOUBLE: {
713 double d = mirror->double_field(fd->offset());
714 _out->print(INT64_FORMAT, *(int64_t*)&d);
715 break;
716 }
717 case T_ARRAY: {
718 oop value = mirror->obj_field_acquire(fd->offset());
719 if (value == NULL) {
720 _out->print("null");
721 } else {
722 typeArrayOop ta = (typeArrayOop)value;
723 _out->print("%d", ta->length());
724 if (value->is_objArray()) {
725 objArrayOop oa = (objArrayOop)value;
726 const char* klass_name = value->klass()->name()->as_quoted_ascii();
727 _out->print(" %s", klass_name);
728 }
729 }
730 break;
731 }
732 case T_OBJECT: {
733 oop value = mirror->obj_field_acquire(fd->offset());
734 if (value == NULL) {
735 _out->print("null");
736 } else if (value->is_instance()) {
737 if (value->is_a(SystemDictionary::String_klass())) {
738 _out->print("\"");
739 _out->print_raw(java_lang_String::as_quoted_ascii(value));
740 _out->print("\"");
741 } else {
742 const char* klass_name = value->klass()->name()->as_quoted_ascii();
743 _out->print("%s", klass_name);
744 }
745 } else {
746 ShouldNotReachHere();
747 }
748 break;
749 }
750 case T_VALUETYPE: {
751 ResetNoHandleMark rnhm;
752 Thread* THREAD = Thread::current();
753 SignatureStream ss(fd->signature(), false);
754 Symbol* name = ss.as_symbol(THREAD);
755 assert(!HAS_PENDING_EXCEPTION, "can resolve klass?");
756 InstanceKlass* holder = fd->field_holder();
757 Klass* k = SystemDictionary::find(name, Handle(holder->class_loader()), Handle(holder->protection_domain()), THREAD);
758 assert(k != NULL && !HAS_PENDING_EXCEPTION, "can resolve klass?");
759 ValueKlass* vk = ValueKlass::cast(k);
760 oop obj;
761 if (flattened) {
762 int field_offset = fd->offset() - vk->first_field_offset();
763 obj = (oop)((address)mirror + field_offset);
764 } else {
765 obj = mirror->obj_field_acquire(fd->offset());
766 }
767 ValueTypeFieldPrinter print_field(_out, obj);
768 vk->do_nonstatic_fields(&print_field);
769 break;
770 }
771 default:
772 ShouldNotReachHere();
773 }
774 }
775
776 void ciInstanceKlass::dump_replay_data(outputStream* out) {
777 ResourceMark rm;
778
779 InstanceKlass* ik = get_instanceKlass();
780 ConstantPool* cp = ik->constants();
781
782 // Try to record related loaded classes
783 Klass* sub = ik->subklass();
784 while (sub != NULL) {
785 if (sub->is_instance_klass()) {
786 out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());
787 }
788 sub = sub->next_sibling();
789 }
790
791 // Dump out the state of the constant pool tags. During replay the
792 // tags will be validated for things which shouldn't change and
793 // classes will be resolved if the tags indicate that they were
794 // resolved at compile time.
|