< prev index next >

src/hotspot/share/memory/heapShared.cpp

Print this page


   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 "classfile/javaClasses.inline.hpp"
  27 #include "classfile/stringTable.hpp"
  28 #include "classfile/symbolTable.hpp"

  29 #include "classfile/vmSymbols.hpp"
  30 #include "logging/log.hpp"
  31 #include "logging/logMessage.hpp"
  32 #include "logging/logStream.hpp"

  33 #include "memory/filemap.hpp"
  34 #include "memory/heapShared.inline.hpp"
  35 #include "memory/iterator.inline.hpp"
  36 #include "memory/metadataFactory.hpp"
  37 #include "memory/metaspaceClosure.hpp"

  38 #include "memory/resourceArea.hpp"
  39 #include "memory/universe.hpp"
  40 #include "oops/compressedOops.inline.hpp"
  41 #include "oops/fieldStreams.hpp"
  42 #include "oops/oop.inline.hpp"
  43 #include "runtime/fieldDescriptor.inline.hpp"
  44 #include "runtime/safepointVerifiers.hpp"
  45 #include "utilities/bitMap.inline.hpp"
  46 #if INCLUDE_G1GC
  47 #include "gc/g1/g1CollectedHeap.hpp"
  48 #endif
  49 
  50 #if INCLUDE_CDS_JAVA_HEAP
  51 
  52 bool HeapShared::_closed_archive_heap_region_mapped = false;
  53 bool HeapShared::_open_archive_heap_region_mapped = false;
  54 bool HeapShared::_archive_heap_region_fixed = false;
  55 
  56 address   HeapShared::_narrow_oop_base;
  57 int       HeapShared::_narrow_oop_shift;


 366     for (int i = 0 ; i < num_entry_fields; i++) {
 367       _entry_field_records->at_put(i, entry_fields->at(i));
 368     }
 369   }
 370 
 371   // the Klasses of the objects in the sub-graphs
 372   GrowableArray<Klass*>* subgraph_object_klasses = info->subgraph_object_klasses();
 373   if (subgraph_object_klasses != NULL) {
 374     int num_subgraphs_klasses = subgraph_object_klasses->length();
 375     _subgraph_object_klasses =
 376       MetaspaceShared::new_ro_array<Klass*>(num_subgraphs_klasses);
 377     for (int i = 0; i < num_subgraphs_klasses; i++) {
 378       Klass* subgraph_k = subgraph_object_klasses->at(i);
 379       if (log_is_enabled(Info, cds, heap)) {
 380         ResourceMark rm;
 381         log_info(cds, heap)(
 382           "Archived object klass %s (%2d) => %s",
 383           _k->external_name(), i, subgraph_k->external_name());
 384       }
 385       _subgraph_object_klasses->at_put(i, subgraph_k);

 386     }
 387   }




 388 }
 389 
 390 struct CopyKlassSubGraphInfoToArchive : StackObj {
 391   CompactHashtableWriter* _writer;
 392   CopyKlassSubGraphInfoToArchive(CompactHashtableWriter* writer) : _writer(writer) {}
 393 
 394   bool do_entry(Klass* klass, KlassSubGraphInfo& info) {
 395     if (info.subgraph_object_klasses() != NULL || info.subgraph_entry_fields() != NULL) {
 396       ArchivedKlassSubGraphInfoRecord* record =
 397         (ArchivedKlassSubGraphInfoRecord*)MetaspaceShared::read_only_space_alloc(sizeof(ArchivedKlassSubGraphInfoRecord));
 398       record->init(&info);
 399 
 400       unsigned int hash = primitive_hash<Klass*>(klass);
 401       u4 delta = MetaspaceShared::object_delta_u4(record);
 402       _writer->add(hash, delta);
 403     }
 404     return true; // keep on iterating
 405   }
 406 };
 407 
 408 // Build the records of archived subgraph infos, which include:
 409 // - Entry points to all subgraphs from the containing class mirror. The entry
 410 //   points are static fields in the mirror. For each entry point, the field
 411 //   offset, value and is_closed_archive flag are recorded in the sub-graph
 412 //   info. The value is stored back to the corresponding field at runtime.
 413 // - A list of klasses that need to be loaded/initialized before archived
 414 //   java object sub-graph can be accessed at runtime.
 415 void HeapShared::write_subgraph_info_table() {
 416   // Allocate the contents of the hashtable(s) inside the RO region of the CDS archive.
 417   DumpTimeKlassSubGraphInfoTable* d_table = _dump_time_subgraph_info_table;
 418   CompactHashtableStats stats;
 419 
 420   _run_time_subgraph_info_table.reset();
 421 
 422   CompactHashtableWriter writer(d_table->_count, &stats);
 423   CopyKlassSubGraphInfoToArchive copy(&writer);
 424   d_table->iterate(&copy);
 425 
 426   writer.dump(&_run_time_subgraph_info_table, "subgraphs");
 427 }
 428 
 429 void HeapShared::serialize_subgraph_info_table_header(SerializeClosure* soc) {
 430   _run_time_subgraph_info_table.serialize_header(soc);
 431 }
 432 
 433 void HeapShared::initialize_from_archived_subgraph(Klass* k) {
 434   if (!open_archive_heap_region_mapped()) {
 435     return; // nothing to do
 436   }
 437   assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces");
 438 
 439   unsigned int hash = primitive_hash<Klass*>(k);
 440   const ArchivedKlassSubGraphInfoRecord* record = _run_time_subgraph_info_table.lookup(k, hash, 0);
 441 
 442   // Initialize from archived data. Currently this is done only
 443   // during VM initialization time. No lock is needed.
 444   if (record != NULL) {
 445     Thread* THREAD = Thread::current();
 446 
 447     int i;
 448     // Load/link/initialize the klasses of the objects in the subgraph.
 449     // NULL class loader is used.
 450     Array<Klass*>* klasses = record->subgraph_object_klasses();
 451     if (klasses != NULL) {
 452       for (i = 0; i < klasses->length(); i++) {
 453         Klass* obj_k = klasses->at(i);
 454         Klass* resolved_k = SystemDictionary::resolve_or_null(
 455                                               (obj_k)->name(), THREAD);
 456         if (resolved_k != obj_k) {
 457           assert(!SystemDictionary::is_well_known_klass(resolved_k),
 458                  "shared well-known classes must not be replaced by JVMTI ClassFileLoadHook");
 459           ResourceMark rm(THREAD);


 588         log_warning(cds, heap)(
 589           "Please check reference field in %s instance in closed archive heap region: %s %s",
 590           k->external_name(), (fs.name())->as_C_string(),
 591           (fs.signature())->as_C_string());
 592       }
 593     }
 594   }
 595 }
 596 
 597 // (1) If orig_obj has not been archived yet, archive it.
 598 // (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
 599 //     trace all  objects that are reachable from it, and make sure these objects are archived.
 600 // (3) Record the klasses of all orig_obj and all reachable objects.
 601 oop HeapShared::archive_reachable_objects_from(int level,
 602                                                KlassSubGraphInfo* subgraph_info,
 603                                                oop orig_obj,
 604                                                bool is_closed_archive,
 605                                                TRAPS) {
 606   assert(orig_obj != NULL, "must be");
 607   assert(!is_archived_object(orig_obj), "sanity");
 608 







 609   // java.lang.Class instances cannot be included in an archived
 610   // object sub-graph.
 611   if (java_lang_Class::is_instance(orig_obj)) {
 612     log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level);
 613     vm_exit(1);
 614   }
 615 
 616   oop archived_obj = find_archived_heap_object(orig_obj);
 617   if (java_lang_String::is_instance(orig_obj) && archived_obj != NULL) {
 618     // To save time, don't walk strings that are already archived. They just contain
 619     // pointers to a type array, whose klass doesn't need to be recorded.
 620     return archived_obj;
 621   }
 622 
 623   if (has_been_seen_during_subgraph_recording(orig_obj)) {
 624     // orig_obj has already been archived and traced. Nothing more to do.
 625     return archived_obj;
 626   } else {
 627     set_has_been_seen_during_subgraph_recording(orig_obj);
 628   }




   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 "classfile/javaClasses.inline.hpp"
  27 #include "classfile/stringTable.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "classfile/systemDictionaryShared.hpp"
  30 #include "classfile/vmSymbols.hpp"
  31 #include "logging/log.hpp"
  32 #include "logging/logMessage.hpp"
  33 #include "logging/logStream.hpp"
  34 #include "memory/archiveUtils.hpp"
  35 #include "memory/filemap.hpp"
  36 #include "memory/heapShared.inline.hpp"
  37 #include "memory/iterator.inline.hpp"
  38 #include "memory/metadataFactory.hpp"
  39 #include "memory/metaspaceClosure.hpp"
  40 #include "memory/metaspaceShared.hpp"
  41 #include "memory/resourceArea.hpp"
  42 #include "memory/universe.hpp"
  43 #include "oops/compressedOops.inline.hpp"
  44 #include "oops/fieldStreams.hpp"
  45 #include "oops/oop.inline.hpp"
  46 #include "runtime/fieldDescriptor.inline.hpp"
  47 #include "runtime/safepointVerifiers.hpp"
  48 #include "utilities/bitMap.inline.hpp"
  49 #if INCLUDE_G1GC
  50 #include "gc/g1/g1CollectedHeap.hpp"
  51 #endif
  52 
  53 #if INCLUDE_CDS_JAVA_HEAP
  54 
  55 bool HeapShared::_closed_archive_heap_region_mapped = false;
  56 bool HeapShared::_open_archive_heap_region_mapped = false;
  57 bool HeapShared::_archive_heap_region_fixed = false;
  58 
  59 address   HeapShared::_narrow_oop_base;
  60 int       HeapShared::_narrow_oop_shift;


 369     for (int i = 0 ; i < num_entry_fields; i++) {
 370       _entry_field_records->at_put(i, entry_fields->at(i));
 371     }
 372   }
 373 
 374   // the Klasses of the objects in the sub-graphs
 375   GrowableArray<Klass*>* subgraph_object_klasses = info->subgraph_object_klasses();
 376   if (subgraph_object_klasses != NULL) {
 377     int num_subgraphs_klasses = subgraph_object_klasses->length();
 378     _subgraph_object_klasses =
 379       MetaspaceShared::new_ro_array<Klass*>(num_subgraphs_klasses);
 380     for (int i = 0; i < num_subgraphs_klasses; i++) {
 381       Klass* subgraph_k = subgraph_object_klasses->at(i);
 382       if (log_is_enabled(Info, cds, heap)) {
 383         ResourceMark rm;
 384         log_info(cds, heap)(
 385           "Archived object klass %s (%2d) => %s",
 386           _k->external_name(), i, subgraph_k->external_name());
 387       }
 388       _subgraph_object_klasses->at_put(i, subgraph_k);
 389       ArchivePtrMarker::mark_pointer(_subgraph_object_klasses->adr_at(i));
 390     }
 391   }
 392 
 393   ArchivePtrMarker::mark_pointer(&_k);
 394   ArchivePtrMarker::mark_pointer(&_entry_field_records);
 395   ArchivePtrMarker::mark_pointer(&_subgraph_object_klasses);
 396 }
 397 
 398 struct CopyKlassSubGraphInfoToArchive : StackObj {
 399   CompactHashtableWriter* _writer;
 400   CopyKlassSubGraphInfoToArchive(CompactHashtableWriter* writer) : _writer(writer) {}
 401 
 402   bool do_entry(Klass* klass, KlassSubGraphInfo& info) {
 403     if (info.subgraph_object_klasses() != NULL || info.subgraph_entry_fields() != NULL) {
 404       ArchivedKlassSubGraphInfoRecord* record =
 405         (ArchivedKlassSubGraphInfoRecord*)MetaspaceShared::read_only_space_alloc(sizeof(ArchivedKlassSubGraphInfoRecord));
 406       record->init(&info);
 407 
 408       unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary(klass);
 409       u4 delta = MetaspaceShared::object_delta_u4(record);
 410       _writer->add(hash, delta);
 411     }
 412     return true; // keep on iterating
 413   }
 414 };
 415 
 416 // Build the records of archived subgraph infos, which include:
 417 // - Entry points to all subgraphs from the containing class mirror. The entry
 418 //   points are static fields in the mirror. For each entry point, the field
 419 //   offset, value and is_closed_archive flag are recorded in the sub-graph
 420 //   info. The value is stored back to the corresponding field at runtime.
 421 // - A list of klasses that need to be loaded/initialized before archived
 422 //   java object sub-graph can be accessed at runtime.
 423 void HeapShared::write_subgraph_info_table() {
 424   // Allocate the contents of the hashtable(s) inside the RO region of the CDS archive.
 425   DumpTimeKlassSubGraphInfoTable* d_table = _dump_time_subgraph_info_table;
 426   CompactHashtableStats stats;
 427 
 428   _run_time_subgraph_info_table.reset();
 429 
 430   CompactHashtableWriter writer(d_table->_count, &stats);
 431   CopyKlassSubGraphInfoToArchive copy(&writer);
 432   d_table->iterate(&copy);
 433 
 434   writer.dump(&_run_time_subgraph_info_table, "subgraphs");
 435 }
 436 
 437 void HeapShared::serialize_subgraph_info_table_header(SerializeClosure* soc) {
 438   _run_time_subgraph_info_table.serialize_header(soc);
 439 }
 440 
 441 void HeapShared::initialize_from_archived_subgraph(Klass* k) {
 442   if (!open_archive_heap_region_mapped() || !MetaspaceObj::is_shared(k)) {
 443     return; // nothing to do
 444   }
 445   assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces");
 446 
 447   unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary(k);
 448   const ArchivedKlassSubGraphInfoRecord* record = _run_time_subgraph_info_table.lookup(k, hash, 0);
 449 
 450   // Initialize from archived data. Currently this is done only
 451   // during VM initialization time. No lock is needed.
 452   if (record != NULL) {
 453     Thread* THREAD = Thread::current();
 454 
 455     int i;
 456     // Load/link/initialize the klasses of the objects in the subgraph.
 457     // NULL class loader is used.
 458     Array<Klass*>* klasses = record->subgraph_object_klasses();
 459     if (klasses != NULL) {
 460       for (i = 0; i < klasses->length(); i++) {
 461         Klass* obj_k = klasses->at(i);
 462         Klass* resolved_k = SystemDictionary::resolve_or_null(
 463                                               (obj_k)->name(), THREAD);
 464         if (resolved_k != obj_k) {
 465           assert(!SystemDictionary::is_well_known_klass(resolved_k),
 466                  "shared well-known classes must not be replaced by JVMTI ClassFileLoadHook");
 467           ResourceMark rm(THREAD);


 596         log_warning(cds, heap)(
 597           "Please check reference field in %s instance in closed archive heap region: %s %s",
 598           k->external_name(), (fs.name())->as_C_string(),
 599           (fs.signature())->as_C_string());
 600       }
 601     }
 602   }
 603 }
 604 
 605 // (1) If orig_obj has not been archived yet, archive it.
 606 // (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
 607 //     trace all  objects that are reachable from it, and make sure these objects are archived.
 608 // (3) Record the klasses of all orig_obj and all reachable objects.
 609 oop HeapShared::archive_reachable_objects_from(int level,
 610                                                KlassSubGraphInfo* subgraph_info,
 611                                                oop orig_obj,
 612                                                bool is_closed_archive,
 613                                                TRAPS) {
 614   assert(orig_obj != NULL, "must be");
 615   assert(!is_archived_object(orig_obj), "sanity");
 616   DEBUG_ONLY({
 617       Klass* klass = orig_obj->klass();
 618       assert(klass != SystemDictionary::Module_klass() &&
 619              klass != SystemDictionary::ResolvedMethodName_klass() &&
 620              klass != SystemDictionary::MemberName_klass() &&
 621              klass != SystemDictionary::Context_klass() &&
 622              klass != SystemDictionary::ClassLoader_klass(), "we can only relocate metaspace object pointers inside java_lang_Class instances");
 623     });
 624   // java.lang.Class instances cannot be included in an archived
 625   // object sub-graph.
 626   if (java_lang_Class::is_instance(orig_obj)) {
 627     log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level);
 628     vm_exit(1);
 629   }
 630 
 631   oop archived_obj = find_archived_heap_object(orig_obj);
 632   if (java_lang_String::is_instance(orig_obj) && archived_obj != NULL) {
 633     // To save time, don't walk strings that are already archived. They just contain
 634     // pointers to a type array, whose klass doesn't need to be recorded.
 635     return archived_obj;
 636   }
 637 
 638   if (has_been_seen_during_subgraph_recording(orig_obj)) {
 639     // orig_obj has already been archived and traced. Nothing more to do.
 640     return archived_obj;
 641   } else {
 642     set_has_been_seen_during_subgraph_recording(orig_obj);
 643   }


< prev index next >