34 #include "logging/log.hpp" |
34 #include "logging/log.hpp" |
35 #include "logging/logConfiguration.hpp" |
35 #include "logging/logConfiguration.hpp" |
36 #include "logging/logStream.hpp" |
36 #include "logging/logStream.hpp" |
37 #include "logging/logTag.hpp" |
37 #include "logging/logTag.hpp" |
38 #include "memory/allocation.inline.hpp" |
38 #include "memory/allocation.inline.hpp" |
|
39 #include "memory/filemap.hpp" |
39 #include "oops/oop.inline.hpp" |
40 #include "oops/oop.inline.hpp" |
40 #include "prims/jvmtiExport.hpp" |
41 #include "prims/jvmtiExport.hpp" |
41 #include "runtime/arguments.hpp" |
42 #include "runtime/arguments.hpp" |
42 #include "runtime/flags/jvmFlag.hpp" |
43 #include "runtime/flags/jvmFlag.hpp" |
43 #include "runtime/flags/jvmFlagConstraintList.hpp" |
44 #include "runtime/flags/jvmFlagConstraintList.hpp" |
1467 const char* unsupported_options[] = { "--limit-modules", |
1469 const char* unsupported_options[] = { "--limit-modules", |
1468 "--upgrade-module-path", |
1470 "--upgrade-module-path", |
1469 "--patch-module" |
1471 "--patch-module" |
1470 }; |
1472 }; |
1471 void Arguments::check_unsupported_dumping_properties() { |
1473 void Arguments::check_unsupported_dumping_properties() { |
1472 assert(DumpSharedSpaces, "this function is only used with -Xshare:dump"); |
1474 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, |
|
1475 "this function is only used with CDS dump time"); |
1473 assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be"); |
1476 assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be"); |
1474 // If a vm option is found in the unsupported_options array, vm will exit with an error message. |
1477 // If a vm option is found in the unsupported_options array, vm will exit with an error message. |
1475 SystemProperty* sp = system_properties(); |
1478 SystemProperty* sp = system_properties(); |
1476 while (sp != NULL) { |
1479 while (sp != NULL) { |
1477 for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) { |
1480 for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) { |
1490 } |
1493 } |
1491 |
1494 |
1492 bool Arguments::check_unsupported_cds_runtime_properties() { |
1495 bool Arguments::check_unsupported_cds_runtime_properties() { |
1493 assert(UseSharedSpaces, "this function is only used with -Xshare:{on,auto}"); |
1496 assert(UseSharedSpaces, "this function is only used with -Xshare:{on,auto}"); |
1494 assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be"); |
1497 assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be"); |
|
1498 if (ArchiveClassesAtExit != NULL) { |
|
1499 // dynamic dumping, just return false for now. |
|
1500 // check_unsupported_dumping_properties() will be called later to check the same set of |
|
1501 // properties, and will exit the VM with the correct error message if the unsupported properties |
|
1502 // are used. |
|
1503 return false; |
|
1504 } |
1495 for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) { |
1505 for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) { |
1496 if (get_property(unsupported_properties[i]) != NULL) { |
1506 if (get_property(unsupported_properties[i]) != NULL) { |
1497 if (RequireSharedSpaces) { |
1507 if (RequireSharedSpaces) { |
1498 warning("CDS is disabled when the %s option is specified.", unsupported_options[i]); |
1508 warning("CDS is disabled when the %s option is specified.", unsupported_options[i]); |
1499 } |
1509 } |
2711 // -Xshare:dump |
2721 // -Xshare:dump |
2712 } else if (match_option(option, "-Xshare:dump")) { |
2722 } else if (match_option(option, "-Xshare:dump")) { |
2713 if (FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true) != JVMFlag::SUCCESS) { |
2723 if (FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true) != JVMFlag::SUCCESS) { |
2714 return JNI_EINVAL; |
2724 return JNI_EINVAL; |
2715 } |
2725 } |
2716 set_mode_flags(_int); // Prevent compilation, which creates objects |
|
2717 // -Xshare:on |
2726 // -Xshare:on |
2718 } else if (match_option(option, "-Xshare:on")) { |
2727 } else if (match_option(option, "-Xshare:on")) { |
2719 if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != JVMFlag::SUCCESS) { |
2728 if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != JVMFlag::SUCCESS) { |
2720 return JNI_EINVAL; |
2729 return JNI_EINVAL; |
2721 } |
2730 } |
2722 if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != JVMFlag::SUCCESS) { |
2731 if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != JVMFlag::SUCCESS) { |
2723 return JNI_EINVAL; |
2732 return JNI_EINVAL; |
2724 } |
2733 } |
2725 // -Xshare:auto |
2734 // -Xshare:auto || -XX:ArchiveClassesAtExit=<archive file> |
2726 } else if (match_option(option, "-Xshare:auto")) { |
2735 } else if (match_option(option, "-Xshare:auto")) { |
2727 if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != JVMFlag::SUCCESS) { |
2736 if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != JVMFlag::SUCCESS) { |
2728 return JNI_EINVAL; |
2737 return JNI_EINVAL; |
2729 } |
2738 } |
2730 if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false) != JVMFlag::SUCCESS) { |
2739 if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false) != JVMFlag::SUCCESS) { |
3108 if (DumpSharedSpaces) { |
3117 if (DumpSharedSpaces) { |
3109 // Disable biased locking now as it interferes with the clean up of |
3118 // Disable biased locking now as it interferes with the clean up of |
3110 // the archived Klasses and Java string objects (at dump time only). |
3119 // the archived Klasses and Java string objects (at dump time only). |
3111 UseBiasedLocking = false; |
3120 UseBiasedLocking = false; |
3112 |
3121 |
|
3122 // Compiler threads may concurrently update the class metadata (such as method entries), so it's |
|
3123 // unsafe with DumpSharedSpaces (which modifies the class metadata in place). Let's disable |
|
3124 // compiler just to be safe. |
|
3125 // |
|
3126 // Note: this is not a concern for DynamicDumpSharedSpaces, which makes a copy of the class metadata |
|
3127 // instead of modifying them in place. The copy is inaccessible to the compiler. |
|
3128 // TODO: revisit the following for the static archive case. |
|
3129 set_mode_flags(_int); |
|
3130 } |
|
3131 if (DumpSharedSpaces || ArchiveClassesAtExit != NULL) { |
3113 // Always verify non-system classes during CDS dump |
3132 // Always verify non-system classes during CDS dump |
3114 if (!BytecodeVerificationRemote) { |
3133 if (!BytecodeVerificationRemote) { |
3115 BytecodeVerificationRemote = true; |
3134 BytecodeVerificationRemote = true; |
3116 log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time."); |
3135 log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time."); |
3117 } |
3136 } |
3118 |
3137 } |
3119 // Compilation is already disabled if the user specifies -Xshare:dump. |
3138 if (ArchiveClassesAtExit == NULL) { |
3120 // Disable compilation in case user specifies -XX:+DumpSharedSpaces instead of -Xshare:dump. |
3139 FLAG_SET_DEFAULT(DynamicDumpSharedSpaces, false); |
3121 set_mode_flags(_int); |
|
3122 } |
3140 } |
3123 if (UseSharedSpaces && patch_mod_javabase) { |
3141 if (UseSharedSpaces && patch_mod_javabase) { |
3124 no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched."); |
3142 no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched."); |
3125 } |
3143 } |
3126 if (UseSharedSpaces && !DumpSharedSpaces && check_unsupported_cds_runtime_properties()) { |
3144 if (UseSharedSpaces && !DumpSharedSpaces && check_unsupported_cds_runtime_properties()) { |
3444 jvm_path, os::file_separator()); |
3463 jvm_path, os::file_separator()); |
3445 } |
3464 } |
3446 return default_archive_path; |
3465 return default_archive_path; |
3447 } |
3466 } |
3448 |
3467 |
3449 static char* get_shared_archive_path() { |
3468 int Arguments::num_archives(const char* archive_path) { |
3450 char *shared_archive_path; |
3469 if (archive_path == NULL) { |
|
3470 return 0; |
|
3471 } |
|
3472 int npaths = 1; |
|
3473 char* p = (char*)archive_path; |
|
3474 while (*p != '\0') { |
|
3475 if (*p == os::path_separator()[0]) { |
|
3476 npaths++; |
|
3477 } |
|
3478 p++; |
|
3479 } |
|
3480 return npaths; |
|
3481 } |
|
3482 |
|
3483 void Arguments::extract_shared_archive_paths(const char* archive_path, |
|
3484 char** base_archive_path, |
|
3485 char** top_archive_path) { |
|
3486 char* begin_ptr = (char*)archive_path; |
|
3487 char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]); |
|
3488 if (end_ptr == NULL || end_ptr == begin_ptr) { |
|
3489 vm_exit_during_initialization("Base archive was not specified", archive_path); |
|
3490 } |
|
3491 size_t len = end_ptr - begin_ptr; |
|
3492 char* cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); |
|
3493 strncpy(cur_path, begin_ptr, len); |
|
3494 cur_path[len] = '\0'; |
|
3495 FileMapInfo::check_archive((const char*)cur_path, true /*is_static*/); |
|
3496 *base_archive_path = cur_path; |
|
3497 |
|
3498 begin_ptr = ++end_ptr; |
|
3499 if (*begin_ptr == '\0') { |
|
3500 vm_exit_during_initialization("Top archive was not specified", archive_path); |
|
3501 } |
|
3502 end_ptr = strchr(begin_ptr, '\0'); |
|
3503 assert(end_ptr != NULL, "sanity"); |
|
3504 len = end_ptr - begin_ptr; |
|
3505 cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); |
|
3506 strncpy(cur_path, begin_ptr, len + 1); |
|
3507 //cur_path[len] = '\0'; |
|
3508 FileMapInfo::check_archive((const char*)cur_path, false /*is_static*/); |
|
3509 *top_archive_path = cur_path; |
|
3510 } |
|
3511 |
|
3512 bool Arguments::init_shared_archive_paths() { |
|
3513 if (ArchiveClassesAtExit != NULL) { |
|
3514 if (DumpSharedSpaces) { |
|
3515 vm_exit_during_initialization("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump"); |
|
3516 } |
|
3517 if (FLAG_SET_CMDLINE(bool, DynamicDumpSharedSpaces, true) != JVMFlag::SUCCESS) { |
|
3518 return false; |
|
3519 } |
|
3520 check_unsupported_dumping_properties(); |
|
3521 SharedDynamicArchivePath = os::strdup_check_oom(ArchiveClassesAtExit, mtArguments); |
|
3522 } |
3451 if (SharedArchiveFile == NULL) { |
3523 if (SharedArchiveFile == NULL) { |
3452 shared_archive_path = Arguments::get_default_shared_archive_path(); |
3524 SharedArchivePath = get_default_shared_archive_path(); |
3453 } else { |
3525 } else { |
3454 shared_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments); |
3526 int archives = num_archives(SharedArchiveFile); |
3455 } |
3527 if (DynamicDumpSharedSpaces || DumpSharedSpaces) { |
3456 return shared_archive_path; |
3528 if (archives > 1) { |
3457 } |
3529 vm_exit_during_initialization( |
|
3530 "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping"); |
|
3531 } |
|
3532 if (DynamicDumpSharedSpaces) { |
|
3533 if (FileMapInfo::same_files(SharedArchiveFile, ArchiveClassesAtExit)) { |
|
3534 vm_exit_during_initialization( |
|
3535 "Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit", |
|
3536 SharedArchiveFile); |
|
3537 } |
|
3538 } |
|
3539 } |
|
3540 if (!DynamicDumpSharedSpaces && !DumpSharedSpaces){ |
|
3541 if (archives > 2) { |
|
3542 vm_exit_during_initialization( |
|
3543 "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option"); |
|
3544 } |
|
3545 if (archives == 1) { |
|
3546 char* temp_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments); |
|
3547 int name_size; |
|
3548 bool success = |
|
3549 FileMapInfo::get_base_archive_name_from_header(temp_archive_path, &name_size, &SharedArchivePath); |
|
3550 if (!success) { |
|
3551 SharedArchivePath = temp_archive_path; |
|
3552 } else { |
|
3553 SharedDynamicArchivePath = temp_archive_path; |
|
3554 } |
|
3555 } else { |
|
3556 extract_shared_archive_paths((const char*)SharedArchiveFile, |
|
3557 &SharedArchivePath, &SharedDynamicArchivePath); |
|
3558 } |
|
3559 } else { // CDS dumping |
|
3560 SharedArchivePath = os::strdup_check_oom(SharedArchiveFile, mtArguments); |
|
3561 } |
|
3562 } |
|
3563 return (SharedArchivePath != NULL); |
|
3564 } |
|
3565 #endif // INCLUDE_CDS |
3458 |
3566 |
3459 #ifndef PRODUCT |
3567 #ifndef PRODUCT |
3460 // Determine whether LogVMOutput should be implicitly turned on. |
3568 // Determine whether LogVMOutput should be implicitly turned on. |
3461 static bool use_vm_log() { |
3569 static bool use_vm_log() { |
3462 if (LogCompilation || !FLAG_IS_DEFAULT(LogFile) || |
3570 if (LogCompilation || !FLAG_IS_DEFAULT(LogFile) || |