64 #include "runtime/mutexLocker.hpp"
65 #include "runtime/os.hpp"
66 #include "runtime/vm_version.hpp"
67 #include "utilities/align.hpp"
68 #include "utilities/bitMap.inline.hpp"
69 #include "utilities/classpathStream.hpp"
70 #include "utilities/defaultStream.hpp"
71 #include "utilities/ostream.hpp"
72 #if INCLUDE_G1GC
73 #include "gc/g1/g1CollectedHeap.hpp"
74 #include "gc/g1/g1HeapRegion.hpp"
75 #endif
76
77 # include <sys/stat.h>
78 # include <errno.h>
79
80 #ifndef O_BINARY // if defined (Win32) use binary files.
81 #define O_BINARY 0 // otherwise do nothing.
82 #endif
83
84 // Fill in the fileMapInfo structure with data about this VM instance.
85
86 // This method copies the vm version info into header_version. If the version is too
87 // long then a truncated version, which has a hash code appended to it, is copied.
88 //
89 // Using a template enables this method to verify that header_version is an array of
90 // length JVM_IDENT_MAX. This ensures that the code that writes to the CDS file and
91 // the code that reads the CDS file will both use the same size buffer. Hence, will
92 // use identical truncation. This is necessary for matching of truncated versions.
93 template <int N> static void get_header_version(char (&header_version) [N]) {
94 assert(N == JVM_IDENT_MAX, "Bad header_version size");
95
96 const char *vm_version = VM_Version::internal_vm_info_string();
97 const int version_len = (int)strlen(vm_version);
98
99 memset(header_version, 0, JVM_IDENT_MAX);
100
101 if (version_len < (JVM_IDENT_MAX-1)) {
102 strcpy(header_version, vm_version);
103
198 set_version(CURRENT_CDS_ARCHIVE_VERSION);
199
200 if (!info->is_static() && base_archive_name_size != 0) {
201 // copy base archive name
202 copy_base_archive_name(CDSConfig::static_archive_path());
203 }
204 _core_region_alignment = core_region_alignment;
205 _obj_alignment = ObjectAlignmentInBytes;
206 _compact_strings = CompactStrings;
207 if (CDSConfig::is_dumping_heap()) {
208 _narrow_oop_mode = CompressedOops::mode();
209 _narrow_oop_base = CompressedOops::base();
210 _narrow_oop_shift = CompressedOops::shift();
211 }
212 _compressed_oops = UseCompressedOops;
213 _compressed_class_ptrs = UseCompressedClassPointers;
214 _use_secondary_supers_table = UseSecondarySupersTable;
215 _max_heap_size = MaxHeapSize;
216 _use_optimized_module_handling = CDSConfig::is_using_optimized_module_handling();
217 _has_full_module_graph = CDSConfig::is_dumping_full_module_graph();
218
219 // The following fields are for sanity checks for whether this archive
220 // will function correctly with this JVM and the bootclasspath it's
221 // invoked with.
222
223 // JVM version string ... changes on each build.
224 get_header_version(_jvm_ident);
225
226 _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
227 _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
228 _max_used_path_index = ClassLoaderExt::max_used_path_index();
229 _num_module_paths = ClassLoader::num_module_path_entries();
230
231 _verify_local = BytecodeVerificationLocal;
232 _verify_remote = BytecodeVerificationRemote;
233 _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
234 _has_non_jar_in_classpath = ClassLoaderExt::has_non_jar_in_classpath();
235 _requested_base_address = (char*)SharedBaseAddress;
236 _mapped_base_address = (char*)SharedBaseAddress;
237 _allow_archiving_with_java_agent = AllowArchivingWithJavaAgent;
238
239 if (!CDSConfig::is_dumping_dynamic_archive()) {
240 set_shared_path_table(info->_shared_path_table);
241 }
242 }
243
244 void FileMapHeader::copy_base_archive_name(const char* archive) {
245 assert(base_archive_name_size() != 0, "_base_archive_name_size not set");
246 assert(base_archive_name_offset() != 0, "_base_archive_name_offset not set");
247 assert(header_size() > sizeof(*this), "_base_archive_name_size not included in header size?");
248 memcpy((char*)this + base_archive_name_offset(), archive, base_archive_name_size());
249 }
250
251 void FileMapHeader::print(outputStream* st) {
252 ResourceMark rm;
253
254 st->print_cr("- magic: 0x%08x", magic());
255 st->print_cr("- crc: 0x%08x", crc());
256 st->print_cr("- version: 0x%x", version());
257 st->print_cr("- header_size: " UINT32_FORMAT, header_size());
284 st->print_cr("- num_module_paths: %d", _num_module_paths);
285 st->print_cr("- max_used_path_index: %d", _max_used_path_index);
286 st->print_cr("- verify_local: %d", _verify_local);
287 st->print_cr("- verify_remote: %d", _verify_remote);
288 st->print_cr("- has_platform_or_app_classes: %d", _has_platform_or_app_classes);
289 st->print_cr("- has_non_jar_in_classpath: %d", _has_non_jar_in_classpath);
290 st->print_cr("- requested_base_address: " INTPTR_FORMAT, p2i(_requested_base_address));
291 st->print_cr("- mapped_base_address: " INTPTR_FORMAT, p2i(_mapped_base_address));
292 st->print_cr("- heap_root_segments.roots_count: %d" , _heap_root_segments.roots_count());
293 st->print_cr("- heap_root_segments.base_offset: " SIZE_FORMAT_X, _heap_root_segments.base_offset());
294 st->print_cr("- heap_root_segments.count: " SIZE_FORMAT, _heap_root_segments.count());
295 st->print_cr("- heap_root_segments.max_size_elems: %d", _heap_root_segments.max_size_in_elems());
296 st->print_cr("- heap_root_segments.max_size_bytes: %d", _heap_root_segments.max_size_in_bytes());
297 st->print_cr("- _heap_oopmap_start_pos: " SIZE_FORMAT, _heap_oopmap_start_pos);
298 st->print_cr("- _heap_ptrmap_start_pos: " SIZE_FORMAT, _heap_ptrmap_start_pos);
299 st->print_cr("- _rw_ptrmap_start_pos: " SIZE_FORMAT, _rw_ptrmap_start_pos);
300 st->print_cr("- _ro_ptrmap_start_pos: " SIZE_FORMAT, _ro_ptrmap_start_pos);
301 st->print_cr("- allow_archiving_with_java_agent:%d", _allow_archiving_with_java_agent);
302 st->print_cr("- use_optimized_module_handling: %d", _use_optimized_module_handling);
303 st->print_cr("- has_full_module_graph %d", _has_full_module_graph);
304 }
305
306 void SharedClassPathEntry::init_as_non_existent(const char* path, TRAPS) {
307 _type = non_existent_entry;
308 set_name(path, CHECK);
309 }
310
311 void SharedClassPathEntry::init(bool is_modules_image,
312 bool is_module_path,
313 ClassPathEntry* cpe, TRAPS) {
314 assert(CDSConfig::is_dumping_archive(), "sanity");
315 _timestamp = 0;
316 _filesize = 0;
317 _from_class_path_attr = false;
318
319 struct stat st;
320 if (os::stat(cpe->name(), &st) == 0) {
321 if ((st.st_mode & S_IFMT) == S_IFDIR) {
322 _type = dir_entry;
323 } else {
1368 if (strncmp(actual_ident, expected_ident, JVM_IDENT_MAX-1) != 0) {
1369 log_info(cds)("_jvm_ident expected: %s", expected_ident);
1370 log_info(cds)(" actual: %s", actual_ident);
1371 log_warning(cds)("The shared archive file was created by a different"
1372 " version or build of HotSpot");
1373 return false;
1374 }
1375
1376 _file_offset = header()->header_size(); // accounts for the size of _base_archive_name
1377
1378 size_t len = os::lseek(fd, 0, SEEK_END);
1379
1380 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
1381 FileMapRegion* r = region_at(i);
1382 if (r->file_offset() > len || len - r->file_offset() < r->used()) {
1383 log_warning(cds)("The shared archive file has been truncated.");
1384 return false;
1385 }
1386 }
1387
1388 return true;
1389 }
1390
1391 void FileMapInfo::seek_to_position(size_t pos) {
1392 if (os::lseek(_fd, (long)pos, SEEK_SET) < 0) {
1393 log_error(cds)("Unable to seek to position " SIZE_FORMAT, pos);
1394 MetaspaceShared::unrecoverable_loading_error();
1395 }
1396 }
1397
1398 // Read the FileMapInfo information from the file.
1399 bool FileMapInfo::open_for_read() {
1400 if (_file_open) {
1401 return true;
1402 }
1403 log_info(cds)("trying to map %s", _full_path);
1404 int fd = os::open(_full_path, O_RDONLY | O_BINARY, 0);
1405 if (fd < 0) {
1406 if (errno == ENOENT) {
1407 log_info(cds)("Specified shared archive not found (%s)", _full_path);
2475 // while AllowArchivingWithJavaAgent is set during the current run.
2476 if (_allow_archiving_with_java_agent && !AllowArchivingWithJavaAgent) {
2477 log_warning(cds)("The setting of the AllowArchivingWithJavaAgent is different "
2478 "from the setting in the shared archive.");
2479 return false;
2480 }
2481
2482 if (_allow_archiving_with_java_agent) {
2483 log_warning(cds)("This archive was created with AllowArchivingWithJavaAgent. It should be used "
2484 "for testing purposes only and should not be used in a production environment");
2485 }
2486
2487 log_info(cds)("Archive was created with UseCompressedOops = %d, UseCompressedClassPointers = %d",
2488 compressed_oops(), compressed_class_pointers());
2489 if (compressed_oops() != UseCompressedOops || compressed_class_pointers() != UseCompressedClassPointers) {
2490 log_info(cds)("Unable to use shared archive.\nThe saved state of UseCompressedOops and UseCompressedClassPointers is "
2491 "different from runtime, CDS will be disabled.");
2492 return false;
2493 }
2494
2495 if (! _use_secondary_supers_table && UseSecondarySupersTable) {
2496 log_warning(cds)("The shared archive was created without UseSecondarySupersTable.");
2497 return false;
2498 }
2499
2500 if (!_use_optimized_module_handling) {
2501 CDSConfig::stop_using_optimized_module_handling();
2502 log_info(cds)("optimized module handling: disabled because archive was created without optimized module handling");
2503 }
2504
2505 if (is_static() && !_has_full_module_graph) {
2506 // Only the static archive can contain the full module graph.
2507 CDSConfig::stop_using_full_module_graph("archive was created without full module graph");
2508 }
2509
2510 return true;
2511 }
2512
2513 bool FileMapInfo::validate_header() {
2514 if (!header()->validate()) {
|
64 #include "runtime/mutexLocker.hpp"
65 #include "runtime/os.hpp"
66 #include "runtime/vm_version.hpp"
67 #include "utilities/align.hpp"
68 #include "utilities/bitMap.inline.hpp"
69 #include "utilities/classpathStream.hpp"
70 #include "utilities/defaultStream.hpp"
71 #include "utilities/ostream.hpp"
72 #if INCLUDE_G1GC
73 #include "gc/g1/g1CollectedHeap.hpp"
74 #include "gc/g1/g1HeapRegion.hpp"
75 #endif
76
77 # include <sys/stat.h>
78 # include <errno.h>
79
80 #ifndef O_BINARY // if defined (Win32) use binary files.
81 #define O_BINARY 0 // otherwise do nothing.
82 #endif
83
84 inline void CDSMustMatchFlags::do_print(outputStream* st, bool v) {
85 st->print("%s", v ? "true" : "false");
86 }
87
88 inline void CDSMustMatchFlags::do_print(outputStream* st, intx v) {
89 st->print(INTX_FORMAT, v);
90 }
91
92 inline void CDSMustMatchFlags::do_print(outputStream* st, uintx v) {
93 st->print(UINTX_FORMAT, v);
94 }
95
96 inline void CDSMustMatchFlags::do_print(outputStream* st, double v) {
97 st->print("%f", v);
98 }
99
100 void CDSMustMatchFlags::init() {
101 assert(CDSConfig::is_dumping_archive(), "sanity");
102 _max_name_width = 0;
103
104 #define INIT_CDS_MUST_MATCH_FLAG(n) \
105 _v_##n = n; \
106 _max_name_width = MAX2(_max_name_width,strlen(#n));
107 CDS_MUST_MATCH_FLAGS_DO(INIT_CDS_MUST_MATCH_FLAG);
108 #undef INIT_CDS_MUST_MATCH_FLAG
109 }
110
111 bool CDSMustMatchFlags::runtime_check() const {
112 #define CHECK_CDS_MUST_MATCH_FLAG(n) \
113 if (_v_##n != n) { \
114 ResourceMark rm; \
115 stringStream ss; \
116 ss.print("VM option %s is different between dumptime (", #n); \
117 do_print(&ss, _v_ ## n); \
118 ss.print(") and runtime ("); \
119 do_print(&ss, n); \
120 ss.print(")"); \
121 log_info(cds)("%s", ss.as_string()); \
122 return false; \
123 }
124 CDS_MUST_MATCH_FLAGS_DO(CHECK_CDS_MUST_MATCH_FLAG);
125 #undef CHECK_CDS_MUST_MATCH_FLAG
126
127 return true;
128 }
129
130 void CDSMustMatchFlags::print_info() const {
131 LogTarget(Info, cds) lt;
132 if (lt.is_enabled()) {
133 LogStream ls(lt);
134 ls.print_cr("Recorded VM flags during dumptime:");
135 print(&ls);
136 }
137 }
138
139 void CDSMustMatchFlags::print(outputStream* st) const {
140 #define PRINT_CDS_MUST_MATCH_FLAG(n) \
141 st->print("- %-s ", #n); \
142 st->sp(int(_max_name_width - strlen(#n))); \
143 do_print(st, _v_##n); \
144 st->cr();
145 CDS_MUST_MATCH_FLAGS_DO(PRINT_CDS_MUST_MATCH_FLAG);
146 #undef PRINT_CDS_MUST_MATCH_FLAG
147 }
148
149 // Fill in the fileMapInfo structure with data about this VM instance.
150
151 // This method copies the vm version info into header_version. If the version is too
152 // long then a truncated version, which has a hash code appended to it, is copied.
153 //
154 // Using a template enables this method to verify that header_version is an array of
155 // length JVM_IDENT_MAX. This ensures that the code that writes to the CDS file and
156 // the code that reads the CDS file will both use the same size buffer. Hence, will
157 // use identical truncation. This is necessary for matching of truncated versions.
158 template <int N> static void get_header_version(char (&header_version) [N]) {
159 assert(N == JVM_IDENT_MAX, "Bad header_version size");
160
161 const char *vm_version = VM_Version::internal_vm_info_string();
162 const int version_len = (int)strlen(vm_version);
163
164 memset(header_version, 0, JVM_IDENT_MAX);
165
166 if (version_len < (JVM_IDENT_MAX-1)) {
167 strcpy(header_version, vm_version);
168
263 set_version(CURRENT_CDS_ARCHIVE_VERSION);
264
265 if (!info->is_static() && base_archive_name_size != 0) {
266 // copy base archive name
267 copy_base_archive_name(CDSConfig::static_archive_path());
268 }
269 _core_region_alignment = core_region_alignment;
270 _obj_alignment = ObjectAlignmentInBytes;
271 _compact_strings = CompactStrings;
272 if (CDSConfig::is_dumping_heap()) {
273 _narrow_oop_mode = CompressedOops::mode();
274 _narrow_oop_base = CompressedOops::base();
275 _narrow_oop_shift = CompressedOops::shift();
276 }
277 _compressed_oops = UseCompressedOops;
278 _compressed_class_ptrs = UseCompressedClassPointers;
279 _use_secondary_supers_table = UseSecondarySupersTable;
280 _max_heap_size = MaxHeapSize;
281 _use_optimized_module_handling = CDSConfig::is_using_optimized_module_handling();
282 _has_full_module_graph = CDSConfig::is_dumping_full_module_graph();
283 _has_valhalla_patched_classes = CDSConfig::is_valhalla_preview();
284 // The following fields are for sanity checks for whether this archive
285 // will function correctly with this JVM and the bootclasspath it's
286 // invoked with.
287
288 // JVM version string ... changes on each build.
289 get_header_version(_jvm_ident);
290
291 _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
292 _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
293 _max_used_path_index = ClassLoaderExt::max_used_path_index();
294 _num_module_paths = ClassLoader::num_module_path_entries();
295
296 _verify_local = BytecodeVerificationLocal;
297 _verify_remote = BytecodeVerificationRemote;
298 _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
299 _has_non_jar_in_classpath = ClassLoaderExt::has_non_jar_in_classpath();
300 _requested_base_address = (char*)SharedBaseAddress;
301 _mapped_base_address = (char*)SharedBaseAddress;
302 _allow_archiving_with_java_agent = AllowArchivingWithJavaAgent;
303 _must_match.init();
304
305 if (!CDSConfig::is_dumping_dynamic_archive()) {
306 set_shared_path_table(info->_shared_path_table);
307 }
308 }
309
310 void FileMapHeader::copy_base_archive_name(const char* archive) {
311 assert(base_archive_name_size() != 0, "_base_archive_name_size not set");
312 assert(base_archive_name_offset() != 0, "_base_archive_name_offset not set");
313 assert(header_size() > sizeof(*this), "_base_archive_name_size not included in header size?");
314 memcpy((char*)this + base_archive_name_offset(), archive, base_archive_name_size());
315 }
316
317 void FileMapHeader::print(outputStream* st) {
318 ResourceMark rm;
319
320 st->print_cr("- magic: 0x%08x", magic());
321 st->print_cr("- crc: 0x%08x", crc());
322 st->print_cr("- version: 0x%x", version());
323 st->print_cr("- header_size: " UINT32_FORMAT, header_size());
350 st->print_cr("- num_module_paths: %d", _num_module_paths);
351 st->print_cr("- max_used_path_index: %d", _max_used_path_index);
352 st->print_cr("- verify_local: %d", _verify_local);
353 st->print_cr("- verify_remote: %d", _verify_remote);
354 st->print_cr("- has_platform_or_app_classes: %d", _has_platform_or_app_classes);
355 st->print_cr("- has_non_jar_in_classpath: %d", _has_non_jar_in_classpath);
356 st->print_cr("- requested_base_address: " INTPTR_FORMAT, p2i(_requested_base_address));
357 st->print_cr("- mapped_base_address: " INTPTR_FORMAT, p2i(_mapped_base_address));
358 st->print_cr("- heap_root_segments.roots_count: %d" , _heap_root_segments.roots_count());
359 st->print_cr("- heap_root_segments.base_offset: " SIZE_FORMAT_X, _heap_root_segments.base_offset());
360 st->print_cr("- heap_root_segments.count: " SIZE_FORMAT, _heap_root_segments.count());
361 st->print_cr("- heap_root_segments.max_size_elems: %d", _heap_root_segments.max_size_in_elems());
362 st->print_cr("- heap_root_segments.max_size_bytes: %d", _heap_root_segments.max_size_in_bytes());
363 st->print_cr("- _heap_oopmap_start_pos: " SIZE_FORMAT, _heap_oopmap_start_pos);
364 st->print_cr("- _heap_ptrmap_start_pos: " SIZE_FORMAT, _heap_ptrmap_start_pos);
365 st->print_cr("- _rw_ptrmap_start_pos: " SIZE_FORMAT, _rw_ptrmap_start_pos);
366 st->print_cr("- _ro_ptrmap_start_pos: " SIZE_FORMAT, _ro_ptrmap_start_pos);
367 st->print_cr("- allow_archiving_with_java_agent:%d", _allow_archiving_with_java_agent);
368 st->print_cr("- use_optimized_module_handling: %d", _use_optimized_module_handling);
369 st->print_cr("- has_full_module_graph %d", _has_full_module_graph);
370 st->print_cr("- has_valhalla_patched_classes %d", _has_valhalla_patched_classes);
371 _must_match.print(st);
372 }
373
374 void SharedClassPathEntry::init_as_non_existent(const char* path, TRAPS) {
375 _type = non_existent_entry;
376 set_name(path, CHECK);
377 }
378
379 void SharedClassPathEntry::init(bool is_modules_image,
380 bool is_module_path,
381 ClassPathEntry* cpe, TRAPS) {
382 assert(CDSConfig::is_dumping_archive(), "sanity");
383 _timestamp = 0;
384 _filesize = 0;
385 _from_class_path_attr = false;
386
387 struct stat st;
388 if (os::stat(cpe->name(), &st) == 0) {
389 if ((st.st_mode & S_IFMT) == S_IFDIR) {
390 _type = dir_entry;
391 } else {
1436 if (strncmp(actual_ident, expected_ident, JVM_IDENT_MAX-1) != 0) {
1437 log_info(cds)("_jvm_ident expected: %s", expected_ident);
1438 log_info(cds)(" actual: %s", actual_ident);
1439 log_warning(cds)("The shared archive file was created by a different"
1440 " version or build of HotSpot");
1441 return false;
1442 }
1443
1444 _file_offset = header()->header_size(); // accounts for the size of _base_archive_name
1445
1446 size_t len = os::lseek(fd, 0, SEEK_END);
1447
1448 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
1449 FileMapRegion* r = region_at(i);
1450 if (r->file_offset() > len || len - r->file_offset() < r->used()) {
1451 log_warning(cds)("The shared archive file has been truncated.");
1452 return false;
1453 }
1454 }
1455
1456 if (!header()->check_must_match_flags()) {
1457 return false;
1458 }
1459
1460 return true;
1461 }
1462
1463 void FileMapInfo::seek_to_position(size_t pos) {
1464 if (os::lseek(_fd, (long)pos, SEEK_SET) < 0) {
1465 log_error(cds)("Unable to seek to position " SIZE_FORMAT, pos);
1466 MetaspaceShared::unrecoverable_loading_error();
1467 }
1468 }
1469
1470 // Read the FileMapInfo information from the file.
1471 bool FileMapInfo::open_for_read() {
1472 if (_file_open) {
1473 return true;
1474 }
1475 log_info(cds)("trying to map %s", _full_path);
1476 int fd = os::open(_full_path, O_RDONLY | O_BINARY, 0);
1477 if (fd < 0) {
1478 if (errno == ENOENT) {
1479 log_info(cds)("Specified shared archive not found (%s)", _full_path);
2547 // while AllowArchivingWithJavaAgent is set during the current run.
2548 if (_allow_archiving_with_java_agent && !AllowArchivingWithJavaAgent) {
2549 log_warning(cds)("The setting of the AllowArchivingWithJavaAgent is different "
2550 "from the setting in the shared archive.");
2551 return false;
2552 }
2553
2554 if (_allow_archiving_with_java_agent) {
2555 log_warning(cds)("This archive was created with AllowArchivingWithJavaAgent. It should be used "
2556 "for testing purposes only and should not be used in a production environment");
2557 }
2558
2559 log_info(cds)("Archive was created with UseCompressedOops = %d, UseCompressedClassPointers = %d",
2560 compressed_oops(), compressed_class_pointers());
2561 if (compressed_oops() != UseCompressedOops || compressed_class_pointers() != UseCompressedClassPointers) {
2562 log_info(cds)("Unable to use shared archive.\nThe saved state of UseCompressedOops and UseCompressedClassPointers is "
2563 "different from runtime, CDS will be disabled.");
2564 return false;
2565 }
2566
2567 if (is_static()) {
2568 const char* err = nullptr;
2569 if (CDSConfig::is_valhalla_preview()) {
2570 if (!_has_valhalla_patched_classes) {
2571 err = "not created";
2572 }
2573 } else {
2574 if (_has_valhalla_patched_classes) {
2575 err = "created";
2576 }
2577 }
2578 if (err != nullptr) {
2579 log_warning(cds)("This archive was %s with --enable-preview -XX:+EnableValhalla. It is "
2580 "incompatible with the current JVM setting", err);
2581 return false;
2582 }
2583 }
2584
2585 if (! _use_secondary_supers_table && UseSecondarySupersTable) {
2586 log_warning(cds)("The shared archive was created without UseSecondarySupersTable.");
2587 return false;
2588 }
2589
2590 if (!_use_optimized_module_handling) {
2591 CDSConfig::stop_using_optimized_module_handling();
2592 log_info(cds)("optimized module handling: disabled because archive was created without optimized module handling");
2593 }
2594
2595 if (is_static() && !_has_full_module_graph) {
2596 // Only the static archive can contain the full module graph.
2597 CDSConfig::stop_using_full_module_graph("archive was created without full module graph");
2598 }
2599
2600 return true;
2601 }
2602
2603 bool FileMapInfo::validate_header() {
2604 if (!header()->validate()) {
|