468 void make_trampolines(); |
468 void make_trampolines(); |
469 void make_klasses_shareable(); |
469 void make_klasses_shareable(); |
470 void sort_methods(InstanceKlass* ik) const; |
470 void sort_methods(InstanceKlass* ik) const; |
471 void set_symbols_permanent(); |
471 void set_symbols_permanent(); |
472 void relocate_buffer_to_target(); |
472 void relocate_buffer_to_target(); |
473 void write_archive(char* read_only_tables_start); |
473 void write_archive(char* serialized_data_start); |
|
474 void write_regions(FileMapInfo* dynamic_info); |
474 |
475 |
475 void init_first_dump_space(address reserved_bottom) { |
476 void init_first_dump_space(address reserved_bottom) { |
476 address first_space_base = reserved_bottom; |
477 address first_space_base = reserved_bottom; |
477 DumpRegion* rw_space = MetaspaceShared::read_write_dump_space(); |
478 DumpRegion* rw_space = MetaspaceShared::read_write_dump_space(); |
478 MetaspaceShared::init_shared_dump_space(rw_space, first_space_base); |
479 MetaspaceShared::init_shared_dump_space(rw_space, first_space_base); |
606 // get the correct addresses. |
607 // get the correct addresses. |
607 assert(current_dump_space() == ro_space, "Must be RO space"); |
608 assert(current_dump_space() == ro_space, "Must be RO space"); |
608 SymbolTable::write_to_archive(false); |
609 SymbolTable::write_to_archive(false); |
609 SystemDictionaryShared::write_to_archive(false); |
610 SystemDictionaryShared::write_to_archive(false); |
610 |
611 |
611 read_only_tables_start = ro_space->top(); |
612 serialized_data_start = ro_space->top(); |
612 WriteClosure wc(ro_space); |
613 WriteClosure wc(ro_space); |
613 SymbolTable::serialize_shared_table_header(&wc, false); |
614 SymbolTable::serialize_shared_table_header(&wc, false); |
614 SystemDictionaryShared::serialize_dictionary_headers(&wc, false); |
615 SystemDictionaryShared::serialize_dictionary_headers(&wc, false); |
615 } |
616 } |
616 |
617 |
650 int num_symbols = _symbols->length(); |
651 int num_symbols = _symbols->length(); |
651 for (i = 0; i < num_symbols; i++) { |
652 for (i = 0; i < num_symbols; i++) { |
652 it->push(&_symbols->at(i)); |
653 it->push(&_symbols->at(i)); |
653 } |
654 } |
654 |
655 |
655 _header->_shared_path_table.metaspace_pointers_do(it); |
656 _header->shared_path_table_metaspace_pointers_do(it); |
656 |
657 |
657 // Do not call these again, as we have already collected all the classes and symbols |
658 // Do not call these again, as we have already collected all the classes and symbols |
658 // that we want to archive. Also, these calls would corrupt the tables when |
659 // that we want to archive. Also, these calls would corrupt the tables when |
659 // ExternalRefUpdater is used. |
660 // ExternalRefUpdater is used. |
660 // |
661 // |
731 _other_region_used_bytes = 0; |
732 _other_region_used_bytes = 0; |
732 |
733 |
733 init_first_dump_space(reserved_bottom); |
734 init_first_dump_space(reserved_bottom); |
734 |
735 |
735 FileMapInfo* mapinfo = new FileMapInfo(false); |
736 FileMapInfo* mapinfo = new FileMapInfo(false); |
736 _header = (DynamicArchiveHeader*)mapinfo->_header; |
737 _header = mapinfo->dynamic_header(); |
737 |
738 |
738 Thread* THREAD = Thread::current(); |
739 Thread* THREAD = Thread::current(); |
739 FileMapInfo* base_info = FileMapInfo::current_info(); |
740 FileMapInfo* base_info = FileMapInfo::current_info(); |
740 int* crc = _header->_base_archive_crc; |
741 _header->set_base_header_crc(base_info->crc()); |
741 *crc++ = base_info->crc(); // base archive header crc |
|
742 for (int i = 0; i < MetaspaceShared::n_regions; i++) { |
742 for (int i = 0; i < MetaspaceShared::n_regions; i++) { |
743 *crc++ = base_info->space_crc(i); |
743 _header->set_base_region_crc(i, base_info->space_crc(i)); |
744 } |
744 } |
745 _header->populate(base_info, os::vm_allocation_granularity()); |
745 _header->populate(base_info, os::vm_allocation_granularity()); |
746 } |
746 } |
747 |
747 |
748 size_t DynamicArchiveBuilder::estimate_trampoline_size() { |
748 size_t DynamicArchiveBuilder::estimate_trampoline_size() { |
772 (AdapterHandlerEntry**)MetaspaceShared::misc_code_space_alloc(sizeof(AdapterHandlerEntry*)); |
776 (AdapterHandlerEntry**)MetaspaceShared::misc_code_space_alloc(sizeof(AdapterHandlerEntry*)); |
773 *adapter_trampoline = NULL; |
777 *adapter_trampoline = NULL; |
774 m->set_adapter_trampoline(to_target(adapter_trampoline)); |
778 m->set_adapter_trampoline(to_target(adapter_trampoline)); |
775 } |
779 } |
776 } |
780 } |
|
781 |
|
782 if (MetaspaceShared::misc_code_dump_space()->used() == 0) { |
|
783 // We have nothing to archive, but let's avoid having an empty region. |
|
784 MetaspaceShared::misc_code_space_alloc(SharedRuntime::trampoline_size()); |
|
785 } |
777 } |
786 } |
778 |
787 |
779 void DynamicArchiveBuilder::make_klasses_shareable() { |
788 void DynamicArchiveBuilder::make_klasses_shareable() { |
780 int i, count = _klasses->length(); |
789 int i, count = _klasses->length(); |
781 |
790 |
896 |
905 |
897 void DynamicArchiveBuilder::relocate_buffer_to_target() { |
906 void DynamicArchiveBuilder::relocate_buffer_to_target() { |
898 RelocateBufferToTarget patcher(this, (address*)_alloc_bottom, _buffer_to_target_delta); |
907 RelocateBufferToTarget patcher(this, (address*)_alloc_bottom, _buffer_to_target_delta); |
899 _ptrmap.iterate(&patcher); |
908 _ptrmap.iterate(&patcher); |
900 |
909 |
901 Array<u8>* table = _header->_shared_path_table.table(); |
910 Array<u8>* table = _header->shared_path_table().table(); |
902 table = to_target(table); |
911 table = to_target(table); |
903 _header->_shared_path_table.set_table(table); |
912 _header->relocate_shared_path_table(table); |
904 } |
913 } |
905 |
914 |
906 static void write_archive_info(FileMapInfo* dynamic_info, DynamicArchiveHeader *header) { |
915 void DynamicArchiveBuilder::write_regions(FileMapInfo* dynamic_info) { |
907 dynamic_info->write_header(); |
|
908 dynamic_info->align_file_position(); |
|
909 dynamic_info->write_region(MetaspaceShared::rw, |
916 dynamic_info->write_region(MetaspaceShared::rw, |
910 MetaspaceShared::read_write_dump_space()->base(), |
917 MetaspaceShared::read_write_dump_space()->base(), |
911 MetaspaceShared::read_write_dump_space()->used(), |
918 MetaspaceShared::read_write_dump_space()->used(), |
912 /*read_only=*/false,/*allow_exec=*/false); |
919 /*read_only=*/false,/*allow_exec=*/false); |
913 dynamic_info->write_region(MetaspaceShared::ro, |
920 dynamic_info->write_region(MetaspaceShared::ro, |
918 MetaspaceShared::misc_code_dump_space()->base(), |
925 MetaspaceShared::misc_code_dump_space()->base(), |
919 MetaspaceShared::misc_code_dump_space()->used(), |
926 MetaspaceShared::misc_code_dump_space()->used(), |
920 /*read_only=*/false,/*allow_exec=*/true); |
927 /*read_only=*/false,/*allow_exec=*/true); |
921 } |
928 } |
922 |
929 |
923 void DynamicArchiveBuilder::write_archive(char* read_only_tables_start) { |
930 void DynamicArchiveBuilder::write_archive(char* serialized_data_start) { |
924 int num_klasses = _klasses->length(); |
931 int num_klasses = _klasses->length(); |
925 int num_symbols = _symbols->length(); |
932 int num_symbols = _symbols->length(); |
926 |
933 |
927 _header->_read_only_tables_start = to_target(read_only_tables_start); |
934 _header->set_serialized_data_start(to_target(serialized_data_start)); |
928 |
935 |
929 FileMapInfo* dynamic_info = FileMapInfo::dynamic_info(); |
936 FileMapInfo* dynamic_info = FileMapInfo::dynamic_info(); |
930 assert(dynamic_info != NULL, "Sanity"); |
937 assert(dynamic_info != NULL, "Sanity"); |
931 |
|
932 // Populate the file offsets, region crcs, etc. No data is written out. |
|
933 write_archive_info(dynamic_info, _header); |
|
934 |
|
935 // the header will no longer change. Compute its crc. |
|
936 dynamic_info->set_header_crc(dynamic_info->compute_header_crc()); |
|
937 |
938 |
938 // Now write the archived data including the file offsets. |
939 // Now write the archived data including the file offsets. |
939 const char* archive_name = Arguments::GetSharedDynamicArchivePath(); |
940 const char* archive_name = Arguments::GetSharedDynamicArchivePath(); |
940 dynamic_info->open_for_write(archive_name); |
941 dynamic_info->open_for_write(archive_name); |
941 write_archive_info(dynamic_info, _header); |
942 write_regions(dynamic_info); |
|
943 dynamic_info->set_header_crc(dynamic_info->compute_header_crc()); |
|
944 dynamic_info->write_header(); |
942 dynamic_info->close(); |
945 dynamic_info->close(); |
943 |
|
944 |
946 |
945 address base = to_target(_alloc_bottom); |
947 address base = to_target(_alloc_bottom); |
946 address top = address(current_dump_space()->top()) + _buffer_to_target_delta; |
948 address top = address(current_dump_space()->top()) + _buffer_to_target_delta; |
947 int file_size = int(top - base); |
949 size_t file_size = pointer_delta(top, base, sizeof(char)); |
948 |
950 |
949 log_info(cds, dynamic)("Written dynamic archive " PTR_FORMAT " - " PTR_FORMAT " [%d bytes header, %d bytes total]", |
951 log_info(cds, dynamic)("Written dynamic archive " PTR_FORMAT " - " PTR_FORMAT |
950 p2i(base), p2i(top), (int)_header->_header_size, file_size); |
952 " [" SIZE_FORMAT " bytes header, " SIZE_FORMAT " bytes total]", |
|
953 p2i(base), p2i(top), _header->header_size(), file_size); |
951 log_info(cds, dynamic)("%d klasses; %d symbols", num_klasses, num_symbols); |
954 log_info(cds, dynamic)("%d klasses; %d symbols", num_klasses, num_symbols); |
952 } |
955 } |
953 |
956 |
954 |
957 |
955 class VM_PopulateDynamicDumpSharedSpace: public VM_Operation { |
958 class VM_PopulateDynamicDumpSharedSpace: public VM_Operation { |
1070 } |
1073 } |
1071 return result; |
1074 return result; |
1072 } |
1075 } |
1073 |
1076 |
1074 address DynamicArchive::map_impl(FileMapInfo* mapinfo) { |
1077 address DynamicArchive::map_impl(FileMapInfo* mapinfo) { |
1075 |
|
1076 |
|
1077 // Read header |
1078 // Read header |
1078 if (!mapinfo->initialize(false)) { |
1079 if (!mapinfo->initialize(false)) { |
1079 return NULL; |
1080 return NULL; |
1080 } |
1081 } |
1081 |
1082 |
1082 _dynamic_header = (DynamicArchiveHeader*)mapinfo->header(); |
1083 _dynamic_header = mapinfo->dynamic_header(); |
1083 |
|
1084 int regions[] = {MetaspaceShared::rw, |
1084 int regions[] = {MetaspaceShared::rw, |
1085 MetaspaceShared::ro, |
1085 MetaspaceShared::ro, |
1086 MetaspaceShared::mc}; |
1086 MetaspaceShared::mc}; |
1087 |
1087 |
1088 size_t len = sizeof(regions)/sizeof(int); |
1088 size_t len = sizeof(regions)/sizeof(int); |
1100 |
1100 |
1101 if (_dynamic_header == NULL) { |
1101 if (_dynamic_header == NULL) { |
1102 return NULL; |
1102 return NULL; |
1103 } |
1103 } |
1104 |
1104 |
1105 intptr_t* buffer = (intptr_t*)_dynamic_header->_read_only_tables_start; |
1105 intptr_t* buffer = (intptr_t*)_dynamic_header->serialized_data_start(); |
1106 ReadClosure rc(&buffer); |
1106 ReadClosure rc(&buffer); |
1107 SymbolTable::serialize_shared_table_header(&rc, false); |
1107 SymbolTable::serialize_shared_table_header(&rc, false); |
1108 SystemDictionaryShared::serialize_dictionary_headers(&rc, false); |
1108 SystemDictionaryShared::serialize_dictionary_headers(&rc, false); |
1109 |
1109 |
1110 return (address)top; |
1110 return (address)top; |
1111 } |
1111 } |
1112 |
1112 |
1113 bool DynamicArchive::validate(FileMapInfo* dynamic_info) { |
1113 bool DynamicArchive::validate(FileMapInfo* dynamic_info) { |
1114 // Check if the recorded base archive matches with the current one |
1114 // Check if the recorded base archive matches with the current one |
1115 FileMapInfo* base_info = FileMapInfo::current_info(); |
1115 FileMapInfo* base_info = FileMapInfo::current_info(); |
1116 DynamicArchiveHeader* dynamic_header = (DynamicArchiveHeader*)dynamic_info->header(); |
1116 DynamicArchiveHeader* dynamic_header = dynamic_info->dynamic_header(); |
1117 int* crc = dynamic_header->_base_archive_crc; |
|
1118 |
1117 |
1119 // Check the header crc |
1118 // Check the header crc |
1120 if (*crc++ != base_info->crc()) { |
1119 if (dynamic_header->base_header_crc() != base_info->crc()) { |
1121 FileMapInfo::fail_continue("Archive header checksum verification failed."); |
1120 FileMapInfo::fail_continue("Archive header checksum verification failed."); |
1122 return false; |
1121 return false; |
1123 } |
1122 } |
1124 |
1123 |
1125 // Check each space's crc |
1124 // Check each space's crc |
1126 for (int i = 0; i < MetaspaceShared::n_regions; i++) { |
1125 for (int i = 0; i < MetaspaceShared::n_regions; i++) { |
1127 if (*crc++ != base_info->space_crc(i)) { |
1126 if (dynamic_header->base_region_crc(i) != base_info->space_crc(i)) { |
1128 FileMapInfo::fail_continue("Archive region #%d checksum verification failed.", i); |
1127 FileMapInfo::fail_continue("Archive region #%d checksum verification failed.", i); |
1129 return false; |
1128 return false; |
1130 } |
1129 } |
1131 } |
1130 } |
1132 |
1131 |