< prev index next > src/hotspot/share/runtime/arguments.cpp
Print this page
#include "utilities/systemMemoryBarrier.hpp"
#if INCLUDE_JFR
#include "jfr/jfr.hpp"
#endif
+ #include <string.h>
+
static const char _default_java_launcher[] = "generic";
#define DEFAULT_JAVA_LAUNCHER _default_java_launcher
char* Arguments::_jvm_flags_file = nullptr;
// Parsing of main arguments
static unsigned int addreads_count = 0;
static unsigned int addexports_count = 0;
static unsigned int addopens_count = 0;
- static unsigned int patch_mod_count = 0;
static unsigned int enable_native_access_count = 0;
static unsigned int enable_final_field_mutation = 0;
static bool patch_mod_javabase = false;
// Check the consistency of vm_init_args
bool Arguments::check_vm_args_consistency() {
// This may modify compiler flags. Must be called before CompilerConfig::check_args_consistency()
! if (!CDSConfig::check_vm_args_consistency(patch_mod_javabase, mode_flag_cmd_line)) {
return false;
}
// Method for adding checks for flag consistency.
// The intent is to warn the user of all possible conflicts,
// Parsing of main arguments
static unsigned int addreads_count = 0;
static unsigned int addexports_count = 0;
static unsigned int addopens_count = 0;
static unsigned int enable_native_access_count = 0;
static unsigned int enable_final_field_mutation = 0;
static bool patch_mod_javabase = false;
// Check the consistency of vm_init_args
bool Arguments::check_vm_args_consistency() {
// This may modify compiler flags. Must be called before CompilerConfig::check_args_consistency()
! if (!CDSConfig::check_vm_args_consistency(mode_flag_cmd_line)) {
return false;
}
// Method for adding checks for flag consistency.
// The intent is to warn the user of all possible conflicts,
// Disable CDS for exploded image
if (!has_jimage()) {
no_shared_spaces("CDS disabled on exploded JDK");
}
+ if (UseAltSubstitutabilityMethod) {
+ no_shared_spaces("Alternate substitutability method doesn't work with CDS yet");
+ }
+
// We need to ensure processor and memory resources have been properly
// configured - which may rely on arguments we just processed - before
// doing the final argument processing. Any argument processing that
// needs to know about processor and memory resources must occur after
// this point.
char* module_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, module_len+1, mtArguments);
if (module_name != nullptr) {
memcpy(module_name, patch_mod_tail, module_len);
*(module_name + module_len) = '\0';
// The path piece begins one past the module_equal sign
! add_patch_mod_prefix(module_name, module_equal + 1);
FREE_C_HEAP_ARRAY(char, module_name);
- if (!create_numbered_module_property("jdk.module.patch", patch_mod_tail, patch_mod_count++)) {
- return JNI_ENOMEM;
- }
} else {
return JNI_ENOMEM;
}
}
return JNI_OK;
}
// Parse -Xss memory string parameter and convert to ThreadStackSize in K.
jint Arguments::parse_xss(const JavaVMOption* option, const char* tail, intx* out_ThreadStackSize) {
// The min and max sizes match the values in globals.hpp, but scaled
// with K. The values have been chosen so that alignment with page
// size doesn't change the max value, which makes the conversions
char* module_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, module_len+1, mtArguments);
if (module_name != nullptr) {
memcpy(module_name, patch_mod_tail, module_len);
*(module_name + module_len) = '\0';
// The path piece begins one past the module_equal sign
! add_patch_mod_prefix(module_name, module_equal + 1, false /* no append */, false /* no cds */);
FREE_C_HEAP_ARRAY(char, module_name);
} else {
return JNI_ENOMEM;
}
}
return JNI_OK;
}
+ // Finalize --patch-module args and --enable-preview related to value class module patches.
+ // Create all numbered properties passing module patches.
+ int Arguments::finalize_patch_module() {
+ // Create numbered properties for each module that has been patched by --patch-module.
+ // Format is "jdk.module.patch.<n>=<module_name>=<path>"
+ if (_patch_mod_prefix != nullptr) {
+ char * prop_value = AllocateHeap(JVM_MAXPATHLEN + JVM_MAXPATHLEN + 1, mtArguments);
+ unsigned int patch_mod_count = 0;
+
+ for (GrowableArrayIterator<ModulePatchPath *> it = _patch_mod_prefix->begin();
+ it != _patch_mod_prefix->end(); ++it) {
+ jio_snprintf(prop_value, JVM_MAXPATHLEN + JVM_MAXPATHLEN + 1, "%s=%s",
+ (*it)->module_name(), (*it)->path_string());
+ if (!create_numbered_module_property("jdk.module.patch", prop_value, patch_mod_count++)) {
+ FreeHeap(prop_value);
+ return JNI_ENOMEM;
+ }
+ }
+ FreeHeap(prop_value);
+ }
+ return JNI_OK;
+ }
+
// Parse -Xss memory string parameter and convert to ThreadStackSize in K.
jint Arguments::parse_xss(const JavaVMOption* option, const char* tail, intx* out_ThreadStackSize) {
// The min and max sizes match the values in globals.hpp, but scaled
// with K. The values have been chosen so that alignment with page
// size doesn't change the max value, which makes the conversions
void Arguments::set_ext_dirs(char *value) {
_ext_dirs = os::strdup_check_oom(value);
}
! void Arguments::add_patch_mod_prefix(const char* module_name, const char* path) {
! // For java.base check for duplicate --patch-module options being specified on the command line.
! // This check is only required for java.base, all other duplicate module specifications
! // will be checked during module system initialization. The module system initialization
! // will throw an ExceptionInInitializerError if this situation occurs.
- if (strcmp(module_name, JAVA_BASE_NAME) == 0) {
- if (patch_mod_javabase) {
- vm_exit_during_initialization("Cannot specify " JAVA_BASE_NAME " more than once to --patch-module");
- } else {
- patch_mod_javabase = true;
}
}
// Create GrowableArray lazily, only if --patch-module has been specified
if (_patch_mod_prefix == nullptr) {
_patch_mod_prefix = new (mtArguments) GrowableArray<ModulePatchPath*>(10, mtArguments);
}
! _patch_mod_prefix->push(new ModulePatchPath(module_name, path));
}
// Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
//
// This is necessary because some apps like to specify classpath like -cp foo.jar:${XYZ}:bar.jar
void Arguments::set_ext_dirs(char *value) {
_ext_dirs = os::strdup_check_oom(value);
}
! void Arguments::add_patch_mod_prefix(const char* module_name, const char* path, bool allow_append, bool allow_cds) {
! if (!allow_cds) {
! CDSConfig::set_module_patching_disables_cds();
! if (strcmp(module_name, JAVA_BASE_NAME) == 0) {
! CDSConfig::set_java_base_module_patching_disables_cds();
}
}
// Create GrowableArray lazily, only if --patch-module has been specified
if (_patch_mod_prefix == nullptr) {
_patch_mod_prefix = new (mtArguments) GrowableArray<ModulePatchPath*>(10, mtArguments);
}
! // Scan patches for matching module
+ int i = _patch_mod_prefix->find_if([&](ModulePatchPath* patch) {
+ return (strcmp(module_name, patch->module_name()) == 0);
+ });
+ if (i == -1) {
+ _patch_mod_prefix->push(new ModulePatchPath(module_name, path));
+ } else {
+ if (allow_append) {
+ // append path to existing module entry
+ _patch_mod_prefix->at(i)->append_path(path);
+ } else {
+ if (strcmp(module_name, JAVA_BASE_NAME) == 0) {
+ vm_exit_during_initialization("Cannot specify " JAVA_BASE_NAME " more than once to --patch-module");
+ } else {
+ vm_exit_during_initialization("Cannot specify a module more than once to --patch-module", module_name);
+ }
+ }
+ }
}
// Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
//
// This is necessary because some apps like to specify classpath like -cp foo.jar:${XYZ}:bar.jar
// Parse the CompilationMode flag
if (!CompilationModeFlag::initialize()) {
return JNI_ERR;
}
! if (!check_vm_args_consistency()) {
return JNI_ERR;
}
#ifndef CAN_SHOW_REGISTERS_ON_ASSERT
UNSUPPORTED_OPTION(ShowRegistersOnAssert);
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
// Parse the CompilationMode flag
if (!CompilationModeFlag::initialize()) {
return JNI_ERR;
}
! ClassLoader::set_preview_mode(is_valhalla_enabled());
+
+ // finalize --module-patch.
+ if (finalize_patch_module() != JNI_OK) {
return JNI_ERR;
}
+ if (!check_vm_args_consistency()) {
+ return JNI_ERR;
+ }
#ifndef CAN_SHOW_REGISTERS_ON_ASSERT
UNSUPPORTED_OPTION(ShowRegistersOnAssert);
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
// verification is not as if both were enabled.
if (BytecodeVerificationLocal && !BytecodeVerificationRemote) {
log_info(verification)("Turning on remote verification because local verification is on");
FLAG_SET_DEFAULT(BytecodeVerificationRemote, true);
}
+ if (!is_valhalla_enabled()) {
+ #define WARN_IF_NOT_DEFAULT_FLAG(flag) \
+ if (!FLAG_IS_DEFAULT(flag)) { \
+ warning("Valhalla-specific flag \"%s\" has no effect when --enable-preview is not specified.", #flag); \
+ }
+
+ #define DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(flag) \
+ WARN_IF_NOT_DEFAULT_FLAG(flag) \
+ FLAG_SET_DEFAULT(flag, false);
+
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(InlineTypePassFieldsAsArgs);
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(InlineTypeReturnedAsFields);
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(UseArrayFlattening);
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(UseFieldFlattening);
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(UseNonAtomicValueFlattening);
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(UseNullableValueFlattening);
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(UseAtomicValueFlattening);
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(PrintInlineLayout);
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(PrintFlatArrayLayout);
+ WARN_IF_NOT_DEFAULT_FLAG(FlatArrayElementMaxOops);
+ WARN_IF_NOT_DEFAULT_FLAG(UseAltSubstitutabilityMethod);
+ #ifdef ASSERT
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(StressCallingConvention);
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(PreloadClasses);
+ WARN_IF_NOT_DEFAULT_FLAG(PrintInlineKlassFields);
+ #endif
+ #ifdef COMPILER1
+ DEBUG_ONLY(DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(C1UseDelayedFlattenedFieldReads);)
+ #endif
+ #ifdef COMPILER2
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(UseArrayLoadStoreProfile);
+ DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT(UseACmpProfile);
+ #endif
+ #undef DISABLE_FLAG_AND_WARN_IF_NOT_DEFAULT
+ #undef WARN_IF_NOT_DEFAULT_FLAG
+ } else {
+ if (is_interpreter_only() && !CDSConfig::is_dumping_archive() && !UseSharedSpaces) {
+ // Disable calling convention optimizations if inline types are not supported.
+ // Also these aren't useful in -Xint. However, don't disable them when dumping or using
+ // the CDS archive, as the values must match between dumptime and runtime.
+ FLAG_SET_DEFAULT(InlineTypePassFieldsAsArgs, false);
+ FLAG_SET_DEFAULT(InlineTypeReturnedAsFields, false);
+ }
+ if (!UseNonAtomicValueFlattening && !UseNullableValueFlattening && !UseAtomicValueFlattening) {
+ // Flattening is disabled
+ FLAG_SET_DEFAULT(UseArrayFlattening, false);
+ FLAG_SET_DEFAULT(UseFieldFlattening, false);
+ }
+ }
#ifndef PRODUCT
if (!LogVMOutput && FLAG_IS_DEFAULT(LogVMOutput)) {
if (use_vm_log()) {
LogVMOutput = true;
< prev index next >