68 #include "runtime/mutexLocker.hpp"
69 #include "runtime/os.hpp"
70 #include "runtime/vm_version.hpp"
71 #include "utilities/align.hpp"
72 #include "utilities/bitMap.inline.hpp"
73 #include "utilities/classpathStream.hpp"
74 #include "utilities/defaultStream.hpp"
75 #include "utilities/ostream.hpp"
76 #if INCLUDE_G1GC
77 #include "gc/g1/g1CollectedHeap.hpp"
78 #include "gc/g1/g1HeapRegion.hpp"
79 #endif
80
81 # include <sys/stat.h>
82 # include <errno.h>
83
84 #ifndef O_BINARY // if defined (Win32) use binary files.
85 #define O_BINARY 0 // otherwise do nothing.
86 #endif
87
88 // Fill in the fileMapInfo structure with data about this VM instance.
89
90 // This method copies the vm version info into header_version. If the version is too
91 // long then a truncated version, which has a hash code appended to it, is copied.
92 //
93 // Using a template enables this method to verify that header_version is an array of
94 // length JVM_IDENT_MAX. This ensures that the code that writes to the CDS file and
95 // the code that reads the CDS file will both use the same size buffer. Hence, will
96 // use identical truncation. This is necessary for matching of truncated versions.
97 template <int N> static void get_header_version(char (&header_version) [N]) {
98 assert(N == JVM_IDENT_MAX, "Bad header_version size");
99
100 const char *vm_version = VM_Version::internal_vm_info_string();
101 const int version_len = (int)strlen(vm_version);
102
103 memset(header_version, 0, JVM_IDENT_MAX);
104
105 if (version_len < (JVM_IDENT_MAX-1)) {
106 strcpy(header_version, vm_version);
107
217 _compact_headers = UseCompactObjectHeaders;
218 if (CDSConfig::is_dumping_heap()) {
219 _narrow_oop_mode = CompressedOops::mode();
220 _narrow_oop_base = CompressedOops::base();
221 _narrow_oop_shift = CompressedOops::shift();
222 }
223 _compressed_oops = UseCompressedOops;
224 _compressed_class_ptrs = UseCompressedClassPointers;
225 if (UseCompressedClassPointers) {
226 #ifdef _LP64
227 _narrow_klass_pointer_bits = CompressedKlassPointers::narrow_klass_pointer_bits();
228 _narrow_klass_shift = ArchiveBuilder::precomputed_narrow_klass_shift();
229 #endif
230 } else {
231 _narrow_klass_pointer_bits = _narrow_klass_shift = -1;
232 }
233 _max_heap_size = MaxHeapSize;
234 _use_optimized_module_handling = CDSConfig::is_using_optimized_module_handling();
235 _has_aot_linked_classes = CDSConfig::is_dumping_aot_linked_classes();
236 _has_full_module_graph = CDSConfig::is_dumping_full_module_graph();
237
238 // The following fields are for sanity checks for whether this archive
239 // will function correctly with this JVM and the bootclasspath it's
240 // invoked with.
241
242 // JVM version string ... changes on each build.
243 get_header_version(_jvm_ident);
244
245 _verify_local = BytecodeVerificationLocal;
246 _verify_remote = BytecodeVerificationRemote;
247 _has_platform_or_app_classes = AOTClassLocationConfig::dumptime()->has_platform_or_app_classes();
248 _requested_base_address = (char*)SharedBaseAddress;
249 _mapped_base_address = (char*)SharedBaseAddress;
250 _allow_archiving_with_java_agent = AllowArchivingWithJavaAgent;
251 }
252
253 void FileMapHeader::copy_base_archive_name(const char* archive) {
254 assert(base_archive_name_size() != 0, "_base_archive_name_size not set");
255 assert(base_archive_name_offset() != 0, "_base_archive_name_offset not set");
256 assert(header_size() > sizeof(*this), "_base_archive_name_size not included in header size?");
257 memcpy((char*)this + base_archive_name_offset(), archive, base_archive_name_size());
258 }
259
260 void FileMapHeader::print(outputStream* st) {
261 ResourceMark rm;
262
263 st->print_cr("- magic: 0x%08x", magic());
264 st->print_cr("- crc: 0x%08x", crc());
265 st->print_cr("- version: 0x%x", version());
266 st->print_cr("- header_size: " UINT32_FORMAT, header_size());
267 st->print_cr("- base_archive_name_offset: " UINT32_FORMAT, base_archive_name_offset());
268 st->print_cr("- base_archive_name_size: " UINT32_FORMAT, base_archive_name_size());
269
270 for (int i = 0; i < NUM_CDS_REGIONS; i++) {
290 st->print_cr("- serialized_data_offset: 0x%zx", _serialized_data_offset);
291 st->print_cr("- jvm_ident: %s", _jvm_ident);
292 st->print_cr("- class_location_config_offset: 0x%zx", _class_location_config_offset);
293 st->print_cr("- verify_local: %d", _verify_local);
294 st->print_cr("- verify_remote: %d", _verify_remote);
295 st->print_cr("- has_platform_or_app_classes: %d", _has_platform_or_app_classes);
296 st->print_cr("- requested_base_address: " INTPTR_FORMAT, p2i(_requested_base_address));
297 st->print_cr("- mapped_base_address: " INTPTR_FORMAT, p2i(_mapped_base_address));
298 st->print_cr("- heap_root_segments.roots_count: %d" , _heap_root_segments.roots_count());
299 st->print_cr("- heap_root_segments.base_offset: 0x%zx", _heap_root_segments.base_offset());
300 st->print_cr("- heap_root_segments.count: %zu", _heap_root_segments.count());
301 st->print_cr("- heap_root_segments.max_size_elems: %d", _heap_root_segments.max_size_in_elems());
302 st->print_cr("- heap_root_segments.max_size_bytes: %d", _heap_root_segments.max_size_in_bytes());
303 st->print_cr("- _heap_oopmap_start_pos: %zu", _heap_oopmap_start_pos);
304 st->print_cr("- _heap_ptrmap_start_pos: %zu", _heap_ptrmap_start_pos);
305 st->print_cr("- _rw_ptrmap_start_pos: %zu", _rw_ptrmap_start_pos);
306 st->print_cr("- _ro_ptrmap_start_pos: %zu", _ro_ptrmap_start_pos);
307 st->print_cr("- allow_archiving_with_java_agent:%d", _allow_archiving_with_java_agent);
308 st->print_cr("- use_optimized_module_handling: %d", _use_optimized_module_handling);
309 st->print_cr("- has_full_module_graph %d", _has_full_module_graph);
310 st->print_cr("- has_aot_linked_classes %d", _has_aot_linked_classes);
311 }
312
313 bool FileMapInfo::validate_class_location() {
314 assert(CDSConfig::is_using_archive(), "runtime only");
315
316 AOTClassLocationConfig* config = header()->class_location_config();
317 bool has_extra_module_paths = false;
318 if (!config->validate(header()->has_aot_linked_classes(), &has_extra_module_paths)) {
319 if (PrintSharedArchiveAndExit) {
320 MetaspaceShared::set_archive_loading_failed();
321 return true;
322 } else {
323 return false;
324 }
325 }
326
327 if (header()->has_full_module_graph() && has_extra_module_paths) {
328 CDSConfig::stop_using_optimized_module_handling();
329 log_info(cds)("optimized module handling: disabled because extra module path(s) are specified");
673 if (strncmp(actual_ident, expected_ident, JVM_IDENT_MAX-1) != 0) {
674 log_info(cds)("_jvm_ident expected: %s", expected_ident);
675 log_info(cds)(" actual: %s", actual_ident);
676 log_warning(cds)("The %s was created by a different"
677 " version or build of HotSpot", file_type);
678 return false;
679 }
680
681 _file_offset = header()->header_size(); // accounts for the size of _base_archive_name
682
683 size_t len = os::lseek(fd, 0, SEEK_END);
684
685 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
686 FileMapRegion* r = region_at(i);
687 if (r->file_offset() > len || len - r->file_offset() < r->used()) {
688 log_warning(cds)("The %s has been truncated.", file_type);
689 return false;
690 }
691 }
692
693 return true;
694 }
695
696 void FileMapInfo::seek_to_position(size_t pos) {
697 if (os::lseek(_fd, (long)pos, SEEK_SET) < 0) {
698 log_error(cds)("Unable to seek to position %zu", pos);
699 MetaspaceShared::unrecoverable_loading_error();
700 }
701 }
702
703 // Read the FileMapInfo information from the file.
704 bool FileMapInfo::open_for_read() {
705 if (_file_open) {
706 return true;
707 }
708 const char* file_type = CDSConfig::type_of_archive_being_loaded();
709 const char* info = CDSConfig::is_dumping_final_static_archive() ?
710 "AOTConfiguration file " : "";
711 log_info(cds)("trying to map %s%s", info, _full_path);
712 int fd = os::open(_full_path, O_RDONLY | O_BINARY, 0);
1913 // while AllowArchivingWithJavaAgent is set during the current run.
1914 if (_allow_archiving_with_java_agent && !AllowArchivingWithJavaAgent) {
1915 log_warning(cds)("The setting of the AllowArchivingWithJavaAgent is different "
1916 "from the setting in the %s.", file_type);
1917 return false;
1918 }
1919
1920 if (_allow_archiving_with_java_agent) {
1921 log_warning(cds)("This %s was created with AllowArchivingWithJavaAgent. It should be used "
1922 "for testing purposes only and should not be used in a production environment", file_type);
1923 }
1924
1925 log_info(cds)("The %s was created with UseCompressedOops = %d, UseCompressedClassPointers = %d, UseCompactObjectHeaders = %d",
1926 file_type, compressed_oops(), compressed_class_pointers(), compact_headers());
1927 if (compressed_oops() != UseCompressedOops || compressed_class_pointers() != UseCompressedClassPointers) {
1928 log_warning(cds)("Unable to use %s.\nThe saved state of UseCompressedOops and UseCompressedClassPointers is "
1929 "different from runtime, CDS will be disabled.", file_type);
1930 return false;
1931 }
1932
1933 if (compact_headers() != UseCompactObjectHeaders) {
1934 log_warning(cds)("Unable to use %s.\nThe %s's UseCompactObjectHeaders setting (%s)"
1935 " does not equal the current UseCompactObjectHeaders setting (%s).", file_type, file_type,
1936 _compact_headers ? "enabled" : "disabled",
1937 UseCompactObjectHeaders ? "enabled" : "disabled");
1938 return false;
1939 }
1940
1941 if (!_use_optimized_module_handling && !CDSConfig::is_dumping_final_static_archive()) {
1942 CDSConfig::stop_using_optimized_module_handling();
1943 log_info(cds)("optimized module handling: disabled because archive was created without optimized module handling");
1944 }
1945
1946 if (is_static()) {
1947 // Only the static archive can contain the full module graph.
1948 if (!_has_full_module_graph) {
1949 CDSConfig::stop_using_full_module_graph("archive was created without full module graph");
1950 }
1951 }
1952
|
68 #include "runtime/mutexLocker.hpp"
69 #include "runtime/os.hpp"
70 #include "runtime/vm_version.hpp"
71 #include "utilities/align.hpp"
72 #include "utilities/bitMap.inline.hpp"
73 #include "utilities/classpathStream.hpp"
74 #include "utilities/defaultStream.hpp"
75 #include "utilities/ostream.hpp"
76 #if INCLUDE_G1GC
77 #include "gc/g1/g1CollectedHeap.hpp"
78 #include "gc/g1/g1HeapRegion.hpp"
79 #endif
80
81 # include <sys/stat.h>
82 # include <errno.h>
83
84 #ifndef O_BINARY // if defined (Win32) use binary files.
85 #define O_BINARY 0 // otherwise do nothing.
86 #endif
87
88 inline void CDSMustMatchFlags::do_print(outputStream* st, bool v) {
89 st->print("%s", v ? "true" : "false");
90 }
91
92 inline void CDSMustMatchFlags::do_print(outputStream* st, intx v) {
93 st->print("%zd", v);
94 }
95
96 inline void CDSMustMatchFlags::do_print(outputStream* st, uintx v) {
97 st->print("%zu", v);
98 }
99
100 inline void CDSMustMatchFlags::do_print(outputStream* st, double v) {
101 st->print("%f", v);
102 }
103
104 void CDSMustMatchFlags::init() {
105 assert(CDSConfig::is_dumping_archive(), "sanity");
106 _max_name_width = 0;
107
108 #define INIT_CDS_MUST_MATCH_FLAG(n) \
109 _v_##n = n; \
110 _max_name_width = MAX2(_max_name_width,strlen(#n));
111 CDS_MUST_MATCH_FLAGS_DO(INIT_CDS_MUST_MATCH_FLAG);
112 #undef INIT_CDS_MUST_MATCH_FLAG
113 }
114
115 bool CDSMustMatchFlags::runtime_check() const {
116 #define CHECK_CDS_MUST_MATCH_FLAG(n) \
117 if (_v_##n != n) { \
118 ResourceMark rm; \
119 stringStream ss; \
120 ss.print("VM option %s is different between dumptime (", #n); \
121 do_print(&ss, _v_ ## n); \
122 ss.print(") and runtime ("); \
123 do_print(&ss, n); \
124 ss.print(")"); \
125 log_info(cds)("%s", ss.as_string()); \
126 return false; \
127 }
128 CDS_MUST_MATCH_FLAGS_DO(CHECK_CDS_MUST_MATCH_FLAG);
129 #undef CHECK_CDS_MUST_MATCH_FLAG
130
131 return true;
132 }
133
134 void CDSMustMatchFlags::print_info() const {
135 LogTarget(Info, cds) lt;
136 if (lt.is_enabled()) {
137 LogStream ls(lt);
138 ls.print_cr("Recorded VM flags during dumptime:");
139 print(&ls);
140 }
141 }
142
143 void CDSMustMatchFlags::print(outputStream* st) const {
144 #define PRINT_CDS_MUST_MATCH_FLAG(n) \
145 st->print("- %-s ", #n); \
146 st->sp(int(_max_name_width - strlen(#n))); \
147 do_print(st, _v_##n); \
148 st->cr();
149 CDS_MUST_MATCH_FLAGS_DO(PRINT_CDS_MUST_MATCH_FLAG);
150 #undef PRINT_CDS_MUST_MATCH_FLAG
151 }
152
153 // Fill in the fileMapInfo structure with data about this VM instance.
154
155 // This method copies the vm version info into header_version. If the version is too
156 // long then a truncated version, which has a hash code appended to it, is copied.
157 //
158 // Using a template enables this method to verify that header_version is an array of
159 // length JVM_IDENT_MAX. This ensures that the code that writes to the CDS file and
160 // the code that reads the CDS file will both use the same size buffer. Hence, will
161 // use identical truncation. This is necessary for matching of truncated versions.
162 template <int N> static void get_header_version(char (&header_version) [N]) {
163 assert(N == JVM_IDENT_MAX, "Bad header_version size");
164
165 const char *vm_version = VM_Version::internal_vm_info_string();
166 const int version_len = (int)strlen(vm_version);
167
168 memset(header_version, 0, JVM_IDENT_MAX);
169
170 if (version_len < (JVM_IDENT_MAX-1)) {
171 strcpy(header_version, vm_version);
172
282 _compact_headers = UseCompactObjectHeaders;
283 if (CDSConfig::is_dumping_heap()) {
284 _narrow_oop_mode = CompressedOops::mode();
285 _narrow_oop_base = CompressedOops::base();
286 _narrow_oop_shift = CompressedOops::shift();
287 }
288 _compressed_oops = UseCompressedOops;
289 _compressed_class_ptrs = UseCompressedClassPointers;
290 if (UseCompressedClassPointers) {
291 #ifdef _LP64
292 _narrow_klass_pointer_bits = CompressedKlassPointers::narrow_klass_pointer_bits();
293 _narrow_klass_shift = ArchiveBuilder::precomputed_narrow_klass_shift();
294 #endif
295 } else {
296 _narrow_klass_pointer_bits = _narrow_klass_shift = -1;
297 }
298 _max_heap_size = MaxHeapSize;
299 _use_optimized_module_handling = CDSConfig::is_using_optimized_module_handling();
300 _has_aot_linked_classes = CDSConfig::is_dumping_aot_linked_classes();
301 _has_full_module_graph = CDSConfig::is_dumping_full_module_graph();
302 _has_valhalla_patched_classes = CDSConfig::is_valhalla_preview();
303
304 // The following fields are for sanity checks for whether this archive
305 // will function correctly with this JVM and the bootclasspath it's
306 // invoked with.
307
308 // JVM version string ... changes on each build.
309 get_header_version(_jvm_ident);
310
311 _verify_local = BytecodeVerificationLocal;
312 _verify_remote = BytecodeVerificationRemote;
313 _has_platform_or_app_classes = AOTClassLocationConfig::dumptime()->has_platform_or_app_classes();
314 _requested_base_address = (char*)SharedBaseAddress;
315 _mapped_base_address = (char*)SharedBaseAddress;
316 _allow_archiving_with_java_agent = AllowArchivingWithJavaAgent;
317 _must_match.init();
318 }
319
320 void FileMapHeader::copy_base_archive_name(const char* archive) {
321 assert(base_archive_name_size() != 0, "_base_archive_name_size not set");
322 assert(base_archive_name_offset() != 0, "_base_archive_name_offset not set");
323 assert(header_size() > sizeof(*this), "_base_archive_name_size not included in header size?");
324 memcpy((char*)this + base_archive_name_offset(), archive, base_archive_name_size());
325 }
326
327 void FileMapHeader::print(outputStream* st) {
328 ResourceMark rm;
329
330 st->print_cr("- magic: 0x%08x", magic());
331 st->print_cr("- crc: 0x%08x", crc());
332 st->print_cr("- version: 0x%x", version());
333 st->print_cr("- header_size: " UINT32_FORMAT, header_size());
334 st->print_cr("- base_archive_name_offset: " UINT32_FORMAT, base_archive_name_offset());
335 st->print_cr("- base_archive_name_size: " UINT32_FORMAT, base_archive_name_size());
336
337 for (int i = 0; i < NUM_CDS_REGIONS; i++) {
357 st->print_cr("- serialized_data_offset: 0x%zx", _serialized_data_offset);
358 st->print_cr("- jvm_ident: %s", _jvm_ident);
359 st->print_cr("- class_location_config_offset: 0x%zx", _class_location_config_offset);
360 st->print_cr("- verify_local: %d", _verify_local);
361 st->print_cr("- verify_remote: %d", _verify_remote);
362 st->print_cr("- has_platform_or_app_classes: %d", _has_platform_or_app_classes);
363 st->print_cr("- requested_base_address: " INTPTR_FORMAT, p2i(_requested_base_address));
364 st->print_cr("- mapped_base_address: " INTPTR_FORMAT, p2i(_mapped_base_address));
365 st->print_cr("- heap_root_segments.roots_count: %d" , _heap_root_segments.roots_count());
366 st->print_cr("- heap_root_segments.base_offset: 0x%zx", _heap_root_segments.base_offset());
367 st->print_cr("- heap_root_segments.count: %zu", _heap_root_segments.count());
368 st->print_cr("- heap_root_segments.max_size_elems: %d", _heap_root_segments.max_size_in_elems());
369 st->print_cr("- heap_root_segments.max_size_bytes: %d", _heap_root_segments.max_size_in_bytes());
370 st->print_cr("- _heap_oopmap_start_pos: %zu", _heap_oopmap_start_pos);
371 st->print_cr("- _heap_ptrmap_start_pos: %zu", _heap_ptrmap_start_pos);
372 st->print_cr("- _rw_ptrmap_start_pos: %zu", _rw_ptrmap_start_pos);
373 st->print_cr("- _ro_ptrmap_start_pos: %zu", _ro_ptrmap_start_pos);
374 st->print_cr("- allow_archiving_with_java_agent:%d", _allow_archiving_with_java_agent);
375 st->print_cr("- use_optimized_module_handling: %d", _use_optimized_module_handling);
376 st->print_cr("- has_full_module_graph %d", _has_full_module_graph);
377 st->print_cr("- has_valhalla_patched_classes %d", _has_valhalla_patched_classes);
378 _must_match.print(st);
379 st->print_cr("- has_aot_linked_classes %d", _has_aot_linked_classes);
380 }
381
382 bool FileMapInfo::validate_class_location() {
383 assert(CDSConfig::is_using_archive(), "runtime only");
384
385 AOTClassLocationConfig* config = header()->class_location_config();
386 bool has_extra_module_paths = false;
387 if (!config->validate(header()->has_aot_linked_classes(), &has_extra_module_paths)) {
388 if (PrintSharedArchiveAndExit) {
389 MetaspaceShared::set_archive_loading_failed();
390 return true;
391 } else {
392 return false;
393 }
394 }
395
396 if (header()->has_full_module_graph() && has_extra_module_paths) {
397 CDSConfig::stop_using_optimized_module_handling();
398 log_info(cds)("optimized module handling: disabled because extra module path(s) are specified");
742 if (strncmp(actual_ident, expected_ident, JVM_IDENT_MAX-1) != 0) {
743 log_info(cds)("_jvm_ident expected: %s", expected_ident);
744 log_info(cds)(" actual: %s", actual_ident);
745 log_warning(cds)("The %s was created by a different"
746 " version or build of HotSpot", file_type);
747 return false;
748 }
749
750 _file_offset = header()->header_size(); // accounts for the size of _base_archive_name
751
752 size_t len = os::lseek(fd, 0, SEEK_END);
753
754 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
755 FileMapRegion* r = region_at(i);
756 if (r->file_offset() > len || len - r->file_offset() < r->used()) {
757 log_warning(cds)("The %s has been truncated.", file_type);
758 return false;
759 }
760 }
761
762 if (!header()->check_must_match_flags()) {
763 return false;
764 }
765
766 return true;
767 }
768
769 void FileMapInfo::seek_to_position(size_t pos) {
770 if (os::lseek(_fd, (long)pos, SEEK_SET) < 0) {
771 log_error(cds)("Unable to seek to position %zu", pos);
772 MetaspaceShared::unrecoverable_loading_error();
773 }
774 }
775
776 // Read the FileMapInfo information from the file.
777 bool FileMapInfo::open_for_read() {
778 if (_file_open) {
779 return true;
780 }
781 const char* file_type = CDSConfig::type_of_archive_being_loaded();
782 const char* info = CDSConfig::is_dumping_final_static_archive() ?
783 "AOTConfiguration file " : "";
784 log_info(cds)("trying to map %s%s", info, _full_path);
785 int fd = os::open(_full_path, O_RDONLY | O_BINARY, 0);
1986 // while AllowArchivingWithJavaAgent is set during the current run.
1987 if (_allow_archiving_with_java_agent && !AllowArchivingWithJavaAgent) {
1988 log_warning(cds)("The setting of the AllowArchivingWithJavaAgent is different "
1989 "from the setting in the %s.", file_type);
1990 return false;
1991 }
1992
1993 if (_allow_archiving_with_java_agent) {
1994 log_warning(cds)("This %s was created with AllowArchivingWithJavaAgent. It should be used "
1995 "for testing purposes only and should not be used in a production environment", file_type);
1996 }
1997
1998 log_info(cds)("The %s was created with UseCompressedOops = %d, UseCompressedClassPointers = %d, UseCompactObjectHeaders = %d",
1999 file_type, compressed_oops(), compressed_class_pointers(), compact_headers());
2000 if (compressed_oops() != UseCompressedOops || compressed_class_pointers() != UseCompressedClassPointers) {
2001 log_warning(cds)("Unable to use %s.\nThe saved state of UseCompressedOops and UseCompressedClassPointers is "
2002 "different from runtime, CDS will be disabled.", file_type);
2003 return false;
2004 }
2005
2006 if (is_static()) {
2007 const char* err = nullptr;
2008 if (CDSConfig::is_valhalla_preview()) {
2009 if (!_has_valhalla_patched_classes) {
2010 err = "not created";
2011 }
2012 } else {
2013 if (_has_valhalla_patched_classes) {
2014 err = "created";
2015 }
2016 }
2017 if (err != nullptr) {
2018 log_warning(cds)("This archive was %s with --enable-preview -XX:+EnableValhalla. It is "
2019 "incompatible with the current JVM setting", err);
2020 return false;
2021 }
2022 }
2023
2024 if (compact_headers() != UseCompactObjectHeaders) {
2025 log_warning(cds)("Unable to use %s.\nThe %s's UseCompactObjectHeaders setting (%s)"
2026 " does not equal the current UseCompactObjectHeaders setting (%s).", file_type, file_type,
2027 _compact_headers ? "enabled" : "disabled",
2028 UseCompactObjectHeaders ? "enabled" : "disabled");
2029 return false;
2030 }
2031
2032 if (!_use_optimized_module_handling && !CDSConfig::is_dumping_final_static_archive()) {
2033 CDSConfig::stop_using_optimized_module_handling();
2034 log_info(cds)("optimized module handling: disabled because archive was created without optimized module handling");
2035 }
2036
2037 if (is_static()) {
2038 // Only the static archive can contain the full module graph.
2039 if (!_has_full_module_graph) {
2040 CDSConfig::stop_using_full_module_graph("archive was created without full module graph");
2041 }
2042 }
2043
|