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 "classfile/javaClasses.inline.hpp"
27 #include "classfile/symbolTable.hpp"
28 #include "classfile/vmSymbols.hpp"
29 #include "logging/log.hpp"
30 #include "logging/logMessage.hpp"
31 #include "logging/logStream.hpp"
32 #include "memory/heapShared.hpp"
33 #include "memory/iterator.inline.hpp"
34 #include "memory/metadataFactory.hpp"
35 #include "memory/metaspaceClosure.hpp"
36 #include "memory/metaspaceShared.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "oops/compressedOops.inline.hpp"
39 #include "oops/oop.inline.hpp"
40 #include "runtime/fieldDescriptor.inline.hpp"
41
42 #if INCLUDE_CDS_JAVA_HEAP
43 KlassSubGraphInfo* HeapShared::_subgraph_info_list = NULL;
44 int HeapShared::_num_archived_subgraph_info_records = 0;
45 Array<ArchivedKlassSubGraphInfoRecord>* HeapShared::_archived_subgraph_info_records = NULL;
46
47 // Currently there is only one class mirror (ArchivedModuleGraph) with archived
48 // sub-graphs.
49 KlassSubGraphInfo* HeapShared::find_subgraph_info(Klass* k) {
50 KlassSubGraphInfo* info = _subgraph_info_list;
51 while (info != NULL) {
52 if (info->klass() == k) {
53 return info;
54 }
55 info = info->next();
56 }
57 return NULL;
58 }
59
60 // Get the subgraph_info for Klass k. A new subgraph_info is created if
61 // there is no existing one for k. The subgraph_info records the relocated
62 // Klass* of the original k.
63 KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
64 Klass* relocated_k = MetaspaceShared::get_relocated_klass(k);
65 KlassSubGraphInfo* info = find_subgraph_info(relocated_k);
66 if (info != NULL) {
67 return info;
68 }
69
70 info = new KlassSubGraphInfo(relocated_k, _subgraph_info_list);
71 _subgraph_info_list = info;
72 return info;
73 }
74
75 int HeapShared::num_of_subgraph_infos() {
76 int num = 0;
77 KlassSubGraphInfo* info = _subgraph_info_list;
78 while (info != NULL) {
79 num ++;
80 info = info->next();
81 }
82 return num;
83 }
84
85 // Add an entry field to the current KlassSubGraphInfo.
86 void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) {
87 assert(DumpSharedSpaces, "dump time only");
88 if (_subgraph_entry_fields == NULL) {
89 _subgraph_entry_fields =
90 new(ResourceObj::C_HEAP, mtClass) GrowableArray<juint>(10, true);
91 }
92 _subgraph_entry_fields->append((juint)static_field_offset);
93 _subgraph_entry_fields->append(CompressedOops::encode(v));
94 }
303 CLEAR_PENDING_EXCEPTION;
304 // None of the field value will be set if there was an exception.
305 // The java code will not see any of the archived objects in the
306 // subgraphs referenced from k in this case.
307 return;
308 }
309
310 // Load the subgraph entry fields from the record and store them back to
311 // the corresponding fields within the mirror.
312 oop m = k->java_mirror();
313 Array<juint>* entry_field_records = record->entry_field_records();
314 if (entry_field_records != NULL) {
315 int efr_len = entry_field_records->length();
316 assert(efr_len % 2 == 0, "sanity");
317 for (i = 0; i < efr_len;) {
318 int field_offset = entry_field_records->at(i);
319 // The object refereced by the field becomes 'known' by GC from this
320 // point. All objects in the subgraph reachable from the object are
321 // also 'known' by GC.
322 oop v = MetaspaceShared::materialize_archived_object(
323 CompressedOops::decode(entry_field_records->at(i+1)));
324 m->obj_field_put(field_offset, v);
325 i += 2;
326 }
327 }
328
329 // Done. Java code can see the archived sub-graphs referenced from k's
330 // mirror after this point.
331 return;
332 }
333 }
334 }
335
336 class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
337 int _level;
338 KlassSubGraphInfo* _subgraph_info;
339 oop _orig_referencing_obj;
340 oop _archived_referencing_obj;
341 public:
342 WalkOopAndArchiveClosure(int level, KlassSubGraphInfo* subgraph_info,
343 oop orig, oop archived) : _level(level),
584 Klass* k = SystemDictionary::resolve_or_null(class_name, THREAD);
585 assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist");
586 InstanceKlass* ik = InstanceKlass::cast(k);
587
588 ArchivableStaticFieldFinder finder(ik, field_name);
589 ik->do_local_static_fields(&finder);
590 assert(finder.found(), "field must exist");
591
592 info->klass = ik;
593 info->offset = finder.offset();
594 info->type = finder.type();
595 }
596 }
597
598 void HeapShared::archive_module_graph_objects(Thread* THREAD) {
599 for (int i = 0; i < num_archivable_static_fields; i++) {
600 ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
601 archive_reachable_objects_from_static_field(info->klass, info->offset, info->type, CHECK);
602 }
603 }
604 #endif // INCLUDE_CDS_JAVA_HEAP
|
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 "classfile/javaClasses.inline.hpp"
27 #include "classfile/symbolTable.hpp"
28 #include "classfile/vmSymbols.hpp"
29 #include "logging/log.hpp"
30 #include "logging/logMessage.hpp"
31 #include "logging/logStream.hpp"
32 #include "memory/heapShared.inline.hpp"
33 #include "memory/iterator.inline.hpp"
34 #include "memory/metadataFactory.hpp"
35 #include "memory/metaspaceClosure.hpp"
36 #include "memory/metaspaceShared.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "oops/compressedOops.inline.hpp"
39 #include "oops/oop.inline.hpp"
40 #include "runtime/fieldDescriptor.inline.hpp"
41 #include "utilities/bitMap.inline.hpp"
42
43 #if INCLUDE_CDS_JAVA_HEAP
44 KlassSubGraphInfo* HeapShared::_subgraph_info_list = NULL;
45 int HeapShared::_num_archived_subgraph_info_records = 0;
46 Array<ArchivedKlassSubGraphInfoRecord>* HeapShared::_archived_subgraph_info_records = NULL;
47
48 // Currently there is only one class mirror (ArchivedModuleGraph) with archived
49 // sub-graphs.
50 KlassSubGraphInfo* HeapShared::find_subgraph_info(Klass* k) {
51 KlassSubGraphInfo* info = _subgraph_info_list;
52 while (info != NULL) {
53 if (info->klass() == k) {
54 return info;
55 }
56 info = info->next();
57 }
58 return NULL;
59 }
60
61 // Get the subgraph_info for Klass k. A new subgraph_info is created if
62 // there is no existing one for k. The subgraph_info records the relocated
63 // Klass* of the original k.
64 KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
65 Klass* relocated_k = MetaspaceShared::get_relocated_klass(k);
66 KlassSubGraphInfo* info = find_subgraph_info(relocated_k);
67 if (info != NULL) {
68 return info;
69 }
70
71 info = new KlassSubGraphInfo(relocated_k, _subgraph_info_list);
72 _subgraph_info_list = info;
73 return info;
74 }
75
76 address HeapShared::_narrow_oop_base;
77 int HeapShared::_narrow_oop_shift;
78
79 int HeapShared::num_of_subgraph_infos() {
80 int num = 0;
81 KlassSubGraphInfo* info = _subgraph_info_list;
82 while (info != NULL) {
83 num ++;
84 info = info->next();
85 }
86 return num;
87 }
88
89 // Add an entry field to the current KlassSubGraphInfo.
90 void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) {
91 assert(DumpSharedSpaces, "dump time only");
92 if (_subgraph_entry_fields == NULL) {
93 _subgraph_entry_fields =
94 new(ResourceObj::C_HEAP, mtClass) GrowableArray<juint>(10, true);
95 }
96 _subgraph_entry_fields->append((juint)static_field_offset);
97 _subgraph_entry_fields->append(CompressedOops::encode(v));
98 }
307 CLEAR_PENDING_EXCEPTION;
308 // None of the field value will be set if there was an exception.
309 // The java code will not see any of the archived objects in the
310 // subgraphs referenced from k in this case.
311 return;
312 }
313
314 // Load the subgraph entry fields from the record and store them back to
315 // the corresponding fields within the mirror.
316 oop m = k->java_mirror();
317 Array<juint>* entry_field_records = record->entry_field_records();
318 if (entry_field_records != NULL) {
319 int efr_len = entry_field_records->length();
320 assert(efr_len % 2 == 0, "sanity");
321 for (i = 0; i < efr_len;) {
322 int field_offset = entry_field_records->at(i);
323 // The object refereced by the field becomes 'known' by GC from this
324 // point. All objects in the subgraph reachable from the object are
325 // also 'known' by GC.
326 oop v = MetaspaceShared::materialize_archived_object(
327 entry_field_records->at(i+1));
328 m->obj_field_put(field_offset, v);
329 i += 2;
330 }
331 }
332
333 // Done. Java code can see the archived sub-graphs referenced from k's
334 // mirror after this point.
335 return;
336 }
337 }
338 }
339
340 class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
341 int _level;
342 KlassSubGraphInfo* _subgraph_info;
343 oop _orig_referencing_obj;
344 oop _archived_referencing_obj;
345 public:
346 WalkOopAndArchiveClosure(int level, KlassSubGraphInfo* subgraph_info,
347 oop orig, oop archived) : _level(level),
588 Klass* k = SystemDictionary::resolve_or_null(class_name, THREAD);
589 assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist");
590 InstanceKlass* ik = InstanceKlass::cast(k);
591
592 ArchivableStaticFieldFinder finder(ik, field_name);
593 ik->do_local_static_fields(&finder);
594 assert(finder.found(), "field must exist");
595
596 info->klass = ik;
597 info->offset = finder.offset();
598 info->type = finder.type();
599 }
600 }
601
602 void HeapShared::archive_module_graph_objects(Thread* THREAD) {
603 for (int i = 0; i < num_archivable_static_fields; i++) {
604 ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
605 archive_reachable_objects_from_static_field(info->klass, info->offset, info->type, CHECK);
606 }
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
700 #endif // INCLUDE_CDS_JAVA_HEAP
|