55 |
55 |
56 bool MetaspaceShared::_link_classes_made_progress; |
56 bool MetaspaceShared::_link_classes_made_progress; |
57 bool MetaspaceShared::_check_classes_made_progress; |
57 bool MetaspaceShared::_check_classes_made_progress; |
58 bool MetaspaceShared::_has_error_classes; |
58 bool MetaspaceShared::_has_error_classes; |
59 bool MetaspaceShared::_archive_loading_failed = false; |
59 bool MetaspaceShared::_archive_loading_failed = false; |
|
60 SharedMiscRegion MetaspaceShared::_mc; |
|
61 SharedMiscRegion MetaspaceShared::_md; |
|
62 |
|
63 void SharedMiscRegion::initialize(ReservedSpace rs, size_t committed_byte_size, SharedSpaceType space_type) { |
|
64 _vs.initialize(rs, committed_byte_size); |
|
65 _alloc_top = _vs.low(); |
|
66 _space_type = space_type; |
|
67 } |
|
68 |
|
69 // NOT thread-safe, but this is called during dump time in single-threaded mode. |
|
70 char* SharedMiscRegion::alloc(size_t num_bytes) { |
|
71 assert(DumpSharedSpaces, "dump time only"); |
|
72 size_t alignment = sizeof(char*); |
|
73 num_bytes = align_size_up(num_bytes, alignment); |
|
74 _alloc_top = (char*)align_ptr_up(_alloc_top, alignment); |
|
75 if (_alloc_top + num_bytes > _vs.high()) { |
|
76 report_out_of_shared_space(_space_type); |
|
77 } |
|
78 |
|
79 char* p = _alloc_top; |
|
80 _alloc_top += num_bytes; |
|
81 |
|
82 memset(p, 0, num_bytes); |
|
83 return p; |
|
84 } |
|
85 |
|
86 void MetaspaceShared::initialize_shared_rs(ReservedSpace* rs) { |
|
87 assert(DumpSharedSpaces, "dump time only"); |
|
88 _shared_rs = rs; |
|
89 |
|
90 // Split up and initialize the misc code and data spaces |
|
91 size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize; |
|
92 ReservedSpace shared_ro_rw = _shared_rs->first_part(metadata_size); |
|
93 ReservedSpace misc_section = _shared_rs->last_part(metadata_size); |
|
94 |
|
95 // Now split into misc sections. |
|
96 ReservedSpace md_rs = misc_section.first_part(SharedMiscDataSize); |
|
97 ReservedSpace mc_rs = misc_section.last_part(SharedMiscDataSize); |
|
98 _md.initialize(md_rs, SharedMiscDataSize, SharedMiscData); |
|
99 _mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscData); |
|
100 } |
|
101 |
60 // Read/write a data stream for restoring/preserving metadata pointers and |
102 // Read/write a data stream for restoring/preserving metadata pointers and |
61 // miscellaneous data from/to the shared archive file. |
103 // miscellaneous data from/to the shared archive file. |
62 |
104 |
63 void MetaspaceShared::serialize(SerializeClosure* soc) { |
105 void MetaspaceShared::serialize(SerializeClosure* soc) { |
64 int tag = 0; |
106 int tag = 0; |
427 GrowableArray<Klass*> *_class_promote_order; |
469 GrowableArray<Klass*> *_class_promote_order; |
428 VirtualSpace _md_vs; |
470 VirtualSpace _md_vs; |
429 VirtualSpace _mc_vs; |
471 VirtualSpace _mc_vs; |
430 CompactHashtableWriter* _string_cht; |
472 CompactHashtableWriter* _string_cht; |
431 GrowableArray<MemRegion> *_string_regions; |
473 GrowableArray<MemRegion> *_string_regions; |
432 char* _md_alloc_low; |
|
433 char* _md_alloc_top; |
|
434 char* _md_alloc_max; |
|
435 static VM_PopulateDumpSharedSpace* _instance; |
|
436 |
474 |
437 public: |
475 public: |
438 VM_PopulateDumpSharedSpace(ClassLoaderData* loader_data, |
476 VM_PopulateDumpSharedSpace(ClassLoaderData* loader_data, |
439 GrowableArray<Klass*> *class_promote_order) : |
477 GrowableArray<Klass*> *class_promote_order) : |
440 _loader_data(loader_data) { |
478 _loader_data(loader_data) { |
441 // Split up and initialize the misc code and data spaces |
|
442 ReservedSpace* shared_rs = MetaspaceShared::shared_rs(); |
|
443 size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize; |
|
444 ReservedSpace shared_ro_rw = shared_rs->first_part(metadata_size); |
|
445 ReservedSpace misc_section = shared_rs->last_part(metadata_size); |
|
446 |
|
447 // Now split into misc sections. |
|
448 ReservedSpace md_rs = misc_section.first_part(SharedMiscDataSize); |
|
449 ReservedSpace mc_rs = misc_section.last_part(SharedMiscDataSize); |
|
450 _md_vs.initialize(md_rs, SharedMiscDataSize); |
|
451 _mc_vs.initialize(mc_rs, SharedMiscCodeSize); |
|
452 _class_promote_order = class_promote_order; |
479 _class_promote_order = class_promote_order; |
453 |
|
454 _md_alloc_low = _md_vs.low(); |
|
455 _md_alloc_top = _md_alloc_low + sizeof(char*); |
|
456 _md_alloc_max = _md_vs.low() + SharedMiscDataSize; |
|
457 |
|
458 assert(_instance == NULL, "must be singleton"); |
|
459 _instance = this; |
|
460 } |
|
461 |
|
462 ~VM_PopulateDumpSharedSpace() { |
|
463 assert(_instance == this, "must be singleton"); |
|
464 _instance = NULL; |
|
465 } |
|
466 |
|
467 static VM_PopulateDumpSharedSpace* instance() { |
|
468 assert(_instance != NULL, "sanity"); |
|
469 return _instance; |
|
470 } |
480 } |
471 |
481 |
472 VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; } |
482 VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; } |
473 void doit(); // outline because gdb sucks |
483 void doit(); // outline because gdb sucks |
474 |
|
475 char* misc_data_space_alloc(size_t num_bytes) { |
|
476 size_t alignment = sizeof(char*); |
|
477 num_bytes = align_size_up(num_bytes, alignment); |
|
478 _md_alloc_top = (char*)align_ptr_up(_md_alloc_top, alignment); |
|
479 if (_md_alloc_top + num_bytes > _md_alloc_max) { |
|
480 report_out_of_shared_space(SharedMiscData); |
|
481 } |
|
482 |
|
483 char* p = _md_alloc_top; |
|
484 _md_alloc_top += num_bytes; |
|
485 |
|
486 memset(p, 0, num_bytes); |
|
487 return p; |
|
488 } |
|
489 |
484 |
490 private: |
485 private: |
491 void handle_misc_data_space_failure(bool success) { |
486 void handle_misc_data_space_failure(bool success) { |
492 if (!success) { |
487 if (!success) { |
493 report_out_of_shared_space(SharedMiscData); |
488 report_out_of_shared_space(SharedMiscData); |
494 } |
489 } |
495 } |
490 } |
496 }; // class VM_PopulateDumpSharedSpace |
491 }; // class VM_PopulateDumpSharedSpace |
497 |
|
498 VM_PopulateDumpSharedSpace* VM_PopulateDumpSharedSpace::_instance; |
|
499 |
492 |
500 void VM_PopulateDumpSharedSpace::doit() { |
493 void VM_PopulateDumpSharedSpace::doit() { |
501 Thread* THREAD = VMThread::vm_thread(); |
494 Thread* THREAD = VMThread::vm_thread(); |
502 NOT_PRODUCT(SystemDictionary::verify();) |
495 NOT_PRODUCT(SystemDictionary::verify();) |
503 // The following guarantee is meant to ensure that no loader constraints |
496 // The following guarantee is meant to ensure that no loader constraints |
553 tty->print("Removing unshareable information ... "); |
546 tty->print("Removing unshareable information ... "); |
554 remove_unshareable_in_classes(); |
547 remove_unshareable_in_classes(); |
555 tty->print_cr("done. "); |
548 tty->print_cr("done. "); |
556 |
549 |
557 // Set up the share data and shared code segments. |
550 // Set up the share data and shared code segments. |
|
551 _md_vs = *MetaspaceShared::misc_data_region()->virtual_space(); |
|
552 _mc_vs = *MetaspaceShared::misc_code_region()->virtual_space(); |
558 char* md_low = _md_vs.low(); |
553 char* md_low = _md_vs.low(); |
559 char* md_top = md_low; |
554 char* md_top = MetaspaceShared::misc_data_region()->alloc_top(); |
560 char* md_end = _md_vs.high(); |
555 char* md_end = _md_vs.high(); |
561 char* mc_low = _mc_vs.low(); |
556 char* mc_low = _mc_vs.low(); |
562 char* mc_top = mc_low; |
557 char* mc_top = MetaspaceShared::misc_code_region()->alloc_top(); |
563 char* mc_end = _mc_vs.high(); |
558 char* mc_end = _mc_vs.high(); |
564 |
|
565 assert(_md_alloc_top != NULL, "sanity"); |
|
566 *(char**)_md_alloc_low = _md_alloc_top; |
|
567 md_top = _md_alloc_top; |
|
568 |
559 |
569 // Reserve space for the list of Klass*s whose vtables are used |
560 // Reserve space for the list of Klass*s whose vtables are used |
570 // for patching others as needed. |
561 // for patching others as needed. |
571 |
562 |
572 void** vtbl_list = (void**)md_top; |
563 void** vtbl_list = (void**)md_top; |
679 |
670 |
680 // Create and write the archive file that maps the shared spaces. |
671 // Create and write the archive file that maps the shared spaces. |
681 |
672 |
682 FileMapInfo* mapinfo = new FileMapInfo(); |
673 FileMapInfo* mapinfo = new FileMapInfo(); |
683 mapinfo->populate_header(MetaspaceShared::max_alignment()); |
674 mapinfo->populate_header(MetaspaceShared::max_alignment()); |
684 |
675 mapinfo->set_misc_data_patching_start((char*)vtbl_list); |
685 // Pass 1 - update file offsets in header. |
676 |
686 mapinfo->write_header(); |
677 for (int pass=1; pass<=2; pass++) { |
687 mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true); |
678 if (pass == 1) { |
688 mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false); |
679 // The first pass doesn't actually write the data to disk. All it |
689 mapinfo->write_region(MetaspaceShared::md, _md_vs.low(), |
680 // does is to update the fields in the mapinfo->_header. |
690 pointer_delta(md_top, _md_vs.low(), sizeof(char)), |
681 } else { |
691 SharedMiscDataSize, |
682 // After the first pass, the contents of mapinfo->_header are finalized, |
692 false, false); |
683 // so we can compute the header's CRC, and write the contents of the header |
693 mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(), |
684 // and the regions into disk. |
694 pointer_delta(mc_top, _mc_vs.low(), sizeof(char)), |
685 mapinfo->open_for_write(); |
695 SharedMiscCodeSize, |
686 mapinfo->set_header_crc(mapinfo->compute_header_crc()); |
696 true, true); |
687 } |
697 mapinfo->write_string_regions(_string_regions); |
688 mapinfo->write_header(); |
698 |
689 mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true); |
699 // Pass 2 - write data. |
690 mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false); |
700 mapinfo->open_for_write(); |
691 mapinfo->write_region(MetaspaceShared::md, _md_vs.low(), |
701 mapinfo->set_header_crc(mapinfo->compute_header_crc()); |
692 pointer_delta(md_top, _md_vs.low(), sizeof(char)), |
702 mapinfo->write_header(); |
693 SharedMiscDataSize, |
703 mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true); |
694 false, false); |
704 mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false); |
695 mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(), |
705 mapinfo->write_region(MetaspaceShared::md, _md_vs.low(), |
696 pointer_delta(mc_top, _mc_vs.low(), sizeof(char)), |
706 pointer_delta(md_top, _md_vs.low(), sizeof(char)), |
697 SharedMiscCodeSize, |
707 SharedMiscDataSize, |
698 true, true); |
708 false, false); |
699 mapinfo->write_string_regions(_string_regions); |
709 mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(), |
700 } |
710 pointer_delta(mc_top, _mc_vs.low(), sizeof(char)), |
|
711 SharedMiscCodeSize, |
|
712 true, true); |
|
713 mapinfo->write_string_regions(_string_regions); |
|
714 |
701 |
715 mapinfo->close(); |
702 mapinfo->close(); |
716 |
703 |
717 memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*)); |
704 memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*)); |
718 os::free(saved_vtbl); |
705 os::free(saved_vtbl); |
1063 // Read the miscellaneous data from the shared file, and |
1045 // Read the miscellaneous data from the shared file, and |
1064 // serialize it out to its various destinations. |
1046 // serialize it out to its various destinations. |
1065 |
1047 |
1066 void MetaspaceShared::initialize_shared_spaces() { |
1048 void MetaspaceShared::initialize_shared_spaces() { |
1067 FileMapInfo *mapinfo = FileMapInfo::current_info(); |
1049 FileMapInfo *mapinfo = FileMapInfo::current_info(); |
1068 |
1050 char* buffer = mapinfo->misc_data_patching_start(); |
1069 char* buffer = mapinfo->header()->region_addr(md); |
|
1070 |
|
1071 buffer = *((char**)buffer); // skip over the md_alloc'ed blocks |
|
1072 |
1051 |
1073 // Skip over (reserve space for) a list of addresses of C++ vtables |
1052 // Skip over (reserve space for) a list of addresses of C++ vtables |
1074 // for Klass objects. They get filled in later. |
1053 // for Klass objects. They get filled in later. |
1075 |
1054 |
1076 void** vtbl_list = (void**)buffer; |
1055 void** vtbl_list = (void**)buffer; |