532 oop _archived_referencing_obj;
533 Thread* _thread;
534 public:
535 WalkOopAndArchiveClosure(int level,
536 bool is_closed_archive,
537 bool record_klasses_only,
538 KlassSubGraphInfo* subgraph_info,
539 oop orig, oop archived, TRAPS) :
540 _level(level), _is_closed_archive(is_closed_archive),
541 _record_klasses_only(record_klasses_only),
542 _subgraph_info(subgraph_info),
543 _orig_referencing_obj(orig), _archived_referencing_obj(archived),
544 _thread(THREAD) {}
545 void do_oop(narrowOop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
546 void do_oop( oop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
547
548 protected:
549 template <class T> void do_oop_work(T *p) {
550 oop obj = RawAccess<>::oop_load(p);
551 if (!CompressedOops::is_null(obj)) {
552 assert(!HeapShared::is_archived_object(obj),
553 "original objects must not point to archived objects");
554
555 size_t field_delta = pointer_delta(p, _orig_referencing_obj, sizeof(char));
556 T* new_p = (T*)(address(_archived_referencing_obj) + field_delta);
557 Thread* THREAD = _thread;
558
559 if (!_record_klasses_only && log_is_enabled(Debug, cds, heap)) {
560 ResourceMark rm;
561 log_debug(cds, heap)("(%d) %s[" SIZE_FORMAT "] ==> " PTR_FORMAT " size %d %s", _level,
562 _orig_referencing_obj->klass()->external_name(), field_delta,
563 p2i(obj), obj->size() * HeapWordSize, obj->klass()->external_name());
564 LogTarget(Trace, cds, heap) log;
565 LogStream out(log);
566 obj->print_on(&out);
567 }
568
569 oop archived = HeapShared::archive_reachable_objects_from(
570 _level + 1, _subgraph_info, obj, _is_closed_archive, THREAD);
571 assert(archived != NULL, "VM should have exited with unarchivable objects for _level > 1");
756 // so it can be restored at runtime.
757 subgraph_info->add_subgraph_entry_field(field_offset, NULL, false);
758 }
759 }
760
761 #ifndef PRODUCT
762 class VerifySharedOopClosure: public BasicOopIterateClosure {
763 private:
764 bool _is_archived;
765
766 public:
767 VerifySharedOopClosure(bool is_archived) : _is_archived(is_archived) {}
768
769 void do_oop(narrowOop *p) { VerifySharedOopClosure::do_oop_work(p); }
770 void do_oop( oop *p) { VerifySharedOopClosure::do_oop_work(p); }
771
772 protected:
773 template <class T> void do_oop_work(T *p) {
774 oop obj = RawAccess<>::oop_load(p);
775 if (!CompressedOops::is_null(obj)) {
776 HeapShared::verify_reachable_objects_from(obj, _is_archived);
777 }
778 }
779 };
780
781 void HeapShared::verify_subgraph_from_static_field(InstanceKlass* k, int field_offset) {
782 assert(DumpSharedSpaces, "dump time only");
783 assert(k->is_shared_boot_class(), "must be boot class");
784
785 oop m = k->java_mirror();
786 oop f = m->obj_field(field_offset);
787 if (!CompressedOops::is_null(f)) {
788 verify_subgraph_from(f);
789 }
790 }
791
792 void HeapShared::verify_subgraph_from(oop orig_obj) {
793 oop archived_obj = find_archived_heap_object(orig_obj);
794 if (archived_obj == NULL) {
795 // It's OK for the root of a subgraph to be not archived. See comments in
979 for (int i = 0; i < num; i++) {
980 ArchivableStaticFieldInfo* f = &fields[i];
981 verify_subgraph_from_static_field(f->klass, f->offset);
982 }
983 log_info(cds, heap)(" Verified %d references", _num_total_verifications);
984 #endif
985 }
986
987 // At dump-time, find the location of all the non-null oop pointers in an archived heap
988 // region. This way we can quickly relocate all the pointers without using
989 // BasicOopIterateClosure at runtime.
990 class FindEmbeddedNonNullPointers: public BasicOopIterateClosure {
991 narrowOop* _start;
992 BitMap *_oopmap;
993 int _num_total_oops;
994 int _num_null_oops;
995 public:
996 FindEmbeddedNonNullPointers(narrowOop* start, BitMap* oopmap)
997 : _start(start), _oopmap(oopmap), _num_total_oops(0), _num_null_oops(0) {}
998
999 virtual bool should_verify_oops(void) {
1000 return false;
1001 }
1002 virtual void do_oop(narrowOop* p) {
1003 _num_total_oops ++;
1004 narrowOop v = *p;
1005 if (!CompressedOops::is_null(v)) {
1006 size_t idx = p - _start;
1007 _oopmap->set_bit(idx);
1008 } else {
1009 _num_null_oops ++;
1010 }
1011 }
1012 virtual void do_oop(oop *p) {
1013 ShouldNotReachHere();
1014 }
1015 int num_total_oops() const { return _num_total_oops; }
1016 int num_null_oops() const { return _num_null_oops; }
1017 };
1018
1019 ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) {
1020 assert(UseCompressedOops, "must be");
1021 size_t num_bits = region.byte_size() / sizeof(narrowOop);
|
532 oop _archived_referencing_obj;
533 Thread* _thread;
534 public:
535 WalkOopAndArchiveClosure(int level,
536 bool is_closed_archive,
537 bool record_klasses_only,
538 KlassSubGraphInfo* subgraph_info,
539 oop orig, oop archived, TRAPS) :
540 _level(level), _is_closed_archive(is_closed_archive),
541 _record_klasses_only(record_klasses_only),
542 _subgraph_info(subgraph_info),
543 _orig_referencing_obj(orig), _archived_referencing_obj(archived),
544 _thread(THREAD) {}
545 void do_oop(narrowOop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
546 void do_oop( oop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
547
548 protected:
549 template <class T> void do_oop_work(T *p) {
550 oop obj = RawAccess<>::oop_load(p);
551 if (!CompressedOops::is_null(obj)) {
552 assert_object_is_in_heap(p, obj);
553 assert(!HeapShared::is_archived_object(obj),
554 "original objects must not point to archived objects");
555
556 size_t field_delta = pointer_delta(p, _orig_referencing_obj, sizeof(char));
557 T* new_p = (T*)(address(_archived_referencing_obj) + field_delta);
558 Thread* THREAD = _thread;
559
560 if (!_record_klasses_only && log_is_enabled(Debug, cds, heap)) {
561 ResourceMark rm;
562 log_debug(cds, heap)("(%d) %s[" SIZE_FORMAT "] ==> " PTR_FORMAT " size %d %s", _level,
563 _orig_referencing_obj->klass()->external_name(), field_delta,
564 p2i(obj), obj->size() * HeapWordSize, obj->klass()->external_name());
565 LogTarget(Trace, cds, heap) log;
566 LogStream out(log);
567 obj->print_on(&out);
568 }
569
570 oop archived = HeapShared::archive_reachable_objects_from(
571 _level + 1, _subgraph_info, obj, _is_closed_archive, THREAD);
572 assert(archived != NULL, "VM should have exited with unarchivable objects for _level > 1");
757 // so it can be restored at runtime.
758 subgraph_info->add_subgraph_entry_field(field_offset, NULL, false);
759 }
760 }
761
762 #ifndef PRODUCT
763 class VerifySharedOopClosure: public BasicOopIterateClosure {
764 private:
765 bool _is_archived;
766
767 public:
768 VerifySharedOopClosure(bool is_archived) : _is_archived(is_archived) {}
769
770 void do_oop(narrowOop *p) { VerifySharedOopClosure::do_oop_work(p); }
771 void do_oop( oop *p) { VerifySharedOopClosure::do_oop_work(p); }
772
773 protected:
774 template <class T> void do_oop_work(T *p) {
775 oop obj = RawAccess<>::oop_load(p);
776 if (!CompressedOops::is_null(obj)) {
777 assert_object_is_in_heap(p, obj);
778
779 HeapShared::verify_reachable_objects_from(obj, _is_archived);
780 }
781 }
782 };
783
784 void HeapShared::verify_subgraph_from_static_field(InstanceKlass* k, int field_offset) {
785 assert(DumpSharedSpaces, "dump time only");
786 assert(k->is_shared_boot_class(), "must be boot class");
787
788 oop m = k->java_mirror();
789 oop f = m->obj_field(field_offset);
790 if (!CompressedOops::is_null(f)) {
791 verify_subgraph_from(f);
792 }
793 }
794
795 void HeapShared::verify_subgraph_from(oop orig_obj) {
796 oop archived_obj = find_archived_heap_object(orig_obj);
797 if (archived_obj == NULL) {
798 // It's OK for the root of a subgraph to be not archived. See comments in
982 for (int i = 0; i < num; i++) {
983 ArchivableStaticFieldInfo* f = &fields[i];
984 verify_subgraph_from_static_field(f->klass, f->offset);
985 }
986 log_info(cds, heap)(" Verified %d references", _num_total_verifications);
987 #endif
988 }
989
990 // At dump-time, find the location of all the non-null oop pointers in an archived heap
991 // region. This way we can quickly relocate all the pointers without using
992 // BasicOopIterateClosure at runtime.
993 class FindEmbeddedNonNullPointers: public BasicOopIterateClosure {
994 narrowOop* _start;
995 BitMap *_oopmap;
996 int _num_total_oops;
997 int _num_null_oops;
998 public:
999 FindEmbeddedNonNullPointers(narrowOop* start, BitMap* oopmap)
1000 : _start(start), _oopmap(oopmap), _num_total_oops(0), _num_null_oops(0) {}
1001
1002 virtual void do_oop(narrowOop* p) {
1003 _num_total_oops ++;
1004 narrowOop v = *p;
1005 if (!CompressedOops::is_null(v)) {
1006 size_t idx = p - _start;
1007 _oopmap->set_bit(idx);
1008 } else {
1009 _num_null_oops ++;
1010 }
1011 }
1012 virtual void do_oop(oop *p) {
1013 ShouldNotReachHere();
1014 }
1015 int num_total_oops() const { return _num_total_oops; }
1016 int num_null_oops() const { return _num_null_oops; }
1017 };
1018
1019 ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) {
1020 assert(UseCompressedOops, "must be");
1021 size_t num_bits = region.byte_size() / sizeof(narrowOop);
|