1 /*
  2  * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  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 "cds/archiveHeapLoader.hpp"
 26 #include "cds/cdsConfig.hpp"
 27 #include "cds/classListWriter.hpp"
 28 #include "cds/filemap.hpp"
 29 #include "cds/heapShared.hpp"
 30 #include "classfile/classLoaderDataShared.hpp"
 31 #include "classfile/moduleEntry.hpp"
 32 #include "include/jvm_io.h"
 33 #include "logging/log.hpp"
 34 #include "memory/universe.hpp"
 35 #include "runtime/arguments.hpp"
 36 #include "runtime/globals_extension.hpp"
 37 #include "runtime/java.hpp"
 38 #include "runtime/vmThread.hpp"
 39 #include "utilities/defaultStream.hpp"
 40 #include "utilities/formatBuffer.hpp"
 41 
 42 bool CDSConfig::_is_dumping_static_archive = false;
 43 bool CDSConfig::_is_dumping_preimage_static_archive = false;
 44 bool CDSConfig::_is_dumping_final_static_archive = false;
 45 bool CDSConfig::_is_dumping_dynamic_archive = false;
 46 bool CDSConfig::_is_using_optimized_module_handling = true;
 47 bool CDSConfig::_is_dumping_full_module_graph = true;
 48 bool CDSConfig::_is_using_full_module_graph = true;
 49 bool CDSConfig::_has_aot_linked_classes = false;
 50 bool CDSConfig::_old_cds_flags_used = false;
 51 bool CDSConfig::_new_aot_flags_used = false;
 52 bool CDSConfig::_disable_heap_dumping = false;
 53 
 54 char* CDSConfig::_default_archive_path = nullptr;
 55 char* CDSConfig::_static_archive_path = nullptr;
 56 char* CDSConfig::_dynamic_archive_path = nullptr;
 57 
 58 JavaThread* CDSConfig::_dumper_thread = nullptr;
 59 
 60 int CDSConfig::get_status() {
 61   assert(Universe::is_fully_initialized(), "status is finalized only after Universe is initialized");
 62   return (is_dumping_archive()              ? IS_DUMPING_ARCHIVE : 0) |
 63          (is_dumping_method_handles()       ? IS_DUMPING_METHOD_HANDLES : 0) |
 64          (is_dumping_static_archive()       ? IS_DUMPING_STATIC_ARCHIVE : 0) |
 65          (is_logging_lambda_form_invokers() ? IS_LOGGING_LAMBDA_FORM_INVOKERS : 0) |
 66          (is_using_archive()                ? IS_USING_ARCHIVE : 0);
 67 }
 68 
 69 void CDSConfig::initialize() {
 70   if (is_dumping_static_archive() && !is_dumping_final_static_archive()) {
 71     // Note: -Xshare and -XX:AOTMode flags are mutually exclusive.
 72     // - Classic workflow: -Xshare:on and -Xshare:dump cannot take effect at the same time.
 73     // - JEP 483 workflow: -XX:AOTMode:record and -XX:AOTMode=on cannot take effect at the same time.
 74     // So we can never come to here with RequireSharedSpaces==true.
 75     assert(!RequireSharedSpaces, "sanity");
 76 
 77     // If dumping the classic archive, or making an AOT training run (dumping a preimage archive),
 78     // for sanity, parse all classes from classfiles.
 79     // TODO: in the future, if we want to support re-training on top of an existing AOT cache, this
 80     // needs to be changed.
 81     UseSharedSpaces = false;
 82   }
 83 
 84   // Initialize shared archive paths which could include both base and dynamic archive paths
 85   // This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly.
 86   //
 87   // UseSharedSpaces may be disabled if -XX:SharedArchiveFile is invalid.
 88   if (is_dumping_static_archive() || is_using_archive()) {
 89     init_shared_archive_paths();
 90   }
 91 
 92   if (!is_dumping_heap()) {
 93     _is_dumping_full_module_graph = false;
 94   }
 95 }
 96 
 97 char* CDSConfig::default_archive_path() {
 98   if (_default_archive_path == nullptr) {
 99     stringStream tmp;
100     const char* subdir = WINDOWS_ONLY("bin") NOT_WINDOWS("lib");
101     tmp.print("%s%s%s%s%s%sclasses", Arguments::get_java_home(), os::file_separator(), subdir,
102               os::file_separator(), Abstract_VM_Version::vm_variant(), os::file_separator());
103 #ifdef _LP64
104     if (!UseCompressedOops) {
105       tmp.print_raw("_nocoops");
106     }
107     if (UseCompactObjectHeaders) {
108       // Note that generation of xxx_coh.jsa variants require
109       // --enable-cds-archive-coh at build time
110       tmp.print_raw("_coh");
111     }
112 #endif
113     tmp.print_raw(".jsa");
114     _default_archive_path = os::strdup(tmp.base());
115   }
116   return _default_archive_path;
117 }
118 
119 int CDSConfig::num_archives(const char* archive_path) {
120   if (archive_path == nullptr) {
121     return 0;
122   }
123   int npaths = 1;
124   char* p = (char*)archive_path;
125   while (*p != '\0') {
126     if (*p == os::path_separator()[0]) {
127       npaths++;
128     }
129     p++;
130   }
131   return npaths;
132 }
133 
134 void CDSConfig::extract_shared_archive_paths(const char* archive_path,
135                                              char** base_archive_path,
136                                              char** top_archive_path) {
137   char* begin_ptr = (char*)archive_path;
138   char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]);
139   if (end_ptr == nullptr || end_ptr == begin_ptr) {
140     vm_exit_during_initialization("Base archive was not specified", archive_path);
141   }
142   size_t len = end_ptr - begin_ptr;
143   char* cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
144   strncpy(cur_path, begin_ptr, len);
145   cur_path[len] = '\0';
146   *base_archive_path = cur_path;
147 
148   begin_ptr = ++end_ptr;
149   if (*begin_ptr == '\0') {
150     vm_exit_during_initialization("Top archive was not specified", archive_path);
151   }
152   end_ptr = strchr(begin_ptr, '\0');
153   assert(end_ptr != nullptr, "sanity");
154   len = end_ptr - begin_ptr;
155   cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
156   strncpy(cur_path, begin_ptr, len + 1);
157   *top_archive_path = cur_path;
158 }
159 
160 void CDSConfig::init_shared_archive_paths() {
161   if (ArchiveClassesAtExit != nullptr) {
162     assert(!RecordDynamicDumpInfo, "already checked");
163     if (is_dumping_static_archive()) {
164       vm_exit_during_initialization("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump");
165     }
166     check_unsupported_dumping_module_options();
167 
168     if (os::same_files(default_archive_path(), ArchiveClassesAtExit)) {
169       vm_exit_during_initialization(
170         "Cannot specify the default CDS archive for -XX:ArchiveClassesAtExit", default_archive_path());
171     }
172   }
173 
174   if (SharedArchiveFile == nullptr) {
175     _static_archive_path = default_archive_path();
176   } else {
177     int archives = num_archives(SharedArchiveFile);
178     assert(archives > 0, "must be");
179 
180     if (is_dumping_archive() && archives > 1) {
181       vm_exit_during_initialization(
182         "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
183     }
184 
185     if (is_dumping_static_archive()) {
186       assert(archives == 1, "must be");
187       // Static dump is simple: only one archive is allowed in SharedArchiveFile. This file
188       // will be overwritten no matter regardless of its contents
189       _static_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments);
190     } else {
191       // SharedArchiveFile may specify one or two files. In case (c), the path for base.jsa
192       // is read from top.jsa
193       //    (a) 1 file:  -XX:SharedArchiveFile=base.jsa
194       //    (b) 2 files: -XX:SharedArchiveFile=base.jsa:top.jsa
195       //    (c) 2 files: -XX:SharedArchiveFile=top.jsa
196       //
197       // However, if either RecordDynamicDumpInfo or ArchiveClassesAtExit is used, we do not
198       // allow cases (b) and (c). Case (b) is already checked above.
199 
200       if (archives > 2) {
201         vm_exit_during_initialization(
202           "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option");
203       }
204       if (archives == 1) {
205         char* base_archive_path = nullptr;
206         bool success =
207           FileMapInfo::get_base_archive_name_from_header(SharedArchiveFile, &base_archive_path);
208         if (!success) {
209           // If +AutoCreateSharedArchive and the specified shared archive does not exist,
210           // regenerate the dynamic archive base on default archive.
211           if (AutoCreateSharedArchive && !os::file_exists(SharedArchiveFile)) {
212             enable_dumping_dynamic_archive();
213             ArchiveClassesAtExit = const_cast<char *>(SharedArchiveFile);
214             _static_archive_path = default_archive_path();
215             SharedArchiveFile = nullptr;
216           } else {
217             if (AutoCreateSharedArchive) {
218               warning("-XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info.");
219               AutoCreateSharedArchive = false;
220             }
221             log_error(cds)("Not a valid %s (%s)", new_aot_flags_used() ? "AOT cache" : "archive", SharedArchiveFile);
222             Arguments::no_shared_spaces("invalid archive");
223           }
224         } else if (base_archive_path == nullptr) {
225           // User has specified a single archive, which is a static archive.
226           _static_archive_path = const_cast<char *>(SharedArchiveFile);
227         } else {
228           // User has specified a single archive, which is a dynamic archive.
229           _dynamic_archive_path = const_cast<char *>(SharedArchiveFile);
230           _static_archive_path = base_archive_path; // has been c-heap allocated.
231         }
232       } else {
233         extract_shared_archive_paths((const char*)SharedArchiveFile,
234                                       &_static_archive_path, &_dynamic_archive_path);
235         if (_static_archive_path == nullptr) {
236           assert(_dynamic_archive_path == nullptr, "must be");
237           Arguments::no_shared_spaces("invalid archive");
238         }
239       }
240 
241       if (_dynamic_archive_path != nullptr) {
242         // Check for case (c)
243         if (RecordDynamicDumpInfo) {
244           vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
245                                         SharedArchiveFile);
246         }
247         if (ArchiveClassesAtExit != nullptr) {
248           vm_exit_during_initialization("-XX:ArchiveClassesAtExit is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
249                                         SharedArchiveFile);
250         }
251       }
252 
253       if (ArchiveClassesAtExit != nullptr && os::same_files(SharedArchiveFile, ArchiveClassesAtExit)) {
254           vm_exit_during_initialization(
255             "Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit",
256             SharedArchiveFile);
257       }
258     }
259   }
260 }
261 
262 void CDSConfig::check_internal_module_property(const char* key, const char* value) {
263   if (Arguments::is_incompatible_cds_internal_module_property(key)) {
264     stop_using_optimized_module_handling();
265     log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
266   }
267 }
268 
269 void CDSConfig::check_incompatible_property(const char* key, const char* value) {
270   static const char* incompatible_properties[] = {
271     "java.system.class.loader",
272     "jdk.module.showModuleResolution",
273     "jdk.module.validation"
274   };
275 
276   for (const char* property : incompatible_properties) {
277     if (strcmp(key, property) == 0) {
278       stop_dumping_full_module_graph();
279       stop_using_full_module_graph();
280       log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value);
281       break;
282     }
283   }
284 
285 }
286 
287 // Returns any JVM command-line option, such as "--patch-module", that's not supported by CDS.
288 static const char* find_any_unsupported_module_option() {
289   // Note that arguments.cpp has translated the command-line options into properties. If we find an
290   // unsupported property, translate it back to its command-line option for better error reporting.
291 
292   // The following properties are checked by Arguments::is_internal_module_property() and cannot be
293   // directly specified in the command-line.
294   static const char* unsupported_module_properties[] = {
295     "jdk.module.limitmods",
296     "jdk.module.upgrade.path",
297     "jdk.module.patch.0"
298   };
299   static const char* unsupported_module_options[] = {
300     "--limit-modules",
301     "--upgrade-module-path",
302     "--patch-module"
303   };
304 
305   assert(ARRAY_SIZE(unsupported_module_properties) == ARRAY_SIZE(unsupported_module_options), "must be");
306   SystemProperty* sp = Arguments::system_properties();
307   while (sp != nullptr) {
308     for (uint i = 0; i < ARRAY_SIZE(unsupported_module_properties); i++) {
309       if (strcmp(sp->key(), unsupported_module_properties[i]) == 0) {
310         return unsupported_module_options[i];
311       }
312     }
313     sp = sp->next();
314   }
315 
316   return nullptr; // not found
317 }
318 
319 void CDSConfig::check_unsupported_dumping_module_options() {
320   assert(is_dumping_archive(), "this function is only used with CDS dump time");
321   const char* option = find_any_unsupported_module_option();
322   if (option != nullptr) {
323     vm_exit_during_initialization("Cannot use the following option when dumping the shared archive", option);
324   }
325   // Check for an exploded module build in use with -Xshare:dump.
326   if (!Arguments::has_jimage()) {
327     vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build");
328   }
329 }
330 
331 bool CDSConfig::has_unsupported_runtime_module_options() {
332   assert(is_using_archive(), "this function is only used with -Xshare:{on,auto}");
333   if (ArchiveClassesAtExit != nullptr) {
334     // dynamic dumping, just return false for now.
335     // check_unsupported_dumping_properties() will be called later to check the same set of
336     // properties, and will exit the VM with the correct error message if the unsupported properties
337     // are used.
338     return false;
339   }
340   const char* option = find_any_unsupported_module_option();
341   if (option != nullptr) {
342     if (RequireSharedSpaces) {
343       warning("CDS is disabled when the %s option is specified.", option);
344     } else {
345       if (new_aot_flags_used()) {
346         log_warning(cds)("AOT cache is disabled when the %s option is specified.", option);
347       } else {
348         log_info(cds)("CDS is disabled when the %s option is specified.", option);
349       }
350     }
351     return true;
352   }
353   return false;
354 }
355 
356 #define CHECK_ALIAS(f) check_flag_alias(FLAG_IS_DEFAULT(f), #f)
357 
358 void CDSConfig::check_flag_alias(bool alias_is_default, const char* alias_name) {
359   if (old_cds_flags_used() && !alias_is_default) {
360     vm_exit_during_initialization(err_msg("Option %s cannot be used at the same time with "
361                                           "-Xshare:on, -Xshare:auto, -Xshare:off, -Xshare:dump, "
362                                           "DumpLoadedClassList, SharedClassListFile, or SharedArchiveFile",
363                                           alias_name));
364   }
365 }
366 
367 void CDSConfig::check_aot_flags() {
368   if (!FLAG_IS_DEFAULT(DumpLoadedClassList) ||
369       !FLAG_IS_DEFAULT(SharedClassListFile) ||
370       !FLAG_IS_DEFAULT(SharedArchiveFile)) {
371     _old_cds_flags_used = true;
372   }
373 
374   CHECK_ALIAS(AOTCache);
375   CHECK_ALIAS(AOTConfiguration);
376   CHECK_ALIAS(AOTMode);
377 
378   if (FLAG_IS_DEFAULT(AOTCache) && FLAG_IS_DEFAULT(AOTConfiguration) && FLAG_IS_DEFAULT(AOTMode)) {
379     // AOTCache/AOTConfiguration/AOTMode not used.
380     return;
381   } else {
382     _new_aot_flags_used = true;
383   }
384 
385   if (FLAG_IS_DEFAULT(AOTMode) || strcmp(AOTMode, "auto") == 0 || strcmp(AOTMode, "on") == 0) {
386     check_aotmode_auto_or_on();
387   } else if (strcmp(AOTMode, "off") == 0) {
388     check_aotmode_off();
389   } else {
390     // AOTMode is record or create
391     if (FLAG_IS_DEFAULT(AOTConfiguration)) {
392       vm_exit_during_initialization(err_msg("-XX:AOTMode=%s cannot be used without setting AOTConfiguration", AOTMode));
393     }
394 
395     if (strcmp(AOTMode, "record") == 0) {
396       check_aotmode_record();
397     } else {
398       assert(strcmp(AOTMode, "create") == 0, "checked by AOTModeConstraintFunc");
399       check_aotmode_create();
400     }
401   }
402 }
403 
404 void CDSConfig::check_aotmode_off() {
405   UseSharedSpaces = false;
406   RequireSharedSpaces = false;
407 }
408 
409 void CDSConfig::check_aotmode_auto_or_on() {
410   if (!FLAG_IS_DEFAULT(AOTConfiguration)) {
411     vm_exit_during_initialization("AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create");
412   }
413 
414   if (!FLAG_IS_DEFAULT(AOTCache)) {
415     assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
416     FLAG_SET_ERGO(SharedArchiveFile, AOTCache);
417   }
418 
419   UseSharedSpaces = true;
420   if (FLAG_IS_DEFAULT(AOTMode) || (strcmp(AOTMode, "auto") == 0)) {
421     RequireSharedSpaces = false;
422   } else {
423     assert(strcmp(AOTMode, "on") == 0, "already checked");
424     RequireSharedSpaces = true;
425   }
426 }
427 
428 void CDSConfig::check_aotmode_record() {
429   if (!FLAG_IS_DEFAULT(AOTCache)) {
430     vm_exit_during_initialization("AOTCache must not be specified when using -XX:AOTMode=record");
431   }
432 
433   assert(FLAG_IS_DEFAULT(DumpLoadedClassList), "already checked");
434   assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
435   FLAG_SET_ERGO(SharedArchiveFile, AOTConfiguration);
436   FLAG_SET_ERGO(DumpLoadedClassList, nullptr);
437   UseSharedSpaces = false;
438   RequireSharedSpaces = false;
439   _is_dumping_static_archive = true;
440   _is_dumping_preimage_static_archive = true;
441 
442   // At VM exit, the module graph may be contaminated with program states.
443   // We will rebuild the module graph when dumping the CDS final image.
444   disable_heap_dumping();
445 }
446 
447 void CDSConfig::check_aotmode_create() {
448   if (FLAG_IS_DEFAULT(AOTCache)) {
449     vm_exit_during_initialization("AOTCache must be specified when using -XX:AOTMode=create");
450   }
451 
452   assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
453 
454   _is_dumping_final_static_archive = true;
455   FLAG_SET_ERGO(SharedArchiveFile, AOTConfiguration);
456   UseSharedSpaces = true;
457   RequireSharedSpaces = true;
458 
459   if (!FileMapInfo::is_preimage_static_archive(AOTConfiguration)) {
460     vm_exit_during_initialization("Must be a valid AOT configuration generated by the current JVM", AOTConfiguration);
461   }
462 
463   CDSConfig::enable_dumping_static_archive();
464 }
465 
466 bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) {
467   check_aot_flags();
468 
469   if (!FLAG_IS_DEFAULT(AOTMode)) {
470     // Using any form of the new AOTMode switch enables enhanced optimizations.
471     FLAG_SET_ERGO_IF_DEFAULT(AOTClassLinking, true);
472   }
473 
474   if (AOTClassLinking) {
475     // If AOTClassLinking is specified, enable all AOT optimizations by default.
476     FLAG_SET_ERGO_IF_DEFAULT(AOTInvokeDynamicLinking, true);
477   } else {
478     // AOTInvokeDynamicLinking depends on AOTClassLinking.
479     FLAG_SET_ERGO(AOTInvokeDynamicLinking, false);
480   }
481 
482   if (is_dumping_static_archive()) {
483     if (is_dumping_preimage_static_archive()) {
484       // Don't tweak execution mode
485     } else if (!mode_flag_cmd_line) {
486       // By default, -Xshare:dump runs in interpreter-only mode, which is required for deterministic archive.
487       //
488       // If your classlist is large and you don't care about deterministic dumping, you can use
489       // -Xshare:dump -Xmixed to improve dumping speed.
490       Arguments::set_mode_flags(Arguments::_int);
491     } else if (Arguments::mode() == Arguments::_comp) {
492       // -Xcomp may use excessive CPU for the test tiers. Also, -Xshare:dump runs a small and fixed set of
493       // Java code, so there's not much benefit in running -Xcomp.
494       log_info(cds)("reduced -Xcomp to -Xmixed for static dumping");
495       Arguments::set_mode_flags(Arguments::_mixed);
496     }
497 
498     // String deduplication may cause CDS to iterate the strings in different order from one
499     // run to another which resulting in non-determinstic CDS archives.
500     // Disable UseStringDeduplication while dumping CDS archive.
501     UseStringDeduplication = false;
502 
503     // Don't use SoftReferences so that objects used by java.lang.invoke tables can be archived.
504     Arguments::PropertyList_add(new SystemProperty("java.lang.invoke.MethodHandleNatives.USE_SOFT_CACHE", "false", false));
505   }
506 
507   // RecordDynamicDumpInfo is not compatible with ArchiveClassesAtExit
508   if (ArchiveClassesAtExit != nullptr && RecordDynamicDumpInfo) {
509     jio_fprintf(defaultStream::output_stream(),
510                 "-XX:+RecordDynamicDumpInfo cannot be used with -XX:ArchiveClassesAtExit.\n");
511     return false;
512   }
513 
514   if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) {
515     disable_dumping_dynamic_archive();
516   } else {
517     enable_dumping_dynamic_archive();
518   }
519 
520   if (AutoCreateSharedArchive) {
521     if (SharedArchiveFile == nullptr) {
522       log_warning(cds)("-XX:+AutoCreateSharedArchive requires -XX:SharedArchiveFile");
523       return false;
524     }
525     if (ArchiveClassesAtExit != nullptr) {
526       log_warning(cds)("-XX:+AutoCreateSharedArchive does not work with ArchiveClassesAtExit");
527       return false;
528     }
529   }
530 
531   if (is_using_archive() && patch_mod_javabase) {
532     Arguments::no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
533   }
534   if (is_using_archive() && has_unsupported_runtime_module_options()) {
535     UseSharedSpaces = false;
536   }
537 
538   if (is_dumping_archive()) {
539     // Always verify non-system classes during CDS dump
540     if (!BytecodeVerificationRemote) {
541       BytecodeVerificationRemote = true;
542       log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time.");
543     }
544   }
545 
546   return true;
547 }
548 
549 bool CDSConfig::is_dumping_classic_static_archive() {
550   return _is_dumping_static_archive &&
551     !is_dumping_preimage_static_archive() &&
552     !is_dumping_final_static_archive();
553 }
554 
555 bool CDSConfig::is_dumping_preimage_static_archive() {
556   return _is_dumping_preimage_static_archive;
557 }
558 
559 bool CDSConfig::is_dumping_final_static_archive() {
560   return _is_dumping_final_static_archive;
561 }
562 
563 bool CDSConfig::allow_only_single_java_thread() {
564   // See comments in JVM_StartThread()
565   return is_dumping_classic_static_archive() || is_dumping_final_static_archive();
566 }
567 
568 bool CDSConfig::is_using_archive() {
569   return UseSharedSpaces;
570 }
571 
572 bool CDSConfig::is_logging_lambda_form_invokers() {
573   return ClassListWriter::is_enabled() || is_dumping_dynamic_archive();
574 }
575 
576 void CDSConfig::stop_using_optimized_module_handling() {
577   _is_using_optimized_module_handling = false;
578   _is_dumping_full_module_graph = false; // This requires is_using_optimized_module_handling()
579   _is_using_full_module_graph = false; // This requires is_using_optimized_module_handling()
580 }
581 
582 
583 CDSConfig::DumperThreadMark::DumperThreadMark(JavaThread* current) {
584   assert(_dumper_thread == nullptr, "sanity");
585   _dumper_thread = current;
586 }
587 
588 CDSConfig::DumperThreadMark::~DumperThreadMark() {
589   assert(_dumper_thread != nullptr, "sanity");
590   _dumper_thread = nullptr;
591 }
592 
593 bool CDSConfig::current_thread_is_vm_or_dumper() {
594   Thread* t = Thread::current();
595   return t != nullptr && (t->is_VM_thread() || t == _dumper_thread);
596 }
597 
598 const char* CDSConfig::type_of_archive_being_loaded() {
599   if (is_dumping_final_static_archive()) {
600     return "AOT configuration file";
601   } else if (new_aot_flags_used()) {
602     return "AOT cache";
603   } else {
604     return "shared archive file";
605   }
606 }
607 
608 const char* CDSConfig::type_of_archive_being_written() {
609   if (is_dumping_preimage_static_archive()) {
610     return "AOT configuration file";
611   } else if (new_aot_flags_used()) {
612     return "AOT cache";
613   } else {
614     return "shared archive file";
615   }
616 }
617 
618 // If an incompatible VM options is found, return a text message that explains why
619 static const char* check_options_incompatible_with_dumping_heap() {
620 #if INCLUDE_CDS_JAVA_HEAP
621   if (!UseCompressedClassPointers) {
622     return "UseCompressedClassPointers must be true";
623   }
624 
625   // Almost all GCs support heap region dump, except ZGC (so far).
626   if (UseZGC) {
627     return "ZGC is not supported";
628   }
629 
630   return nullptr;
631 #else
632   return "JVM not configured for writing Java heap objects";
633 #endif
634 }
635 
636 void CDSConfig::log_reasons_for_not_dumping_heap() {
637   const char* reason;
638 
639   assert(!is_dumping_heap(), "sanity");
640 
641   if (_disable_heap_dumping) {
642     reason = "Programmatically disabled";
643   } else {
644     reason = check_options_incompatible_with_dumping_heap();
645   }
646 
647   assert(reason != nullptr, "sanity");
648   log_info(cds)("Archived java heap is not supported: %s", reason);
649 }
650 
651 // This is *Legacy* optimization for lambdas before JEP 483. May be removed in the future.
652 bool CDSConfig::is_dumping_lambdas_in_legacy_mode() {
653   return !is_dumping_method_handles();
654 }
655 
656 #if INCLUDE_CDS_JAVA_HEAP
657 bool CDSConfig::are_vm_options_incompatible_with_dumping_heap() {
658   return check_options_incompatible_with_dumping_heap() != nullptr;
659 }
660 
661 bool CDSConfig::is_dumping_heap() {
662   if (!(is_dumping_classic_static_archive() || is_dumping_final_static_archive())
663       || are_vm_options_incompatible_with_dumping_heap()
664       || _disable_heap_dumping) {
665     return false;
666   }
667   return true;
668 }
669 
670 bool CDSConfig::is_loading_heap() {
671   return ArchiveHeapLoader::is_in_use();
672 }
673 
674 bool CDSConfig::is_using_full_module_graph() {
675   if (ClassLoaderDataShared::is_full_module_graph_loaded()) {
676     return true;
677   }
678 
679   if (!_is_using_full_module_graph) {
680     return false;
681   }
682 
683   if (is_using_archive() && ArchiveHeapLoader::can_use()) {
684     // Classes used by the archived full module graph are loaded in JVMTI early phase.
685     assert(!(JvmtiExport::should_post_class_file_load_hook() && JvmtiExport::has_early_class_hook_env()),
686            "CDS should be disabled if early class hooks are enabled");
687     return true;
688   } else {
689     _is_using_full_module_graph = false;
690     return false;
691   }
692 }
693 
694 void CDSConfig::stop_dumping_full_module_graph(const char* reason) {
695   if (_is_dumping_full_module_graph) {
696     _is_dumping_full_module_graph = false;
697     if (reason != nullptr) {
698       log_info(cds)("full module graph cannot be dumped: %s", reason);
699     }
700   }
701 }
702 
703 void CDSConfig::stop_using_full_module_graph(const char* reason) {
704   assert(!ClassLoaderDataShared::is_full_module_graph_loaded(), "you call this function too late!");
705   if (_is_using_full_module_graph) {
706     _is_using_full_module_graph = false;
707     if (reason != nullptr) {
708       log_info(cds)("full module graph cannot be loaded: %s", reason);
709     }
710   }
711 }
712 
713 bool CDSConfig::is_dumping_aot_linked_classes() {
714   if (is_dumping_preimage_static_archive()) {
715     return false;
716   } else if (is_dumping_dynamic_archive()) {
717     return is_using_full_module_graph() && AOTClassLinking;
718   } else if (is_dumping_static_archive()) {
719     return is_dumping_full_module_graph() && AOTClassLinking;
720   } else {
721     return false;
722   }
723 }
724 
725 bool CDSConfig::is_using_aot_linked_classes() {
726   // Make sure we have the exact same module graph as in the assembly phase, or else
727   // some aot-linked classes may not be visible so cannot be loaded.
728   return is_using_full_module_graph() && _has_aot_linked_classes;
729 }
730 
731 void CDSConfig::set_has_aot_linked_classes(bool has_aot_linked_classes) {
732   _has_aot_linked_classes |= has_aot_linked_classes;
733 }
734 
735 bool CDSConfig::is_initing_classes_at_dump_time() {
736   return is_dumping_heap() && is_dumping_aot_linked_classes();
737 }
738 
739 bool CDSConfig::is_dumping_invokedynamic() {
740   // Requires is_dumping_aot_linked_classes(). Otherwise the classes of some archived heap
741   // objects used by the archive indy callsites may be replaced at runtime.
742   return AOTInvokeDynamicLinking && is_dumping_aot_linked_classes() && is_dumping_heap();
743 }
744 
745 // When we are dumping aot-linked classes and we are able to write archived heap objects, we automatically
746 // enable the archiving of MethodHandles. This will in turn enable the archiving of MethodTypes and hidden
747 // classes that are used in the implementation of MethodHandles.
748 // Archived MethodHandles are required for higher-level optimizations such as AOT resolution of invokedynamic
749 // and dynamic proxies.
750 bool CDSConfig::is_dumping_method_handles() {
751   return is_initing_classes_at_dump_time();
752 }
753 
754 #endif // INCLUDE_CDS_JAVA_HEAP