27 #include "classfile/symbolTable.hpp" |
27 #include "classfile/symbolTable.hpp" |
28 #include "classfile/vmSymbols.hpp" |
28 #include "classfile/vmSymbols.hpp" |
29 #include "logging/log.hpp" |
29 #include "logging/log.hpp" |
30 #include "logging/logMessage.hpp" |
30 #include "logging/logMessage.hpp" |
31 #include "logging/logStream.hpp" |
31 #include "logging/logStream.hpp" |
32 #include "memory/heapShared.hpp" |
32 #include "memory/heapShared.inline.hpp" |
33 #include "memory/iterator.inline.hpp" |
33 #include "memory/iterator.inline.hpp" |
34 #include "memory/metadataFactory.hpp" |
34 #include "memory/metadataFactory.hpp" |
35 #include "memory/metaspaceClosure.hpp" |
35 #include "memory/metaspaceClosure.hpp" |
36 #include "memory/metaspaceShared.hpp" |
36 #include "memory/metaspaceShared.hpp" |
37 #include "memory/resourceArea.hpp" |
37 #include "memory/resourceArea.hpp" |
38 #include "oops/compressedOops.inline.hpp" |
38 #include "oops/compressedOops.inline.hpp" |
39 #include "oops/oop.inline.hpp" |
39 #include "oops/oop.inline.hpp" |
40 #include "runtime/fieldDescriptor.inline.hpp" |
40 #include "runtime/fieldDescriptor.inline.hpp" |
|
41 #include "utilities/bitMap.inline.hpp" |
41 |
42 |
42 #if INCLUDE_CDS_JAVA_HEAP |
43 #if INCLUDE_CDS_JAVA_HEAP |
43 KlassSubGraphInfo* HeapShared::_subgraph_info_list = NULL; |
44 KlassSubGraphInfo* HeapShared::_subgraph_info_list = NULL; |
44 int HeapShared::_num_archived_subgraph_info_records = 0; |
45 int HeapShared::_num_archived_subgraph_info_records = 0; |
45 Array<ArchivedKlassSubGraphInfoRecord>* HeapShared::_archived_subgraph_info_records = NULL; |
46 Array<ArchivedKlassSubGraphInfoRecord>* HeapShared::_archived_subgraph_info_records = NULL; |
318 int field_offset = entry_field_records->at(i); |
322 int field_offset = entry_field_records->at(i); |
319 // The object refereced by the field becomes 'known' by GC from this |
323 // The object refereced by the field becomes 'known' by GC from this |
320 // point. All objects in the subgraph reachable from the object are |
324 // point. All objects in the subgraph reachable from the object are |
321 // also 'known' by GC. |
325 // also 'known' by GC. |
322 oop v = MetaspaceShared::materialize_archived_object( |
326 oop v = MetaspaceShared::materialize_archived_object( |
323 CompressedOops::decode(entry_field_records->at(i+1))); |
327 entry_field_records->at(i+1)); |
324 m->obj_field_put(field_offset, v); |
328 m->obj_field_put(field_offset, v); |
325 i += 2; |
329 i += 2; |
326 } |
330 } |
327 } |
331 } |
328 |
332 |
599 for (int i = 0; i < num_archivable_static_fields; i++) { |
603 for (int i = 0; i < num_archivable_static_fields; i++) { |
600 ArchivableStaticFieldInfo* info = &archivable_static_fields[i]; |
604 ArchivableStaticFieldInfo* info = &archivable_static_fields[i]; |
601 archive_reachable_objects_from_static_field(info->klass, info->offset, info->type, CHECK); |
605 archive_reachable_objects_from_static_field(info->klass, info->offset, info->type, CHECK); |
602 } |
606 } |
603 } |
607 } |
|
608 |
|
609 // At dump-time, find the location of all the non-null oop pointers in an archived heap |
|
610 // region. This way we can quickly relocate all the pointers without using |
|
611 // BasicOopIterateClosure at runtime. |
|
612 class FindEmbeddedNonNullPointers: public BasicOopIterateClosure { |
|
613 narrowOop* _start; |
|
614 BitMap *_oopmap; |
|
615 int _num_total_oops; |
|
616 int _num_null_oops; |
|
617 public: |
|
618 FindEmbeddedNonNullPointers(narrowOop* start, BitMap* oopmap) |
|
619 : _start(start), _oopmap(oopmap), _num_total_oops(0), _num_null_oops(0) {} |
|
620 |
|
621 virtual bool should_verify_oops(void) { |
|
622 return false; |
|
623 } |
|
624 virtual void do_oop(narrowOop* p) { |
|
625 _num_total_oops ++; |
|
626 narrowOop v = *p; |
|
627 if (!CompressedOops::is_null(v)) { |
|
628 size_t idx = p - _start; |
|
629 _oopmap->set_bit(idx); |
|
630 } else { |
|
631 _num_null_oops ++; |
|
632 } |
|
633 } |
|
634 virtual void do_oop(oop *p) { |
|
635 ShouldNotReachHere(); |
|
636 } |
|
637 int num_total_oops() const { return _num_total_oops; } |
|
638 int num_null_oops() const { return _num_null_oops; } |
|
639 }; |
|
640 |
|
641 ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) { |
|
642 assert(UseCompressedOops, "must be"); |
|
643 size_t num_bits = region.byte_size() / sizeof(narrowOop); |
|
644 ResourceBitMap oopmap(num_bits); |
|
645 |
|
646 HeapWord* p = region.start(); |
|
647 HeapWord* end = region.end(); |
|
648 FindEmbeddedNonNullPointers finder((narrowOop*)p, &oopmap); |
|
649 |
|
650 int num_objs = 0; |
|
651 while (p < end) { |
|
652 oop o = (oop)p; |
|
653 o->oop_iterate(&finder); |
|
654 p += o->size(); |
|
655 ++ num_objs; |
|
656 } |
|
657 |
|
658 log_info(cds, heap)("calculate_oopmap: objects = %6d, embedded oops = %7d, nulls = %7d", |
|
659 num_objs, finder.num_total_oops(), finder.num_null_oops()); |
|
660 return oopmap; |
|
661 } |
|
662 |
|
663 void HeapShared::init_narrow_oop_decoding(address base, int shift) { |
|
664 _narrow_oop_base = base; |
|
665 _narrow_oop_shift = shift; |
|
666 } |
|
667 |
|
668 // Patch all the embedded oop pointers inside an archived heap region, |
|
669 // to be consistent with the runtime oop encoding. |
|
670 class PatchEmbeddedPointers: public BitMapClosure { |
|
671 narrowOop* _start; |
|
672 |
|
673 public: |
|
674 PatchEmbeddedPointers(narrowOop* start) : _start(start) {} |
|
675 |
|
676 bool do_bit(size_t offset) { |
|
677 narrowOop* p = _start + offset; |
|
678 narrowOop v = *p; |
|
679 assert(!CompressedOops::is_null(v), "null oops should have been filtered out at dump time"); |
|
680 oop o = HeapShared::decode_with_archived_oop_encoding_mode(v); |
|
681 RawAccess<IS_NOT_NULL>::oop_store(p, o); |
|
682 return true; |
|
683 } |
|
684 }; |
|
685 |
|
686 void HeapShared::patch_archived_heap_embedded_pointers(MemRegion region, address oopmap, |
|
687 size_t oopmap_size_in_bits) { |
|
688 BitMapView bm((BitMap::bm_word_t*)oopmap, oopmap_size_in_bits); |
|
689 |
|
690 #ifndef PRODUCT |
|
691 ResourceMark rm; |
|
692 ResourceBitMap checkBm = calculate_oopmap(region); |
|
693 assert(bm.is_same(checkBm), "sanity"); |
|
694 #endif |
|
695 |
|
696 PatchEmbeddedPointers patcher((narrowOop*)region.start()); |
|
697 bm.iterate(&patcher); |
|
698 } |
|
699 |
604 #endif // INCLUDE_CDS_JAVA_HEAP |
700 #endif // INCLUDE_CDS_JAVA_HEAP |