src/hotspot/share/memory/heapShared.cpp
changeset 52402 72d4e10305b9
parent 52319 625f6c742392
child 52465 3e0ebf913679
equal deleted inserted replaced
52401:595ab4f025d7 52402:72d4e10305b9
    35 #include "memory/iterator.inline.hpp"
    35 #include "memory/iterator.inline.hpp"
    36 #include "memory/metadataFactory.hpp"
    36 #include "memory/metadataFactory.hpp"
    37 #include "memory/metaspaceClosure.hpp"
    37 #include "memory/metaspaceClosure.hpp"
    38 #include "memory/resourceArea.hpp"
    38 #include "memory/resourceArea.hpp"
    39 #include "oops/compressedOops.inline.hpp"
    39 #include "oops/compressedOops.inline.hpp"
       
    40 #include "oops/fieldStreams.hpp"
    40 #include "oops/oop.inline.hpp"
    41 #include "oops/oop.inline.hpp"
    41 #include "runtime/fieldDescriptor.inline.hpp"
    42 #include "runtime/fieldDescriptor.inline.hpp"
    42 #include "runtime/safepointVerifiers.hpp"
    43 #include "runtime/safepointVerifiers.hpp"
    43 #include "utilities/bitMap.inline.hpp"
    44 #include "utilities/bitMap.inline.hpp"
    44 #if INCLUDE_G1GC
    45 #if INCLUDE_G1GC
    45 #include "gc/g1/g1CollectedHeap.hpp"
    46 #include "gc/g1/g1CollectedHeap.hpp"
    46 #endif
    47 #endif
    47 
    48 
    48 #if INCLUDE_CDS_JAVA_HEAP
    49 #if INCLUDE_CDS_JAVA_HEAP
    49 
    50 
       
    51 bool HeapShared::_closed_archive_heap_region_mapped = false;
    50 bool HeapShared::_open_archive_heap_region_mapped = false;
    52 bool HeapShared::_open_archive_heap_region_mapped = false;
    51 bool HeapShared::_archive_heap_region_fixed = false;
    53 bool HeapShared::_archive_heap_region_fixed = false;
    52 
    54 
    53 address   HeapShared::_narrow_oop_base;
    55 address   HeapShared::_narrow_oop_base;
    54 int       HeapShared::_narrow_oop_shift;
    56 int       HeapShared::_narrow_oop_shift;
       
    57 
       
    58 //
       
    59 // If you add new entries to the following tables, you should know what you're doing!
       
    60 //
       
    61 
       
    62 // Entry fields for shareable subgraphs archived in the closed archive heap
       
    63 // region. Warning: Objects in the subgraphs should not have reference fields
       
    64 // assigned at runtime.
       
    65 static ArchivableStaticFieldInfo closed_archive_subgraph_entry_fields[] = {
       
    66   {"java/lang/Integer$IntegerCache",           "archivedCache"},
       
    67 };
       
    68 // Entry fields for subgraphs archived in the open archive heap region.
       
    69 static ArchivableStaticFieldInfo open_archive_subgraph_entry_fields[] = {
       
    70   {"jdk/internal/module/ArchivedModuleGraph",  "archivedSystemModules"},
       
    71   {"jdk/internal/module/ArchivedModuleGraph",  "archivedModuleFinder"},
       
    72   {"jdk/internal/module/ArchivedModuleGraph",  "archivedMainModule"},
       
    73   {"jdk/internal/module/ArchivedModuleGraph",  "archivedConfiguration"},
       
    74   {"java/util/ImmutableCollections$ListN",     "EMPTY_LIST"},
       
    75   {"java/util/ImmutableCollections$MapN",      "EMPTY_MAP"},
       
    76   {"java/util/ImmutableCollections$SetN",      "EMPTY_SET"},
       
    77   {"java/lang/module/Configuration",           "EMPTY_CONFIGURATION"},
       
    78 };
       
    79 
       
    80 const static int num_closed_archive_subgraph_entry_fields =
       
    81   sizeof(closed_archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo);
       
    82 const static int num_open_archive_subgraph_entry_fields =
       
    83   sizeof(open_archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo);
    55 
    84 
    56 ////////////////////////////////////////////////////////////////
    85 ////////////////////////////////////////////////////////////////
    57 //
    86 //
    58 // Java heap object archiving support
    87 // Java heap object archiving support
    59 //
    88 //
   187   G1CollectedHeap::heap()->begin_archive_alloc_range();
   216   G1CollectedHeap::heap()->begin_archive_alloc_range();
   188 
   217 
   189   // Archive interned string objects
   218   // Archive interned string objects
   190   StringTable::write_to_archive();
   219   StringTable::write_to_archive();
   191 
   220 
       
   221   archive_object_subgraphs(closed_archive_subgraph_entry_fields,
       
   222                            num_closed_archive_subgraph_entry_fields,
       
   223                            true /* is_closed_archive */, THREAD);
       
   224 
   192   G1CollectedHeap::heap()->end_archive_alloc_range(closed_archive,
   225   G1CollectedHeap::heap()->end_archive_alloc_range(closed_archive,
   193                                                    os::vm_allocation_granularity());
   226                                                    os::vm_allocation_granularity());
   194 }
   227 }
   195 
   228 
   196 void HeapShared::copy_open_archive_heap_objects(
   229 void HeapShared::copy_open_archive_heap_objects(
   202 
   235 
   203   java_lang_Class::archive_basic_type_mirrors(THREAD);
   236   java_lang_Class::archive_basic_type_mirrors(THREAD);
   204 
   237 
   205   archive_klass_objects(THREAD);
   238   archive_klass_objects(THREAD);
   206 
   239 
   207   archive_object_subgraphs(THREAD);
   240   archive_object_subgraphs(open_archive_subgraph_entry_fields,
       
   241                            num_open_archive_subgraph_entry_fields,
       
   242                            false /* is_closed_archive */,
       
   243                            THREAD);
   208 
   244 
   209   G1CollectedHeap::heap()->end_archive_alloc_range(open_archive,
   245   G1CollectedHeap::heap()->end_archive_alloc_range(open_archive,
   210                                                    os::vm_allocation_granularity());
   246                                                    os::vm_allocation_granularity());
   211 }
   247 }
   212 
   248 
   235   }
   271   }
   236   return info;
   272   return info;
   237 }
   273 }
   238 
   274 
   239 // Add an entry field to the current KlassSubGraphInfo.
   275 // Add an entry field to the current KlassSubGraphInfo.
   240 void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) {
   276 void KlassSubGraphInfo::add_subgraph_entry_field(
       
   277       int static_field_offset, oop v, bool is_closed_archive) {
   241   assert(DumpSharedSpaces, "dump time only");
   278   assert(DumpSharedSpaces, "dump time only");
   242   if (_subgraph_entry_fields == NULL) {
   279   if (_subgraph_entry_fields == NULL) {
   243     _subgraph_entry_fields =
   280     _subgraph_entry_fields =
   244       new(ResourceObj::C_HEAP, mtClass) GrowableArray<juint>(10, true);
   281       new(ResourceObj::C_HEAP, mtClass) GrowableArray<juint>(10, true);
   245   }
   282   }
   246   _subgraph_entry_fields->append((juint)static_field_offset);
   283   _subgraph_entry_fields->append((juint)static_field_offset);
   247   _subgraph_entry_fields->append(CompressedOops::encode(v));
   284   _subgraph_entry_fields->append(CompressedOops::encode(v));
       
   285   _subgraph_entry_fields->append(is_closed_archive ? 1 : 0);
   248 }
   286 }
   249 
   287 
   250 // Add the Klass* for an object in the current KlassSubGraphInfo's subgraphs.
   288 // Add the Klass* for an object in the current KlassSubGraphInfo's subgraphs.
   251 // Only objects of boot classes can be included in sub-graph.
   289 // Only objects of boot classes can be included in sub-graph.
   252 void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k, Klass *relocated_k) {
   290 void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k, Klass *relocated_k) {
   313 
   351 
   314   // populate the entry fields
   352   // populate the entry fields
   315   GrowableArray<juint>* entry_fields = info->subgraph_entry_fields();
   353   GrowableArray<juint>* entry_fields = info->subgraph_entry_fields();
   316   if (entry_fields != NULL) {
   354   if (entry_fields != NULL) {
   317     int num_entry_fields = entry_fields->length();
   355     int num_entry_fields = entry_fields->length();
   318     assert(num_entry_fields % 2 == 0, "sanity");
   356     assert(num_entry_fields % 3 == 0, "sanity");
   319     _entry_field_records =
   357     _entry_field_records =
   320       MetaspaceShared::new_ro_array<juint>(num_entry_fields);
   358       MetaspaceShared::new_ro_array<juint>(num_entry_fields);
   321     for (int i = 0 ; i < num_entry_fields; i++) {
   359     for (int i = 0 ; i < num_entry_fields; i++) {
   322       _entry_field_records->at_put(i, entry_fields->at(i));
   360       _entry_field_records->at_put(i, entry_fields->at(i));
   323     }
   361     }
   363 };
   401 };
   364 
   402 
   365 // Build the records of archived subgraph infos, which include:
   403 // Build the records of archived subgraph infos, which include:
   366 // - Entry points to all subgraphs from the containing class mirror. The entry
   404 // - Entry points to all subgraphs from the containing class mirror. The entry
   367 //   points are static fields in the mirror. For each entry point, the field
   405 //   points are static fields in the mirror. For each entry point, the field
   368 //   offset and value are recorded in the sub-graph info. The value are stored
   406 //   offset, value and is_closed_archive flag are recorded in the sub-graph
   369 //   back to the corresponding field at runtime.
   407 //   info. The value is stored back to the corresponding field at runtime.
   370 // - A list of klasses that need to be loaded/initialized before archived
   408 // - A list of klasses that need to be loaded/initialized before archived
   371 //   java object sub-graph can be accessed at runtime.
   409 //   java object sub-graph can be accessed at runtime.
   372 void HeapShared::write_subgraph_info_table() {
   410 void HeapShared::write_subgraph_info_table() {
   373   // Allocate the contents of the hashtable(s) inside the RO region of the CDS archive.
   411   // Allocate the contents of the hashtable(s) inside the RO region of the CDS archive.
   374   DumpTimeKlassSubGraphInfoTable* d_table = _dump_time_subgraph_info_table;
   412   DumpTimeKlassSubGraphInfoTable* d_table = _dump_time_subgraph_info_table;
   446     // the corresponding fields within the mirror.
   484     // the corresponding fields within the mirror.
   447     oop m = k->java_mirror();
   485     oop m = k->java_mirror();
   448     Array<juint>* entry_field_records = record->entry_field_records();
   486     Array<juint>* entry_field_records = record->entry_field_records();
   449     if (entry_field_records != NULL) {
   487     if (entry_field_records != NULL) {
   450       int efr_len = entry_field_records->length();
   488       int efr_len = entry_field_records->length();
   451       assert(efr_len % 2 == 0, "sanity");
   489       assert(efr_len % 3 == 0, "sanity");
   452       for (i = 0; i < efr_len;) {
   490       for (i = 0; i < efr_len;) {
   453         int field_offset = entry_field_records->at(i);
   491         int field_offset = entry_field_records->at(i);
   454         // The object refereced by the field becomes 'known' by GC from this
   492         narrowOop nv = entry_field_records->at(i+1);
   455         // point. All objects in the subgraph reachable from the object are
   493         int is_closed_archive = entry_field_records->at(i+2);
   456         // also 'known' by GC.
   494         oop v;
   457         oop v = materialize_archived_object(entry_field_records->at(i+1));
   495         if (is_closed_archive == 0) {
       
   496           // It's an archived object in the open archive heap regions, not shared.
       
   497           // The object refereced by the field becomes 'known' by GC from this
       
   498           // point. All objects in the subgraph reachable from the object are
       
   499           // also 'known' by GC.
       
   500           v = materialize_archived_object(nv);
       
   501         } else {
       
   502           // Shared object in the closed archive heap regions. Decode directly.
       
   503           assert(!CompressedOops::is_null(nv), "shared object is null");
       
   504           v = HeapShared::decode_from_archive(nv);
       
   505         }
   458         m->obj_field_put(field_offset, v);
   506         m->obj_field_put(field_offset, v);
   459         i += 2;
   507         i += 3;
   460 
   508 
   461         log_debug(cds, heap)("  " PTR_FORMAT " init field @ %2d = " PTR_FORMAT, p2i(k), field_offset, p2i(v));
   509         log_debug(cds, heap)("  " PTR_FORMAT " init field @ %2d = " PTR_FORMAT, p2i(k), field_offset, p2i(v));
   462       }
   510       }
   463 
   511 
   464     // Done. Java code can see the archived sub-graphs referenced from k's
   512     // Done. Java code can see the archived sub-graphs referenced from k's
   467   }
   515   }
   468 }
   516 }
   469 
   517 
   470 class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
   518 class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
   471   int _level;
   519   int _level;
       
   520   bool _is_closed_archive;
   472   bool _record_klasses_only;
   521   bool _record_klasses_only;
   473   KlassSubGraphInfo* _subgraph_info;
   522   KlassSubGraphInfo* _subgraph_info;
   474   oop _orig_referencing_obj;
   523   oop _orig_referencing_obj;
   475   oop _archived_referencing_obj;
   524   oop _archived_referencing_obj;
   476   Thread* _thread;
   525   Thread* _thread;
   477  public:
   526  public:
   478   WalkOopAndArchiveClosure(int level, bool record_klasses_only,
   527   WalkOopAndArchiveClosure(int level,
       
   528                            bool is_closed_archive,
       
   529                            bool record_klasses_only,
   479                            KlassSubGraphInfo* subgraph_info,
   530                            KlassSubGraphInfo* subgraph_info,
   480                            oop orig, oop archived, TRAPS) :
   531                            oop orig, oop archived, TRAPS) :
   481     _level(level), _record_klasses_only(record_klasses_only),
   532     _level(level), _is_closed_archive(is_closed_archive),
       
   533     _record_klasses_only(record_klasses_only),
   482     _subgraph_info(subgraph_info),
   534     _subgraph_info(subgraph_info),
   483     _orig_referencing_obj(orig), _archived_referencing_obj(archived),
   535     _orig_referencing_obj(orig), _archived_referencing_obj(archived),
   484     _thread(THREAD) {}
   536     _thread(THREAD) {}
   485   void do_oop(narrowOop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
   537   void do_oop(narrowOop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
   486   void do_oop(      oop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
   538   void do_oop(      oop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
   504         LogTarget(Trace, cds, heap) log;
   556         LogTarget(Trace, cds, heap) log;
   505         LogStream out(log);
   557         LogStream out(log);
   506         obj->print_on(&out);
   558         obj->print_on(&out);
   507       }
   559       }
   508 
   560 
   509       oop archived = HeapShared::archive_reachable_objects_from(_level + 1, _subgraph_info, obj, THREAD);
   561       oop archived = HeapShared::archive_reachable_objects_from(
       
   562           _level + 1, _subgraph_info, obj, _is_closed_archive, THREAD);
   510       assert(archived != NULL, "VM should have exited with unarchivable objects for _level > 1");
   563       assert(archived != NULL, "VM should have exited with unarchivable objects for _level > 1");
   511       assert(HeapShared::is_archived_object(archived), "must be");
   564       assert(HeapShared::is_archived_object(archived), "must be");
   512 
   565 
   513       if (!_record_klasses_only) {
   566       if (!_record_klasses_only) {
   514         // Update the reference in the archived copy of the referencing object.
   567         // Update the reference in the archived copy of the referencing object.
   518       }
   571       }
   519     }
   572     }
   520   }
   573   }
   521 };
   574 };
   522 
   575 
       
   576 void HeapShared::check_closed_archive_heap_region_object(InstanceKlass* k,
       
   577                                                          Thread* THREAD) {
       
   578   // Check fields in the object
       
   579   for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
       
   580     if (!fs.access_flags().is_static()) {
       
   581       BasicType ft = fs.field_descriptor().field_type();
       
   582       if (!fs.access_flags().is_final() && (ft == T_ARRAY || T_OBJECT)) {
       
   583         ResourceMark rm(THREAD);
       
   584         log_warning(cds, heap)(
       
   585           "Please check reference field in %s instance in closed archive heap region: %s %s",
       
   586           k->external_name(), (fs.name())->as_C_string(),
       
   587           (fs.signature())->as_C_string());
       
   588       }
       
   589     }
       
   590   }
       
   591 }
       
   592 
   523 // (1) If orig_obj has not been archived yet, archive it.
   593 // (1) If orig_obj has not been archived yet, archive it.
   524 // (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
   594 // (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
   525 //     trace all  objects that are reachable from it, and make sure these objects are archived.
   595 //     trace all  objects that are reachable from it, and make sure these objects are archived.
   526 // (3) Record the klasses of all orig_obj and all reachable objects.
   596 // (3) Record the klasses of all orig_obj and all reachable objects.
   527 oop HeapShared::archive_reachable_objects_from(int level, KlassSubGraphInfo* subgraph_info, oop orig_obj, TRAPS) {
   597 oop HeapShared::archive_reachable_objects_from(int level,
       
   598                                                KlassSubGraphInfo* subgraph_info,
       
   599                                                oop orig_obj,
       
   600                                                bool is_closed_archive,
       
   601                                                TRAPS) {
   528   assert(orig_obj != NULL, "must be");
   602   assert(orig_obj != NULL, "must be");
   529   assert(!is_archived_object(orig_obj), "sanity");
   603   assert(!is_archived_object(orig_obj), "sanity");
   530 
   604 
   531   // java.lang.Class instances cannot be included in an archived
   605   // java.lang.Class instances cannot be included in an archived
   532   // object sub-graph.
   606   // object sub-graph.
   576   assert(archived_obj != NULL, "must be");
   650   assert(archived_obj != NULL, "must be");
   577   Klass *orig_k = orig_obj->klass();
   651   Klass *orig_k = orig_obj->klass();
   578   Klass *relocated_k = archived_obj->klass();
   652   Klass *relocated_k = archived_obj->klass();
   579   subgraph_info->add_subgraph_object_klass(orig_k, relocated_k);
   653   subgraph_info->add_subgraph_object_klass(orig_k, relocated_k);
   580 
   654 
   581   WalkOopAndArchiveClosure walker(level, record_klasses_only, subgraph_info, orig_obj, archived_obj, THREAD);
   655   WalkOopAndArchiveClosure walker(level, is_closed_archive, record_klasses_only,
       
   656                                   subgraph_info, orig_obj, archived_obj, THREAD);
   582   orig_obj->oop_iterate(&walker);
   657   orig_obj->oop_iterate(&walker);
       
   658   if (is_closed_archive && orig_k->is_instance_klass()) {
       
   659     check_closed_archive_heap_region_object(InstanceKlass::cast(orig_k), THREAD);
       
   660   }
   583   return archived_obj;
   661   return archived_obj;
   584 }
   662 }
   585 
   663 
   586 //
   664 //
   587 // Start from the given static field in a java mirror and archive the
   665 // Start from the given static field in a java mirror and archive the
   619 //
   697 //
   620 void HeapShared::archive_reachable_objects_from_static_field(InstanceKlass *k,
   698 void HeapShared::archive_reachable_objects_from_static_field(InstanceKlass *k,
   621                                                              const char* klass_name,
   699                                                              const char* klass_name,
   622                                                              int field_offset,
   700                                                              int field_offset,
   623                                                              const char* field_name,
   701                                                              const char* field_name,
       
   702                                                              bool is_closed_archive,
   624                                                              TRAPS) {
   703                                                              TRAPS) {
   625   assert(DumpSharedSpaces, "dump time only");
   704   assert(DumpSharedSpaces, "dump time only");
   626   assert(k->is_shared_boot_class(), "must be boot class");
   705   assert(k->is_shared_boot_class(), "must be boot class");
   627 
   706 
   628   oop m = k->java_mirror();
   707   oop m = k->java_mirror();
   629   oop archived_m = find_archived_heap_object(m);
       
   630   if (CompressedOops::is_null(archived_m)) {
       
   631     return;
       
   632   }
       
   633 
   708 
   634   KlassSubGraphInfo* subgraph_info = get_subgraph_info(k);
   709   KlassSubGraphInfo* subgraph_info = get_subgraph_info(k);
   635   oop f = m->obj_field(field_offset);
   710   oop f = m->obj_field(field_offset);
   636 
   711 
   637   log_debug(cds, heap)("Start archiving from: %s::%s (" PTR_FORMAT ")", klass_name, field_name, p2i(f));
   712   log_debug(cds, heap)("Start archiving from: %s::%s (" PTR_FORMAT ")", klass_name, field_name, p2i(f));
   641       LogTarget(Trace, cds, heap) log;
   716       LogTarget(Trace, cds, heap) log;
   642       LogStream out(log);
   717       LogStream out(log);
   643       f->print_on(&out);
   718       f->print_on(&out);
   644     }
   719     }
   645 
   720 
   646     oop af = archive_reachable_objects_from(1, subgraph_info, f, CHECK);
   721     oop af = archive_reachable_objects_from(1, subgraph_info, f,
       
   722                                             is_closed_archive, CHECK);
   647 
   723 
   648     if (af == NULL) {
   724     if (af == NULL) {
   649       log_error(cds, heap)("Archiving failed %s::%s (some reachable objects cannot be archived)",
   725       log_error(cds, heap)("Archiving failed %s::%s (some reachable objects cannot be archived)",
   650                            klass_name, field_name);
   726                            klass_name, field_name);
   651     } else {
   727     } else {
   652       // Note: the field value is not preserved in the archived mirror.
   728       // Note: the field value is not preserved in the archived mirror.
   653       // Record the field as a new subGraph entry point. The recorded
   729       // Record the field as a new subGraph entry point. The recorded
   654       // information is restored from the archive at runtime.
   730       // information is restored from the archive at runtime.
   655       subgraph_info->add_subgraph_entry_field(field_offset, af);
   731       subgraph_info->add_subgraph_entry_field(field_offset, af, is_closed_archive);
   656       log_info(cds, heap)("Archived field %s::%s => " PTR_FORMAT, klass_name, field_name, p2i(af));
   732       log_info(cds, heap)("Archived field %s::%s => " PTR_FORMAT, klass_name, field_name, p2i(af));
   657     }
   733     }
   658   } else {
   734   } else {
   659     // The field contains null, we still need to record the entry point,
   735     // The field contains null, we still need to record the entry point,
   660     // so it can be restored at runtime.
   736     // so it can be restored at runtime.
   661     subgraph_info->add_subgraph_entry_field(field_offset, NULL);
   737     subgraph_info->add_subgraph_entry_field(field_offset, NULL, false);
   662   }
   738   }
   663 }
   739 }
   664 
   740 
   665 #ifndef PRODUCT
   741 #ifndef PRODUCT
   666 class VerifySharedOopClosure: public BasicOopIterateClosure {
   742 class VerifySharedOopClosure: public BasicOopIterateClosure {
   685 void HeapShared::verify_subgraph_from_static_field(InstanceKlass* k, int field_offset) {
   761 void HeapShared::verify_subgraph_from_static_field(InstanceKlass* k, int field_offset) {
   686   assert(DumpSharedSpaces, "dump time only");
   762   assert(DumpSharedSpaces, "dump time only");
   687   assert(k->is_shared_boot_class(), "must be boot class");
   763   assert(k->is_shared_boot_class(), "must be boot class");
   688 
   764 
   689   oop m = k->java_mirror();
   765   oop m = k->java_mirror();
   690   oop archived_m = find_archived_heap_object(m);
       
   691   if (CompressedOops::is_null(archived_m)) {
       
   692     return;
       
   693   }
       
   694   oop f = m->obj_field(field_offset);
   766   oop f = m->obj_field(field_offset);
   695   if (!CompressedOops::is_null(f)) {
   767   if (!CompressedOops::is_null(f)) {
   696     verify_subgraph_from(f);
   768     verify_subgraph_from(f);
   697   }
   769   }
   698 }
   770 }
   780   _num_total_subgraph_recordings ++;
   852   _num_total_subgraph_recordings ++;
   781   _num_total_walked_objs      += _num_new_walked_objs;
   853   _num_total_walked_objs      += _num_new_walked_objs;
   782   _num_total_archived_objs    += _num_new_archived_objs;
   854   _num_total_archived_objs    += _num_new_archived_objs;
   783   _num_total_recorded_klasses +=  num_new_recorded_klasses;
   855   _num_total_recorded_klasses +=  num_new_recorded_klasses;
   784 }
   856 }
   785 
       
   786 struct ArchivableStaticFieldInfo {
       
   787   const char* klass_name;
       
   788   const char* field_name;
       
   789   InstanceKlass* klass;
       
   790   int offset;
       
   791   BasicType type;
       
   792 };
       
   793 
       
   794 // If you add new entries to this table, you should know what you're doing!
       
   795 static ArchivableStaticFieldInfo archivable_static_fields[] = {
       
   796   {"jdk/internal/module/ArchivedModuleGraph",  "archivedSystemModules"},
       
   797   {"jdk/internal/module/ArchivedModuleGraph",  "archivedModuleFinder"},
       
   798   {"jdk/internal/module/ArchivedModuleGraph",  "archivedMainModule"},
       
   799   {"jdk/internal/module/ArchivedModuleGraph",  "archivedConfiguration"},
       
   800   {"java/util/ImmutableCollections$ListN",     "EMPTY_LIST"},
       
   801   {"java/util/ImmutableCollections$MapN",      "EMPTY_MAP"},
       
   802   {"java/util/ImmutableCollections$SetN",      "EMPTY_SET"},
       
   803   {"java/lang/Integer$IntegerCache",           "archivedCache"},
       
   804   {"java/lang/module/Configuration",           "EMPTY_CONFIGURATION"},
       
   805 };
       
   806 
       
   807 const static int num_archivable_static_fields =
       
   808   sizeof(archivable_static_fields) / sizeof(ArchivableStaticFieldInfo);
       
   809 
   857 
   810 class ArchivableStaticFieldFinder: public FieldClosure {
   858 class ArchivableStaticFieldFinder: public FieldClosure {
   811   InstanceKlass* _ik;
   859   InstanceKlass* _ik;
   812   Symbol* _field_name;
   860   Symbol* _field_name;
   813   bool _found;
   861   bool _found;
   826   }
   874   }
   827   bool found()     { return _found;  }
   875   bool found()     { return _found;  }
   828   int offset()     { return _offset; }
   876   int offset()     { return _offset; }
   829 };
   877 };
   830 
   878 
   831 void HeapShared::init_archivable_static_fields(Thread* THREAD) {
   879 void HeapShared::init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[],
   832   _dump_time_subgraph_info_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeKlassSubGraphInfoTable();
   880                                             int num, Thread* THREAD) {
   833 
   881   for (int i = 0; i < num; i++) {
   834   for (int i = 0; i < num_archivable_static_fields; i++) {
   882     ArchivableStaticFieldInfo* info = &fields[i];
   835     ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
       
   836     TempNewSymbol klass_name =  SymbolTable::new_symbol(info->klass_name, THREAD);
   883     TempNewSymbol klass_name =  SymbolTable::new_symbol(info->klass_name, THREAD);
   837     TempNewSymbol field_name =  SymbolTable::new_symbol(info->field_name, THREAD);
   884     TempNewSymbol field_name =  SymbolTable::new_symbol(info->field_name, THREAD);
   838 
   885 
   839     Klass* k = SystemDictionary::resolve_or_null(klass_name, THREAD);
   886     Klass* k = SystemDictionary::resolve_or_null(klass_name, THREAD);
   840     assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist");
   887     assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist");
   847     info->klass = ik;
   894     info->klass = ik;
   848     info->offset = finder.offset();
   895     info->offset = finder.offset();
   849   }
   896   }
   850 }
   897 }
   851 
   898 
   852 void HeapShared::archive_object_subgraphs(Thread* THREAD) {
   899 void HeapShared::init_subgraph_entry_fields(Thread* THREAD) {
       
   900   _dump_time_subgraph_info_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeKlassSubGraphInfoTable();
       
   901 
       
   902   init_subgraph_entry_fields(closed_archive_subgraph_entry_fields,
       
   903                              num_closed_archive_subgraph_entry_fields,
       
   904                              THREAD);
       
   905   init_subgraph_entry_fields(open_archive_subgraph_entry_fields,
       
   906                              num_open_archive_subgraph_entry_fields,
       
   907                              THREAD);
       
   908 }
       
   909 
       
   910 void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
       
   911                                           int num, bool is_closed_archive,
       
   912                                           Thread* THREAD) {
       
   913   _num_total_subgraph_recordings = 0;
       
   914   _num_total_walked_objs = 0;
       
   915   _num_total_archived_objs = 0;
       
   916   _num_total_recorded_klasses = 0;
       
   917   _num_total_verifications = 0;
       
   918 
   853   // For each class X that has one or more archived fields:
   919   // For each class X that has one or more archived fields:
   854   // [1] Dump the subgraph of each archived field
   920   // [1] Dump the subgraph of each archived field
   855   // [2] Create a list of all the class of the objects that can be reached
   921   // [2] Create a list of all the class of the objects that can be reached
   856   //     by any of these static fields.
   922   //     by any of these static fields.
   857   //     At runtime, these classes are initialized before X's archived fields
   923   //     At runtime, these classes are initialized before X's archived fields
   858   //     are restored by HeapShared::initialize_from_archived_subgraph().
   924   //     are restored by HeapShared::initialize_from_archived_subgraph().
   859   int i;
   925   int i;
   860   for (i = 0; i < num_archivable_static_fields; ) {
   926   for (i = 0; i < num; ) {
   861     ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
   927     ArchivableStaticFieldInfo* info = &fields[i];
   862     const char* klass_name = info->klass_name;
   928     const char* klass_name = info->klass_name;
   863     start_recording_subgraph(info->klass, klass_name);
   929     start_recording_subgraph(info->klass, klass_name);
   864 
   930 
   865     // If you have specified consecutive fields of the same klass in
   931     // If you have specified consecutive fields of the same klass in
   866     // archivable_static_fields[], these will be archived in the same
   932     // fields[], these will be archived in the same
   867     // {start_recording_subgraph ... done_recording_subgraph} pass to
   933     // {start_recording_subgraph ... done_recording_subgraph} pass to
   868     // save time.
   934     // save time.
   869     for (; i < num_archivable_static_fields; i++) {
   935     for (; i < num; i++) {
   870       ArchivableStaticFieldInfo* f = &archivable_static_fields[i];
   936       ArchivableStaticFieldInfo* f = &fields[i];
   871       if (f->klass_name != klass_name) {
   937       if (f->klass_name != klass_name) {
   872         break;
   938         break;
   873       }
   939       }
   874       archive_reachable_objects_from_static_field(f->klass, f->klass_name,
   940       archive_reachable_objects_from_static_field(f->klass, f->klass_name,
   875                                                   f->offset, f->field_name, CHECK);
   941                                                   f->offset, f->field_name,
       
   942                                                   is_closed_archive, CHECK);
   876     }
   943     }
   877     done_recording_subgraph(info->klass, klass_name);
   944     done_recording_subgraph(info->klass, klass_name);
   878   }
   945   }
   879 
   946 
   880   log_info(cds, heap)("Performed subgraph records = %d times", _num_total_subgraph_recordings);
   947   log_info(cds, heap)("Archived subgraph records in %s archive heap region = %d",
   881   log_info(cds, heap)("Walked %d objects", _num_total_walked_objs);
   948                       is_closed_archive ? "closed" : "open",
   882   log_info(cds, heap)("Archived %d objects", _num_total_archived_objs);
   949                       _num_total_subgraph_recordings);
   883   log_info(cds, heap)("Recorded %d klasses", _num_total_recorded_klasses);
   950   log_info(cds, heap)("  Walked %d objects", _num_total_walked_objs);
   884 
   951   log_info(cds, heap)("  Archived %d objects", _num_total_archived_objs);
       
   952   log_info(cds, heap)("  Recorded %d klasses", _num_total_recorded_klasses);
   885 
   953 
   886 #ifndef PRODUCT
   954 #ifndef PRODUCT
   887   for (int i = 0; i < num_archivable_static_fields; i++) {
   955   for (int i = 0; i < num; i++) {
   888     ArchivableStaticFieldInfo* f = &archivable_static_fields[i];
   956     ArchivableStaticFieldInfo* f = &fields[i];
   889     verify_subgraph_from_static_field(f->klass, f->offset);
   957     verify_subgraph_from_static_field(f->klass, f->offset);
   890   }
   958   }
   891   log_info(cds, heap)("Verified %d references", _num_total_verifications);
   959   log_info(cds, heap)("  Verified %d references", _num_total_verifications);
   892 #endif
   960 #endif
   893 }
   961 }
   894 
   962 
   895 // At dump-time, find the location of all the non-null oop pointers in an archived heap
   963 // At dump-time, find the location of all the non-null oop pointers in an archived heap
   896 // region. This way we can quickly relocate all the pointers without using
   964 // region. This way we can quickly relocate all the pointers without using