Projects
openEuler:24.03:SP1:Everything
openjdk-1.8.0
_service:tar_scm:add-appcds-file-lock.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:add-appcds-file-lock.patch of Package openjdk-1.8.0
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index f27d04d0..306315e9 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -4022,8 +4022,12 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, if (_host_klass == NULL && SystemDictionaryShared::is_sharing_possible(loader_data)) { if (name != NULL) { ResourceMark rm(THREAD); - classlist_file->print_cr("%s", name->as_C_string()); - classlist_file->flush(); + char *class_name = name->as_C_string(); + // TODO Skip JFR-related classes in classlist file to avoid conflicts between appcds and jfr. + if ((class_name != NULL) && (strstr(class_name, "jfr") == NULL)) { + classlist_file->print_cr("%s", class_name); + classlist_file->flush(); + } } } } diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index d27bf484..3f28d38e 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -1283,41 +1283,43 @@ instanceKlassHandle SystemDictionary::load_shared_class( // null) or the same class loader is used to load previously // defined class bool bFound = false; - if (class_loader.is_null()) { - // condition1: Bootstrap class loader loaded - bFound = (ik()->class_loader_data() == NULL || ik()->class_loader_data()->is_the_null_class_loader_data()); - } else if (ik()->class_loader_data() != NULL) { - // condition2: App Class Loader - // condition3: ExtClass Loader - // Condition4: not fake class Loader, real one - bFound = ((ik->has_fake_loader_data_App() && SystemDictionary::is_app_class_loader(class_loader)) || - (ik->has_fake_loader_data_Ext() && SystemDictionary::is_ext_class_loader(class_loader)) || - (!ik->has_fake_loader_data() && ik()->class_loader() == class_loader())); - } - if (!bFound) { - return instanceKlassHandle(); - } + if (class_loader.is_null()) { + // condition1: Bootstrap class loader loaded + bFound = (ik()->class_loader_data() == NULL || ik()->class_loader_data()->is_the_null_class_loader_data()); + } else if (ik()->class_loader_data() != NULL) { + // condition2: App Class Loader + // condition3: ExtClass Loader + // condition4: not fake class Loader, real one + bFound = ((ik->has_fake_loader_data_App() && SystemDictionary::is_app_class_loader(class_loader)) || + (ik->has_fake_loader_data_Ext() && SystemDictionary::is_ext_class_loader(class_loader)) || + (!ik->has_fake_loader_data() && ik()->class_loader() == class_loader())); + } + if (!bFound) { + return instanceKlassHandle(); + } - // get protection domain for this class if not loaded by null class loader - if (class_loader.not_null()) { - ResourceMark rm(THREAD); - char* name = ik->name()->as_C_string(); - Handle klass_name = java_lang_String::create_from_str(name, CHECK_0); - JavaValue result(T_OBJECT); - - // ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader()); - JavaCalls::call_virtual(&result, - class_loader, - KlassHandle(THREAD, SystemDictionary::URLClassLoader_klass()), - vmSymbols::getProtectionDomainInternal_name(), - vmSymbols::getProtectionDomainInternal_signature(), - klass_name, - THREAD); - return load_shared_class(ik, class_loader, Handle(THREAD, (oop) result.get_jobject()), THREAD); - } else { - return load_shared_class(ik, class_loader, Handle(), THREAD); - } + // get protection domain for this class if not loaded by null class loader + if (class_loader.not_null()) { + ResourceMark rm(THREAD); + char* name = ik->name()->as_C_string(); + Handle klass_name = java_lang_String::create_from_str(name, CHECK_0); + JavaValue result(T_OBJECT); + + // load_shared_class need protected domain to handle non-bootstrap loaded class, + // so here call_virtual to call getProtectionDomainInternal function of URLClassLoader.java, + // to get protected domain and save into result. + JavaCalls::call_virtual(&result, + class_loader, + KlassHandle(THREAD, SystemDictionary::URLClassLoader_klass()), + vmSymbols::getProtectionDomainInternal_name(), + vmSymbols::getProtectionDomainInternal_signature(), + klass_name, + THREAD); + return load_shared_class(ik, class_loader, Handle(THREAD, (oop) result.get_jobject()), THREAD); + } else { + return load_shared_class(ik, class_loader, Handle(), THREAD); } + } } return instanceKlassHandle(); } @@ -1396,8 +1398,12 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik, // unless AppCDS is enabled if (SystemDictionaryShared::is_sharing_possible(loader_data)) { ResourceMark rm(THREAD); - classlist_file->print_cr("%s", ik->name()->as_C_string()); - classlist_file->flush(); + char *class_name = ik->name()->as_C_string(); + // TODO Skip JFR-related classes in classlist file to avoid conflicts between appcds and jfr. + if ((class_name != NULL) && (strstr(class_name, "jfr") == NULL)) { + classlist_file->print_cr("%s", class_name); + classlist_file->flush(); + } } } @@ -1472,8 +1478,10 @@ instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Ha // the call stack. Bootstrap classloader is parallel-capable, // so no concurrency issues are expected. CLEAR_PENDING_EXCEPTION; - k = JfrUpcalls::load_event_handler_proxy_class(THREAD); - assert(!k.is_null(), "invariant"); + if (!DumpSharedSpaces) { + k = JfrUpcalls::load_event_handler_proxy_class(THREAD); + assert(!k.is_null(), "invariant"); + } } #endif diff --git a/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp b/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp index a8dbda2e..1bd61b02 100644 --- a/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp +++ b/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp @@ -28,6 +28,7 @@ #include "classfile/dictionary.hpp" #include "classfile/systemDictionary.hpp" +#include "verifier.hpp" class SystemDictionaryShared: public SystemDictionary { public: @@ -70,7 +71,16 @@ public: static void finalize_verification_dependencies() {} static bool check_verification_dependencies(Klass* k, Handle class_loader, Handle protection_domain, - char** message_buffer, TRAPS) {return true;} + char** message_buffer, TRAPS) { + if (EnableSplitVerifierForAppCDS) { + ClassVerifier split_verifier(k, THREAD); + split_verifier.verify_class(THREAD); + if (HAS_PENDING_EXCEPTION) { + return false; // use the existing exception + } + } + return true; + } }; #endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index 9923058b..eb267b83 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -561,7 +561,8 @@ void ClassVerifier::verify_class(TRAPS) { for (int index = 0; index < num_methods; index++) { // Check for recursive re-verification before each method. - if (was_recursively_verified()) return; + // in CDS Sharing state we still verify the code. + if (!UseAppCDS && was_recursively_verified()) return; Method* m = methods->at(index); if (m->is_native() || m->is_abstract() || m->is_overpass()) { diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp index 17447587..d2095e63 100644 --- a/hotspot/src/share/vm/memory/filemap.cpp +++ b/hotspot/src/share/vm/memory/filemap.cpp @@ -22,6 +22,7 @@ * */ +#include "jvm.h" #include "precompiled.hpp" #include "classfile/classLoader.hpp" #include "classfile/sharedClassUtil.hpp" @@ -33,10 +34,13 @@ #include "memory/oopFactory.hpp" #include "oops/objArrayOop.hpp" #include "runtime/arguments.hpp" +#include "runtime/globals.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" #include "services/memTracker.hpp" +#include "utilities/debug.hpp" #include "utilities/defaultStream.hpp" +#include "utilities/ostream.hpp" # include <sys/stat.h> # include <errno.h> @@ -362,11 +366,33 @@ bool FileMapInfo::open_for_read() { return true; } - // Write the FileMapInfo information to the file. - void FileMapInfo::open_for_write() { - _full_path = make_log_name(Arguments::GetSharedArchivePath(), NULL); + if (UseAppCDS && AppCDSLockFile != NULL) { + char* pos = strrchr(const_cast<char*>(AppCDSLockFile), '/'); + if (pos != NULL && pos != AppCDSLockFile) { // No directory path specified + char buf[PATH_MAX + 1] = "\0"; + char filePath[PATH_MAX] = "\0"; + int length = pos - AppCDSLockFile + 1; + strncpy(filePath, AppCDSLockFile, length); + if (realpath(filePath, buf) == NULL) { + fail_stop("A risky filePath:%s, buf:%s, length:%d", filePath, buf, length); + } + _appcds_file_lock_path = os::strdup(AppCDSLockFile, mtInternal); + if (_appcds_file_lock_path == NULL) { + fail_stop("Failed to create appcds file lock."); + } + int lock_fd = open(_appcds_file_lock_path, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR); + if (lock_fd < 0) { + tty->print_cr("The lock path is: %s", _appcds_file_lock_path); + tty->print_cr("Failed to create jsa file !\n Please check: \n 1. The directory exists.\n " + "2. You have the permission.\n 3. Make sure no other process using the same lock file.\n"); + JVM_Halt(0); + } + tty->print_cr("You are using file lock %s in concurrent mode", AppCDSLockFile); + } + } + _full_path = make_log_name(Arguments::GetSharedArchivePath(), NULL); if (PrintSharedSpaces) { tty->print_cr("Dumping shared data to file: "); tty->print_cr(" %s", _full_path); @@ -452,6 +478,7 @@ void FileMapInfo::write_bytes(const void* buffer, int nbytes) { // close and remove the file. See bug 6372906. close(); remove(_full_path); + remove(_appcds_file_lock_path); fail_stop("Unable to write to shared archive file."); } } @@ -492,6 +519,10 @@ void FileMapInfo::write_bytes_aligned(const void* buffer, int nbytes) { // Close the shared archive file. This does NOT unmap mapped regions. void FileMapInfo::close() { + if (UseAppCDS && AppCDSLockFile != NULL) { + // delete appcds.lock + remove(_appcds_file_lock_path); + } if (_file_open) { if (::close(_fd) < 0) { fail_stop("Unable to close the shared archive file."); diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp index acff6c9d..c09fbca1 100644 --- a/hotspot/src/share/vm/memory/filemap.hpp +++ b/hotspot/src/share/vm/memory/filemap.hpp @@ -143,6 +143,7 @@ public: FileMapHeader * _header; const char* _full_path; + const char* _appcds_file_lock_path; char* _paths_misc_info; static FileMapInfo* _current_info; diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 073c38ac..ebb5e114 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -36,6 +36,7 @@ #include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" #include "runtime/arguments_ext.hpp" +#include "runtime/globals.hpp" #include "runtime/globals_extension.hpp" #include "runtime/java.hpp" #include "services/management.hpp" @@ -1493,7 +1494,6 @@ void Arguments::set_use_compressed_oops() { // the only value that can override MaxHeapSize if we are // to use UseCompressedOops is InitialHeapSize. size_t max_heap_size = MAX2(MaxHeapSize, InitialHeapSize); - if (max_heap_size <= max_heap_for_compressed_oops()) { #if !defined(COMPILER1) || defined(TIERED) if (FLAG_IS_DEFAULT(UseCompressedOops)) { @@ -3023,9 +3023,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, if (!process_argument("+UseAppCDS", args->ignoreUnrecognized, origin)) { return JNI_EINVAL; } else { - const char* n = "SharedArchiveFile"; - Flag* shared_archive_flag = Flag::find_flag(n, strlen(n), true, true); - shared_archive_flag->unlock_diagnostic(); FLAG_SET_CMDLINE(bool, UseAppCDS, true); } } @@ -3382,6 +3379,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, } else if (match_option(option, "-Xshare:off", &tail)) { FLAG_SET_CMDLINE(bool, UseSharedSpaces, false); FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false); + // -Xtypecheck + } else if (match_option(option, "-Xtypecheck:on", &tail)) { + FLAG_SET_CMDLINE(bool, EnableSplitVerifierForAppCDS, true); // -Xverify } else if (match_option(option, "-Xverify", &tail)) { if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) { @@ -3632,7 +3632,10 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true); FLAG_SET_CMDLINE(bool, TraceClassPaths, true); } - + if (DumpSharedSpaces && !UseAppCDS && AppCDSLockFile != NULL) { + jio_fprintf(defaultStream::error_stream(), "AppCDSLockFile is only used when AppCDS is enabled."); + return JNI_ERR; + } // Change the default value for flags which have different default values // when working with older JDKs. #ifdef LINUX @@ -4057,6 +4060,7 @@ static char* get_shared_archive_path() { return shared_archive_path; } + #ifndef PRODUCT // Determine whether LogVMOutput should be implicitly turned on. static bool use_vm_log() { @@ -4199,6 +4203,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) { return JNI_ENOMEM; } + // Set up VerifySharedSpaces if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) { VerifySharedSpaces = true; diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index 6f7ff138..03f293e3 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -473,6 +473,7 @@ class Arguments : AllStatic { static bool CheckCompileOnly; static char* SharedArchivePath; + static char* AppCDSLockPath; public: // Parses the arguments, first phase diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 65b11caa..b72efd45 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -4007,15 +4007,21 @@ class CommandLineFlags { product(ccstr, SharedClassListFile, NULL, \ "Override the default CDS class list") \ \ - diagnostic(ccstr, SharedArchiveFile, NULL, \ + product(ccstr, SharedArchiveFile, NULL, \ "Override the default location of the CDS archive file") \ \ + product(ccstr, AppCDSLockFile, NULL, \ + "Override the default location of the AppCDS lock file") \ + \ product(ccstr, ExtraSharedClassListFile, NULL, \ "Extra classlist for building the CDS archive file") \ \ product(bool, UseAppCDS, false, \ "Enable Application Class Data Sharing (AppCDS)") \ \ + product(bool, EnableSplitVerifierForAppCDS, false, \ + "Enable Type Check (AppCDS)") \ + \ experimental(uintx, ArrayAllocatorMallocLimit, \ SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx), \ "Allocation less than this value will be allocated " \ diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index 2b458fe4..587b839b 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -34,6 +34,9 @@ #include "utilities/ostream.hpp" #include "utilities/top.hpp" #include "utilities/xmlstream.hpp" + +# include <sys/file.h> + #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" #endif @@ -376,7 +379,7 @@ stringStream::~stringStream() {} xmlStream* xtty; outputStream* tty; outputStream* gclog_or_tty; -CDS_ONLY(fileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive +CDS_ONLY(jsaFileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive extern Mutex* tty_lock; #define EXTRACHARLEN 32 @@ -760,6 +763,36 @@ void fileStream::flush() { fflush(_file); } +jsaFileStream::jsaFileStream(const char* file_name) : fileStream(file_name, "a") { + if (_file != NULL) { + if (flock(fileno(_file), LOCK_EX | LOCK_NB) != 0) { + if (errno == EWOULDBLOCK) { + warning("file %s is locked by another process\n", file_name); + } else { + warning("Cannot lock file %s due to %s\n", file_name, strerror(errno)); + } + fclose(_file); + _file = NULL; + _need_close = false; + } else { + if (::ftruncate(fileno(_file), 0) != 0) { + warning("Fail to ftruncate file %s due to %s\n", file_name, strerror(errno)); + } + ::rewind(_file); + } + } +} + +jsaFileStream::~jsaFileStream() { + // flock is released automatically when _file is closed + // Ensure the following sequnce in fclose + // 1. fflush. 2. flock(unlock); 3. close + if (_file != NULL) { + if (_need_close) fclose(_file); + _file = NULL; + } +} + fdStream::fdStream(const char* file_name) { _fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666); _need_close = true; @@ -1362,7 +1395,7 @@ void ostream_init_log() { if (DumpLoadedClassList != NULL) { const char* list_name = make_log_name(DumpLoadedClassList, NULL); classlist_file = new(ResourceObj::C_HEAP, mtInternal) - fileStream(list_name); + jsaFileStream(list_name); FREE_C_HEAP_ARRAY(char, list_name, mtInternal); } #endif diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp index 530c523c..c69289fb 100644 --- a/hotspot/src/share/vm/utilities/ostream.hpp +++ b/hotspot/src/share/vm/utilities/ostream.hpp @@ -214,7 +214,13 @@ class fileStream : public outputStream { void flush(); }; -CDS_ONLY(extern fileStream* classlist_file;) +class jsaFileStream : public fileStream { + public: + jsaFileStream(const char* file_name); + ~jsaFileStream(); +}; + +CDS_ONLY(extern jsaFileStream* classlist_file;) // unlike fileStream, fdStream does unbuffered I/O by calling // open() and write() directly. It is async-safe, but output
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2