7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
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.inline.hpp"
30 #include "classfile/javaClasses.hpp"
31 #include "classfile/systemDictionary.hpp"
32 #include "classfile/vmClasses.hpp"
33 #include "memory/allocation.hpp"
34 #include "memory/allocation.inline.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "oops/instanceKlass.inline.hpp"
37 #include "oops/klass.inline.hpp"
38 #include "oops/oop.inline.hpp"
39 #include "oops/fieldStreams.inline.hpp"
40 #include "runtime/fieldDescriptor.inline.hpp"
41 #include "runtime/handles.inline.hpp"
42 #include "runtime/jniHandles.inline.hpp"
43
44 // ciInstanceKlass
45 //
46 // This class represents a Klass* in the HotSpot virtual machine
47 // whose Klass part in an InstanceKlass.
48
49
50 // ------------------------------------------------------------------
51 // ciInstanceKlass::ciInstanceKlass
52 //
53 // Loaded instance klass.
54 ciInstanceKlass::ciInstanceKlass(Klass* k) :
55 ciKlass(k)
56 {
57 assert(get_Klass()->is_instance_klass(), "wrong type");
58 assert(get_instanceKlass()->is_loaded(), "must be at least loaded");
59 InstanceKlass* ik = get_instanceKlass();
100 _protection_domain = JNIHandles::make_global(h_protection_domain);
101 _is_shared = true;
102 }
103
104 // Lazy fields get filled in only upon request.
105 _super = NULL;
106 _java_mirror = NULL;
107
108 if (is_shared()) {
109 if (k != vmClasses::Object_klass()) {
110 super();
111 }
112 //compute_nonstatic_fields(); // done outside of constructor
113 }
114
115 _field_cache = NULL;
116 }
117
118 // Version for unloaded classes:
119 ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
120 jobject loader, jobject protection_domain)
121 : ciKlass(name, T_OBJECT)
122 {
123 assert(name->char_at(0) != JVM_SIGNATURE_ARRAY, "not an instance klass");
124 _init_state = (InstanceKlass::ClassState)0;
125 _has_nonstatic_fields = false;
126 _nonstatic_fields = NULL;
127 _has_injected_fields = -1;
128 _is_hidden = false;
129 _is_record = false;
130 _loader = loader;
131 _protection_domain = protection_domain;
132 _is_shared = false;
133 _super = NULL;
134 _java_mirror = NULL;
135 _field_cache = NULL;
136 }
137
138
139
140 // ------------------------------------------------------------------
141 // ciInstanceKlass::compute_shared_is_initialized
142 void ciInstanceKlass::compute_shared_init_state() {
143 GUARDED_VM_ENTRY(
144 InstanceKlass* ik = get_instanceKlass();
145 _init_state = ik->init_state();
146 )
342 if (name()->index_of_at(len+1, "/", 1) >= 0)
343 return false;
344
345 return true;
346 }
347
348 // ------------------------------------------------------------------
349 // ciInstanceKlass::print_impl
350 //
351 // Implementation of the print method.
352 void ciInstanceKlass::print_impl(outputStream* st) {
353 ciKlass::print_impl(st);
354 GUARDED_VM_ENTRY(st->print(" loader=" INTPTR_FORMAT, p2i(loader()));)
355 if (is_loaded()) {
356 st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=",
357 bool_to_str(is_initialized()),
358 bool_to_str(has_finalizer()),
359 bool_to_str(has_subklass()),
360 layout_helper());
361
362 _flags.print_klass_flags();
363
364 if (_super) {
365 st->print(" super=");
366 _super->print_name();
367 }
368 if (_java_mirror) {
369 st->print(" mirror=PRESENT");
370 }
371 } else {
372 st->print(" loaded=false");
373 }
374 }
375
376 // ------------------------------------------------------------------
377 // ciInstanceKlass::super
378 //
379 // Get the superklass of this klass.
380 ciInstanceKlass* ciInstanceKlass::super() {
381 assert(is_loaded(), "must be loaded");
382 if (_super == NULL && !is_java_lang_Object()) {
383 GUARDED_VM_ENTRY(
384 Klass* super_klass = get_instanceKlass()->super();
385 _super = CURRENT_ENV->get_instance_klass(super_klass);
386 )
442 ciField* field = _nonstatic_fields->at(i);
443 int field_off = field->offset_in_bytes();
444 if (field_off == field_offset)
445 return field;
446 if (field_off > field_offset)
447 break;
448 // could do binary search or check bins, but probably not worth it
449 }
450 return NULL;
451 }
452 VM_ENTRY_MARK;
453 InstanceKlass* k = get_instanceKlass();
454 fieldDescriptor fd;
455 if (!k->find_field_from_offset(field_offset, is_static, &fd)) {
456 return NULL;
457 }
458 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
459 return field;
460 }
461
462 // ------------------------------------------------------------------
463 // ciInstanceKlass::get_field_by_name
464 ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) {
465 VM_ENTRY_MARK;
466 InstanceKlass* k = get_instanceKlass();
467 fieldDescriptor fd;
468 Klass* def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd);
469 if (def == NULL) {
470 return NULL;
471 }
472 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
473 return field;
474 }
475
476
477 static int sort_field_by_offset(ciField** a, ciField** b) {
478 return (*a)->offset_in_bytes() - (*b)->offset_in_bytes();
479 // (no worries about 32-bit overflow...)
480 }
481
500 int super_flen = super->nof_nonstatic_fields();
501 super_fields = super->_nonstatic_fields;
502 assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
503 }
504
505 GrowableArray<ciField*>* fields = NULL;
506 GUARDED_VM_ENTRY({
507 fields = compute_nonstatic_fields_impl(super_fields);
508 });
509
510 if (fields == NULL) {
511 // This can happen if this class (java.lang.Class) has invisible fields.
512 if (super_fields != NULL) {
513 _nonstatic_fields = super_fields;
514 return super_fields->length();
515 } else {
516 return 0;
517 }
518 }
519
520 int flen = fields->length();
521
522 // Now sort them by offset, ascending.
523 // (In principle, they could mix with superclass fields.)
524 fields->sort(sort_field_by_offset);
525 _nonstatic_fields = fields;
526 return flen;
527 }
528
529 GrowableArray<ciField*>*
530 ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>*
531 super_fields) {
532 ASSERT_IN_VM;
533 Arena* arena = CURRENT_ENV->arena();
534 int flen = 0;
535 GrowableArray<ciField*>* fields = NULL;
536 InstanceKlass* k = get_instanceKlass();
537 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
538 if (fs.access_flags().is_static()) continue;
539 flen += 1;
540 }
541
542 // allocate the array:
543 if (flen == 0) {
544 return NULL; // return nothing if none are locally declared
545 }
546 if (super_fields != NULL) {
547 flen += super_fields->length();
548 }
549 fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL);
550 if (super_fields != NULL) {
551 fields->appendAll(super_fields);
552 }
553
554 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
555 if (fs.access_flags().is_static()) continue;
556 fieldDescriptor& fd = fs.field_descriptor();
557 ciField* field = new (arena) ciField(&fd);
558 fields->append(field);
559 }
560 assert(fields->length() == flen, "sanity");
561 return fields;
562 }
563
564 bool ciInstanceKlass::compute_injected_fields_helper() {
565 ASSERT_IN_VM;
566 InstanceKlass* k = get_instanceKlass();
567
568 for (InternalFieldStream fs(k); !fs.done(); fs.next()) {
569 if (fs.access_flags().is_static()) continue;
570 return true;
571 }
572 return false;
573 }
574
575 void ciInstanceKlass::compute_injected_fields() {
576 assert(is_loaded(), "must be loaded");
577
578 int has_injected_fields = 0;
579 if (super() != NULL && super()->has_injected_fields()) {
580 has_injected_fields = 1;
638 VM_ENTRY_MARK;
639 MutexLocker ml(Compile_lock);
640 Klass* k = get_instanceKlass()->implementor();
641 if (k != NULL) {
642 if (k == get_instanceKlass()) {
643 // More than one implementors. Use 'this' in this case.
644 impl = this;
645 } else {
646 impl = CURRENT_THREAD_ENV->get_instance_klass(k);
647 }
648 }
649 }
650 // Memoize this result.
651 if (!is_shared()) {
652 _implementor = impl;
653 }
654 }
655 return impl;
656 }
657
658 // Utility class for printing of the contents of the static fields for
659 // use by compilation replay. It only prints out the information that
660 // could be consumed by the compiler, so for primitive types it prints
661 // out the actual value. For Strings it's the actual string value.
662 // For array types it it's first level array size since that's the
663 // only value which statically unchangeable. For all other reference
664 // types it simply prints out the dynamic type.
665
666 class StaticFinalFieldPrinter : public FieldClosure {
667 outputStream* _out;
668 const char* _holder;
669 public:
670 StaticFinalFieldPrinter(outputStream* out, const char* holder) :
671 _out(out),
672 _holder(holder) {
673 }
674 void do_field(fieldDescriptor* fd) {
675 if (fd->is_final() && !fd->has_initial_value()) {
676 ResourceMark rm;
677 oop mirror = fd->field_holder()->java_mirror();
678 _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
679 switch (fd->field_type()) {
680 case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break;
681 case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break;
682 case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break;
683 case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break;
684 case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break;
685 case T_LONG: _out->print_cr(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break;
686 case T_FLOAT: {
687 float f = mirror->float_field(fd->offset());
688 _out->print_cr("%d", *(int*)&f);
689 break;
690 }
691 case T_DOUBLE: {
692 double d = mirror->double_field(fd->offset());
693 _out->print_cr(INT64_FORMAT, *(int64_t*)&d);
694 break;
695 }
696 case T_ARRAY: // fall-through
697 case T_OBJECT: {
698 oop value = mirror->obj_field_acquire(fd->offset());
699 if (value == NULL) {
700 _out->print_cr("null");
701 } else if (value->is_instance()) {
702 assert(fd->field_type() == T_OBJECT, "");
703 if (value->is_a(vmClasses::String_klass())) {
704 const char* ascii_value = java_lang_String::as_quoted_ascii(value);
705 _out->print_cr("\"%s\"", (ascii_value != NULL) ? ascii_value : "");
706 } else {
707 const char* klass_name = value->klass()->name()->as_quoted_ascii();
708 _out->print_cr("%s", klass_name);
709 }
710 } else if (value->is_array()) {
711 typeArrayOop ta = (typeArrayOop)value;
712 _out->print("%d", ta->length());
713 if (value->is_objArray()) {
714 objArrayOop oa = (objArrayOop)value;
715 const char* klass_name = value->klass()->name()->as_quoted_ascii();
716 _out->print(" %s", klass_name);
717 }
718 _out->cr();
719 } else {
720 ShouldNotReachHere();
721 }
722 break;
723 }
724 default:
725 ShouldNotReachHere();
726 }
727 }
728 }
729 };
730
731 const char *ciInstanceKlass::replay_name() const {
732 return CURRENT_ENV->replay_name(get_instanceKlass());
733 }
734
735 void ciInstanceKlass::dump_replay_instanceKlass(outputStream* out, InstanceKlass* ik) {
736 if (ik->is_hidden()) {
737 const char *name = CURRENT_ENV->dyno_name(ik);
738 if (name != NULL) {
739 out->print_cr("instanceKlass %s # %s", name, ik->name()->as_quoted_ascii());
740 } else {
741 out->print_cr("# instanceKlass %s", ik->name()->as_quoted_ascii());
742 }
743 } else {
744 out->print_cr("instanceKlass %s", ik->name()->as_quoted_ascii());
745 }
746 }
747
748 void ciInstanceKlass::dump_replay_data(outputStream* out) {
749 ResourceMark rm;
|
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
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/ciInlineKlass.hpp"
28 #include "ci/ciInstance.hpp"
29 #include "ci/ciInstanceKlass.hpp"
30 #include "ci/ciUtilities.inline.hpp"
31 #include "classfile/javaClasses.hpp"
32 #include "classfile/systemDictionary.hpp"
33 #include "classfile/vmClasses.hpp"
34 #include "memory/allocation.hpp"
35 #include "memory/allocation.inline.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "oops/instanceKlass.inline.hpp"
38 #include "oops/klass.inline.hpp"
39 #include "oops/oop.inline.hpp"
40 #include "oops/fieldStreams.inline.hpp"
41 #include "oops/inlineKlass.inline.hpp"
42 #include "runtime/fieldDescriptor.inline.hpp"
43 #include "runtime/handles.inline.hpp"
44 #include "runtime/jniHandles.inline.hpp"
45
46 // ciInstanceKlass
47 //
48 // This class represents a Klass* in the HotSpot virtual machine
49 // whose Klass part in an InstanceKlass.
50
51
52 // ------------------------------------------------------------------
53 // ciInstanceKlass::ciInstanceKlass
54 //
55 // Loaded instance klass.
56 ciInstanceKlass::ciInstanceKlass(Klass* k) :
57 ciKlass(k)
58 {
59 assert(get_Klass()->is_instance_klass(), "wrong type");
60 assert(get_instanceKlass()->is_loaded(), "must be at least loaded");
61 InstanceKlass* ik = get_instanceKlass();
102 _protection_domain = JNIHandles::make_global(h_protection_domain);
103 _is_shared = true;
104 }
105
106 // Lazy fields get filled in only upon request.
107 _super = NULL;
108 _java_mirror = NULL;
109
110 if (is_shared()) {
111 if (k != vmClasses::Object_klass()) {
112 super();
113 }
114 //compute_nonstatic_fields(); // done outside of constructor
115 }
116
117 _field_cache = NULL;
118 }
119
120 // Version for unloaded classes:
121 ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
122 jobject loader, jobject protection_domain,
123 BasicType bt)
124 : ciKlass(name, bt)
125 {
126 assert(name->char_at(0) != JVM_SIGNATURE_ARRAY, "not an instance klass");
127 _init_state = (InstanceKlass::ClassState)0;
128 _has_nonstatic_fields = false;
129 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields
130 _has_injected_fields = -1;
131 _is_hidden = false;
132 _is_record = false;
133 _loader = loader;
134 _protection_domain = protection_domain;
135 _is_shared = false;
136 _super = NULL;
137 _java_mirror = NULL;
138 _field_cache = NULL;
139 }
140
141
142
143 // ------------------------------------------------------------------
144 // ciInstanceKlass::compute_shared_is_initialized
145 void ciInstanceKlass::compute_shared_init_state() {
146 GUARDED_VM_ENTRY(
147 InstanceKlass* ik = get_instanceKlass();
148 _init_state = ik->init_state();
149 )
345 if (name()->index_of_at(len+1, "/", 1) >= 0)
346 return false;
347
348 return true;
349 }
350
351 // ------------------------------------------------------------------
352 // ciInstanceKlass::print_impl
353 //
354 // Implementation of the print method.
355 void ciInstanceKlass::print_impl(outputStream* st) {
356 ciKlass::print_impl(st);
357 GUARDED_VM_ENTRY(st->print(" loader=" INTPTR_FORMAT, p2i(loader()));)
358 if (is_loaded()) {
359 st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=",
360 bool_to_str(is_initialized()),
361 bool_to_str(has_finalizer()),
362 bool_to_str(has_subklass()),
363 layout_helper());
364
365 _flags.print_klass_flags(st);
366
367 if (_super) {
368 st->print(" super=");
369 _super->print_name_on(st);
370 }
371 if (_java_mirror) {
372 st->print(" mirror=PRESENT");
373 }
374 } else {
375 st->print(" loaded=false");
376 }
377 }
378
379 // ------------------------------------------------------------------
380 // ciInstanceKlass::super
381 //
382 // Get the superklass of this klass.
383 ciInstanceKlass* ciInstanceKlass::super() {
384 assert(is_loaded(), "must be loaded");
385 if (_super == NULL && !is_java_lang_Object()) {
386 GUARDED_VM_ENTRY(
387 Klass* super_klass = get_instanceKlass()->super();
388 _super = CURRENT_ENV->get_instance_klass(super_klass);
389 )
445 ciField* field = _nonstatic_fields->at(i);
446 int field_off = field->offset_in_bytes();
447 if (field_off == field_offset)
448 return field;
449 if (field_off > field_offset)
450 break;
451 // could do binary search or check bins, but probably not worth it
452 }
453 return NULL;
454 }
455 VM_ENTRY_MARK;
456 InstanceKlass* k = get_instanceKlass();
457 fieldDescriptor fd;
458 if (!k->find_field_from_offset(field_offset, is_static, &fd)) {
459 return NULL;
460 }
461 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
462 return field;
463 }
464
465 ciField* ciInstanceKlass::get_non_flattened_field_by_offset(int field_offset) {
466 if (super() != NULL && super()->has_nonstatic_fields()) {
467 ciField* f = super()->get_non_flattened_field_by_offset(field_offset);
468 if (f != NULL) {
469 return f;
470 }
471 }
472
473 VM_ENTRY_MARK;
474 InstanceKlass* k = get_instanceKlass();
475 Arena* arena = CURRENT_ENV->arena();
476 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
477 if (fs.access_flags().is_static()) continue;
478 fieldDescriptor& fd = fs.field_descriptor();
479 if (fd.offset() == field_offset) {
480 ciField* f = new (arena) ciField(&fd);
481 return f;
482 }
483 }
484
485 return NULL;
486 }
487
488 // ------------------------------------------------------------------
489 // ciInstanceKlass::get_field_by_name
490 ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) {
491 VM_ENTRY_MARK;
492 InstanceKlass* k = get_instanceKlass();
493 fieldDescriptor fd;
494 Klass* def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd);
495 if (def == NULL) {
496 return NULL;
497 }
498 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
499 return field;
500 }
501
502
503 static int sort_field_by_offset(ciField** a, ciField** b) {
504 return (*a)->offset_in_bytes() - (*b)->offset_in_bytes();
505 // (no worries about 32-bit overflow...)
506 }
507
526 int super_flen = super->nof_nonstatic_fields();
527 super_fields = super->_nonstatic_fields;
528 assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
529 }
530
531 GrowableArray<ciField*>* fields = NULL;
532 GUARDED_VM_ENTRY({
533 fields = compute_nonstatic_fields_impl(super_fields);
534 });
535
536 if (fields == NULL) {
537 // This can happen if this class (java.lang.Class) has invisible fields.
538 if (super_fields != NULL) {
539 _nonstatic_fields = super_fields;
540 return super_fields->length();
541 } else {
542 return 0;
543 }
544 }
545
546 _nonstatic_fields = fields;
547 return fields->length();
548 }
549
550 GrowableArray<ciField*>* ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>* super_fields, bool flatten) {
551 ASSERT_IN_VM;
552 Arena* arena = CURRENT_ENV->arena();
553 int flen = 0;
554 GrowableArray<ciField*>* fields = NULL;
555 InstanceKlass* k = get_instanceKlass();
556 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
557 if (fs.access_flags().is_static()) continue;
558 flen += 1;
559 }
560
561 // allocate the array:
562 if (flen == 0) {
563 return NULL; // return nothing if none are locally declared
564 }
565 if (super_fields != NULL) {
566 flen += super_fields->length();
567 }
568
569 fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL);
570 if (super_fields != NULL) {
571 fields->appendAll(super_fields);
572 }
573
574 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
575 if (fs.access_flags().is_static()) continue;
576 fieldDescriptor& fd = fs.field_descriptor();
577 if (fd.is_inlined() && flatten) {
578 // Inline type fields are embedded
579 int field_offset = fd.offset();
580 // Get InlineKlass and adjust number of fields
581 Klass* k = get_instanceKlass()->get_inline_type_field_klass(fd.index());
582 ciInlineKlass* vk = CURRENT_ENV->get_klass(k)->as_inline_klass();
583 flen += vk->nof_nonstatic_fields() - 1;
584 // Iterate over fields of the flattened inline type and copy them to 'this'
585 for (int i = 0; i < vk->nof_nonstatic_fields(); ++i) {
586 ciField* flattened_field = vk->nonstatic_field_at(i);
587 // Adjust offset to account for missing oop header
588 int offset = field_offset + (flattened_field->offset() - vk->first_field_offset());
589 // A flattened field can be treated as final if the non-flattened
590 // field is declared final or the holder klass is an inline type itself.
591 bool is_final = fd.is_final() || is_inlinetype();
592 ciField* field = new (arena) ciField(flattened_field, this, offset, is_final);
593 fields->append(field);
594 }
595 } else {
596 ciField* field = new (arena) ciField(&fd);
597 fields->append(field);
598 }
599 }
600 assert(fields->length() == flen, "sanity");
601 // Now sort them by offset, ascending.
602 // (In principle, they could mix with superclass fields.)
603 fields->sort(sort_field_by_offset);
604 return fields;
605 }
606
607 bool ciInstanceKlass::compute_injected_fields_helper() {
608 ASSERT_IN_VM;
609 InstanceKlass* k = get_instanceKlass();
610
611 for (InternalFieldStream fs(k); !fs.done(); fs.next()) {
612 if (fs.access_flags().is_static()) continue;
613 return true;
614 }
615 return false;
616 }
617
618 void ciInstanceKlass::compute_injected_fields() {
619 assert(is_loaded(), "must be loaded");
620
621 int has_injected_fields = 0;
622 if (super() != NULL && super()->has_injected_fields()) {
623 has_injected_fields = 1;
681 VM_ENTRY_MARK;
682 MutexLocker ml(Compile_lock);
683 Klass* k = get_instanceKlass()->implementor();
684 if (k != NULL) {
685 if (k == get_instanceKlass()) {
686 // More than one implementors. Use 'this' in this case.
687 impl = this;
688 } else {
689 impl = CURRENT_THREAD_ENV->get_instance_klass(k);
690 }
691 }
692 }
693 // Memoize this result.
694 if (!is_shared()) {
695 _implementor = impl;
696 }
697 }
698 return impl;
699 }
700
701 bool ciInstanceKlass::can_be_inline_klass(bool is_exact) {
702 if (!EnableValhalla) {
703 return false;
704 }
705 if (!is_loaded() || is_inlinetype()) {
706 // Not loaded or known to be an inline klass
707 return true;
708 }
709 if (!is_exact) {
710 // Not exact, check if this is a valid super for an inline klass
711 VM_ENTRY_MARK;
712 return !get_instanceKlass()->invalid_inline_super();
713 }
714 return false;
715 }
716
717 // Utility class for printing of the contents of the static fields for
718 // use by compilation replay. It only prints out the information that
719 // could be consumed by the compiler, so for primitive types it prints
720 // out the actual value. For Strings it's the actual string value.
721 // For array types it it's first level array size since that's the
722 // only value which statically unchangeable. For all other reference
723 // types it simply prints out the dynamic type.
724
725 class StaticFieldPrinter : public FieldClosure {
726 protected:
727 outputStream* _out;
728 public:
729 StaticFieldPrinter(outputStream* out) :
730 _out(out) {
731 }
732 void do_field_helper(fieldDescriptor* fd, oop obj, bool flattened);
733 };
734
735 class StaticFinalFieldPrinter : public StaticFieldPrinter {
736 const char* _holder;
737 public:
738 StaticFinalFieldPrinter(outputStream* out, const char* holder) :
739 StaticFieldPrinter(out), _holder(holder) {
740 }
741 void do_field(fieldDescriptor* fd) {
742 if (fd->is_final() && !fd->has_initial_value()) {
743 ResourceMark rm;
744 InstanceKlass* holder = fd->field_holder();
745 oop mirror = holder->java_mirror();
746 _out->print("staticfield %s %s ", _holder, fd->name()->as_quoted_ascii());
747 BasicType bt = fd->field_type();
748 if (bt != T_OBJECT && bt != T_ARRAY) {
749 _out->print("%s ", fd->signature()->as_quoted_ascii());
750 }
751 do_field_helper(fd, mirror, false);
752 _out->cr();
753 }
754 }
755 };
756
757 class InlineTypeFieldPrinter : public StaticFieldPrinter {
758 oop _obj;
759 public:
760 InlineTypeFieldPrinter(outputStream* out, oop obj) :
761 StaticFieldPrinter(out), _obj(obj) {
762 }
763 void do_field(fieldDescriptor* fd) {
764 do_field_helper(fd, _obj, true);
765 _out->print(" ");
766 }
767 };
768
769 void StaticFieldPrinter::do_field_helper(fieldDescriptor* fd, oop mirror, bool flattened) {
770 BasicType bt = fd->field_type();
771 switch (bt) {
772 case T_BYTE: _out->print("%d", mirror->byte_field(fd->offset())); break;
773 case T_BOOLEAN: _out->print("%d", mirror->bool_field(fd->offset())); break;
774 case T_SHORT: _out->print("%d", mirror->short_field(fd->offset())); break;
775 case T_CHAR: _out->print("%d", mirror->char_field(fd->offset())); break;
776 case T_INT: _out->print("%d", mirror->int_field(fd->offset())); break;
777 case T_LONG: _out->print(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break;
778 case T_FLOAT: {
779 float f = mirror->float_field(fd->offset());
780 _out->print("%d", *(int*)&f);
781 break;
782 }
783 case T_DOUBLE: {
784 double d = mirror->double_field(fd->offset());
785 _out->print(INT64_FORMAT, *(int64_t*)&d);
786 break;
787 }
788 case T_ARRAY: // fall-through
789 case T_OBJECT: {
790 _out->print("%s ", fd->signature()->as_quoted_ascii());
791 oop value = mirror->obj_field_acquire(fd->offset());
792 if (value == NULL) {
793 _out->print_cr("null");
794 } else if (value->is_instance()) {
795 assert(fd->field_type() == T_OBJECT, "");
796 if (value->is_a(vmClasses::String_klass())) {
797 const char* ascii_value = java_lang_String::as_quoted_ascii(value);
798 _out->print("\"%s\"", (ascii_value != NULL) ? ascii_value : "");
799 } else {
800 const char* klass_name = value->klass()->name()->as_quoted_ascii();
801 _out->print("%s", klass_name);
802 }
803 } else if (value->is_array()) {
804 typeArrayOop ta = (typeArrayOop)value;
805 _out->print("%d", ta->length());
806 if (value->is_objArray() || value->is_flatArray()) {
807 objArrayOop oa = (objArrayOop)value;
808 const char* klass_name = value->klass()->name()->as_quoted_ascii();
809 _out->print(" %s", klass_name);
810 }
811 } else {
812 ShouldNotReachHere();
813 }
814 break;
815 }
816 case T_PRIMITIVE_OBJECT: {
817 ResetNoHandleMark rnhm;
818 Thread* THREAD = Thread::current();
819 SignatureStream ss(fd->signature(), false);
820 Symbol* name = ss.as_symbol();
821 assert(!HAS_PENDING_EXCEPTION, "can resolve klass?");
822 InstanceKlass* holder = fd->field_holder();
823 InstanceKlass* k = SystemDictionary::find_instance_klass(name,
824 Handle(THREAD, holder->class_loader()),
825 Handle(THREAD, holder->protection_domain()));
826 assert(k != NULL && !HAS_PENDING_EXCEPTION, "can resolve klass?");
827 InlineKlass* vk = InlineKlass::cast(k);
828 oop obj;
829 if (flattened) {
830 int field_offset = fd->offset() - vk->first_field_offset();
831 obj = cast_to_oop(cast_from_oop<address>(mirror) + field_offset);
832 } else {
833 obj = mirror->obj_field_acquire(fd->offset());
834 }
835 InlineTypeFieldPrinter print_field(_out, obj);
836 vk->do_nonstatic_fields(&print_field);
837 break;
838 }
839 default:
840 ShouldNotReachHere();
841 }
842 }
843
844 const char *ciInstanceKlass::replay_name() const {
845 return CURRENT_ENV->replay_name(get_instanceKlass());
846 }
847
848 void ciInstanceKlass::dump_replay_instanceKlass(outputStream* out, InstanceKlass* ik) {
849 if (ik->is_hidden()) {
850 const char *name = CURRENT_ENV->dyno_name(ik);
851 if (name != NULL) {
852 out->print_cr("instanceKlass %s # %s", name, ik->name()->as_quoted_ascii());
853 } else {
854 out->print_cr("# instanceKlass %s", ik->name()->as_quoted_ascii());
855 }
856 } else {
857 out->print_cr("instanceKlass %s", ik->name()->as_quoted_ascii());
858 }
859 }
860
861 void ciInstanceKlass::dump_replay_data(outputStream* out) {
862 ResourceMark rm;
|