From d58020d3190f0385db2c79c6fdee8424bc7b1bd2 Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 17 Jun 2019 16:41:38 +0100 Subject: 8202353: os::readdir should use readdir instead of readdir_r Summary: Summary: os::readdir uses POSIX readdir, drop buffer arg, fix JFR uses. Reviewed-by: coleenp, tschatzl, bsrbnd, shade, phh Conflicts: src/os/linux/vm/os_linux.inline.hpp --- src/os/aix/vm/os_aix.cpp | 3 +-- src/os/aix/vm/os_aix.inline.hpp | 35 -------------------------------- src/os/aix/vm/perfMemory_aix.cpp | 13 +++--------- src/os/bsd/vm/os_bsd.cpp | 3 +-- src/os/bsd/vm/os_bsd.inline.hpp | 33 ------------------------------ src/os/bsd/vm/perfMemory_bsd.cpp | 13 +++--------- src/os/linux/vm/os_linux.cpp | 3 +-- src/os/linux/vm/os_linux.inline.hpp | 14 +++---------- src/os/linux/vm/perfMemory_linux.cpp | 14 +++---------- src/os/posix/vm/os_posix.cpp | 15 ++++++++++++++ src/os/solaris/vm/os_solaris.cpp | 4 +--- src/os/solaris/vm/os_solaris.inline.hpp | 31 ---------------------------- src/os/solaris/vm/perfMemory_solaris.cpp | 13 +++--------- src/os/windows/vm/os_windows.cpp | 8 +++----- src/os/windows/vm/os_windows.inline.hpp | 8 -------- src/os/windows/vm/perfMemory_windows.cpp | 12 +++-------- src/share/vm/runtime/arguments.cpp | 12 +++-------- src/share/vm/runtime/os.hpp | 3 +-- 18 files changed, 44 insertions(+), 193 deletions(-) diff --git a/src/os/aix/vm/os_aix.cpp b/src/os/aix/vm/os_aix.cpp index b03ce2458..717f692c2 100644 --- a/src/os/aix/vm/os_aix.cpp +++ b/src/os/aix/vm/os_aix.cpp @@ -4184,8 +4184,7 @@ bool os::dir_is_empty(const char* path) { /* Scan the directory */ bool result = true; - char buf[sizeof(struct dirent) + MAX_PATH]; - while (result && (ptr = ::readdir(dir)) != NULL) { + while (result && (ptr = readdir(dir)) != NULL) { if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) { result = false; } diff --git a/src/os/aix/vm/os_aix.inline.hpp b/src/os/aix/vm/os_aix.inline.hpp index a97c94c07..421ea342e 100644 --- a/src/os/aix/vm/os_aix.inline.hpp +++ b/src/os/aix/vm/os_aix.inline.hpp @@ -92,19 +92,6 @@ inline void os::dll_unload(void *lib) { inline const int os::default_file_open_flags() { return 0;} -inline DIR* os::opendir(const char* dirname) -{ - assert(dirname != NULL, "just checking"); - return ::opendir(dirname); -} - -inline int os::readdir_buf_size(const char *path) -{ - // according to aix sys/limits, NAME_MAX must be retrieved at runtime. */ - const long my_NAME_MAX = pathconf(path, _PC_NAME_MAX); - return my_NAME_MAX + sizeof(dirent) + 1; -} - inline jlong os::lseek(int fd, jlong offset, int whence) { return (jlong) ::lseek64(fd, offset, whence); } @@ -121,28 +108,6 @@ inline int os::ftruncate(int fd, jlong length) { return ::ftruncate64(fd, length); } -inline struct dirent* os::readdir(DIR* dirp, dirent *dbuf) -{ - dirent* p; - int status; - assert(dirp != NULL, "just checking"); - - // NOTE: Linux readdir_r (on RH 6.2 and 7.2 at least) is NOT like the POSIX - // version. Here is the doc for this function: - // http://www.gnu.org/manual/glibc-2.2.3/html_node/libc_262.html - - if((status = ::readdir_r(dirp, dbuf, &p)) != 0) { - errno = status; - return NULL; - } else - return p; -} - -inline int os::closedir(DIR *dirp) { - assert(dirp != NULL, "argument is NULL"); - return ::closedir(dirp); -} - // macros for restartable system calls #define RESTARTABLE(_cmd, _result) do { \ diff --git a/src/os/aix/vm/perfMemory_aix.cpp b/src/os/aix/vm/perfMemory_aix.cpp index 96f8451d2..80ae9e7a8 100644 --- a/src/os/aix/vm/perfMemory_aix.cpp +++ b/src/os/aix/vm/perfMemory_aix.cpp @@ -612,9 +612,8 @@ static char* get_user_name_slow(int vmid, TRAPS) { // to determine the user name for the process id. // struct dirent* dentry; - char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal); errno = 0; - while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { + while ((dentry = os::readdir(tmpdirp)) != NULL) { // check if the directory entry is a hsperfdata file if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { @@ -648,9 +647,8 @@ static char* get_user_name_slow(int vmid, TRAPS) { } struct dirent* udentry; - char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal); errno = 0; - while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { + while ((udentry = os::readdir(subdirp)) != NULL) { if (filename_to_pid(udentry->d_name) == vmid) { struct stat statbuf; @@ -694,11 +692,9 @@ static char* get_user_name_slow(int vmid, TRAPS) { } } os::closedir(subdirp); - FREE_C_HEAP_ARRAY(char, udbuf, mtInternal); FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); } os::closedir(tmpdirp); - FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal); return(oldest_user); } @@ -774,10 +770,8 @@ static void cleanup_sharedmem_resources(const char* dirname) { // loop under these conditions is dependent upon the implementation of // opendir/readdir. struct dirent* entry; - char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); - errno = 0; - while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { + while ((entry = os::readdir(dirp)) != NULL) { pid_t pid = filename_to_pid(entry->d_name); @@ -816,7 +810,6 @@ static void cleanup_sharedmem_resources(const char* dirname) { // Close the directory and reset the current working directory. close_directory_secure_cwd(dirp, saved_cwd_fd); - FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); } // Make the user specific temporary directory. Returns true if diff --git a/src/os/bsd/vm/os_bsd.cpp b/src/os/bsd/vm/os_bsd.cpp index 99a039988..1c0336edd 100644 --- a/src/os/bsd/vm/os_bsd.cpp +++ b/src/os/bsd/vm/os_bsd.cpp @@ -3957,8 +3957,7 @@ bool os::dir_is_empty(const char* path) { /* Scan the directory */ bool result = true; - char buf[sizeof(struct dirent) + MAX_PATH]; - while (result && (ptr = ::readdir(dir)) != NULL) { + while (result && (ptr = readdir(dir)) != NULL) { if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) { result = false; } diff --git a/src/os/bsd/vm/os_bsd.inline.hpp b/src/os/bsd/vm/os_bsd.inline.hpp index 10b39941d..c35abf486 100644 --- a/src/os/bsd/vm/os_bsd.inline.hpp +++ b/src/os/bsd/vm/os_bsd.inline.hpp @@ -95,17 +95,6 @@ inline void os::dll_unload(void *lib) { inline const int os::default_file_open_flags() { return 0;} -inline DIR* os::opendir(const char* dirname) -{ - assert(dirname != NULL, "just checking"); - return ::opendir(dirname); -} - -inline int os::readdir_buf_size(const char *path) -{ - return NAME_MAX + sizeof(dirent) + 1; -} - inline jlong os::lseek(int fd, jlong offset, int whence) { return (jlong) ::lseek(fd, offset, whence); } @@ -122,28 +111,6 @@ inline int os::ftruncate(int fd, jlong length) { return ::ftruncate(fd, length); } -inline struct dirent* os::readdir(DIR* dirp, dirent *dbuf) -{ - dirent* p; - int status; - assert(dirp != NULL, "just checking"); - - // NOTE: Bsd readdir_r (on RH 6.2 and 7.2 at least) is NOT like the POSIX - // version. Here is the doc for this function: - // http://www.gnu.org/manual/glibc-2.2.3/html_node/libc_262.html - - if((status = ::readdir_r(dirp, dbuf, &p)) != 0) { - errno = status; - return NULL; - } else - return p; -} - -inline int os::closedir(DIR *dirp) { - assert(dirp != NULL, "argument is NULL"); - return ::closedir(dirp); -} - // macros for restartable system calls #define RESTARTABLE(_cmd, _result) do { \ diff --git a/src/os/bsd/vm/perfMemory_bsd.cpp b/src/os/bsd/vm/perfMemory_bsd.cpp index df4fca613..802d0908f 100644 --- a/src/os/bsd/vm/perfMemory_bsd.cpp +++ b/src/os/bsd/vm/perfMemory_bsd.cpp @@ -533,9 +533,8 @@ static char* get_user_name_slow(int vmid, TRAPS) { // to determine the user name for the process id. // struct dirent* dentry; - char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal); errno = 0; - while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { + while ((dentry = os::readdir(tmpdirp)) != NULL) { // check if the directory entry is a hsperfdata file if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { @@ -557,9 +556,8 @@ static char* get_user_name_slow(int vmid, TRAPS) { } struct dirent* udentry; - char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal); errno = 0; - while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { + while ((udentry = os::readdir(subdirp)) != NULL) { if (filename_to_pid(udentry->d_name) == vmid) { struct stat statbuf; @@ -603,11 +601,9 @@ static char* get_user_name_slow(int vmid, TRAPS) { } } os::closedir(subdirp); - FREE_C_HEAP_ARRAY(char, udbuf, mtInternal); FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); } os::closedir(tmpdirp); - FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal); return(oldest_user); } @@ -686,10 +682,8 @@ static void cleanup_sharedmem_resources(const char* dirname) { // opendir/readdir. // struct dirent* entry; - char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); - errno = 0; - while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { + while ((entry = os::readdir(dirp)) != NULL) { pid_t pid = filename_to_pid(entry->d_name); @@ -729,7 +723,6 @@ static void cleanup_sharedmem_resources(const char* dirname) { // close the directory and reset the current working directory close_directory_secure_cwd(dirp, saved_cwd_fd); - FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); } // make the user specific temporary directory. Returns true if diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp index a499e499e..03cabfefb 100644 --- a/src/os/linux/vm/os_linux.cpp +++ b/src/os/linux/vm/os_linux.cpp @@ -5501,8 +5501,7 @@ bool os::dir_is_empty(const char* path) { /* Scan the directory */ bool result = true; - char buf[sizeof(struct dirent) + MAX_PATH]; - while (result && (ptr = ::readdir(dir)) != NULL) { + while (result && (ptr = readdir(dir)) != NULL) { if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) { result = false; } diff --git a/src/os/linux/vm/os_linux.inline.hpp b/src/os/linux/vm/os_linux.inline.hpp index fea10fa64..2e73b1549 100644 --- a/src/os/linux/vm/os_linux.inline.hpp +++ b/src/os/linux/vm/os_linux.inline.hpp @@ -87,17 +87,6 @@ inline void os::dll_unload(void *lib) { inline const int os::default_file_open_flags() { return 0;} -inline DIR* os::opendir(const char* dirname) -{ - assert(dirname != NULL, "just checking"); - return ::opendir(dirname); -} - -inline int os::readdir_buf_size(const char *path) -{ - return NAME_MAX + sizeof(dirent) + 1; -} - inline jlong os::lseek(int fd, jlong offset, int whence) { return (jlong) ::lseek64(fd, offset, whence); } @@ -114,6 +103,7 @@ inline int os::ftruncate(int fd, jlong length) { return ::ftruncate64(fd, length); } +<<<<<<< HEAD // readdir_r has been deprecated since glibc 2.24. // See https://sourceware.org/bugzilla/show_bug.cgi?id=19056 for more details. #pragma GCC diagnostic ignored "-Wdeprecated-declarations" @@ -141,6 +131,8 @@ inline int os::closedir(DIR *dirp) { return ::closedir(dirp); } +======= +>>>>>>> 76168a8... 8202353: os::readdir should use readdir instead of readdir_r // macros for restartable system calls #define RESTARTABLE(_cmd, _result) do { \ diff --git a/src/os/linux/vm/perfMemory_linux.cpp b/src/os/linux/vm/perfMemory_linux.cpp index 4143f655a..8293b7168 100644 --- a/src/os/linux/vm/perfMemory_linux.cpp +++ b/src/os/linux/vm/perfMemory_linux.cpp @@ -533,9 +533,8 @@ static char* get_user_name_slow(int vmid, TRAPS) { // to determine the user name for the process id. // struct dirent* dentry; - char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal); errno = 0; - while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { + while ((dentry = os::readdir(tmpdirp)) != NULL) { // check if the directory entry is a hsperfdata file if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { @@ -569,9 +568,8 @@ static char* get_user_name_slow(int vmid, TRAPS) { } struct dirent* udentry; - char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal); errno = 0; - while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { + while ((udentry = os::readdir(subdirp)) != NULL) { if (filename_to_pid(udentry->d_name) == vmid) { struct stat statbuf; @@ -615,11 +613,9 @@ static char* get_user_name_slow(int vmid, TRAPS) { } } os::closedir(subdirp); - FREE_C_HEAP_ARRAY(char, udbuf, mtInternal); FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); } os::closedir(tmpdirp); - FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal); return(oldest_user); } @@ -698,10 +694,8 @@ static void cleanup_sharedmem_resources(const char* dirname) { // opendir/readdir. // struct dirent* entry; - char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); - errno = 0; - while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { + while ((entry = os::readdir(dirp)) != NULL) { pid_t pid = filename_to_pid(entry->d_name); @@ -738,8 +732,6 @@ static void cleanup_sharedmem_resources(const char* dirname) { // close the directory and reset the current working directory close_directory_secure_cwd(dirp, saved_cwd_fd); - - FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); } // make the user specific temporary directory. Returns true if diff --git a/src/os/posix/vm/os_posix.cpp b/src/os/posix/vm/os_posix.cpp index 534b19258..a43a855b2 100644 --- a/src/os/posix/vm/os_posix.cpp +++ b/src/os/posix/vm/os_posix.cpp @@ -302,6 +302,21 @@ FILE* os::open(int fd, const char* mode) { return ::fdopen(fd, mode); } +DIR* os::opendir(const char* dirname) { + assert(dirname != NULL, "just checking"); + return ::opendir(dirname); +} + +struct dirent* os::readdir(DIR* dirp) { + assert(dirp != NULL, "just checking"); + return ::readdir(dirp); +} + +int os::closedir(DIR *dirp) { + assert(dirp != NULL, "just checking"); + return ::closedir(dirp); +} + // Builds a platform dependent Agent_OnLoad_ function name // which is used to find statically linked in agents. // Parameters: diff --git a/src/os/solaris/vm/os_solaris.cpp b/src/os/solaris/vm/os_solaris.cpp index 014a6d37a..6956f63d9 100644 --- a/src/os/solaris/vm/os_solaris.cpp +++ b/src/os/solaris/vm/os_solaris.cpp @@ -5163,9 +5163,7 @@ bool os::dir_is_empty(const char* path) { /* Scan the directory */ bool result = true; - char buf[sizeof(struct dirent) + MAX_PATH]; - struct dirent *dbuf = (struct dirent *) buf; - while (result && (ptr = readdir(dir, dbuf)) != NULL) { + while (result && (ptr = readdir(dir)) != NULL) { if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) { result = false; } diff --git a/src/os/solaris/vm/os_solaris.inline.hpp b/src/os/solaris/vm/os_solaris.inline.hpp index 921fcf7c0..8e095ab69 100644 --- a/src/os/solaris/vm/os_solaris.inline.hpp +++ b/src/os/solaris/vm/os_solaris.inline.hpp @@ -71,37 +71,6 @@ inline void os::bang_stack_shadow_pages() { } inline void os::dll_unload(void *lib) { ::dlclose(lib); } -inline DIR* os::opendir(const char* dirname) { - assert(dirname != NULL, "just checking"); - return ::opendir(dirname); -} - -inline int os::readdir_buf_size(const char *path) { - int size = pathconf(path, _PC_NAME_MAX); - return (size < 0 ? MAXPATHLEN : size) + sizeof(dirent) + 1; -} - -inline struct dirent* os::readdir(DIR* dirp, dirent* dbuf) { - assert(dirp != NULL, "just checking"); -#if defined(_LP64) || defined(_GNU_SOURCE) || _FILE_OFFSET_BITS==64 - dirent* p; - int status; - - if((status = ::readdir_r(dirp, dbuf, &p)) != 0) { - errno = status; - return NULL; - } else - return p; -#else // defined(_LP64) || defined(_GNU_SOURCE) || _FILE_OFFSET_BITS==64 - return ::readdir_r(dirp, dbuf); -#endif // defined(_LP64) || defined(_GNU_SOURCE) || _FILE_OFFSET_BITS==64 -} - -inline int os::closedir(DIR *dirp) { - assert(dirp != NULL, "argument is NULL"); - return ::closedir(dirp); -} - ////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// diff --git a/src/os/solaris/vm/perfMemory_solaris.cpp b/src/os/solaris/vm/perfMemory_solaris.cpp index 7c6f61604..8af1b2441 100644 --- a/src/os/solaris/vm/perfMemory_solaris.cpp +++ b/src/os/solaris/vm/perfMemory_solaris.cpp @@ -524,9 +524,8 @@ static char* get_user_name_slow(int vmid, TRAPS) { // to determine the user name for the process id. // struct dirent* dentry; - char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal); errno = 0; - while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { + while ((dentry = os::readdir(tmpdirp)) != NULL) { // check if the directory entry is a hsperfdata file if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { @@ -560,9 +559,8 @@ static char* get_user_name_slow(int vmid, TRAPS) { } struct dirent* udentry; - char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal); errno = 0; - while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { + while ((udentry = os::readdir(subdirp)) != NULL) { if (filename_to_pid(udentry->d_name) == vmid) { struct stat statbuf; @@ -606,11 +604,9 @@ static char* get_user_name_slow(int vmid, TRAPS) { } } os::closedir(subdirp); - FREE_C_HEAP_ARRAY(char, udbuf, mtInternal); FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); } os::closedir(tmpdirp); - FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal); return(oldest_user); } @@ -737,10 +733,8 @@ static void cleanup_sharedmem_resources(const char* dirname) { // opendir/readdir. // struct dirent* entry; - char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); - errno = 0; - while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { + while ((entry = os::readdir(dirp)) != NULL) { pid_t pid = filename_to_pid(entry->d_name); @@ -780,7 +774,6 @@ static void cleanup_sharedmem_resources(const char* dirname) { // close the directory and reset the current working directory close_directory_secure_cwd(dirp, saved_cwd_fd); - FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); } // make the user specific temporary directory. Returns true if diff --git a/src/os/windows/vm/os_windows.cpp b/src/os/windows/vm/os_windows.cpp index 2aca06d56..06eebde00 100644 --- a/src/os/windows/vm/os_windows.cpp +++ b/src/os/windows/vm/os_windows.cpp @@ -1172,14 +1172,12 @@ os::opendir(const char *dirname) return dirp; } -/* parameter dbuf unused on Windows */ - struct dirent * -os::readdir(DIR *dirp, dirent *dbuf) +os::readdir(DIR *dirp) { assert(dirp != NULL, "just checking"); // hotspot change if (dirp->handle == INVALID_HANDLE_VALUE) { - return 0; + return NULL; } strcpy(dirp->dirent.d_name, dirp->find_data.cFileName); @@ -1187,7 +1185,7 @@ os::readdir(DIR *dirp, dirent *dbuf) if (!FindNextFile(dirp->handle, &dirp->find_data)) { if (GetLastError() == ERROR_INVALID_HANDLE) { errno = EBADF; - return 0; + return NULL; } FindClose(dirp->handle); dirp->handle = INVALID_HANDLE_VALUE; diff --git a/src/os/windows/vm/os_windows.inline.hpp b/src/os/windows/vm/os_windows.inline.hpp index 30ce4682e..5dac11c90 100644 --- a/src/os/windows/vm/os_windows.inline.hpp +++ b/src/os/windows/vm/os_windows.inline.hpp @@ -65,14 +65,6 @@ inline bool os::allocate_stack_guard_pages() { return true; } -inline int os::readdir_buf_size(const char *path) -{ - /* As Windows doesn't use the directory entry buffer passed to - os::readdir() this can be as short as possible */ - - return 1; -} - // Bang the shadow pages if they need to be touched to be mapped. inline void os::bang_stack_shadow_pages() { // Write to each page of our new frame to force OS mapping. diff --git a/src/os/windows/vm/perfMemory_windows.cpp b/src/os/windows/vm/perfMemory_windows.cpp index b32fd9a15..c4cf8c1d5 100644 --- a/src/os/windows/vm/perfMemory_windows.cpp +++ b/src/os/windows/vm/perfMemory_windows.cpp @@ -316,9 +316,8 @@ static char* get_user_name_slow(int vmid) { // to determine the user name for the process id. // struct dirent* dentry; - char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal); errno = 0; - while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { + while ((dentry = os::readdir(tmpdirp)) != NULL) { // check if the directory entry is a hsperfdata file if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { @@ -351,9 +350,8 @@ static char* get_user_name_slow(int vmid) { } struct dirent* udentry; - char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal); errno = 0; - while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { + while ((udentry = os::readdir(subdirp)) != NULL) { if (filename_to_pid(udentry->d_name) == vmid) { struct stat statbuf; @@ -405,11 +403,9 @@ static char* get_user_name_slow(int vmid) { } } os::closedir(subdirp); - FREE_C_HEAP_ARRAY(char, udbuf, mtInternal); FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); } os::closedir(tmpdirp); - FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal); return(latest_user); } @@ -639,9 +635,8 @@ static void cleanup_sharedmem_resources(const char* dirname) { // opendir/readdir. // struct dirent* entry; - char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); errno = 0; - while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { + while ((entry = os::readdir(dirp)) != NULL) { int pid = filename_to_pid(entry->d_name); @@ -682,7 +677,6 @@ static void cleanup_sharedmem_resources(const char* dirname) { errno = 0; } os::closedir(dirp); - FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); } // create a file mapping object with the requested name, and size diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp index 43e31d224..2665b6b8c 100644 --- a/src/share/vm/runtime/arguments.cpp +++ b/src/share/vm/runtime/arguments.cpp @@ -556,8 +556,7 @@ char* SysClassPath::add_jars_to_path(char* path, const char* directory) { /* Scan the directory for jars/zips, appending them to path. */ struct dirent *entry; - char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtInternal); - while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) { + while ((entry = os::readdir(dir)) != NULL) { const char* name = entry->d_name; const char* ext = name + strlen(name) - 4; bool isJarOrZip = ext > name && @@ -571,7 +570,6 @@ char* SysClassPath::add_jars_to_path(char* path, const char* directory) { FREE_C_HEAP_ARRAY(char, jarpath, mtInternal); } } - FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); os::closedir(dir); return path; } @@ -3485,14 +3483,12 @@ static bool has_jar_files(const char* directory) { if (dir == NULL) return false; struct dirent *entry; - char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtInternal); bool hasJarFile = false; - while (!hasJarFile && (entry = os::readdir(dir, (dirent *) dbuf)) != NULL) { + while (!hasJarFile && (entry = os::readdir(dir)) != NULL) { const char* name = entry->d_name; const char* ext = name + strlen(name) - 4; hasJarFile = ext > name && (os::file_name_strcmp(ext, ".jar") == 0); } - FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); os::closedir(dir); return hasJarFile ; } @@ -3574,8 +3570,7 @@ static bool check_endorsed_and_ext_dirs() { if (dir != NULL) { int num_ext_jars = 0; struct dirent *entry; - char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(extDir), mtInternal); - while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) { + while ((entry = os::readdir(dir)) != NULL) { const char* name = entry->d_name; const char* ext = name + strlen(name) - 4; if (ext > name && (os::file_name_strcmp(ext, ".jar") == 0)) { @@ -3594,7 +3589,6 @@ static bool check_endorsed_and_ext_dirs() { } } } - FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); os::closedir(dir); if (num_ext_jars > 0) { nonEmptyDirs += 1; diff --git a/src/share/vm/runtime/os.hpp b/src/share/vm/runtime/os.hpp index 931f4cb5b..14cd94237 100644 --- a/src/share/vm/runtime/os.hpp +++ b/src/share/vm/runtime/os.hpp @@ -561,8 +561,7 @@ class os: AllStatic { // Reading directories. static DIR* opendir(const char* dirname); - static int readdir_buf_size(const char *path); - static struct dirent* readdir(DIR* dirp, dirent* dbuf); + static struct dirent* readdir(DIR* dirp); static int closedir(DIR* dirp); // Dynamic library extension -- cgit v1.2.3 From c031422db44212de9ef302ec58fda123c70aba48 Mon Sep 17 00:00:00 2001 From: bell-sw Date: Wed, 23 Oct 2019 11:07:37 +0300 Subject: Merge conflict fix. JB had some local changes in old code that is removed now: https://github.com/JetBrains/jdk8u_hotspot/commit/4426ec26 https://github.com/JetBrains/jdk8u_hotspot/commit/b35de605 --- src/os/linux/vm/os_linux.inline.hpp | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/os/linux/vm/os_linux.inline.hpp b/src/os/linux/vm/os_linux.inline.hpp index 2e73b1549..a23bd5631 100644 --- a/src/os/linux/vm/os_linux.inline.hpp +++ b/src/os/linux/vm/os_linux.inline.hpp @@ -103,36 +103,6 @@ inline int os::ftruncate(int fd, jlong length) { return ::ftruncate64(fd, length); } -<<<<<<< HEAD -// readdir_r has been deprecated since glibc 2.24. -// See https://sourceware.org/bugzilla/show_bug.cgi?id=19056 for more details. -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -inline struct dirent* os::readdir(DIR* dirp, dirent *dbuf) -{ - - dirent* p; - int status; - assert(dirp != NULL, "just checking"); - - // NOTE: Linux readdir_r (on RH 6.2 and 7.2 at least) is NOT like the POSIX - // version. Here is the doc for this function: - // http://www.gnu.org/manual/glibc-2.2.3/html_node/libc_262.html - - if((status = ::readdir_r(dirp, dbuf, &p)) != 0) { - errno = status; - return NULL; - } else - return p; - -} - -inline int os::closedir(DIR *dirp) { - assert(dirp != NULL, "argument is NULL"); - return ::closedir(dirp); -} - -======= ->>>>>>> 76168a8... 8202353: os::readdir should use readdir instead of readdir_r // macros for restartable system calls #define RESTARTABLE(_cmd, _result) do { \ -- cgit v1.2.3 From 4e38a81c0fd8f26e292182949985e77d3da80c92 Mon Sep 17 00:00:00 2001 From: thartmann Date: Tue, 30 Apr 2019 14:49:19 +0200 Subject: 8219807: C2 crash in IfNode::up_one_dom(Node*, bool) Summary: Guard against regions degraded to copies. Reviewed-by: kvn --- src/share/vm/opto/ifnode.cpp | 2 +- test/compiler/c2/TestIfWithDeadRegion.java | 57 ++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 test/compiler/c2/TestIfWithDeadRegion.java diff --git a/src/share/vm/opto/ifnode.cpp b/src/share/vm/opto/ifnode.cpp index 3101455e2..68f068d06 100644 --- a/src/share/vm/opto/ifnode.cpp +++ b/src/share/vm/opto/ifnode.cpp @@ -601,7 +601,7 @@ Node* IfNode::up_one_dom(Node *curr, bool linear_only) { if( din4->is_Call() && // Handle a slow-path call on either arm (din4 = din4->in(0)) ) din4 = din4->in(0); - if( din3 == din4 && din3->is_If() ) + if (din3 != NULL && din3 == din4 && din3->is_If()) // Regions not degraded to a copy return din3; // Skip around diamonds } diff --git a/test/compiler/c2/TestIfWithDeadRegion.java b/test/compiler/c2/TestIfWithDeadRegion.java new file mode 100644 index 000000000..1117908e1 --- /dev/null +++ b/test/compiler/c2/TestIfWithDeadRegion.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8219807 + * @summary Test IfNode::up_one_dom() with dead regions. + * @compile -XDstringConcat=inline TestIfWithDeadRegion.java + * @run main/othervm -XX:CompileCommand=compileonly,compiler.c2.TestIfWithDeadRegion::test + * compiler.c2.TestIfWithDeadRegion + */ + +package compiler.c2; + +import java.util.function.Supplier; + +public class TestIfWithDeadRegion { + + static String msg; + + static String getString(String s, int i) { + String current = s + String.valueOf(i); + System.nanoTime(); + return current; + } + + static void test(Supplier supplier) { + msg = supplier.get(); + } + + public static void main(String[] args) { + for (int i = 0; i < 20_000; ++i) { + test(() -> getString("Test1", 42)); + test(() -> getString("Test2", 42)); + } + } +} -- cgit v1.2.3 From 8b6c6c44ffecc0da439b9364b17556d6361a492f Mon Sep 17 00:00:00 2001 From: ogatak Date: Tue, 18 Jun 2019 09:33:34 -0400 Subject: 8185979: PPC64: Implement SHA2 intrinsic Reviewed-by: mdoerr, goetz Contributed-by: Bruno Rosa , Gustavo Serra Scalet , Igor Nunes , Martin Doerr --- src/cpu/ppc/vm/assembler_ppc.hpp | 7 +- src/cpu/ppc/vm/assembler_ppc.inline.hpp | 19 +- src/cpu/ppc/vm/macroAssembler_ppc.hpp | 34 + src/cpu/ppc/vm/macroAssembler_ppc_sha.cpp | 1136 ++++++++++++++++++++ src/cpu/ppc/vm/stubGenerator_ppc.cpp | 31 + src/cpu/ppc/vm/stubRoutines_ppc_64.hpp | 2 +- src/cpu/ppc/vm/vm_version_ppc.cpp | 41 +- src/cpu/ppc/vm/vm_version_ppc.hpp | 3 + src/share/vm/opto/library_call.cpp | 18 +- src/share/vm/opto/runtime.cpp | 22 +- .../cli/testcases/GenericTestCaseForOtherCPU.java | 3 +- .../sha/predicate/IntrinsicPredicates.java | 16 +- 12 files changed, 1308 insertions(+), 24 deletions(-) create mode 100644 src/cpu/ppc/vm/macroAssembler_ppc_sha.cpp diff --git a/src/cpu/ppc/vm/assembler_ppc.hpp b/src/cpu/ppc/vm/assembler_ppc.hpp index b14f2b6d0..16884ca51 100644 --- a/src/cpu/ppc/vm/assembler_ppc.hpp +++ b/src/cpu/ppc/vm/assembler_ppc.hpp @@ -2000,7 +2000,8 @@ class Assembler : public AbstractAssembler { inline void vsbox( VectorRegister d, VectorRegister a); // SHA (introduced with Power 8) - // Not yet implemented. + inline void vshasigmad(VectorRegister d, VectorRegister a, bool st, int six); + inline void vshasigmaw(VectorRegister d, VectorRegister a, bool st, int six); // Vector Binary Polynomial Multiplication (introduced with Power 8) inline void vpmsumb( VectorRegister d, VectorRegister a, VectorRegister b); @@ -2096,6 +2097,10 @@ class Assembler : public AbstractAssembler { inline void lvsl( VectorRegister d, Register s2); inline void lvsr( VectorRegister d, Register s2); + // Endianess specific concatenation of 2 loaded vectors. + inline void load_perm(VectorRegister perm, Register addr); + inline void vec_perm(VectorRegister first_dest, VectorRegister second, VectorRegister perm); + // RegisterOrConstant versions. // These emitters choose between the versions using two registers and // those with register and immediate, depending on the content of roc. diff --git a/src/cpu/ppc/vm/assembler_ppc.inline.hpp b/src/cpu/ppc/vm/assembler_ppc.inline.hpp index 1d2c05e2a..badeecf77 100644 --- a/src/cpu/ppc/vm/assembler_ppc.inline.hpp +++ b/src/cpu/ppc/vm/assembler_ppc.inline.hpp @@ -789,7 +789,8 @@ inline void Assembler::vncipherlast(VectorRegister d, VectorRegister a, VectorRe inline void Assembler::vsbox( VectorRegister d, VectorRegister a) { emit_int32( VSBOX_OPCODE | vrt(d) | vra(a) ); } // SHA (introduced with Power 8) -// Not yet implemented. +inline void Assembler::vshasigmad(VectorRegister d, VectorRegister a, bool st, int six) { emit_int32( VSHASIGMAD_OPCODE | vrt(d) | vra(a) | vst(st) | vsix(six)); } +inline void Assembler::vshasigmaw(VectorRegister d, VectorRegister a, bool st, int six) { emit_int32( VSHASIGMAW_OPCODE | vrt(d) | vra(a) | vst(st) | vsix(six)); } // Vector Binary Polynomial Multiplication (introduced with Power 8) inline void Assembler::vpmsumb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMB_OPCODE | vrt(d) | vra(a) | vrb(b)); } @@ -887,6 +888,22 @@ inline void Assembler::stvxl( VectorRegister d, Register s2) { emit_int32( STVXL inline void Assembler::lvsl( VectorRegister d, Register s2) { emit_int32( LVSL_OPCODE | vrt(d) | rb(s2)); } inline void Assembler::lvsr( VectorRegister d, Register s2) { emit_int32( LVSR_OPCODE | vrt(d) | rb(s2)); } +inline void Assembler::load_perm(VectorRegister perm, Register addr) { +#if defined(VM_LITTLE_ENDIAN) + lvsr(perm, addr); +#else + lvsl(perm, addr); +#endif +} + +inline void Assembler::vec_perm(VectorRegister first_dest, VectorRegister second, VectorRegister perm) { +#if defined(VM_LITTLE_ENDIAN) + vperm(first_dest, second, first_dest, perm); +#else + vperm(first_dest, first_dest, second, perm); +#endif +} + inline void Assembler::load_const(Register d, void* x, Register tmp) { load_const(d, (long)x, tmp); } diff --git a/src/cpu/ppc/vm/macroAssembler_ppc.hpp b/src/cpu/ppc/vm/macroAssembler_ppc.hpp index 3c6cea51b..afcec9a47 100644 --- a/src/cpu/ppc/vm/macroAssembler_ppc.hpp +++ b/src/cpu/ppc/vm/macroAssembler_ppc.hpp @@ -667,6 +667,40 @@ class MacroAssembler: public Assembler { void kernel_crc32_singleByte(Register crc, Register buf, Register len, Register table, Register tmp); + // SHA-2 auxiliary functions and public interfaces + private: + void sha256_deque(const VectorRegister src, + const VectorRegister dst1, const VectorRegister dst2, const VectorRegister dst3); + void sha256_load_h_vec(const VectorRegister a, const VectorRegister e, const Register hptr); + void sha256_round(const VectorRegister* hs, const int total_hs, int& h_cnt, const VectorRegister kpw); + void sha256_load_w_plus_k_vec(const Register buf_in, const VectorRegister* ws, + const int total_ws, const Register k, const VectorRegister* kpws, + const int total_kpws); + void sha256_calc_4w(const VectorRegister w0, const VectorRegister w1, + const VectorRegister w2, const VectorRegister w3, const VectorRegister kpw0, + const VectorRegister kpw1, const VectorRegister kpw2, const VectorRegister kpw3, + const Register j, const Register k); + void sha256_update_sha_state(const VectorRegister a, const VectorRegister b, + const VectorRegister c, const VectorRegister d, const VectorRegister e, + const VectorRegister f, const VectorRegister g, const VectorRegister h, + const Register hptr); + + void sha512_load_w_vec(const Register buf_in, const VectorRegister* ws, const int total_ws); + void sha512_update_sha_state(const Register state, const VectorRegister* hs, const int total_hs); + void sha512_round(const VectorRegister* hs, const int total_hs, int& h_cnt, const VectorRegister kpw); + void sha512_load_h_vec(const Register state, const VectorRegister* hs, const int total_hs); + void sha512_calc_2w(const VectorRegister w0, const VectorRegister w1, + const VectorRegister w2, const VectorRegister w3, + const VectorRegister w4, const VectorRegister w5, + const VectorRegister w6, const VectorRegister w7, + const VectorRegister kpw0, const VectorRegister kpw1, const Register j, + const VectorRegister vRb, const Register k); + + public: + void sha256(bool multi_block); + void sha512(bool multi_block); + + // // Debugging // diff --git a/src/cpu/ppc/vm/macroAssembler_ppc_sha.cpp b/src/cpu/ppc/vm/macroAssembler_ppc_sha.cpp new file mode 100644 index 000000000..7a82ed3f9 --- /dev/null +++ b/src/cpu/ppc/vm/macroAssembler_ppc_sha.cpp @@ -0,0 +1,1136 @@ +// Copyright (c) 2017 Instituto de Pesquisas Eldorado. All rights reserved. +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +// +// This code is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License version 2 only, as +// published by the Free Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// version 2 for more details (a copy is included in the LICENSE file that +// accompanied this code). +// +// You should have received a copy of the GNU General Public License version +// 2 along with this work; if not, write to the Free Software Foundation, +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +// or visit www.oracle.com if you need additional information or have any +// questions. + +// Implemented according to "Descriptions of SHA-256, SHA-384, and SHA-512" +// (http://www.iwar.org.uk/comsec/resources/cipher/sha256-384-512.pdf). + +#include "asm/macroAssembler.inline.hpp" +#include "runtime/stubRoutines.hpp" + +/********************************************************************** + * SHA 256 + *********************************************************************/ + +void MacroAssembler::sha256_deque(const VectorRegister src, + const VectorRegister dst1, + const VectorRegister dst2, + const VectorRegister dst3) { + vsldoi (dst1, src, src, 12); + vsldoi (dst2, src, src, 8); + vsldoi (dst3, src, src, 4); +} + +void MacroAssembler::sha256_round(const VectorRegister* hs, + const int total_hs, + int& h_cnt, + const VectorRegister kpw) { + // convenience registers: cycle from 0-7 downwards + const VectorRegister a = hs[(total_hs + 0 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister b = hs[(total_hs + 1 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister c = hs[(total_hs + 2 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister d = hs[(total_hs + 3 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister e = hs[(total_hs + 4 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister f = hs[(total_hs + 5 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister g = hs[(total_hs + 6 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister h = hs[(total_hs + 7 - (h_cnt % total_hs)) % total_hs]; + // temporaries + VectorRegister ch = VR0; + VectorRegister maj = VR1; + VectorRegister bsa = VR2; + VectorRegister bse = VR3; + VectorRegister vt0 = VR4; + VectorRegister vt1 = VR5; + VectorRegister vt2 = VR6; + VectorRegister vt3 = VR7; + + vsel (ch, g, f, e); + vxor (maj, a, b); + vshasigmaw (bse, e, 1, 0xf); + vadduwm (vt2, ch, kpw); + vadduwm (vt1, h, bse); + vsel (maj, b, c, maj); + vadduwm (vt3, vt1, vt2); + vshasigmaw (bsa, a, 1, 0); + vadduwm (vt0, bsa, maj); + + vadduwm (d, d, vt3); + vadduwm (h, vt3, vt0); + + // advance vector pointer to the next iteration + h_cnt++; +} + +void MacroAssembler::sha256_load_h_vec(const VectorRegister a, + const VectorRegister e, + const Register hptr) { + // temporaries + Register tmp = R8; + VectorRegister vt0 = VR0; + VectorRegister vRb = VR6; + // labels + Label sha256_aligned; + + andi_ (tmp, hptr, 0xf); + lvx (a, hptr); + addi (tmp, hptr, 16); + lvx (e, tmp); + beq (CCR0, sha256_aligned); + + // handle unaligned accesses + load_perm(vRb, hptr); + addi (tmp, hptr, 32); + vec_perm(a, e, vRb); + + lvx (vt0, tmp); + vec_perm(e, vt0, vRb); + + // aligned accesses + bind(sha256_aligned); +} + +void MacroAssembler::sha256_load_w_plus_k_vec(const Register buf_in, + const VectorRegister* ws, + const int total_ws, + const Register k, + const VectorRegister* kpws, + const int total_kpws) { + Label w_aligned, after_w_load; + + Register tmp = R8; + VectorRegister vt0 = VR0; + VectorRegister vt1 = VR1; + VectorRegister vRb = VR6; + + andi_ (tmp, buf_in, 0xF); + beq (CCR0, w_aligned); // address ends with 0x0, not 0x8 + + // deal with unaligned addresses + lvx (ws[0], buf_in); + load_perm(vRb, buf_in); + + for (int n = 1; n < total_ws; n++) { + VectorRegister w_cur = ws[n]; + VectorRegister w_prev = ws[n-1]; + + addi (tmp, buf_in, n * 16); + lvx (w_cur, tmp); + vec_perm(w_prev, w_cur, vRb); + } + addi (tmp, buf_in, total_ws * 16); + lvx (vt0, tmp); + vec_perm(ws[total_ws-1], vt0, vRb); + b (after_w_load); + + bind(w_aligned); + + // deal with aligned addresses + lvx(ws[0], buf_in); + for (int n = 1; n < total_ws; n++) { + VectorRegister w = ws[n]; + addi (tmp, buf_in, n * 16); + lvx (w, tmp); + } + + bind(after_w_load); + +#if defined(VM_LITTLE_ENDIAN) + // Byte swapping within int values + li (tmp, 8); + lvsl (vt0, tmp); + vspltisb (vt1, 0xb); + vxor (vt1, vt0, vt1); + for (int n = 0; n < total_ws; n++) { + VectorRegister w = ws[n]; + vec_perm(w, w, vt1); + } +#endif + + // Loading k, which is always aligned to 16-bytes + lvx (kpws[0], k); + for (int n = 1; n < total_kpws; n++) { + VectorRegister kpw = kpws[n]; + addi (tmp, k, 16 * n); + lvx (kpw, tmp); + } + + // Add w to K + assert(total_ws == total_kpws, "Redesign the loop below"); + for (int n = 0; n < total_kpws; n++) { + VectorRegister kpw = kpws[n]; + VectorRegister w = ws[n]; + + vadduwm (kpw, kpw, w); + } +} + +void MacroAssembler::sha256_calc_4w(const VectorRegister w0, + const VectorRegister w1, + const VectorRegister w2, + const VectorRegister w3, + const VectorRegister kpw0, + const VectorRegister kpw1, + const VectorRegister kpw2, + const VectorRegister kpw3, + const Register j, + const Register k) { + // Temporaries + const VectorRegister vt0 = VR0; + const VectorRegister vt1 = VR1; + const VectorSRegister vsrt1 = vt1->to_vsr(); + const VectorRegister vt2 = VR2; + const VectorRegister vt3 = VR3; + const VectorSRegister vst3 = vt3->to_vsr(); + const VectorRegister vt4 = VR4; + + // load to k[j] + lvx (vt0, j, k); + + // advance j + addi (j, j, 16); // 16 bytes were read + +#if defined(VM_LITTLE_ENDIAN) + // b = w[j-15], w[j-14], w[j-13], w[j-12] + vsldoi (vt1, w1, w0, 12); + + // c = w[j-7], w[j-6], w[j-5], w[j-4] + vsldoi (vt2, w3, w2, 12); + +#else + // b = w[j-15], w[j-14], w[j-13], w[j-12] + vsldoi (vt1, w0, w1, 4); + + // c = w[j-7], w[j-6], w[j-5], w[j-4] + vsldoi (vt2, w2, w3, 4); +#endif + + // d = w[j-2], w[j-1], w[j-4], w[j-3] + vsldoi (vt3, w3, w3, 8); + + // b = s0(w[j-15]) , s0(w[j-14]) , s0(w[j-13]) , s0(w[j-12]) + vshasigmaw (vt1, vt1, 0, 0); + + // d = s1(w[j-2]) , s1(w[j-1]) , s1(w[j-4]) , s1(w[j-3]) + vshasigmaw (vt3, vt3, 0, 0xf); + + // c = s0(w[j-15]) + w[j-7], + // s0(w[j-14]) + w[j-6], + // s0(w[j-13]) + w[j-5], + // s0(w[j-12]) + w[j-4] + vadduwm (vt2, vt1, vt2); + + // c = s0(w[j-15]) + w[j-7] + w[j-16], + // s0(w[j-14]) + w[j-6] + w[j-15], + // s0(w[j-13]) + w[j-5] + w[j-14], + // s0(w[j-12]) + w[j-4] + w[j-13] + vadduwm (vt2, vt2, w0); + + // e = s0(w[j-15]) + w[j-7] + w[j-16] + s1(w[j-2]), // w[j] + // s0(w[j-14]) + w[j-6] + w[j-15] + s1(w[j-1]), // w[j+1] + // s0(w[j-13]) + w[j-5] + w[j-14] + s1(w[j-4]), // UNDEFINED + // s0(w[j-12]) + w[j-4] + w[j-13] + s1(w[j-3]) // UNDEFINED + vadduwm (vt4, vt2, vt3); + + // At this point, e[0] and e[1] are the correct values to be stored at w[j] + // and w[j+1]. + // e[2] and e[3] are not considered. + // b = s1(w[j]) , s1(s(w[j+1]) , UNDEFINED , UNDEFINED + vshasigmaw (vt1, vt4, 0, 0xf); + + // v5 = s1(w[j-2]) , s1(w[j-1]) , s1(w[j]) , s1(w[j+1]) +#if defined(VM_LITTLE_ENDIAN) + xxmrgld (vst3, vsrt1, vst3); +#else + xxmrghd (vst3, vst3, vsrt1); +#endif + + // c = s0(w[j-15]) + w[j-7] + w[j-16] + s1(w[j-2]), // w[j] + // s0(w[j-14]) + w[j-6] + w[j-15] + s1(w[j-1]), // w[j+1] + // s0(w[j-13]) + w[j-5] + w[j-14] + s1(w[j]), // w[j+2] + // s0(w[j-12]) + w[j-4] + w[j-13] + s1(w[j+1]) // w[j+4] + vadduwm (vt2, vt2, vt3); + + // Updating w0 to w3 to hold the new previous 16 values from w. + vmr (w0, w1); + vmr (w1, w2); + vmr (w2, w3); + vmr (w3, vt2); + + // store k + w to v9 (4 values at once) +#if defined(VM_LITTLE_ENDIAN) + vadduwm (kpw0, vt2, vt0); + + vsldoi (kpw1, kpw0, kpw0, 12); + vsldoi (kpw2, kpw0, kpw0, 8); + vsldoi (kpw3, kpw0, kpw0, 4); +#else + vadduwm (kpw3, vt2, vt0); + + vsldoi (kpw2, kpw3, kpw3, 12); + vsldoi (kpw1, kpw3, kpw3, 8); + vsldoi (kpw0, kpw3, kpw3, 4); +#endif +} + +void MacroAssembler::sha256_update_sha_state(const VectorRegister a, + const VectorRegister b_, + const VectorRegister c, + const VectorRegister d, + const VectorRegister e, + const VectorRegister f, + const VectorRegister g, + const VectorRegister h, + const Register hptr) { + // temporaries + VectorRegister vt0 = VR0; + VectorRegister vt1 = VR1; + VectorRegister vt2 = VR2; + VectorRegister vt3 = VR3; + VectorRegister vt4 = VR4; + VectorRegister vt5 = VR5; + VectorRegister vaux = VR6; + VectorRegister vRb = VR6; + Register tmp = R8; + Register of16 = R8; + Register of32 = R9; + Label state_load_aligned; + + // Load hptr + andi_ (tmp, hptr, 0xf); + li (of16, 16); + lvx (vt0, hptr); + lvx (vt5, of16, hptr); + beq (CCR0, state_load_aligned); + + // handle unaligned accesses + li (of32, 32); + load_perm(vRb, hptr); + + vec_perm(vt0, vt5, vRb); // vt0 = hptr[0]..hptr[3] + + lvx (vt1, hptr, of32); + vec_perm(vt5, vt1, vRb); // vt5 = hptr[4]..hptr[7] + + // aligned accesses + bind(state_load_aligned); + +#if defined(VM_LITTLE_ENDIAN) + vmrglw (vt1, b_, a); // vt1 = {a, b, ?, ?} + vmrglw (vt2, d, c); // vt2 = {c, d, ?, ?} + vmrglw (vt3, f, e); // vt3 = {e, f, ?, ?} + vmrglw (vt4, h, g); // vt4 = {g, h, ?, ?} + xxmrgld (vt1->to_vsr(), vt2->to_vsr(), vt1->to_vsr()); // vt1 = {a, b, c, d} + xxmrgld (vt3->to_vsr(), vt4->to_vsr(), vt3->to_vsr()); // vt3 = {e, f, g, h} + vadduwm (a, vt0, vt1); // a = {a+hptr[0], b+hptr[1], c+hptr[2], d+hptr[3]} + vadduwm (e, vt5, vt3); // e = {e+hptr[4], f+hptr[5], g+hptr[6], h+hptr[7]} + + // Save hptr back, works for any alignment + xxswapd (vt0->to_vsr(), a->to_vsr()); + stxvd2x (vt0->to_vsr(), hptr); + xxswapd (vt5->to_vsr(), e->to_vsr()); + stxvd2x (vt5->to_vsr(), of16, hptr); +#else + vmrglw (vt1, a, b_); // vt1 = {a, b, ?, ?} + vmrglw (vt2, c, d); // vt2 = {c, d, ?, ?} + vmrglw (vt3, e, f); // vt3 = {e, f, ?, ?} + vmrglw (vt4, g, h); // vt4 = {g, h, ?, ?} + xxmrgld (vt1->to_vsr(), vt1->to_vsr(), vt2->to_vsr()); // vt1 = {a, b, c, d} + xxmrgld (vt3->to_vsr(), vt3->to_vsr(), vt4->to_vsr()); // vt3 = {e, f, g, h} + vadduwm (d, vt0, vt1); // d = {a+hptr[0], b+hptr[1], c+hptr[2], d+hptr[3]} + vadduwm (h, vt5, vt3); // h = {e+hptr[4], f+hptr[5], g+hptr[6], h+hptr[7]} + + // Save hptr back, works for any alignment + stxvd2x (d->to_vsr(), hptr); + stxvd2x (h->to_vsr(), of16, hptr); +#endif +} + +static const uint32_t sha256_round_table[64] __attribute((aligned(16))) = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, +}; +static const uint32_t *sha256_round_consts = sha256_round_table; + +// R3_ARG1 - byte[] Input string with padding but in Big Endian +// R4_ARG2 - int[] SHA.state (at first, the root of primes) +// R5_ARG3 - int offset +// R6_ARG4 - int limit +// +// Internal Register usage: +// R7 - k +// R8 - tmp | j | of16 +// R9 - of32 +// VR0-VR8 - ch, maj, bsa, bse, vt0-vt3 | vt0-vt5, vaux/vRb +// VR9-VR16 - a-h +// VR17-VR20 - w0-w3 +// VR21-VR23 - vRb | vaux0-vaux2 +// VR24-VR27 - kpw0-kpw3 +void MacroAssembler::sha256(bool multi_block) { + static const ssize_t buf_size = 64; + static const uint8_t w_size = sizeof(sha256_round_table)/sizeof(uint32_t); +#ifdef AIX + // malloc provides 16 byte alignment + if (((uintptr_t)sha256_round_consts & 0xF) != 0) { + uint32_t *new_round_consts = (uint32_t*)malloc(sizeof(sha256_round_table)); + guarantee(new_round_consts, "oom"); + memcpy(new_round_consts, sha256_round_consts, sizeof(sha256_round_table)); + sha256_round_consts = (const uint32_t*)new_round_consts; + } +#endif + + Register buf_in = R3_ARG1; + Register state = R4_ARG2; + Register ofs = R5_ARG3; + Register limit = R6_ARG4; + + Label sha_loop, core_loop; + + // Save non-volatile vector registers in the red zone + static const VectorRegister nv[] = { + VR20, VR21, VR22, VR23, VR24, VR25, VR26, VR27/*, VR28, VR29, VR30, VR31*/ + }; + static const uint8_t nv_size = sizeof(nv) / sizeof (VectorRegister); + + for (int c = 0; c < nv_size; c++) { + Register tmp = R8; + li (tmp, (c - (nv_size)) * 16); + stvx(nv[c], tmp, R1); + } + + // Load hash state to registers + VectorRegister a = VR9; + VectorRegister b = VR10; + VectorRegister c = VR11; + VectorRegister d = VR12; + VectorRegister e = VR13; + VectorRegister f = VR14; + VectorRegister g = VR15; + VectorRegister h = VR16; + static const VectorRegister hs[] = {a, b, c, d, e, f, g, h}; + static const int total_hs = sizeof(hs)/sizeof(VectorRegister); + // counter for cycling through hs vector to avoid register moves between iterations + int h_cnt = 0; + + // Load a-h registers from the memory pointed by state +#if defined(VM_LITTLE_ENDIAN) + sha256_load_h_vec(a, e, state); +#else + sha256_load_h_vec(d, h, state); +#endif + + // keep k loaded also during MultiBlock loops + Register k = R7; + assert(((uintptr_t)sha256_round_consts & 0xF) == 0, "k alignment"); + load_const_optimized(k, (address)sha256_round_consts, R0); + + // Avoiding redundant loads + if (multi_block) { + align(OptoLoopAlignment); + } + bind(sha_loop); +#if defined(VM_LITTLE_ENDIAN) + sha256_deque(a, b, c, d); + sha256_deque(e, f, g, h); +#else + sha256_deque(d, c, b, a); + sha256_deque(h, g, f, e); +#endif + + // Load 16 elements from w out of the loop. + // Order of the int values is Endianess specific. + VectorRegister w0 = VR17; + VectorRegister w1 = VR18; + VectorRegister w2 = VR19; + VectorRegister w3 = VR20; + static const VectorRegister ws[] = {w0, w1, w2, w3}; + static const int total_ws = sizeof(ws)/sizeof(VectorRegister); + + VectorRegister kpw0 = VR24; + VectorRegister kpw1 = VR25; + VectorRegister kpw2 = VR26; + VectorRegister kpw3 = VR27; + static const VectorRegister kpws[] = {kpw0, kpw1, kpw2, kpw3}; + static const int total_kpws = sizeof(kpws)/sizeof(VectorRegister); + + sha256_load_w_plus_k_vec(buf_in, ws, total_ws, k, kpws, total_kpws); + + // Cycle through the first 16 elements + assert(total_ws == total_kpws, "Redesign the loop below"); + for (int n = 0; n < total_ws; n++) { + VectorRegister vaux0 = VR21; + VectorRegister vaux1 = VR22; + VectorRegister vaux2 = VR23; + + sha256_deque(kpws[n], vaux0, vaux1, vaux2); + +#if defined(VM_LITTLE_ENDIAN) + sha256_round(hs, total_hs, h_cnt, kpws[n]); + sha256_round(hs, total_hs, h_cnt, vaux0); + sha256_round(hs, total_hs, h_cnt, vaux1); + sha256_round(hs, total_hs, h_cnt, vaux2); +#else + sha256_round(hs, total_hs, h_cnt, vaux2); + sha256_round(hs, total_hs, h_cnt, vaux1); + sha256_round(hs, total_hs, h_cnt, vaux0); + sha256_round(hs, total_hs, h_cnt, kpws[n]); +#endif + } + + Register tmp = R8; + // loop the 16th to the 64th iteration by 8 steps + li (tmp, (w_size - 16) / total_hs); + mtctr(tmp); + + // j will be aligned to 4 for loading words. + // Whenever read, advance the pointer (e.g: when j is used in a function) + Register j = R8; + li (j, 16*4); + + align(OptoLoopAlignment); + bind(core_loop); + + // due to VectorRegister rotate, always iterate in multiples of total_hs + for (int n = 0; n < total_hs/4; n++) { + sha256_calc_4w(w0, w1, w2, w3, kpw0, kpw1, kpw2, kpw3, j, k); + sha256_round(hs, total_hs, h_cnt, kpw0); + sha256_round(hs, total_hs, h_cnt, kpw1); + sha256_round(hs, total_hs, h_cnt, kpw2); + sha256_round(hs, total_hs, h_cnt, kpw3); + } + + bdnz (core_loop); + + // Update hash state + sha256_update_sha_state(a, b, c, d, e, f, g, h, state); + + if (multi_block) { + addi(buf_in, buf_in, buf_size); + addi(ofs, ofs, buf_size); + cmplw(CCR0, ofs, limit); + ble(CCR0, sha_loop); + + // return ofs + mr(R3_RET, ofs); + } + + // Restore non-volatile registers + for (int c = 0; c < nv_size; c++) { + Register tmp = R8; + li (tmp, (c - (nv_size)) * 16); + lvx(nv[c], tmp, R1); + } +} + + +/********************************************************************** + * SHA 512 + *********************************************************************/ + +void MacroAssembler::sha512_load_w_vec(const Register buf_in, + const VectorRegister* ws, + const int total_ws) { + Register tmp = R8; + VectorRegister vRb = VR8; + VectorRegister aux = VR9; + Label is_aligned, after_alignment; + + andi_ (tmp, buf_in, 0xF); + beq (CCR0, is_aligned); // address ends with 0x0, not 0x8 + + // deal with unaligned addresses + lvx (ws[0], buf_in); + load_perm(vRb, buf_in); + + for (int n = 1; n < total_ws; n++) { + VectorRegister w_cur = ws[n]; + VectorRegister w_prev = ws[n-1]; + addi (tmp, buf_in, n * 16); + lvx (w_cur, tmp); + vec_perm(w_prev, w_cur, vRb); + } + addi (tmp, buf_in, total_ws * 16); + lvx (aux, tmp); + vec_perm(ws[total_ws-1], aux, vRb); + b (after_alignment); + + bind(is_aligned); + lvx (ws[0], buf_in); + for (int n = 1; n < total_ws; n++) { + VectorRegister w = ws[n]; + addi (tmp, buf_in, n * 16); + lvx (w, tmp); + } + + bind(after_alignment); +} + +// Update hash state +void MacroAssembler::sha512_update_sha_state(const Register state, + const VectorRegister* hs, + const int total_hs) { + +#if defined(VM_LITTLE_ENDIAN) + int start_idx = 0; +#else + int start_idx = 1; +#endif + + // load initial hash from the memory pointed by state + VectorRegister ini_a = VR10; + VectorRegister ini_c = VR12; + VectorRegister ini_e = VR14; + VectorRegister ini_g = VR16; + static const VectorRegister inis[] = {ini_a, ini_c, ini_e, ini_g}; + static const int total_inis = sizeof(inis)/sizeof(VectorRegister); + + Label state_save_aligned, after_state_save_aligned; + + Register addr = R7; + Register tmp = R8; + VectorRegister vRb = VR8; + VectorRegister aux = VR9; + + andi_(tmp, state, 0xf); + beq(CCR0, state_save_aligned); + // deal with unaligned addresses + + { + VectorRegister a = hs[0]; + VectorRegister b_ = hs[1]; + VectorRegister c = hs[2]; + VectorRegister d = hs[3]; + VectorRegister e = hs[4]; + VectorRegister f = hs[5]; + VectorRegister g = hs[6]; + VectorRegister h = hs[7]; + load_perm(vRb, state); + lvx (ini_a, state); + addi (addr, state, 16); + + lvx (ini_c, addr); + addi (addr, state, 32); + vec_perm(ini_a, ini_c, vRb); + + lvx (ini_e, addr); + addi (addr, state, 48); + vec_perm(ini_c, ini_e, vRb); + + lvx (ini_g, addr); + addi (addr, state, 64); + vec_perm(ini_e, ini_g, vRb); + + lvx (aux, addr); + vec_perm(ini_g, aux, vRb); + +#if defined(VM_LITTLE_ENDIAN) + xxmrgld(a->to_vsr(), b_->to_vsr(), a->to_vsr()); + xxmrgld(c->to_vsr(), d->to_vsr(), c->to_vsr()); + xxmrgld(e->to_vsr(), f->to_vsr(), e->to_vsr()); + xxmrgld(g->to_vsr(), h->to_vsr(), g->to_vsr()); +#else + xxmrgld(b_->to_vsr(), a->to_vsr(), b_->to_vsr()); + xxmrgld(d->to_vsr(), c->to_vsr(), d->to_vsr()); + xxmrgld(f->to_vsr(), e->to_vsr(), f->to_vsr()); + xxmrgld(h->to_vsr(), g->to_vsr(), h->to_vsr()); +#endif + + for (int n = start_idx; n < total_hs; n += 2) { + VectorRegister h_cur = hs[n]; + VectorRegister ini_cur = inis[n/2]; + + vaddudm(h_cur, ini_cur, h_cur); + } + + for (int n = start_idx; n < total_hs; n += 2) { + VectorRegister h_cur = hs[n]; + + mfvrd (tmp, h_cur); +#if defined(VM_LITTLE_ENDIAN) + std (tmp, 8*n + 8, state); +#else + std (tmp, 8*n - 8, state); +#endif + vsldoi (aux, h_cur, h_cur, 8); + mfvrd (tmp, aux); + std (tmp, 8*n + 0, state); + } + + b (after_state_save_aligned); + } + + bind(state_save_aligned); + { + for (int n = 0; n < total_hs; n += 2) { +#if defined(VM_LITTLE_ENDIAN) + VectorRegister h_cur = hs[n]; + VectorRegister h_next = hs[n+1]; +#else + VectorRegister h_cur = hs[n+1]; + VectorRegister h_next = hs[n]; +#endif + VectorRegister ini_cur = inis[n/2]; + + if (n/2 == 0) { + lvx(ini_cur, state); + } else { + addi(addr, state, (n/2) * 16); + lvx(ini_cur, addr); + } + xxmrgld(h_cur->to_vsr(), h_next->to_vsr(), h_cur->to_vsr()); + } + + for (int n = start_idx; n < total_hs; n += 2) { + VectorRegister h_cur = hs[n]; + VectorRegister ini_cur = inis[n/2]; + + vaddudm(h_cur, ini_cur, h_cur); + } + + for (int n = start_idx; n < total_hs; n += 2) { + VectorRegister h_cur = hs[n]; + + if (n/2 == 0) { + stvx(h_cur, state); + } else { + addi(addr, state, (n/2) * 16); + stvx(h_cur, addr); + } + } + } + + bind(after_state_save_aligned); +} + +// Use h_cnt to cycle through hs elements but also increment it at the end +void MacroAssembler::sha512_round(const VectorRegister* hs, + const int total_hs, int& h_cnt, + const VectorRegister kpw) { + + // convenience registers: cycle from 0-7 downwards + const VectorRegister a = hs[(total_hs + 0 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister b = hs[(total_hs + 1 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister c = hs[(total_hs + 2 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister d = hs[(total_hs + 3 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister e = hs[(total_hs + 4 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister f = hs[(total_hs + 5 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister g = hs[(total_hs + 6 - (h_cnt % total_hs)) % total_hs]; + const VectorRegister h = hs[(total_hs + 7 - (h_cnt % total_hs)) % total_hs]; + // temporaries + const VectorRegister Ch = VR20; + const VectorRegister Maj = VR21; + const VectorRegister bsa = VR22; + const VectorRegister bse = VR23; + const VectorRegister tmp1 = VR24; + const VectorRegister tmp2 = VR25; + + vsel (Ch, g, f, e); + vxor (Maj, a, b); + vshasigmad(bse, e, 1, 0xf); + vaddudm (tmp2, Ch, kpw); + vaddudm (tmp1, h, bse); + vsel (Maj, b, c, Maj); + vaddudm (tmp1, tmp1, tmp2); + vshasigmad(bsa, a, 1, 0); + vaddudm (tmp2, bsa, Maj); + vaddudm (d, d, tmp1); + vaddudm (h, tmp1, tmp2); + + // advance vector pointer to the next iteration + h_cnt++; +} + +void MacroAssembler::sha512_calc_2w(const VectorRegister w0, + const VectorRegister w1, + const VectorRegister w2, + const VectorRegister w3, + const VectorRegister w4, + const VectorRegister w5, + const VectorRegister w6, + const VectorRegister w7, + const VectorRegister kpw0, + const VectorRegister kpw1, + const Register j, + const VectorRegister vRb, + const Register k) { + // Temporaries + const VectorRegister VR_a = VR20; + const VectorRegister VR_b = VR21; + const VectorRegister VR_c = VR22; + const VectorRegister VR_d = VR23; + + // load to k[j] + lvx (VR_a, j, k); + // advance j + addi (j, j, 16); // 16 bytes were read + +#if defined(VM_LITTLE_ENDIAN) + // v6 = w[j-15], w[j-14] + vperm (VR_b, w1, w0, vRb); + // v12 = w[j-7], w[j-6] + vperm (VR_c, w5, w4, vRb); +#else + // v6 = w[j-15], w[j-14] + vperm (VR_b, w0, w1, vRb); + // v12 = w[j-7], w[j-6] + vperm (VR_c, w4, w5, vRb); +#endif + + // v6 = s0(w[j-15]) , s0(w[j-14]) + vshasigmad (VR_b, VR_b, 0, 0); + // v5 = s1(w[j-2]) , s1(w[j-1]) + vshasigmad (VR_d, w7, 0, 0xf); + // v6 = s0(w[j-15]) + w[j-7] , s0(w[j-14]) + w[j-6] + vaddudm (VR_b, VR_b, VR_c); + // v8 = s1(w[j-2]) + w[j-16] , s1(w[j-1]) + w[j-15] + vaddudm (VR_d, VR_d, w0); + // v9 = s0(w[j-15]) + w[j-7] + w[j-16] + s1(w[j-2]), // w[j] + // s0(w[j-14]) + w[j-6] + w[j-15] + s1(w[j-1]), // w[j+1] + vaddudm (VR_c, VR_d, VR_b); + // Updating w0 to w7 to hold the new previous 16 values from w. + vmr (w0, w1); + vmr (w1, w2); + vmr (w2, w3); + vmr (w3, w4); + vmr (w4, w5); + vmr (w5, w6); + vmr (w6, w7); + vmr (w7, VR_c); + +#if defined(VM_LITTLE_ENDIAN) + // store k + w to kpw0 (2 values at once) + vaddudm (kpw0, VR_c, VR_a); + // kpw1 holds (k + w)[1] + vsldoi (kpw1, kpw0, kpw0, 8); +#else + // store k + w to kpw0 (2 values at once) + vaddudm (kpw1, VR_c, VR_a); + // kpw1 holds (k + w)[1] + vsldoi (kpw0, kpw1, kpw1, 8); +#endif +} + +void MacroAssembler::sha512_load_h_vec(const Register state, + const VectorRegister* hs, + const int total_hs) { +#if defined(VM_LITTLE_ENDIAN) + VectorRegister a = hs[0]; + VectorRegister g = hs[6]; + int start_idx = 0; +#else + VectorRegister a = hs[1]; + VectorRegister g = hs[7]; + int start_idx = 1; +#endif + + Register addr = R7; + VectorRegister vRb = VR8; + Register tmp = R8; + Label state_aligned, after_state_aligned; + + andi_(tmp, state, 0xf); + beq(CCR0, state_aligned); + + // deal with unaligned addresses + VectorRegister aux = VR9; + + lvx(hs[start_idx], state); + load_perm(vRb, state); + + for (int n = start_idx + 2; n < total_hs; n += 2) { + VectorRegister h_cur = hs[n]; + VectorRegister h_prev2 = hs[n - 2]; + addi(addr, state, (n/2) * 16); + lvx(h_cur, addr); + vec_perm(h_prev2, h_cur, vRb); + } + addi(addr, state, (total_hs/2) * 16); + lvx (aux, addr); + vec_perm(hs[total_hs - 2 + start_idx], aux, vRb); + b (after_state_aligned); + + bind(state_aligned); + + // deal with aligned addresses + lvx(hs[start_idx], state); + + for (int n = start_idx + 2; n < total_hs; n += 2) { + VectorRegister h_cur = hs[n]; + addi(addr, state, (n/2) * 16); + lvx(h_cur, addr); + } + + bind(after_state_aligned); +} + +static const uint64_t sha512_round_table[80] __attribute((aligned(16))) = { + 0x428a2f98d728ae22, 0x7137449123ef65cd, + 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, + 0x3956c25bf348b538, 0x59f111f1b605d019, + 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, + 0xd807aa98a3030242, 0x12835b0145706fbe, + 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, + 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, + 0x9bdc06a725c71235, 0xc19bf174cf692694, + 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, + 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, + 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, + 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, + 0x983e5152ee66dfab, 0xa831c66d2db43210, + 0xb00327c898fb213f, 0xbf597fc7beef0ee4, + 0xc6e00bf33da88fc2, 0xd5a79147930aa725, + 0x06ca6351e003826f, 0x142929670a0e6e70, + 0x27b70a8546d22ffc, 0x2e1b21385c26c926, + 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, + 0x650a73548baf63de, 0x766a0abb3c77b2a8, + 0x81c2c92e47edaee6, 0x92722c851482353b, + 0xa2bfe8a14cf10364, 0xa81a664bbc423001, + 0xc24b8b70d0f89791, 0xc76c51a30654be30, + 0xd192e819d6ef5218, 0xd69906245565a910, + 0xf40e35855771202a, 0x106aa07032bbd1b8, + 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, + 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, + 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, + 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, + 0x748f82ee5defb2fc, 0x78a5636f43172f60, + 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, + 0xbef9a3f7b2c67915, 0xc67178f2e372532b, + 0xca273eceea26619c, 0xd186b8c721c0c207, + 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, + 0x06f067aa72176fba, 0x0a637dc5a2c898a6, + 0x113f9804bef90dae, 0x1b710b35131c471b, + 0x28db77f523047d84, 0x32caab7b40c72493, + 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, + 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, + 0x5fcb6fab3ad6faec, 0x6c44198c4a475817, +}; +static const uint64_t *sha512_round_consts = sha512_round_table; + +// R3_ARG1 - byte[] Input string with padding but in Big Endian +// R4_ARG2 - int[] SHA.state (at first, the root of primes) +// R5_ARG3 - int offset +// R6_ARG4 - int limit +// +// Internal Register usage: +// R7 R8 R9 - volatile temporaries +// VR0-VR7 - a-h +// VR8 - vRb +// VR9 - aux (highly volatile, use with care) +// VR10-VR17 - w0-w7 | ini_a-ini_h +// VR18 - vsp16 | kplusw0 +// VR19 - vsp32 | kplusw1 +// VR20-VR25 - sha512_calc_2w and sha512_round temporaries +void MacroAssembler::sha512(bool multi_block) { + static const ssize_t buf_size = 128; + static const uint8_t w_size = sizeof(sha512_round_table)/sizeof(uint64_t); +#ifdef AIX + // malloc provides 16 byte alignment + if (((uintptr_t)sha512_round_consts & 0xF) != 0) { + uint64_t *new_round_consts = (uint64_t*)malloc(sizeof(sha512_round_table)); + guarantee(new_round_consts, "oom"); + memcpy(new_round_consts, sha512_round_consts, sizeof(sha512_round_table)); + sha512_round_consts = (const uint64_t*)new_round_consts; + } +#endif + + Register buf_in = R3_ARG1; + Register state = R4_ARG2; + Register ofs = R5_ARG3; + Register limit = R6_ARG4; + + Label sha_loop, core_loop; + + // Save non-volatile vector registers in the red zone + static const VectorRegister nv[] = { + VR20, VR21, VR22, VR23, VR24, VR25/*, VR26, VR27, VR28, VR29, VR30, VR31*/ + }; + static const uint8_t nv_size = sizeof(nv) / sizeof (VectorRegister); + + for (int c = 0; c < nv_size; c++) { + Register idx = R7; + li (idx, (c - (nv_size)) * 16); + stvx(nv[c], idx, R1); + } + + // Load hash state to registers + VectorRegister a = VR0; + VectorRegister b = VR1; + VectorRegister c = VR2; + VectorRegister d = VR3; + VectorRegister e = VR4; + VectorRegister f = VR5; + VectorRegister g = VR6; + VectorRegister h = VR7; + static const VectorRegister hs[] = {a, b, c, d, e, f, g, h}; + static const int total_hs = sizeof(hs)/sizeof(VectorRegister); + // counter for cycling through hs vector to avoid register moves between iterations + int h_cnt = 0; + + // Load a-h registers from the memory pointed by state + sha512_load_h_vec(state, hs, total_hs); + + Register k = R9; + assert(((uintptr_t)sha512_round_consts & 0xF) == 0, "k alignment"); + load_const_optimized(k, (address)sha512_round_consts, R0); + + if (multi_block) { + align(OptoLoopAlignment); + } + bind(sha_loop); + + for (int n = 0; n < total_hs; n += 2) { +#if defined(VM_LITTLE_ENDIAN) + VectorRegister h_cur = hs[n]; + VectorRegister h_next = hs[n + 1]; +#else + VectorRegister h_cur = hs[n + 1]; + VectorRegister h_next = hs[n]; +#endif + vsldoi (h_next, h_cur, h_cur, 8); + } + + // Load 16 elements from w out of the loop. + // Order of the long values is Endianess specific. + VectorRegister w0 = VR10; + VectorRegister w1 = VR11; + VectorRegister w2 = VR12; + VectorRegister w3 = VR13; + VectorRegister w4 = VR14; + VectorRegister w5 = VR15; + VectorRegister w6 = VR16; + VectorRegister w7 = VR17; + static const VectorRegister ws[] = {w0, w1, w2, w3, w4, w5, w6, w7}; + static const int total_ws = sizeof(ws)/sizeof(VectorRegister); + + // Load 16 w into vectors and setup vsl for vperm + sha512_load_w_vec(buf_in, ws, total_ws); + +#if defined(VM_LITTLE_ENDIAN) + VectorRegister vsp16 = VR18; + VectorRegister vsp32 = VR19; + VectorRegister shiftarg = VR9; + + vspltisw(vsp16, 8); + vspltisw(shiftarg, 1); + vsl (vsp16, vsp16, shiftarg); + vsl (vsp32, vsp16, shiftarg); + + VectorRegister vsp8 = VR9; + vspltish(vsp8, 8); + + // Convert input from Big Endian to Little Endian + for (int c = 0; c < total_ws; c++) { + VectorRegister w = ws[c]; + vrlh (w, w, vsp8); + } + for (int c = 0; c < total_ws; c++) { + VectorRegister w = ws[c]; + vrlw (w, w, vsp16); + } + for (int c = 0; c < total_ws; c++) { + VectorRegister w = ws[c]; + vrld (w, w, vsp32); + } +#endif + + Register Rb = R10; + VectorRegister vRb = VR8; + li (Rb, 8); + load_perm(vRb, Rb); + + VectorRegister kplusw0 = VR18; + VectorRegister kplusw1 = VR19; + + Register addr = R7; + + for (int n = 0; n < total_ws; n++) { + VectorRegister w = ws[n]; + + if (n == 0) { + lvx (kplusw0, k); + } else { + addi (addr, k, n * 16); + lvx (kplusw0, addr); + } +#if defined(VM_LITTLE_ENDIAN) + vaddudm(kplusw0, kplusw0, w); + vsldoi (kplusw1, kplusw0, kplusw0, 8); +#else + vaddudm(kplusw1, kplusw0, w); + vsldoi (kplusw0, kplusw1, kplusw1, 8); +#endif + + sha512_round(hs, total_hs, h_cnt, kplusw0); + sha512_round(hs, total_hs, h_cnt, kplusw1); + } + + Register tmp = R8; + li (tmp, (w_size-16)/total_hs); + mtctr (tmp); + // j will be aligned to 4 for loading words. + // Whenever read, advance the pointer (e.g: when j is used in a function) + Register j = tmp; + li (j, 8*16); + + align(OptoLoopAlignment); + bind(core_loop); + + // due to VectorRegister rotate, always iterate in multiples of total_hs + for (int n = 0; n < total_hs/2; n++) { + sha512_calc_2w(w0, w1, w2, w3, w4, w5, w6, w7, kplusw0, kplusw1, j, vRb, k); + sha512_round(hs, total_hs, h_cnt, kplusw0); + sha512_round(hs, total_hs, h_cnt, kplusw1); + } + + bdnz (core_loop); + + sha512_update_sha_state(state, hs, total_hs); + + if (multi_block) { + addi(buf_in, buf_in, buf_size); + addi(ofs, ofs, buf_size); + cmplw(CCR0, ofs, limit); + ble(CCR0, sha_loop); + + // return ofs + mr(R3_RET, ofs); + } + + // Restore non-volatile registers + for (int c = 0; c < nv_size; c++) { + Register idx = R7; + li (idx, (c - (nv_size)) * 16); + lvx(nv[c], idx, R1); + } +} diff --git a/src/cpu/ppc/vm/stubGenerator_ppc.cpp b/src/cpu/ppc/vm/stubGenerator_ppc.cpp index 12dd846ce..12cff00c8 100644 --- a/src/cpu/ppc/vm/stubGenerator_ppc.cpp +++ b/src/cpu/ppc/vm/stubGenerator_ppc.cpp @@ -2652,6 +2652,28 @@ class StubGenerator: public StubCodeGenerator { return start; } + address generate_sha256_implCompress(bool multi_block, const char *name) { + assert(UseSHA, "need SHA instructions"); + StubCodeMark mark(this, "StubRoutines", name); + address start = __ function_entry(); + + __ sha256 (multi_block); + + __ blr(); + return start; + } + + address generate_sha512_implCompress(bool multi_block, const char *name) { + assert(UseSHA, "need SHA instructions"); + StubCodeMark mark(this, "StubRoutines", name); + address start = __ function_entry(); + + __ sha512 (multi_block); + + __ blr(); + return start; + } + void generate_arraycopy_stubs() { // Note: the disjoint stubs must be generated first, some of // the conjoint stubs use them. @@ -2881,6 +2903,15 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_montgomerySquare = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_square); } + + if (UseSHA256Intrinsics) { + StubRoutines::_sha256_implCompress = generate_sha256_implCompress(false, "sha256_implCompress"); + StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true, "sha256_implCompressMB"); + } + if (UseSHA512Intrinsics) { + StubRoutines::_sha512_implCompress = generate_sha512_implCompress(false, "sha512_implCompress"); + StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(true, "sha512_implCompressMB"); + } } public: diff --git a/src/cpu/ppc/vm/stubRoutines_ppc_64.hpp b/src/cpu/ppc/vm/stubRoutines_ppc_64.hpp index 3655c1f78..cf9ebc4e6 100644 --- a/src/cpu/ppc/vm/stubRoutines_ppc_64.hpp +++ b/src/cpu/ppc/vm/stubRoutines_ppc_64.hpp @@ -34,7 +34,7 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _call_ enum platform_dependent_constants { code_size1 = 20000, // simply increase if too small (assembler will crash if too small) - code_size2 = 20000 // simply increase if too small (assembler will crash if too small) + code_size2 = 22000 // simply increase if too small (assembler will crash if too small) }; // CRC32 Intrinsics. diff --git a/src/cpu/ppc/vm/vm_version_ppc.cpp b/src/cpu/ppc/vm/vm_version_ppc.cpp index 6761c02a2..e7fad4843 100644 --- a/src/cpu/ppc/vm/vm_version_ppc.cpp +++ b/src/cpu/ppc/vm/vm_version_ppc.cpp @@ -110,7 +110,7 @@ void VM_Version::initialize() { // Create and print feature-string. char buf[(num_features+1) * 16]; // Max 16 chars per feature. jio_snprintf(buf, sizeof(buf), - "ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s", + "ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s%s", (has_fsqrt() ? " fsqrt" : ""), (has_isel() ? " isel" : ""), (has_lxarxeh() ? " lxarxeh" : ""), @@ -124,7 +124,8 @@ void VM_Version::initialize() { (has_vcipher() ? " aes" : ""), (has_vpmsumb() ? " vpmsumb" : ""), (has_mfdscr() ? " mfdscr" : ""), - (has_vsx() ? " vsx" : "") + (has_vsx() ? " vsx" : ""), + (has_vshasig() ? " sha" : "") // Make sure number of %s matches num_features! ); _features_str = strdup(buf); @@ -206,17 +207,43 @@ void VM_Version::initialize() { } #endif - if (UseSHA) { - warning("SHA instructions are not available on this CPU"); + if (has_vshasig()) { + if (FLAG_IS_DEFAULT(UseSHA)) { + UseSHA = true; + } + } else if (UseSHA) { + if (!FLAG_IS_DEFAULT(UseSHA)) + warning("SHA instructions are not available on this CPU"); FLAG_SET_DEFAULT(UseSHA, false); } - if (UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics) { - warning("SHA intrinsics are not available on this CPU"); + + if (UseSHA1Intrinsics) { + warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU."); FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); + } + + if (UseSHA && has_vshasig()) { + if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) { + FLAG_SET_DEFAULT(UseSHA256Intrinsics, true); + } + } else if (UseSHA256Intrinsics) { + warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU."); FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); + } + + if (UseSHA && has_vshasig()) { + if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) { + FLAG_SET_DEFAULT(UseSHA512Intrinsics, true); + } + } else if (UseSHA512Intrinsics) { + warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU."); FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); } + if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) { + FLAG_SET_DEFAULT(UseSHA, false); + } + if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) { UseMontgomeryMultiplyIntrinsic = true; } @@ -503,6 +530,7 @@ void VM_Version::determine_features() { a->vpmsumb(VR0, VR1, VR2); // code[12] -> vpmsumb a->mfdscr(R0); // code[13] -> mfdscr a->lxvd2x(VSR0, R3_ARG1); // code[14] -> vsx + a->vshasigmaw(VR0, VR1, 1, 0xF); // code[15] -> vshasig a->blr(); // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it. @@ -551,6 +579,7 @@ void VM_Version::determine_features() { if (code[feature_cntr++]) features |= vpmsumb_m; if (code[feature_cntr++]) features |= mfdscr_m; if (code[feature_cntr++]) features |= vsx_m; + if (code[feature_cntr++]) features |= vshasig_m; // Print the detection code. if (PrintAssembly) { diff --git a/src/cpu/ppc/vm/vm_version_ppc.hpp b/src/cpu/ppc/vm/vm_version_ppc.hpp index 6245e1c64..86243a1a8 100644 --- a/src/cpu/ppc/vm/vm_version_ppc.hpp +++ b/src/cpu/ppc/vm/vm_version_ppc.hpp @@ -47,6 +47,7 @@ protected: vpmsumb, mfdscr, vsx, + vshasig, num_features // last entry to count features }; enum Feature_Flag_Set { @@ -63,6 +64,7 @@ protected: dcba_m = (1 << dcba ), lqarx_m = (1 << lqarx ), vcipher_m = (1 << vcipher), + vshasig_m = (1 << vshasig), vpmsumb_m = (1 << vpmsumb), mfdscr_m = (1 << mfdscr ), vsx_m = (1 << vsx ), @@ -99,6 +101,7 @@ public: static bool has_vpmsumb() { return (_features & vpmsumb_m) != 0; } static bool has_mfdscr() { return (_features & mfdscr_m) != 0; } static bool has_vsx() { return (_features & vsx_m) != 0; } + static bool has_vshasig() { return (_features & vshasig_m) != 0; } static const char* cpu_features() { return _features_str; } diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp index 5f2bb3084..db36fb349 100644 --- a/src/share/vm/opto/library_call.cpp +++ b/src/share/vm/opto/library_call.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -6759,10 +6759,18 @@ bool LibraryCallKit::inline_sha_implCompressMB(Node* digestBase_obj, ciInstanceK if (state == NULL) return false; // Call the stub. - Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, - OptoRuntime::digestBase_implCompressMB_Type(), - stubAddr, stubName, TypePtr::BOTTOM, - src_start, state, ofs, limit); + Node *call; + if (CCallingConventionRequiresIntsAsLongs) { + call = make_runtime_call(RC_LEAF|RC_NO_FP, + OptoRuntime::digestBase_implCompressMB_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + src_start, state, ofs XTOP, limit XTOP); + } else { + call = make_runtime_call(RC_LEAF|RC_NO_FP, + OptoRuntime::digestBase_implCompressMB_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + src_start, state, ofs, limit); + } // return ofs (int) Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); set_result(result); diff --git a/src/share/vm/opto/runtime.cpp b/src/share/vm/opto/runtime.cpp index 364152c56..57d2f5764 100644 --- a/src/share/vm/opto/runtime.cpp +++ b/src/share/vm/opto/runtime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -930,12 +930,24 @@ const TypeFunc* OptoRuntime::digestBase_implCompressMB_Type() { // create input type (domain) int num_args = 4; int argcnt = num_args; + if(CCallingConventionRequiresIntsAsLongs) { + argcnt += 2; + } const Type** fields = TypeTuple::fields(argcnt); int argp = TypeFunc::Parms; - fields[argp++] = TypePtr::NOTNULL; // buf - fields[argp++] = TypePtr::NOTNULL; // state - fields[argp++] = TypeInt::INT; // ofs - fields[argp++] = TypeInt::INT; // limit + if(CCallingConventionRequiresIntsAsLongs) { + fields[argp++] = TypePtr::NOTNULL; // buf + fields[argp++] = TypePtr::NOTNULL; // state + fields[argp++] = TypeLong::LONG; // ofs + fields[argp++] = Type::HALF; + fields[argp++] = TypeLong::LONG; // limit + fields[argp++] = Type::HALF; + } else { + fields[argp++] = TypePtr::NOTNULL; // buf + fields[argp++] = TypePtr::NOTNULL; // state + fields[argp++] = TypeInt::INT; // ofs + fields[argp++] = TypeInt::INT; // limit + } assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); diff --git a/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java b/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java index c5d21ed4b..32850711a 100644 --- a/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java +++ b/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java @@ -36,7 +36,8 @@ public class GenericTestCaseForOtherCPU extends public GenericTestCaseForOtherCPU(String optionName) { // Execute the test case on any CPU except SPARC and X86 super(optionName, new NotPredicate(new OrPredicate(Platform::isSparc, - new OrPredicate(Platform::isX64, Platform::isX86)))); + new OrPredicate(Platform::isPPC, + new OrPredicate(Platform::isX64, Platform::isX86))))); } @Override diff --git a/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java b/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java index 51ab609dc..bac466575 100644 --- a/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java +++ b/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java @@ -63,12 +63,20 @@ public class IntrinsicPredicates { null); public static final BooleanSupplier SHA256_INSTRUCTION_AVAILABLE - = new CPUSpecificPredicate("sparc.*", new String[] { "sha256" }, - null); + = new OrPredicate(new CPUSpecificPredicate("sparc.*", new String[] { "sha256" }, + null), + new OrPredicate(new CPUSpecificPredicate("ppc64.*", new String[] { "sha" }, + null), + new CPUSpecificPredicate("ppc64le.*", new String[] { "sha" }, + null))); public static final BooleanSupplier SHA512_INSTRUCTION_AVAILABLE - = new CPUSpecificPredicate("sparc.*", new String[] { "sha512" }, - null); + = new OrPredicate(new CPUSpecificPredicate("sparc.*", new String[] { "sha512" }, + null), + new OrPredicate(new CPUSpecificPredicate("ppc64.*", new String[] { "sha" }, + null), + new CPUSpecificPredicate("ppc64le.*", new String[] { "sha" }, + null))); public static final BooleanSupplier ANY_SHA_INSTRUCTION_AVAILABLE = new OrPredicate(IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE, -- cgit v1.2.3 From 7430f9717c9a04efedbb8651fe1af84a5b10d2aa Mon Sep 17 00:00:00 2001 From: ysuenaga Date: Wed, 19 Jun 2019 09:42:12 +0900 Subject: 8225636: SA can't handle prelinked libraries Reviewed-by: sspitsyn, cjplummer --- agent/src/os/linux/ps_core.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/agent/src/os/linux/ps_core.c b/agent/src/os/linux/ps_core.c index 541c857b5..c62e58d0f 100644 --- a/agent/src/os/linux/ps_core.c +++ b/agent/src/os/linux/ps_core.c @@ -865,8 +865,51 @@ err: #define LD_BASE_OFFSET offsetof(struct r_debug, r_ldbase) #define LINK_MAP_ADDR_OFFSET offsetof(struct link_map, l_addr) #define LINK_MAP_NAME_OFFSET offsetof(struct link_map, l_name) +#define LINK_MAP_LD_OFFSET offsetof(struct link_map, l_ld) #define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next) +// Calculate the load address of shared library +// on prelink-enabled environment. +// +// In case of GDB, it would be calculated by offset of link_map.l_ld +// and the address of .dynamic section. +// See GDB implementation: lm_addr_check @ solib-svr4.c +static uintptr_t calc_prelinked_load_address(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* elf_ehdr, uintptr_t link_map_addr) { + ELF_PHDR *phbuf; + uintptr_t lib_ld; + uintptr_t lib_dyn_addr = 0L; + uintptr_t load_addr; + int i; + + phbuf = read_program_header_table(lib_fd, elf_ehdr); + if (phbuf == NULL) { + print_debug("can't read program header of shared object\n"); + return 0L; + } + + // Get the address of .dynamic section from shared library. + for (i = 0; i < elf_ehdr->e_phnum; i++) { + if (phbuf[i].p_type == PT_DYNAMIC) { + lib_dyn_addr = phbuf[i].p_vaddr; + break; + } + } + + free(phbuf); + + if (ps_pdread(ph, (psaddr_t)link_map_addr + LINK_MAP_LD_OFFSET, + &lib_ld, sizeof(uintptr_t)) != PS_OK) { + print_debug("can't read address of dynamic section in shared object\n"); + return 0L; + } + + // Return the load address which is calculated by the address of .dynamic + // and link_map.l_ld . + load_addr = lib_ld - lib_dyn_addr; + print_debug("lib_ld = 0x%lx, lib_dyn_addr = 0x%lx -> lib_base_diff = 0x%lx\n", lib_ld, lib_dyn_addr, load_addr); + return load_addr; +} + // read shared library info from runtime linker's data structures. // This work is done by librtlb_db in Solaris static bool read_shared_lib_info(struct ps_prochandle* ph) { @@ -968,6 +1011,14 @@ static bool read_shared_lib_info(struct ps_prochandle* ph) { // continue with other libraries... } else { if (read_elf_header(lib_fd, &elf_ehdr)) { + if (lib_base_diff == 0x0L) { + lib_base_diff = calc_prelinked_load_address(ph, lib_fd, &elf_ehdr, link_map_addr); + if (lib_base_diff == 0x0L) { + close(lib_fd); + return false; + } + } + lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr); print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n", lib_name, lib_base, lib_base_diff); -- cgit v1.2.3 From ff2b3621dd634f80e3a72c33739158e85d3c696b Mon Sep 17 00:00:00 2001 From: thartmann Date: Tue, 19 Feb 2019 08:58:55 +0100 Subject: 8218721: C1's CEE optimization produces safepoint poll with invalid debug information Summary: Bail out of CEE if one of the gotos is a safepoint but the if is not. Reviewed-by: vlivanov, mdoerr --- src/share/vm/c1/c1_Optimizer.cpp | 8 +- test/compiler/c1/TestGotoIf.jasm | 171 +++++++++++++++++++++++++++++++++++ test/compiler/c1/TestGotoIfMain.java | 46 ++++++++++ 3 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 test/compiler/c1/TestGotoIf.jasm create mode 100644 test/compiler/c1/TestGotoIfMain.java diff --git a/src/share/vm/c1/c1_Optimizer.cpp b/src/share/vm/c1/c1_Optimizer.cpp index f366462f6..a2ba0e376 100644 --- a/src/share/vm/c1/c1_Optimizer.cpp +++ b/src/share/vm/c1/c1_Optimizer.cpp @@ -175,6 +175,12 @@ void CE_Eliminator::block_do(BlockBegin* block) { for_each_phi_fun(t_block, phi, return; ); for_each_phi_fun(f_block, phi, return; ); + // Only replace safepoint gotos if state_before information is available (if is a safepoint) + bool is_safepoint = if_->is_safepoint(); + if (!is_safepoint && (t_goto->is_safepoint() || f_goto->is_safepoint())) { + return; + } + // 2) substitute conditional expression // with an IfOp followed by a Goto // cut if_ away and get node before @@ -203,7 +209,7 @@ void CE_Eliminator::block_do(BlockBegin* block) { // append Goto to successor ValueStack* state_before = if_->state_before(); - Goto* goto_ = new Goto(sux, state_before, if_->is_safepoint() || t_goto->is_safepoint() || f_goto->is_safepoint()); + Goto* goto_ = new Goto(sux, state_before, is_safepoint); // prepare state for Goto ValueStack* goto_state = if_state; diff --git a/test/compiler/c1/TestGotoIf.jasm b/test/compiler/c1/TestGotoIf.jasm new file mode 100644 index 000000000..b5dc03af2 --- /dev/null +++ b/test/compiler/c1/TestGotoIf.jasm @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +public class compiler/c1/TestGotoIf version 52:0 { + public Field f1:"I"; + public Field f2:"I"; + public static Field i:"I"; + + Method "":"()V" stack 1 locals 1 { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + + public Method test1:"()I" stack 3 locals 1 { + aload_0; + getfield Field f1:"I"; + aload_0; + getfield Field f2:"I"; + iconst_1; + isub; + // Without the fix, if got eliminated by CEE + if_icmpgt Null; + iconst_1; + Return: stack_frame_type stack1; + stack_map int; + ireturn; + Null: stack_frame_type same; + iconst_0; + goto Return; // Backbranch (t_goto) with safepoint + } + + public Method test2:"()I" stack 3 locals 1 { + aload_0; + getfield Field f1:"I"; + aload_0; + getfield Field f2:"I"; + iconst_1; + isub; + goto Skip; + Return: stack_frame_type full; + stack_map int; + ireturn; + Skip: stack_frame_type full; + stack_map int, int; + // Without the fix, if got eliminated by CEE + if_icmpgt Null; + iconst_1; + goto Return; // Backbranch (f_goto) with safepoint + Null: stack_frame_type full; + stack_map; + iconst_0; + goto Return; // Backbranch (t_goto) with safepoint + } + + public Method test3:"()I" stack 3 locals 1 { + aload_0; + getfield Field f1:"I"; + aload_0; + getfield Field f2:"I"; + iconst_1; + isub; + goto Skip; + Return: stack_frame_type full; + stack_map int; + ireturn; + Null: stack_frame_type full; + stack_map; + iconst_0; + goto Return; // Backbranch (t_goto) with safepoint + Skip: stack_frame_type full; + stack_map int, int; + // If will be eliminated by CEE + if_icmpgt Null; // Backbranch (if) with safepoint + iconst_1; + goto Return; // Backbranch (f_goto) with safepoint + } + + public Method test4:"()I" stack 3 locals 1 { + aload_0; + getfield Field f1:"I"; + aload_0; + getfield Field f2:"I"; + iconst_1; + isub; + goto Skip; + Null: stack_frame_type full; + stack_map; + iconst_0; + Return: stack_frame_type full; + stack_map int; + ireturn; + Skip: stack_frame_type full; + stack_map int, int; + // If will be eliminated by CEE + if_icmpgt Null; // Backbranch (if) with safepoint + iconst_1; + goto Return; // Backbranch (f_goto) with safepoint + } + + public Method test5:"()I" stack 3 locals 2 { + aload_0; + getfield Field f1:"I"; + aload_0; + getfield Field f2:"I"; + iconst_1; + isub; + goto Skip; + Null: stack_frame_type full; + stack_map; + iconst_0; + goto Return; + Skip: stack_frame_type full; + stack_map int, int; + // If will be eliminated by CEE + if_icmpgt Null; // Backbranch (if) with safepoint + iconst_1; + Return: stack_frame_type full; + stack_map int; + ireturn; + } + + public Method test6:"()I" stack 4 locals 1 { + getstatic Field i:"I"; + Loop: stack_frame_type full; + stack_map int; + // Decrement i and exit loop if < 0 + iconst_0; + getstatic Field i:"I"; + iconst_1; + isub; + dup; + putstatic Field i:"I"; + if_icmpgt Exit; + + iconst_1; + // Without the fix, if got eliminated by CEE + if_icmpgt Null; + iconst_1; + goto Loop; // Backbranch (f_goto) with safepoint + Null: stack_frame_type same; + iconst_0; + goto Loop; // Backbranch (t_goto) with safepoint + + Exit: stack_frame_type full; + stack_map int; + iconst_0; + ireturn; + } +} diff --git a/test/compiler/c1/TestGotoIfMain.java b/test/compiler/c1/TestGotoIfMain.java new file mode 100644 index 000000000..ac8b1b8be --- /dev/null +++ b/test/compiler/c1/TestGotoIfMain.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8218721 + * @compile TestGotoIf.jasm + * @run main/othervm -XX:TieredStopAtLevel=1 -Xcomp + * -XX:CompileCommand=compileonly,compiler.c1.TestGotoIf::test* + * compiler.c1.TestGotoIfMain + */ + +package compiler.c1; + +public class TestGotoIfMain { + public static void main(String[] args) { + TestGotoIf test = new TestGotoIf(); + test.i = 5; + test.test1(); + test.test2(); + test.test3(); + test.test4(); + test.test5(); + test.test6(); + } +} -- cgit v1.2.3 From 907bdb8286eb8fbf930cf9ee5a7ff16b8e6a9109 Mon Sep 17 00:00:00 2001 From: sgehwolf Date: Fri, 21 Sep 2018 16:58:36 +0200 Subject: 8210761: libjsig is being compiled without optimization Reviewed-by: clanger, andrew --- make/aix/makefiles/jsig.make | 7 ++++++- make/bsd/makefiles/jsig.make | 7 ++++++- make/linux/makefiles/jsig.make | 7 ++++++- make/solaris/makefiles/jsig.make | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/make/aix/makefiles/jsig.make b/make/aix/makefiles/jsig.make index f8bf93872..ae453f2d9 100644 --- a/make/aix/makefiles/jsig.make +++ b/make/aix/makefiles/jsig.make @@ -54,10 +54,15 @@ ifeq ($(DEBUG_BINARIES), true) JSIG_DEBUG_CFLAGS = -g endif +# Optimize jsig lib at level -O3 unless it's a slowdebug build +ifneq ($(DEBUG_LEVEL), slowdebug) + JSIG_OPT_FLAGS = $(OPT_CFLAGS) +endif + $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) @echo Making signal interposition lib... $(QUIETLY) $(CXX) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ - $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< -ldl + $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(JSIG_OPT_FLAGS) -o $@ $< -ldl #ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) # $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO) diff --git a/make/bsd/makefiles/jsig.make b/make/bsd/makefiles/jsig.make index 29779b002..b5860bfd8 100644 --- a/make/bsd/makefiles/jsig.make +++ b/make/bsd/makefiles/jsig.make @@ -59,10 +59,15 @@ ifeq ($(DEBUG_BINARIES), true) JSIG_DEBUG_CFLAGS = -g endif +# Optimize jsig lib at level -O3 unless it's a slowdebug build +ifneq ($(DEBUG_LEVEL), slowdebug) + JSIG_OPT_FLAGS = $(OPT_CFLAGS) +endif + $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) @echo Making signal interposition lib... $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ - $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(EXTRA_CFLAGS) -o $@ $< + $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(JSIG_OPT_FLAGS) $(EXTRA_CFLAGS) -o $@ $< ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) ifeq ($(OS_VENDOR), Darwin) $(DSYMUTIL) $@ diff --git a/make/linux/makefiles/jsig.make b/make/linux/makefiles/jsig.make index 9bf3b738b..6290db5af 100644 --- a/make/linux/makefiles/jsig.make +++ b/make/linux/makefiles/jsig.make @@ -51,10 +51,15 @@ ifeq ($(DEBUG_BINARIES), true) JSIG_DEBUG_CFLAGS = -g endif +# Optimize jsig lib at level -O3 unless it's a slowdebug build +ifneq ($(DEBUG_LEVEL), slowdebug) + JSIG_OPT_FLAGS = $(OPT_CFLAGS) +endif + $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) @echo Making signal interposition lib... $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ - $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(EXTRA_CFLAGS) -o $@ $< -ldl + $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(JSIG_OPT_FLAGS) $(EXTRA_CFLAGS) -o $@ $< -ldl ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) ifneq ($(STRIP_POLICY),no_strip) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO) diff --git a/make/solaris/makefiles/jsig.make b/make/solaris/makefiles/jsig.make index bbc098245..74b07214b 100644 --- a/make/solaris/makefiles/jsig.make +++ b/make/solaris/makefiles/jsig.make @@ -47,10 +47,15 @@ else LFLAGS_JSIG += -mt -xnolib endif +# Optimize jsig lib unless it's a slowdebug build +ifneq ($(DEBUG_LEVEL), slowdebug) + JSIG_OPT_FLAGS = -xO4 -g +endif + $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) @echo Making signal interposition lib... $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ - $(LFLAGS_JSIG) -o $@ $(JSIGSRCDIR)/jsig.c -ldl + $(LFLAGS_JSIG) $(JSIG_OPT_FLAGS) -o $@ $(JSIGSRCDIR)/jsig.c -ldl ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@ -- cgit v1.2.3 From 1f58f4e8a5c72cd675b5ca293b75fb35ce2d4fde Mon Sep 17 00:00:00 2001 From: gziemski Date: Tue, 24 May 2016 12:42:43 -0500 Subject: 8152856: Xcode 7.3 -Wshift-negative-value compile failure on Mac OS X Summary: Implement _lh_array_tag_type_value as const, not enum. Reviewed-by: vlivanov, minqi --- src/share/vm/oops/klass.hpp | 3 ++- src/share/vm/opto/library_call.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/share/vm/oops/klass.hpp b/src/share/vm/oops/klass.hpp index 9f612c3e7..df018923c 100644 --- a/src/share/vm/oops/klass.hpp +++ b/src/share/vm/oops/klass.hpp @@ -335,10 +335,11 @@ protected: _lh_header_size_mask = right_n_bits(BitsPerByte), // shifted mask _lh_array_tag_bits = 2, _lh_array_tag_shift = BitsPerInt - _lh_array_tag_bits, - _lh_array_tag_type_value = ~0x00, // 0xC0000000 >> 30 _lh_array_tag_obj_value = ~0x01 // 0x80000000 >> 30 }; + static const unsigned int _lh_array_tag_type_value = 0Xffffffff; // ~0x00, // 0xC0000000 >> 30 + static int layout_helper_size_in_bytes(jint lh) { assert(lh > (jint)_lh_neutral_value, "must be instance"); return (int) lh & ~_lh_instance_slow_path_bit; diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp index db36fb349..4bb5ca886 100644 --- a/src/share/vm/opto/library_call.cpp +++ b/src/share/vm/opto/library_call.cpp @@ -3803,7 +3803,7 @@ Node* LibraryCallKit::generate_array_guard_common(Node* kls, RegionNode* region, } // Now test the correct condition. jint nval = (obj_array - ? ((jint)Klass::_lh_array_tag_type_value + ? (jint)(Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift) : Klass::_lh_neutral_value); Node* cmp = _gvn.transform(new(C) CmpINode(layout_val, intcon(nval))); -- cgit v1.2.3 From ec99eb43d6654fd0b51b0ecc884a97a443d48818 Mon Sep 17 00:00:00 2001 From: sgehwolf Date: Mon, 7 Aug 2017 12:19:17 +0200 Subject: 8185900: hotspot build failed with gcc version Red Hat 4.4.7-3 Summary: Cast to void* within DTRACE_CLASS* macros. Reviewed-by: coleenp, shade --- src/share/vm/oops/instanceKlass.cpp | 4 ++-- src/share/vm/services/classLoadingService.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/share/vm/oops/instanceKlass.cpp b/src/share/vm/oops/instanceKlass.cpp index 6aff230b6..0204188ad 100644 --- a/src/share/vm/oops/instanceKlass.cpp +++ b/src/share/vm/oops/instanceKlass.cpp @@ -147,7 +147,7 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end, len = name->utf8_length(); \ } \ HOTSPOT_CLASS_INITIALIZATION_##type( \ - data, len, (clss)->class_loader(), thread_type); \ + data, len, (void *)(clss)->class_loader(), thread_type); \ } #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \ @@ -160,7 +160,7 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end, len = name->utf8_length(); \ } \ HOTSPOT_CLASS_INITIALIZATION_##type( \ - data, len, (clss)->class_loader(), thread_type, wait); \ + data, len, (void *)(clss)->class_loader(), thread_type, wait); \ } #endif /* USDT2 */ diff --git a/src/share/vm/services/classLoadingService.cpp b/src/share/vm/services/classLoadingService.cpp index 92a548ba5..fce2b27f8 100644 --- a/src/share/vm/services/classLoadingService.cpp +++ b/src/share/vm/services/classLoadingService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,7 @@ HS_DTRACE_PROBE_DECL4(hotspot, class__unloaded, char*, int, oop, bool); len = name->utf8_length(); \ } \ HOTSPOT_CLASS_##type( /* type = unloaded, loaded */ \ - data, len, (clss)->class_loader(), (shared)); \ + data, len, (void *)(clss)->class_loader(), (shared)); \ } #endif /* USDT2 */ -- cgit v1.2.3 From 3ec5c4703a57c060f688a487c32961152ef74d6f Mon Sep 17 00:00:00 2001 From: shade Date: Wed, 24 Jul 2019 21:43:36 +0200 Subject: 8228405: Incorrect format strings in PhaseIdealLoop::rc_predicate Reviewed-by: andrew, phh --- src/share/vm/opto/loopPredicate.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/share/vm/opto/loopPredicate.cpp b/src/share/vm/opto/loopPredicate.cpp index 5d2b469d4..db7c10846 100644 --- a/src/share/vm/opto/loopPredicate.cpp +++ b/src/share/vm/opto/loopPredicate.cpp @@ -611,7 +611,11 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl, const TypeInt* idx_type = TypeInt::INT; if ((stride > 0) == (scale > 0) == upper) { if (TraceLoopPredicate) { - predString->print(limit->is_Con() ? "(%d " : "(limit ", con_limit); + if (limit->is_Con()) { + predString->print("(%d ", con_limit); + } else { + predString->print("(limit "); + } predString->print("- %d) ", stride); } // Check if (limit - stride) may overflow @@ -639,7 +643,11 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl, register_new_node(max_idx_expr, ctrl); } else { if (TraceLoopPredicate) { - predString->print(init->is_Con() ? "%d " : "init ", con_init); + if (init->is_Con()) { + predString->print("%d ", con_init); + } else { + predString->print("init "); + } } idx_type = _igvn.type(init)->isa_int(); max_idx_expr = init; @@ -675,7 +683,11 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl, if (offset && (!offset->is_Con() || con_offset != 0)){ if (TraceLoopPredicate) { - predString->print(offset->is_Con() ? "+ %d " : "+ offset", con_offset); + if (offset->is_Con()) { + predString->print("+ %d ", con_offset); + } else { + predString->print("+ offset"); + } } // Check if (max_idx_expr + offset) may overflow const TypeInt* offset_type = _igvn.type(offset)->isa_int(); -- cgit v1.2.3 From ce2d3fab87218670fad07601402003ba91031bd1 Mon Sep 17 00:00:00 2001 From: thartmann Date: Mon, 23 Mar 2015 10:15:53 +0100 Subject: 8075136: Unnecessary sign extension for byte array access Summary: Added C2 matching rules to remove unnecessary sign extension for byte array access. Reviewed-by: roland, kvn, aph, adinn --- src/cpu/x86/vm/x86_64.ad | 61 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/src/cpu/x86/vm/x86_64.ad b/src/cpu/x86/vm/x86_64.ad index e20b02d2b..e36604faf 100644 --- a/src/cpu/x86/vm/x86_64.ad +++ b/src/cpu/x86/vm/x86_64.ad @@ -3740,6 +3740,23 @@ operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) %} %} +// Indirect Memory Plus Positive Index Register Plus Offset Operand +operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) +%{ + constraint(ALLOC_IN_RC(ptr_reg)); + predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); + match(AddP (AddP reg (ConvI2L idx)) off); + + op_cost(10); + format %{"[$reg + $off + $idx]" %} + interface(MEMORY_INTER) %{ + base($reg); + index($idx); + scale(0x0); + disp($off); + %} +%} + // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) %{ @@ -3891,6 +3908,23 @@ operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale %} %} +// Indirect Memory Times Plus Positive Index Register Plus Offset Operand +operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) +%{ + constraint(ALLOC_IN_RC(ptr_reg)); + predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); + match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); + + op_cost(10); + format %{"[$reg + $off + $idx]" %} + interface(MEMORY_INTER) %{ + base($reg); + index($idx); + scale(0x0); + disp($off); + %} +%} + // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) %{ @@ -4082,11 +4116,11 @@ operand cmpOpUCF2() %{ // case of this is memory operands. opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, - indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, + indIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, indCompressedOopOffset, indirectNarrow, indOffset8Narrow, indOffset32Narrow, indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, - indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); + indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); //----------PIPELINE----------------------------------------------------------- // Rules which define the behavior of the target architectures pipeline. @@ -5120,6 +5154,17 @@ instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) ins_pipe(ialu_reg_reg_fat); %} +instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) +%{ + match(Set dst mem); + + ins_cost(110); + format %{ "leaq $dst, $mem\t# ptr posidxoff" %} + opcode(0x8D); + ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); + ins_pipe(ialu_reg_reg_fat); +%} + instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) %{ match(Set dst mem); @@ -5204,6 +5249,18 @@ instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) ins_pipe(ialu_reg_reg_fat); %} +instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) +%{ + predicate(Universe::narrow_oop_shift() == 0); + match(Set dst mem); + + ins_cost(110); + format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} + opcode(0x8D); + ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); + ins_pipe(ialu_reg_reg_fat); +%} + instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) %{ predicate(Universe::narrow_oop_shift() == 0); -- cgit v1.2.3 From d59b0da51e4c3026707bc87de6b2485ec58a58de Mon Sep 17 00:00:00 2001 From: roland Date: Tue, 21 May 2019 09:08:01 +0200 Subject: 8224580: Matcher can cause oop field/array element to be reloaded Reviewed-by: neliasso, rkennke, dlong --- src/share/vm/opto/matcher.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/share/vm/opto/matcher.cpp b/src/share/vm/opto/matcher.cpp index b4dda4803..965f1a952 100644 --- a/src/share/vm/opto/matcher.cpp +++ b/src/share/vm/opto/matcher.cpp @@ -2043,6 +2043,12 @@ void Matcher::find_shared( Node *n ) { // Node is shared and has no reason to clone. Flag it as shared. // This causes it to match into a register for the sharing. set_shared(n); // Flag as shared and + if (n->is_DecodeNarrowPtr()) { + // Oop field/array element loads must be shared but since + // they are shared through a DecodeN they may appear to have + // a single use so force sharing here. + set_shared(n->in(1)); + } mstack.pop(); // remove node from stack continue; } @@ -2165,13 +2171,6 @@ void Matcher::find_shared( Node *n ) { continue; // for(int i = ...) } - if( mop == Op_AddP && m->in(AddPNode::Base)->is_DecodeNarrowPtr()) { - // Bases used in addresses must be shared but since - // they are shared through a DecodeN they may appear - // to have a single use so force sharing here. - set_shared(m->in(AddPNode::Base)->in(1)); - } - // if 'n' and 'm' are part of a graph for BMI instruction, clone this node. #ifdef X86 if (UseBMI1Instructions && is_bmi_pattern(n, m)) { -- cgit v1.2.3 From 931d2c6911ff54de05fcbcbd64529d29aafd5e5e Mon Sep 17 00:00:00 2001 From: sgehwolf Date: Thu, 25 Apr 2019 14:02:51 +0200 Subject: 8222737: [TESTBUG] Allow for tier 1 like testing in OpenJDK 8u Reviewed-by: adinn, shade, andrew --- test/Makefile | 6 +++--- test/TEST.groups | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/test/Makefile b/test/Makefile index e91844ece..447619b47 100644 --- a/test/Makefile +++ b/test/Makefile @@ -119,11 +119,11 @@ TEST_ROOT := $(shell pwd) # Root of all test results ifdef ALT_OUTPUTDIR - ABS_BUILD_ROOT = $(ALT_OUTPUTDIR)/$(PLATFORM)-$(ARCH) + ABS_BUILD_ROOT = $(ALT_OUTPUTDIR) else ABS_BUILD_ROOT = $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH) endif -ABS_TEST_OUTPUT_DIR = $(ABS_BUILD_ROOT)/testoutput +ABS_TEST_OUTPUT_DIR = $(ABS_BUILD_ROOT)/testoutput/$(UNIQUE_DIR) # Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test) ifndef PRODUCT_HOME @@ -267,7 +267,7 @@ JTREG_BASIC_OPTIONS += -agentvm # Only run automatic tests JTREG_BASIC_OPTIONS += -a # Report details on all failed or error tests, times too -JTREG_BASIC_OPTIONS += -v:fail,error,time +JTREG_BASIC_OPTIONS += -v:fail,error,summary # Retain all files for failing tests JTREG_BASIC_OPTIONS += -retain:fail,error # Ignore tests are not run and completely silent about it diff --git a/test/TEST.groups b/test/TEST.groups index 40750364b..216e307cf 100644 --- a/test/TEST.groups +++ b/test/TEST.groups @@ -124,7 +124,6 @@ compact3 = \ -:needs_jre \ -:needs_jdk - # When called from top level the test suites use the hotspot_ prefix hotspot_wbapitest = \ sanity/ @@ -147,6 +146,11 @@ hotspot_all = \ :hotspot_gc \ :hotspot_runtime \ :hotspot_serviceability + +# Right now tier1 runs all hotspot tests +hotspot_tier1 = \ + :jdk + # Tests that require compact3 API's # needs_compact3 = \ -- cgit v1.2.3 From 3cc64a479d048a741804f461d5faf212d9ae2df4 Mon Sep 17 00:00:00 2001 From: zgu Date: Tue, 29 Jan 2019 08:28:24 -0500 Subject: 8217785: Padding ParallelTaskTerminator::_offered_termination variable Reviewed-by: shade, tschatzl --- src/share/vm/utilities/taskqueue.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/share/vm/utilities/taskqueue.hpp b/src/share/vm/utilities/taskqueue.hpp index 8bdb38d31..d2b39c943 100644 --- a/src/share/vm/utilities/taskqueue.hpp +++ b/src/share/vm/utilities/taskqueue.hpp @@ -29,6 +29,7 @@ #include "memory/allocation.inline.hpp" #include "runtime/mutex.hpp" #include "runtime/orderAccess.inline.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/stack.hpp" // Simple TaskQueue stats that are collected by default in debug builds. @@ -607,7 +608,9 @@ class ParallelTaskTerminator: public StackObj { private: int _n_threads; TaskQueueSetSuper* _queue_set; + char _pad_before[DEFAULT_CACHE_LINE_SIZE]; int _offered_termination; + char _pad_after[DEFAULT_CACHE_LINE_SIZE]; #ifdef TRACESPINNING static uint _total_yields; -- cgit v1.2.3 From bb98bb673f361a26b454d9a945ff6550950f183d Mon Sep 17 00:00:00 2001 From: mdoerr Date: Sun, 11 Aug 2019 19:11:08 -0400 Subject: 8188868: PPC64: Support AES intrinsics on Big Endian Reviewed-by: goetz --- src/cpu/ppc/vm/assembler_ppc.hpp | 1 + src/cpu/ppc/vm/assembler_ppc.inline.hpp | 8 + src/cpu/ppc/vm/stubGenerator_ppc.cpp | 359 ++++++++++++++++---------------- src/cpu/ppc/vm/stubRoutines_ppc_64.hpp | 2 +- src/cpu/ppc/vm/vm_version_ppc.cpp | 13 -- 5 files changed, 195 insertions(+), 188 deletions(-) diff --git a/src/cpu/ppc/vm/assembler_ppc.hpp b/src/cpu/ppc/vm/assembler_ppc.hpp index 16884ca51..88ac813a1 100644 --- a/src/cpu/ppc/vm/assembler_ppc.hpp +++ b/src/cpu/ppc/vm/assembler_ppc.hpp @@ -2100,6 +2100,7 @@ class Assembler : public AbstractAssembler { // Endianess specific concatenation of 2 loaded vectors. inline void load_perm(VectorRegister perm, Register addr); inline void vec_perm(VectorRegister first_dest, VectorRegister second, VectorRegister perm); + inline void vec_perm(VectorRegister dest, VectorRegister first, VectorRegister second, VectorRegister perm); // RegisterOrConstant versions. // These emitters choose between the versions using two registers and diff --git a/src/cpu/ppc/vm/assembler_ppc.inline.hpp b/src/cpu/ppc/vm/assembler_ppc.inline.hpp index badeecf77..5d8066372 100644 --- a/src/cpu/ppc/vm/assembler_ppc.inline.hpp +++ b/src/cpu/ppc/vm/assembler_ppc.inline.hpp @@ -904,6 +904,14 @@ inline void Assembler::vec_perm(VectorRegister first_dest, VectorRegister second #endif } +inline void Assembler::vec_perm(VectorRegister dest, VectorRegister first, VectorRegister second, VectorRegister perm) { +#if defined(VM_LITTLE_ENDIAN) + vperm(dest, second, first, perm); +#else + vperm(dest, first, second, perm); +#endif +} + inline void Assembler::load_const(Register d, void* x, Register tmp) { load_const(d, (long)x, tmp); } diff --git a/src/cpu/ppc/vm/stubGenerator_ppc.cpp b/src/cpu/ppc/vm/stubGenerator_ppc.cpp index 12cff00c8..7f2c4427f 100644 --- a/src/cpu/ppc/vm/stubGenerator_ppc.cpp +++ b/src/cpu/ppc/vm/stubGenerator_ppc.cpp @@ -2224,7 +2224,7 @@ class StubGenerator: public StubCodeGenerator { return start; } - // Arguments for generated stub (little endian only): + // Arguments for generated stub: // R3_ARG1 - source byte array address // R4_ARG2 - destination byte array address // R5_ARG3 - round key array @@ -2243,7 +2243,6 @@ class StubGenerator: public StubCodeGenerator { Register keylen = R8; Register temp = R9; Register keypos = R10; - Register hex = R11; Register fifteen = R12; VectorRegister vRet = VR0; @@ -2263,164 +2262,170 @@ class StubGenerator: public StubCodeGenerator { VectorRegister vTmp3 = VR11; VectorRegister vTmp4 = VR12; - VectorRegister vLow = VR13; - VectorRegister vHigh = VR14; - - __ li (hex, 16); __ li (fifteen, 15); - __ vspltisb (fSplt, 0x0f); // load unaligned from[0-15] to vsRet __ lvx (vRet, from); __ lvx (vTmp1, fifteen, from); __ lvsl (fromPerm, from); +#ifdef VM_LITTLE_ENDIAN + __ vspltisb (fSplt, 0x0f); __ vxor (fromPerm, fromPerm, fSplt); +#endif __ vperm (vRet, vRet, vTmp1, fromPerm); // load keylen (44 or 52 or 60) __ lwz (keylen, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT), key); // to load keys - __ lvsr (keyPerm, key); - __ vxor (vTmp2, vTmp2, vTmp2); + __ load_perm (keyPerm, key); +#ifdef VM_LITTLE_ENDIAN __ vspltisb (vTmp2, -16); __ vrld (keyPerm, keyPerm, vTmp2); __ vrld (keyPerm, keyPerm, vTmp2); __ vsldoi (keyPerm, keyPerm, keyPerm, 8); +#endif - // load the 1st round key to vKey1 - __ li (keypos, 0); + // load the 1st round key to vTmp1 + __ lvx (vTmp1, key); + __ li (keypos, 16); __ lvx (vKey1, keypos, key); - __ addi (keypos, keypos, 16); - __ lvx (vTmp1, keypos, key); - __ vperm (vKey1, vTmp1, vKey1, keyPerm); + __ vec_perm (vTmp1, vKey1, keyPerm); // 1st round - __ vxor (vRet, vRet, vKey1); + __ vxor (vRet, vRet, vTmp1); // load the 2nd round key to vKey1 - __ addi (keypos, keypos, 16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey1, vTmp2, vTmp1, keyPerm); + __ li (keypos, 32); + __ lvx (vKey2, keypos, key); + __ vec_perm (vKey1, vKey2, keyPerm); // load the 3rd round key to vKey2 - __ addi (keypos, keypos, 16); - __ lvx (vTmp1, keypos, key); - __ vperm (vKey2, vTmp1, vTmp2, keyPerm); + __ li (keypos, 48); + __ lvx (vKey3, keypos, key); + __ vec_perm (vKey2, vKey3, keyPerm); // load the 4th round key to vKey3 - __ addi (keypos, keypos, 16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey3, vTmp2, vTmp1, keyPerm); + __ li (keypos, 64); + __ lvx (vKey4, keypos, key); + __ vec_perm (vKey3, vKey4, keyPerm); // load the 5th round key to vKey4 - __ addi (keypos, keypos, 16); + __ li (keypos, 80); __ lvx (vTmp1, keypos, key); - __ vperm (vKey4, vTmp1, vTmp2, keyPerm); + __ vec_perm (vKey4, vTmp1, keyPerm); // 2nd - 5th rounds - __ vcipher (vRet, vRet, vKey1); - __ vcipher (vRet, vRet, vKey2); - __ vcipher (vRet, vRet, vKey3); - __ vcipher (vRet, vRet, vKey4); + __ vcipher (vRet, vRet, vKey1); + __ vcipher (vRet, vRet, vKey2); + __ vcipher (vRet, vRet, vKey3); + __ vcipher (vRet, vRet, vKey4); // load the 6th round key to vKey1 - __ addi (keypos, keypos, 16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey1, vTmp2, vTmp1, keyPerm); + __ li (keypos, 96); + __ lvx (vKey2, keypos, key); + __ vec_perm (vKey1, vTmp1, vKey2, keyPerm); // load the 7th round key to vKey2 - __ addi (keypos, keypos, 16); - __ lvx (vTmp1, keypos, key); - __ vperm (vKey2, vTmp1, vTmp2, keyPerm); + __ li (keypos, 112); + __ lvx (vKey3, keypos, key); + __ vec_perm (vKey2, vKey3, keyPerm); // load the 8th round key to vKey3 - __ addi (keypos, keypos, 16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey3, vTmp2, vTmp1, keyPerm); + __ li (keypos, 128); + __ lvx (vKey4, keypos, key); + __ vec_perm (vKey3, vKey4, keyPerm); // load the 9th round key to vKey4 - __ addi (keypos, keypos, 16); + __ li (keypos, 144); __ lvx (vTmp1, keypos, key); - __ vperm (vKey4, vTmp1, vTmp2, keyPerm); + __ vec_perm (vKey4, vTmp1, keyPerm); // 6th - 9th rounds - __ vcipher (vRet, vRet, vKey1); - __ vcipher (vRet, vRet, vKey2); - __ vcipher (vRet, vRet, vKey3); - __ vcipher (vRet, vRet, vKey4); + __ vcipher (vRet, vRet, vKey1); + __ vcipher (vRet, vRet, vKey2); + __ vcipher (vRet, vRet, vKey3); + __ vcipher (vRet, vRet, vKey4); // load the 10th round key to vKey1 - __ addi (keypos, keypos, 16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey1, vTmp2, vTmp1, keyPerm); + __ li (keypos, 160); + __ lvx (vKey2, keypos, key); + __ vec_perm (vKey1, vTmp1, vKey2, keyPerm); // load the 11th round key to vKey2 - __ addi (keypos, keypos, 16); + __ li (keypos, 176); __ lvx (vTmp1, keypos, key); - __ vperm (vKey2, vTmp1, vTmp2, keyPerm); + __ vec_perm (vKey2, vTmp1, keyPerm); // if all round keys are loaded, skip next 4 rounds __ cmpwi (CCR0, keylen, 44); __ beq (CCR0, L_doLast); // 10th - 11th rounds - __ vcipher (vRet, vRet, vKey1); - __ vcipher (vRet, vRet, vKey2); + __ vcipher (vRet, vRet, vKey1); + __ vcipher (vRet, vRet, vKey2); // load the 12th round key to vKey1 - __ addi (keypos, keypos, 16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey1, vTmp2, vTmp1, keyPerm); + __ li (keypos, 192); + __ lvx (vKey2, keypos, key); + __ vec_perm (vKey1, vTmp1, vKey2, keyPerm); // load the 13th round key to vKey2 - __ addi (keypos, keypos, 16); + __ li (keypos, 208); __ lvx (vTmp1, keypos, key); - __ vperm (vKey2, vTmp1, vTmp2, keyPerm); + __ vec_perm (vKey2, vTmp1, keyPerm); // if all round keys are loaded, skip next 2 rounds __ cmpwi (CCR0, keylen, 52); __ beq (CCR0, L_doLast); // 12th - 13th rounds - __ vcipher (vRet, vRet, vKey1); - __ vcipher (vRet, vRet, vKey2); + __ vcipher (vRet, vRet, vKey1); + __ vcipher (vRet, vRet, vKey2); // load the 14th round key to vKey1 - __ addi (keypos, keypos, 16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey1, vTmp2, vTmp1, keyPerm); + __ li (keypos, 224); + __ lvx (vKey2, keypos, key); + __ vec_perm (vKey1, vTmp1, vKey2, keyPerm); // load the 15th round key to vKey2 - __ addi (keypos, keypos, 16); + __ li (keypos, 240); __ lvx (vTmp1, keypos, key); - __ vperm (vKey2, vTmp1, vTmp2, keyPerm); + __ vec_perm (vKey2, vTmp1, keyPerm); __ bind(L_doLast); // last two rounds - __ vcipher (vRet, vRet, vKey1); - __ vcipherlast (vRet, vRet, vKey2); - - __ neg (temp, to); - __ lvsr (toPerm, temp); - __ vspltisb (vTmp2, -1); - __ vxor (vTmp1, vTmp1, vTmp1); - __ vperm (vTmp2, vTmp2, vTmp1, toPerm); - __ vxor (toPerm, toPerm, fSplt); + __ vcipher (vRet, vRet, vKey1); + __ vcipherlast (vRet, vRet, vKey2); + + // store result (unaligned) +#ifdef VM_LITTLE_ENDIAN + __ lvsl (toPerm, to); +#else + __ lvsr (toPerm, to); +#endif + __ vspltisb (vTmp3, -1); + __ vspltisb (vTmp4, 0); __ lvx (vTmp1, to); - __ vperm (vRet, vRet, vRet, toPerm); - __ vsel (vTmp1, vTmp1, vRet, vTmp2); - __ lvx (vTmp4, fifteen, to); + __ lvx (vTmp2, fifteen, to); +#ifdef VM_LITTLE_ENDIAN + __ vperm (vTmp3, vTmp3, vTmp4, toPerm); // generate select mask + __ vxor (toPerm, toPerm, fSplt); // swap bytes +#else + __ vperm (vTmp3, vTmp4, vTmp3, toPerm); // generate select mask +#endif + __ vperm (vTmp4, vRet, vRet, toPerm); // rotate data + __ vsel (vTmp2, vTmp4, vTmp2, vTmp3); + __ vsel (vTmp1, vTmp1, vTmp4, vTmp3); + __ stvx (vTmp2, fifteen, to); // store this one first (may alias) __ stvx (vTmp1, to); - __ vsel (vRet, vRet, vTmp4, vTmp2); - __ stvx (vRet, fifteen, to); __ blr(); return start; } - // Arguments for generated stub (little endian only): + // Arguments for generated stub: // R3_ARG1 - source byte array address // R4_ARG2 - destination byte array address // R5_ARG3 - K (key) in little endian int array @@ -2442,7 +2447,6 @@ class StubGenerator: public StubCodeGenerator { Register keylen = R8; Register temp = R9; Register keypos = R10; - Register hex = R11; Register fifteen = R12; VectorRegister vRet = VR0; @@ -2463,30 +2467,30 @@ class StubGenerator: public StubCodeGenerator { VectorRegister vTmp3 = VR12; VectorRegister vTmp4 = VR13; - VectorRegister vLow = VR14; - VectorRegister vHigh = VR15; - - __ li (hex, 16); __ li (fifteen, 15); - __ vspltisb (fSplt, 0x0f); // load unaligned from[0-15] to vsRet __ lvx (vRet, from); __ lvx (vTmp1, fifteen, from); __ lvsl (fromPerm, from); +#ifdef VM_LITTLE_ENDIAN + __ vspltisb (fSplt, 0x0f); __ vxor (fromPerm, fromPerm, fSplt); +#endif __ vperm (vRet, vRet, vTmp1, fromPerm); // align [and byte swap in LE] // load keylen (44 or 52 or 60) __ lwz (keylen, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT), key); // to load keys - __ lvsr (keyPerm, key); + __ load_perm (keyPerm, key); +#ifdef VM_LITTLE_ENDIAN __ vxor (vTmp2, vTmp2, vTmp2); __ vspltisb (vTmp2, -16); __ vrld (keyPerm, keyPerm, vTmp2); __ vrld (keyPerm, keyPerm, vTmp2); __ vsldoi (keyPerm, keyPerm, keyPerm, 8); +#endif __ cmpwi (CCR0, keylen, 44); __ beq (CCR0, L_do44); @@ -2494,32 +2498,32 @@ class StubGenerator: public StubCodeGenerator { __ cmpwi (CCR0, keylen, 52); __ beq (CCR0, L_do52); - // load the 15th round key to vKey11 + // load the 15th round key to vKey1 __ li (keypos, 240); - __ lvx (vTmp1, keypos, key); - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey1, vTmp1, vTmp2, keyPerm); + __ lvx (vKey1, keypos, key); + __ li (keypos, 224); + __ lvx (vKey2, keypos, key); + __ vec_perm (vKey1, vKey2, vKey1, keyPerm); - // load the 14th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp1, keypos, key); - __ vperm (vKey2, vTmp2, vTmp1, keyPerm); + // load the 14th round key to vKey2 + __ li (keypos, 208); + __ lvx (vKey3, keypos, key); + __ vec_perm (vKey2, vKey3, vKey2, keyPerm); - // load the 13th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey3, vTmp1, vTmp2, keyPerm); + // load the 13th round key to vKey3 + __ li (keypos, 192); + __ lvx (vKey4, keypos, key); + __ vec_perm (vKey3, vKey4, vKey3, keyPerm); - // load the 12th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp1, keypos, key); - __ vperm (vKey4, vTmp2, vTmp1, keyPerm); + // load the 12th round key to vKey4 + __ li (keypos, 176); + __ lvx (vKey5, keypos, key); + __ vec_perm (vKey4, vKey5, vKey4, keyPerm); - // load the 11th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey5, vTmp1, vTmp2, keyPerm); + // load the 11th round key to vKey5 + __ li (keypos, 160); + __ lvx (vTmp1, keypos, key); + __ vec_perm (vKey5, vTmp1, vKey5, keyPerm); // 1st - 5th rounds __ vxor (vRet, vRet, vKey1); @@ -2532,22 +2536,22 @@ class StubGenerator: public StubCodeGenerator { __ bind (L_do52); - // load the 13th round key to vKey11 + // load the 13th round key to vKey1 __ li (keypos, 208); - __ lvx (vTmp1, keypos, key); - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey1, vTmp1, vTmp2, keyPerm); + __ lvx (vKey1, keypos, key); + __ li (keypos, 192); + __ lvx (vKey2, keypos, key); + __ vec_perm (vKey1, vKey2, vKey1, keyPerm); - // load the 12th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp1, keypos, key); - __ vperm (vKey2, vTmp2, vTmp1, keyPerm); + // load the 12th round key to vKey2 + __ li (keypos, 176); + __ lvx (vKey3, keypos, key); + __ vec_perm (vKey2, vKey3, vKey2, keyPerm); - // load the 11th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey3, vTmp1, vTmp2, keyPerm); + // load the 11th round key to vKey3 + __ li (keypos, 160); + __ lvx (vTmp1, keypos, key); + __ vec_perm (vKey3, vTmp1, vKey3, keyPerm); // 1st - 3rd rounds __ vxor (vRet, vRet, vKey1); @@ -2558,42 +2562,42 @@ class StubGenerator: public StubCodeGenerator { __ bind (L_do44); - // load the 11th round key to vKey11 + // load the 11th round key to vKey1 __ li (keypos, 176); + __ lvx (vKey1, keypos, key); + __ li (keypos, 160); __ lvx (vTmp1, keypos, key); - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey1, vTmp1, vTmp2, keyPerm); + __ vec_perm (vKey1, vTmp1, vKey1, keyPerm); // 1st round __ vxor (vRet, vRet, vKey1); __ bind (L_doLast); - // load the 10th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp1, keypos, key); - __ vperm (vKey1, vTmp2, vTmp1, keyPerm); + // load the 10th round key to vKey1 + __ li (keypos, 144); + __ lvx (vKey2, keypos, key); + __ vec_perm (vKey1, vKey2, vTmp1, keyPerm); - // load the 9th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey2, vTmp1, vTmp2, keyPerm); + // load the 9th round key to vKey2 + __ li (keypos, 128); + __ lvx (vKey3, keypos, key); + __ vec_perm (vKey2, vKey3, vKey2, keyPerm); - // load the 8th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp1, keypos, key); - __ vperm (vKey3, vTmp2, vTmp1, keyPerm); + // load the 8th round key to vKey3 + __ li (keypos, 112); + __ lvx (vKey4, keypos, key); + __ vec_perm (vKey3, vKey4, vKey3, keyPerm); - // load the 7th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey4, vTmp1, vTmp2, keyPerm); + // load the 7th round key to vKey4 + __ li (keypos, 96); + __ lvx (vKey5, keypos, key); + __ vec_perm (vKey4, vKey5, vKey4, keyPerm); - // load the 6th round key to vKey10 - __ addi (keypos, keypos, -16); + // load the 6th round key to vKey5 + __ li (keypos, 80); __ lvx (vTmp1, keypos, key); - __ vperm (vKey5, vTmp2, vTmp1, keyPerm); + __ vec_perm (vKey5, vTmp1, vKey5, keyPerm); // last 10th - 6th rounds __ vncipher (vRet, vRet, vKey1); @@ -2602,30 +2606,29 @@ class StubGenerator: public StubCodeGenerator { __ vncipher (vRet, vRet, vKey4); __ vncipher (vRet, vRet, vKey5); - // load the 5th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey1, vTmp1, vTmp2, keyPerm); + // load the 5th round key to vKey1 + __ li (keypos, 64); + __ lvx (vKey2, keypos, key); + __ vec_perm (vKey1, vKey2, vTmp1, keyPerm); - // load the 4th round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp1, keypos, key); - __ vperm (vKey2, vTmp2, vTmp1, keyPerm); + // load the 4th round key to vKey2 + __ li (keypos, 48); + __ lvx (vKey3, keypos, key); + __ vec_perm (vKey2, vKey3, vKey2, keyPerm); - // load the 3rd round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey3, vTmp1, vTmp2, keyPerm); + // load the 3rd round key to vKey3 + __ li (keypos, 32); + __ lvx (vKey4, keypos, key); + __ vec_perm (vKey3, vKey4, vKey3, keyPerm); - // load the 2nd round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp1, keypos, key); - __ vperm (vKey4, vTmp2, vTmp1, keyPerm); + // load the 2nd round key to vKey4 + __ li (keypos, 16); + __ lvx (vKey5, keypos, key); + __ vec_perm (vKey4, vKey5, vKey4, keyPerm); - // load the 1st round key to vKey10 - __ addi (keypos, keypos, -16); - __ lvx (vTmp2, keypos, key); - __ vperm (vKey5, vTmp1, vTmp2, keyPerm); + // load the 1st round key to vKey5 + __ lvx (vTmp1, key); + __ vec_perm (vKey5, vTmp1, vKey5, keyPerm); // last 5th - 1th rounds __ vncipher (vRet, vRet, vKey1); @@ -2634,19 +2637,27 @@ class StubGenerator: public StubCodeGenerator { __ vncipher (vRet, vRet, vKey4); __ vncipherlast (vRet, vRet, vKey5); - __ neg (temp, to); - __ lvsr (toPerm, temp); - __ vspltisb (vTmp2, -1); - __ vxor (vTmp1, vTmp1, vTmp1); - __ vperm (vTmp2, vTmp2, vTmp1, toPerm); - __ vxor (toPerm, toPerm, fSplt); + // store result (unaligned) +#ifdef VM_LITTLE_ENDIAN + __ lvsl (toPerm, to); +#else + __ lvsr (toPerm, to); +#endif + __ vspltisb (vTmp3, -1); + __ vspltisb (vTmp4, 0); __ lvx (vTmp1, to); - __ vperm (vRet, vRet, vRet, toPerm); - __ vsel (vTmp1, vTmp1, vRet, vTmp2); - __ lvx (vTmp4, fifteen, to); + __ lvx (vTmp2, fifteen, to); +#ifdef VM_LITTLE_ENDIAN + __ vperm (vTmp3, vTmp3, vTmp4, toPerm); // generate select mask + __ vxor (toPerm, toPerm, fSplt); // swap bytes +#else + __ vperm (vTmp3, vTmp4, vTmp3, toPerm); // generate select mask +#endif + __ vperm (vTmp4, vRet, vRet, toPerm); // rotate data + __ vsel (vTmp2, vTmp4, vTmp2, vTmp3); + __ vsel (vTmp1, vTmp1, vTmp4, vTmp3); + __ stvx (vTmp2, fifteen, to); // store this one first (may alias) __ stvx (vTmp1, to); - __ vsel (vRet, vRet, vTmp4, vTmp2); - __ stvx (vRet, fifteen, to); __ blr(); return start; diff --git a/src/cpu/ppc/vm/stubRoutines_ppc_64.hpp b/src/cpu/ppc/vm/stubRoutines_ppc_64.hpp index cf9ebc4e6..e6e90ae76 100644 --- a/src/cpu/ppc/vm/stubRoutines_ppc_64.hpp +++ b/src/cpu/ppc/vm/stubRoutines_ppc_64.hpp @@ -34,7 +34,7 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _call_ enum platform_dependent_constants { code_size1 = 20000, // simply increase if too small (assembler will crash if too small) - code_size2 = 22000 // simply increase if too small (assembler will crash if too small) + code_size2 = 24000 // simply increase if too small (assembler will crash if too small) }; // CRC32 Intrinsics. diff --git a/src/cpu/ppc/vm/vm_version_ppc.cpp b/src/cpu/ppc/vm/vm_version_ppc.cpp index e7fad4843..bbc52691b 100644 --- a/src/cpu/ppc/vm/vm_version_ppc.cpp +++ b/src/cpu/ppc/vm/vm_version_ppc.cpp @@ -174,7 +174,6 @@ void VM_Version::initialize() { } // The AES intrinsic stubs require AES instruction support. -#if defined(VM_LITTLE_ENDIAN) if (has_vcipher()) { if (FLAG_IS_DEFAULT(UseAES)) { UseAES = true; @@ -195,18 +194,6 @@ void VM_Version::initialize() { FLAG_SET_DEFAULT(UseAESIntrinsics, false); } -#else - if (UseAES) { - warning("AES instructions are not available on this CPU"); - FLAG_SET_DEFAULT(UseAES, false); - } - if (UseAESIntrinsics) { - if (!FLAG_IS_DEFAULT(UseAESIntrinsics)) - warning("AES intrinsics are not available on this CPU"); - FLAG_SET_DEFAULT(UseAESIntrinsics, false); - } -#endif - if (has_vshasig()) { if (FLAG_IS_DEFAULT(UseSHA)) { UseSHA = true; -- cgit v1.2.3 From 428b767212e17f5bde8e6e8cd78a59fee0e8195a Mon Sep 17 00:00:00 2001 From: manc Date: Tue, 30 Apr 2019 18:44:41 -0700 Subject: 8223177: Data race on JvmtiEnvBase::_tag_map in double-checked locking Summary: Add memory fences on accesses to JvmtiEnvBase::_tag_map Reviewed-by: dholmes, jcbeyler, sspitsyn --- src/share/vm/prims/jvmtiEnvBase.hpp | 10 +++++++++- src/share/vm/prims/jvmtiTagMap.cpp | 6 +++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/share/vm/prims/jvmtiEnvBase.hpp b/src/share/vm/prims/jvmtiEnvBase.hpp index e8c23b10f..55ea70ab3 100644 --- a/src/share/vm/prims/jvmtiEnvBase.hpp +++ b/src/share/vm/prims/jvmtiEnvBase.hpp @@ -32,6 +32,7 @@ #include "runtime/fieldDescriptor.hpp" #include "runtime/frame.hpp" #include "runtime/handles.inline.hpp" +#include "runtime/orderAccess.hpp" #include "runtime/thread.hpp" #include "runtime/vm_operations.hpp" #include "utilities/growableArray.hpp" @@ -97,7 +98,7 @@ class JvmtiEnvBase : public CHeapObj { const void *_env_local_storage; // per env agent allocated data. jvmtiEventCallbacks _event_callbacks; jvmtiExtEventCallbacks _ext_event_callbacks; - JvmtiTagMap* _tag_map; + JvmtiTagMap* volatile _tag_map; JvmtiEnvEventEnable _env_event_enable; jvmtiCapabilities _current_capabilities; jvmtiCapabilities _prohibited_capabilities; @@ -251,6 +252,13 @@ class JvmtiEnvBase : public CHeapObj { return _tag_map; } + JvmtiTagMap* acquire_tag_map() { + return (JvmtiTagMap*)OrderAccess::load_ptr_acquire(&_tag_map); + } + + void release_set_tag_map(JvmtiTagMap* tag_map) { + OrderAccess::release_store_ptr(&_tag_map, tag_map); + } // return true if event is enabled globally or for any thread // True only if there is a callback for it. diff --git a/src/share/vm/prims/jvmtiTagMap.cpp b/src/share/vm/prims/jvmtiTagMap.cpp index c45181dc7..6902f95a8 100644 --- a/src/share/vm/prims/jvmtiTagMap.cpp +++ b/src/share/vm/prims/jvmtiTagMap.cpp @@ -430,7 +430,7 @@ JvmtiTagMap::JvmtiTagMap(JvmtiEnv* env) : _hashmap = new JvmtiTagHashmap(); // finally add us to the environment - ((JvmtiEnvBase *)env)->set_tag_map(this); + ((JvmtiEnvBase *)env)->release_set_tag_map(this); } @@ -499,7 +499,7 @@ void JvmtiTagMap::destroy_entry(JvmtiTagHashmapEntry* entry) { // returns the tag map for the given environments. If the tag map // doesn't exist then it is created. JvmtiTagMap* JvmtiTagMap::tag_map_for(JvmtiEnv* env) { - JvmtiTagMap* tag_map = ((JvmtiEnvBase*)env)->tag_map(); + JvmtiTagMap* tag_map = ((JvmtiEnvBase*)env)->acquire_tag_map(); if (tag_map == NULL) { MutexLocker mu(JvmtiThreadState_lock); tag_map = ((JvmtiEnvBase*)env)->tag_map(); @@ -3282,7 +3282,7 @@ void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { if (JvmtiEnv::environments_might_exist()) { JvmtiEnvIterator it; for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) { - JvmtiTagMap* tag_map = env->tag_map(); + JvmtiTagMap* tag_map = env->acquire_tag_map(); if (tag_map != NULL && !tag_map->is_empty()) { tag_map->do_weak_oops(is_alive, f); } -- cgit v1.2.3 From e14b0c53f20d51bf31d11bf6dd904dcbf78b20a4 Mon Sep 17 00:00:00 2001 From: manc Date: Wed, 1 May 2019 20:25:31 -0700 Subject: 8223227: Rename acquire_tag_map() to tag_map_acquire() in jvmtiEnvBase Reviewed-by: dholmes, jcbeyler --- src/share/vm/prims/jvmtiEnvBase.hpp | 2 +- src/share/vm/prims/jvmtiTagMap.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/share/vm/prims/jvmtiEnvBase.hpp b/src/share/vm/prims/jvmtiEnvBase.hpp index 55ea70ab3..c6a7db187 100644 --- a/src/share/vm/prims/jvmtiEnvBase.hpp +++ b/src/share/vm/prims/jvmtiEnvBase.hpp @@ -252,7 +252,7 @@ class JvmtiEnvBase : public CHeapObj { return _tag_map; } - JvmtiTagMap* acquire_tag_map() { + JvmtiTagMap* tag_map_acquire() { return (JvmtiTagMap*)OrderAccess::load_ptr_acquire(&_tag_map); } diff --git a/src/share/vm/prims/jvmtiTagMap.cpp b/src/share/vm/prims/jvmtiTagMap.cpp index 6902f95a8..ba48fc3ef 100644 --- a/src/share/vm/prims/jvmtiTagMap.cpp +++ b/src/share/vm/prims/jvmtiTagMap.cpp @@ -499,7 +499,7 @@ void JvmtiTagMap::destroy_entry(JvmtiTagHashmapEntry* entry) { // returns the tag map for the given environments. If the tag map // doesn't exist then it is created. JvmtiTagMap* JvmtiTagMap::tag_map_for(JvmtiEnv* env) { - JvmtiTagMap* tag_map = ((JvmtiEnvBase*)env)->acquire_tag_map(); + JvmtiTagMap* tag_map = ((JvmtiEnvBase*)env)->tag_map_acquire(); if (tag_map == NULL) { MutexLocker mu(JvmtiThreadState_lock); tag_map = ((JvmtiEnvBase*)env)->tag_map(); @@ -3282,7 +3282,7 @@ void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { if (JvmtiEnv::environments_might_exist()) { JvmtiEnvIterator it; for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) { - JvmtiTagMap* tag_map = env->acquire_tag_map(); + JvmtiTagMap* tag_map = env->tag_map_acquire(); if (tag_map != NULL && !tag_map->is_empty()) { tag_map->do_weak_oops(is_alive, f); } -- cgit v1.2.3 From de20ecc174aeb1e1971ba66aa4d75e85a938a8bf Mon Sep 17 00:00:00 2001 From: neliasso Date: Mon, 19 Aug 2019 17:36:36 +0200 Subject: 8219517: assert(false) failed: infinite loop in PhaseIterGVN::optimize Reviewed-by: kvn, thartmann --- src/share/vm/opto/memnode.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/share/vm/opto/memnode.cpp b/src/share/vm/opto/memnode.cpp index 14b0ff9a9..590111a39 100644 --- a/src/share/vm/opto/memnode.cpp +++ b/src/share/vm/opto/memnode.cpp @@ -1359,6 +1359,14 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) { Node* in = mem->in(i); Node* m = optimize_memory_chain(in, t_oop, this, phase); if (m == mem) { + if (i == 1) { + // if the first edge was a loop, check second edge too. + // If both are replaceable - we are in an infinite loop + Node *n = optimize_memory_chain(mem->in(2), t_oop, this, phase); + if (n == mem) { + break; + } + } set_req(Memory, mem->in(cnt - i)); return this; // made change } -- cgit v1.2.3 From c4f3c040a9a4cd6fbdb861809cc17d987a2f9523 Mon Sep 17 00:00:00 2001 From: thartmann Date: Mon, 11 Mar 2019 11:42:57 +0100 Subject: 8218201: Failures when vmIntrinsics::_getClass is not inlined Summary: Fix BCEscapeAnalyzer to correctly handle _getClass intrinsic. Reviewed-by: kvn, dlong, redestad, neliasso --- src/share/vm/ci/bcEscapeAnalyzer.cpp | 42 ++++++++++----------- src/share/vm/ci/bcEscapeAnalyzer.hpp | 4 +- test/compiler/escapeAnalysis/TestGetClass.java | 52 ++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 25 deletions(-) create mode 100644 test/compiler/escapeAnalysis/TestGetClass.java diff --git a/src/share/vm/ci/bcEscapeAnalyzer.cpp b/src/share/vm/ci/bcEscapeAnalyzer.cpp index 4c4db3e85..2b9e0e514 100644 --- a/src/share/vm/ci/bcEscapeAnalyzer.cpp +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp @@ -1170,45 +1170,43 @@ void BCEscapeAnalyzer::iterate_blocks(Arena *arena) { } } -bool BCEscapeAnalyzer::do_analysis() { +void BCEscapeAnalyzer::do_analysis() { Arena* arena = CURRENT_ENV->arena(); // identify basic blocks _methodBlocks = _method->get_method_blocks(); iterate_blocks(arena); - // TEMPORARY - return true; } vmIntrinsics::ID BCEscapeAnalyzer::known_intrinsic() { vmIntrinsics::ID iid = method()->intrinsic_id(); - if (iid == vmIntrinsics::_getClass || iid == vmIntrinsics::_fillInStackTrace || - iid == vmIntrinsics::_hashCode) + iid == vmIntrinsics::_hashCode) { return iid; - else + } else { return vmIntrinsics::_none; + } } -bool BCEscapeAnalyzer::compute_escape_for_intrinsic(vmIntrinsics::ID iid) { +void BCEscapeAnalyzer::compute_escape_for_intrinsic(vmIntrinsics::ID iid) { ArgumentMap arg; arg.clear(); switch (iid) { - case vmIntrinsics::_getClass: - _return_local = false; - break; - case vmIntrinsics::_fillInStackTrace: - arg.set(0); // 'this' - set_returned(arg); - break; - case vmIntrinsics::_hashCode: - // initialized state is correct - break; + case vmIntrinsics::_getClass: + _return_local = false; + _return_allocated = false; + break; + case vmIntrinsics::_fillInStackTrace: + arg.set(0); // 'this' + set_returned(arg); + break; + case vmIntrinsics::_hashCode: + // initialized state is correct + break; default: assert(false, "unexpected intrinsic"); } - return true; } void BCEscapeAnalyzer::initialize() { @@ -1279,7 +1277,7 @@ void BCEscapeAnalyzer::compute_escape_info() { vmIntrinsics::ID iid = known_intrinsic(); // check if method can be analyzed - if (iid == vmIntrinsics::_none && (method()->is_abstract() || method()->is_native() || !method()->holder()->is_initialized() + if (iid == vmIntrinsics::_none && (method()->is_abstract() || method()->is_native() || !method()->holder()->is_initialized() || _level > MaxBCEAEstimateLevel || method()->code_size() > MaxBCEAEstimateSize)) { if (BCEATraceLevel >= 1) { @@ -1312,8 +1310,6 @@ void BCEscapeAnalyzer::compute_escape_info() { tty->print_cr(" (%d bytes)", method()->code_size()); } - bool success; - initialize(); // Do not scan method if it has no object parameters and @@ -1329,9 +1325,9 @@ void BCEscapeAnalyzer::compute_escape_info() { } if (iid != vmIntrinsics::_none) - success = compute_escape_for_intrinsic(iid); + compute_escape_for_intrinsic(iid); else { - success = do_analysis(); + do_analysis(); } // don't store interprocedural escape information if it introduces diff --git a/src/share/vm/ci/bcEscapeAnalyzer.hpp b/src/share/vm/ci/bcEscapeAnalyzer.hpp index 74a0d3106..acca5a210 100644 --- a/src/share/vm/ci/bcEscapeAnalyzer.hpp +++ b/src/share/vm/ci/bcEscapeAnalyzer.hpp @@ -101,8 +101,8 @@ class BCEscapeAnalyzer : public ResourceObj { void clear_escape_info(); void compute_escape_info(); vmIntrinsics::ID known_intrinsic(); - bool compute_escape_for_intrinsic(vmIntrinsics::ID iid); - bool do_analysis(); + void compute_escape_for_intrinsic(vmIntrinsics::ID iid); + void do_analysis(); void read_escape_info(); diff --git a/test/compiler/escapeAnalysis/TestGetClass.java b/test/compiler/escapeAnalysis/TestGetClass.java new file mode 100644 index 000000000..7b2b587b2 --- /dev/null +++ b/test/compiler/escapeAnalysis/TestGetClass.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8218201 + * @summary BCEscapeAnalyzer assigns wrong escape state to getClass return value. + * @run main/othervm -XX:-TieredCompilation -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_getClass + * -XX:CompileCommand=quiet -XX:CompileCommand=compileonly,compiler.escapeAnalysis.TestGetClass::test + * -XX:+PrintCompilation compiler.escapeAnalysis.TestGetClass + */ + +package compiler.escapeAnalysis; + +public class TestGetClass { + static Object obj = new Object(); + + public static boolean test() { + if (obj.getClass() == Object.class) { + synchronized (obj) { + return true; + } + } + return false; + } + + public static void main(String[] args) { + if (!test()) { + throw new RuntimeException("Test failed"); + } + } +} -- cgit v1.2.3 From 128f2aca25ef28d2c3622cef32b9b4a85ff2f82e Mon Sep 17 00:00:00 2001 From: fyang Date: Mon, 21 Jan 2019 13:31:42 +0800 Subject: 8217359: C2 compiler triggers SIGSEGV after transformation in ConvI2LNode::Ideal Reviewed-by: thartmann Contributed-by: jitao8@huawei.com --- src/share/vm/opto/connode.cpp | 6 +++- test/compiler/c2/Test8217359.java | 74 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 test/compiler/c2/Test8217359.java diff --git a/src/share/vm/opto/connode.cpp b/src/share/vm/opto/connode.cpp index 604e971f9..ff56804df 100644 --- a/src/share/vm/opto/connode.cpp +++ b/src/share/vm/opto/connode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1083,7 +1083,11 @@ Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { assert(rxlo == (int)rxlo && rxhi == (int)rxhi, "x should not overflow"); assert(rylo == (int)rylo && ryhi == (int)ryhi, "y should not overflow"); Node* cx = phase->C->constrained_convI2L(phase, x, TypeInt::make(rxlo, rxhi, widen), NULL); + Node *hook = new (phase->C) Node(1); + hook->init_req(0, cx); // Add a use to cx to prevent him from dying Node* cy = phase->C->constrained_convI2L(phase, y, TypeInt::make(rylo, ryhi, widen), NULL); + hook->del_req(0); // Just yank bogus edge + hook->destruct(); switch (op) { case Op_AddI: return new (phase->C) AddLNode(cx, cy); case Op_SubI: return new (phase->C) SubLNode(cx, cy); diff --git a/test/compiler/c2/Test8217359.java b/test/compiler/c2/Test8217359.java new file mode 100644 index 000000000..ca0d2cc75 --- /dev/null +++ b/test/compiler/c2/Test8217359.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2019, Huawei Technologies Co. Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8217359 + * @summary C2 compiler triggers SIGSEGV after transformation in ConvI2LNode::Ideal + * + * @run main/othervm -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,compiler.c2.Test8217359::test + * compiler.c2.Test8217359 + */ + +package compiler.c2; + +public class Test8217359 { + + public static int ival = 0; + public static long lsum = 0; + public static long lval = 0; + + public static void test() { + short s = -25632; + float f = 0.512F, f1 = 2.556F; + int i6 = 32547, i7 = 9, i8 = -9, i9 = 36, i10 = -223; + + for (i6 = 4; i6 < 182; i6++) { + i8 = 1; + while (++i8 < 17) { + f1 = 1; + do { + i7 += (182 + (f1 * f1)); + } while (++f1 < 1); + + Test8217359.ival += (i8 | Test8217359.ival); + } + } + + for (i9 = 9; i9 < 100; ++i9) { + i10 -= i6; + i10 >>= s; + i7 += (((i9 * i10) + i6) - Test8217359.lval); + } + + lsum += i6 + i7 + i8; + } + + public static void main(String[] args) { + for (int i = 0; i < 16000; i++) { + test(); + } + } + +} -- cgit v1.2.3 From 0e9f1b75fd63986059978f676e0dc775cc9d5dc0 Mon Sep 17 00:00:00 2001 From: roland Date: Fri, 28 Sep 2018 14:24:22 +0200 Subject: 8211232: GraphKit::make_runtime_call() sometimes attaches wrong memory state to call Reviewed-by: kvn --- src/share/vm/opto/graphKit.cpp | 9 ++++----- src/share/vm/opto/graphKit.hpp | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp index 16313f097..dabc7e758 100644 --- a/src/share/vm/opto/graphKit.cpp +++ b/src/share/vm/opto/graphKit.cpp @@ -1787,12 +1787,13 @@ Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_p // A better answer would be to separate out card marks from other memory. // For now, return the input memory state, so that it can be reused // after the call, if this call has restricted memory effects. -Node* GraphKit::set_predefined_input_for_runtime_call(SafePointNode* call) { +Node* GraphKit::set_predefined_input_for_runtime_call(SafePointNode* call, Node* narrow_mem) { // Set fixed predefined input arguments Node* memory = reset_memory(); + Node* m = narrow_mem == NULL ? memory : narrow_mem; call->init_req( TypeFunc::Control, control() ); call->init_req( TypeFunc::I_O, top() ); // does no i/o - call->init_req( TypeFunc::Memory, memory ); // may gc ptrs + call->init_req( TypeFunc::Memory, m ); // may gc ptrs call->init_req( TypeFunc::FramePtr, frameptr() ); call->init_req( TypeFunc::ReturnAdr, top() ); return memory; @@ -2382,9 +2383,7 @@ Node* GraphKit::make_runtime_call(int flags, } else { assert(!wide_out, "narrow in => narrow out"); Node* narrow_mem = memory(adr_type); - prev_mem = reset_memory(); - map()->set_memory(narrow_mem); - set_predefined_input_for_runtime_call(call); + prev_mem = set_predefined_input_for_runtime_call(call, narrow_mem); } // Hook each parm in order. Stop looking at the first NULL. diff --git a/src/share/vm/opto/graphKit.hpp b/src/share/vm/opto/graphKit.hpp index c584cef75..7a363fd33 100644 --- a/src/share/vm/opto/graphKit.hpp +++ b/src/share/vm/opto/graphKit.hpp @@ -700,7 +700,7 @@ class GraphKit : public Phase { void set_predefined_output_for_runtime_call(Node* call, Node* keep_mem, const TypePtr* hook_mem); - Node* set_predefined_input_for_runtime_call(SafePointNode* call); + Node* set_predefined_input_for_runtime_call(SafePointNode* call, Node* narrow_mem = NULL); // Replace the call with the current state of the kit. Requires // that the call was generated with separate io_projs so that -- cgit v1.2.3 From 952faa71fe757f25a94ade541b7433ecc2dc7727 Mon Sep 17 00:00:00 2001 From: roland Date: Fri, 14 Dec 2018 11:22:26 +0100 Subject: 8215265: C2: range check elimination may allow illegal out of bound access Reviewed-by: thartmann, kvn --- src/share/vm/opto/loopTransform.cpp | 20 +++-- src/share/vm/opto/loopnode.hpp | 2 +- .../RangeCheckEliminationScaleNotOne.java | 100 +++++++++++++++++++++ 3 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 test/compiler/rangechecks/RangeCheckEliminationScaleNotOne.java diff --git a/src/share/vm/opto/loopTransform.cpp b/src/share/vm/opto/loopTransform.cpp index 8b656ff7a..7ef67c155 100644 --- a/src/share/vm/opto/loopTransform.cpp +++ b/src/share/vm/opto/loopTransform.cpp @@ -1537,13 +1537,20 @@ bool IdealLoopTree::dominates_backedge(Node* ctrl) { //------------------------------adjust_limit----------------------------------- // Helper function for add_constraint(). -Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl) { +Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up) { // Compute "I :: (limit-offset)/scale" Node *con = new (C) SubINode(rc_limit, offset); register_new_node(con, pre_ctrl); Node *X = new (C) DivINode(0, con, scale); register_new_node(X, pre_ctrl); + // When the absolute value of scale is greater than one, the integer + // division may round limit down so add one to the limit. + if (round_up) { + X = new (C) AddINode(X, _igvn.intcon(1)); + register_new_node(X, pre_ctrl); + } + // Adjust loop limit loop_limit = (stride_con > 0) ? (Node*)(new (C) MinINode(loop_limit, X)) @@ -1584,7 +1591,7 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset // (upper_limit-offset) may overflow or underflow. // But it is fine since main loop will either have // less iterations or will be skipped in such case. - *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl); + *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl, false); // The underflow limit: low_limit <= scale*I+offset. // For pre-loop compute @@ -1620,7 +1627,8 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset // max(pre_limit, original_limit) is used in do_range_check(). } // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond); - *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl); + *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl, + scale_con > 1 && stride_con > 0); } else { // stride_con*scale_con < 0 // For negative stride*scale pre-loop checks for overflow and @@ -1646,7 +1654,8 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset Node *plus_one = new (C) AddINode(offset, one); register_new_node( plus_one, pre_ctrl ); // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond); - *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl); + *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl, + scale_con < -1 && stride_con > 0); if (low_limit->get_int() == -max_jint) { if (!RangeLimitCheck) return; @@ -1681,7 +1690,8 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset // I > (low_limit-(offset+1))/scale // ) - *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl); + *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl, + false); } } diff --git a/src/share/vm/opto/loopnode.hpp b/src/share/vm/opto/loopnode.hpp index d97bf07ca..0ce98a063 100644 --- a/src/share/vm/opto/loopnode.hpp +++ b/src/share/vm/opto/loopnode.hpp @@ -959,7 +959,7 @@ public: // loop. Scale_con, offset and limit are all loop invariant. void add_constraint( int stride_con, int scale_con, Node *offset, Node *low_limit, Node *upper_limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit ); // Helper function for add_constraint(). - Node* adjust_limit( int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl ); + Node* adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up); // Partially peel loop up through last_peel node. bool partial_peel( IdealLoopTree *loop, Node_List &old_new ); diff --git a/test/compiler/rangechecks/RangeCheckEliminationScaleNotOne.java b/test/compiler/rangechecks/RangeCheckEliminationScaleNotOne.java new file mode 100644 index 000000000..50b268a25 --- /dev/null +++ b/test/compiler/rangechecks/RangeCheckEliminationScaleNotOne.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8215265 + * @summary C2: range check elimination may allow illegal out of bound access + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:-UseLoopPredicate RangeCheckEliminationScaleNotOne + * + */ + +import java.util.Arrays; + +public class RangeCheckEliminationScaleNotOne { + public static void main(String[] args) { + { + int[] array = new int[199]; + boolean[] flags = new boolean[100]; + Arrays.fill(flags, true); + flags[0] = false; + flags[1] = false; + for (int i = 0; i < 20_000; i++) { + test1(100, array, 0, flags); + } + boolean ex = false; + try { + test1(100, array, -5, flags); + } catch (ArrayIndexOutOfBoundsException aie) { + ex = true; + } + if (!ex) { + throw new RuntimeException("no AIOOB exception"); + } + } + + { + int[] array = new int[199]; + boolean[] flags = new boolean[100]; + Arrays.fill(flags, true); + flags[0] = false; + flags[1] = false; + for (int i = 0; i < 20_000; i++) { + test2(100, array, 198, flags); + } + boolean ex = false; + try { + test2(100, array, 203, flags); + } catch (ArrayIndexOutOfBoundsException aie) { + ex = true; + } + if (!ex) { + throw new RuntimeException("no AIOOB exception"); + } + } + } + + private static int test1(int stop, int[] array, int offset, boolean[] flags) { + if (array == null) {} + int res = 0; + for (int i = 0; i < stop; i++) { + if (flags[i]) { + res += array[2 * i + offset]; + } + } + return res; + } + + + private static int test2(int stop, int[] array, int offset, boolean[] flags) { + if (array == null) {} + int res = 0; + for (int i = 0; i < stop; i++) { + if (flags[i]) { + res += array[-2 * i + offset]; + } + } + return res; + } +} -- cgit v1.2.3 From 5f30df6cd70279fe9e8e1e6acb0f6b341fb9e675 Mon Sep 17 00:00:00 2001 From: kvn Date: Fri, 15 Jun 2018 08:28:08 -0700 Subject: 8202948: C2: assert(init_offset >= 0) failed: positive offset from object start Summary: convert the assert into compilation check which will skip superword optimization Reviewed-by: roland, thartmann --- src/share/vm/opto/superword.cpp | 4 +- .../loopopts/superword/TestNegBaseOffset.java | 59 ++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 test/compiler/loopopts/superword/TestNegBaseOffset.java diff --git a/src/share/vm/opto/superword.cpp b/src/share/vm/opto/superword.cpp index f005ef411..718f077d0 100644 --- a/src/share/vm/opto/superword.cpp +++ b/src/share/vm/opto/superword.cpp @@ -482,7 +482,9 @@ bool SuperWord::ref_is_alignable(SWPointer& p) { if (init_nd->is_Con() && p.invar() == NULL) { int init = init_nd->bottom_type()->is_int()->get_con(); int init_offset = init * p.scale_in_bytes() + offset; - assert(init_offset >= 0, "positive offset from object start"); + if (init_offset < 0) { // negative offset from object start? + return false; // may happen in dead loop + } if (vw % span == 0) { // If vm is a multiple of span, we use formula (1). if (span > 0) { diff --git a/test/compiler/loopopts/superword/TestNegBaseOffset.java b/test/compiler/loopopts/superword/TestNegBaseOffset.java new file mode 100644 index 000000000..4fe83eed5 --- /dev/null +++ b/test/compiler/loopopts/superword/TestNegBaseOffset.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8202948 + * @summary Test skipping vector packs with negative base offset. + * @comment Test fails only with -Xcomp when profiling data is not present. + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions + * -Xcomp -XX:-TieredCompilation -XX:CICompilerCount=1 + * -XX:CompileOnly=compiler/loopopts/superword/TestNegBaseOffset + * compiler.loopopts.superword.TestNegBaseOffset + */ + +package compiler.loopopts.superword; + +public class TestNegBaseOffset { + public static final int N = 400; + public static int iFld=10; + public static int iArr[]=new int[N]; + + public static void mainTest() { + int i0=1, i2; + while (++i0 < 339) { + if ((i0 % 2) == 0) { + for (i2 = 2; i2 > i0; i2 -= 3) { + iArr[i2 - 1] &= iFld; + } + } + } + } + + public static void main(String[] strArr) { + for (int i = 0; i < 10; i++) { + mainTest(); + } + } +} + -- cgit v1.2.3 From b3d1660b2bd63f104bca1ad7c147355e1e622529 Mon Sep 17 00:00:00 2001 From: neliasso Date: Thu, 14 Feb 2019 14:31:32 +0100 Subject: 8087128: C2: Disallow definition split on MachCopySpill nodes Reviewed-by: kvn --- src/share/vm/opto/reg_split.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/share/vm/opto/reg_split.cpp b/src/share/vm/opto/reg_split.cpp index af798914a..a132f1f9f 100644 --- a/src/share/vm/opto/reg_split.cpp +++ b/src/share/vm/opto/reg_split.cpp @@ -1171,9 +1171,8 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { (deflrg._direct_conflict || deflrg._must_spill)) || // Check for LRG being up in a register and we are inside a high // pressure area. Spill it down immediately. - (defup && is_high_pressure(b,&deflrg,insidx))) ) { + (defup && is_high_pressure(b,&deflrg,insidx) && !n->is_SpillCopy())) ) { assert( !n->rematerialize(), "" ); - assert( !n->is_SpillCopy(), "" ); // Do a split at the def site. maxlrg = split_DEF( n, b, insidx, maxlrg, Reachblock, debug_defs, splits, slidx ); // If it wasn't split bail -- cgit v1.2.3 From 2ecc2916e80fca8ec0561e33364227e10a8f3fdc Mon Sep 17 00:00:00 2001 From: kvn Date: Fri, 19 Jun 2015 17:46:42 -0700 Subject: 8080157: assert(allocates2(pc)) failed: not in CodeBuffer memory Summary: increase code_size2 for stubs Reviewed-by: iveresov --- src/cpu/x86/vm/stubRoutines_x86_64.hpp | 2 +- src/share/vm/runtime/stubRoutines.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cpu/x86/vm/stubRoutines_x86_64.hpp b/src/cpu/x86/vm/stubRoutines_x86_64.hpp index 15922b8ae..b048fd74e 100644 --- a/src/cpu/x86/vm/stubRoutines_x86_64.hpp +++ b/src/cpu/x86/vm/stubRoutines_x86_64.hpp @@ -33,7 +33,7 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _ enum platform_dependent_constants { code_size1 = 19000, // simply increase if too small (assembler will crash if too small) - code_size2 = 23000 // simply increase if too small (assembler will crash if too small) + code_size2 = 24000 // simply increase if too small (assembler will crash if too small) }; class x86 { diff --git a/src/share/vm/runtime/stubRoutines.cpp b/src/share/vm/runtime/stubRoutines.cpp index eb3064034..6b8f7e754 100644 --- a/src/share/vm/runtime/stubRoutines.cpp +++ b/src/share/vm/runtime/stubRoutines.cpp @@ -174,6 +174,9 @@ void StubRoutines::initialize1() { } CodeBuffer buffer(_code1); StubGenerator_generate(&buffer, false); + // When new stubs added we need to make sure there is some space left + // to catch situation when we should increase size again. + assert(buffer.insts_remaining() > 200, "increase code_size1"); } } @@ -226,6 +229,9 @@ void StubRoutines::initialize2() { } CodeBuffer buffer(_code2); StubGenerator_generate(&buffer, true); + // When new stubs added we need to make sure there is some space left + // to catch situation when we should increase size again. + assert(buffer.insts_remaining() > 200, "increase code_size2"); } #ifdef ASSERT -- cgit v1.2.3 From 807e718b7912681e89cb883923407b025f607417 Mon Sep 17 00:00:00 2001 From: hseigel Date: Thu, 11 Jul 2019 09:26:04 -0400 Subject: 8226798: JVM crash in klassItable::initialize_itable_for_interface(int, InstanceKlass*, bool, Thread*) Summary: When calculating vtable size at class load time, do not look for miranda method if matching package private method is found in a super class. Reviewed-by: acorn, lfoltan --- src/share/vm/oops/klassVtable.cpp | 22 +++++++++++++- test/runtime/VtableTests/VTableTest.java | 50 ++++++++++++++++++++++++++++++++ test/runtime/VtableTests/pkg/A.java | 28 ++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 test/runtime/VtableTests/VTableTest.java create mode 100644 test/runtime/VtableTests/pkg/A.java diff --git a/src/share/vm/oops/klassVtable.cpp b/src/share/vm/oops/klassVtable.cpp index 315d97f3e..61dd4c21d 100644 --- a/src/share/vm/oops/klassVtable.cpp +++ b/src/share/vm/oops/klassVtable.cpp @@ -663,6 +663,7 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, Method* super_method = NULL; InstanceKlass *holder = NULL; Method* recheck_method = NULL; + bool found_pkg_prvt_method = false; while (k != NULL) { // lookup through the hierarchy for a method with matching name and sign. super_method = InstanceKlass::cast(k)->lookup_method(name, signature); @@ -684,12 +685,31 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, return false; // else keep looking for transitive overrides } + // If we get here then one of the super classes has a package private method + // that will not get overridden because it is in a different package. But, + // that package private method does "override" any matching methods in super + // interfaces, so there will be no miranda vtable entry created. So, set flag + // to TRUE for use below, in case there are no methods in super classes that + // this target method overrides. + assert(super_method->is_package_private(), "super_method must be package private"); + assert(!superk->is_same_class_package(classloader(), classname), + "Must be different packages"); + found_pkg_prvt_method = true; } // Start with lookup result and continue to search up k = superk->super(); // haven't found an override match yet; continue to look } + // If found_pkg_prvt_method is set, then the ONLY matching method in the + // superclasses is package private in another package. That matching method will + // prevent a miranda vtable entry from being created. Because the target method can not + // override the package private method in another package, then it needs to be the root + // for its own vtable entry. + if (found_pkg_prvt_method) { + return true; + } + // if the target method is public or protected it may have a matching // miranda method in the super, whose entry it should re-use. // Actually, to handle cases that javac would not generate, we need @@ -697,7 +717,7 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, InstanceKlass *sk = InstanceKlass::cast(super); if (sk->has_miranda_methods()) { if (sk->lookup_method_in_all_interfaces(name, signature, Klass::find_defaults) != NULL) { - return false; // found a matching miranda; we do not need a new entry + return false; // found a matching miranda; we do not need a new entry } } return true; // found no match; we need a new entry diff --git a/test/runtime/VtableTests/VTableTest.java b/test/runtime/VtableTests/VTableTest.java new file mode 100644 index 000000000..2ca32e43f --- /dev/null +++ b/test/runtime/VtableTests/VTableTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8226798 + * @summary Check that the vTable for class C gets set up without causing + * an assertion failure. + * @compile pkg/A.java + * @run main VTableTest + */ + +public class VTableTest { + + interface Intf { + public default void m() { } + public default void unusedButNeededToReproduceIssue() { } + } + + static class B extends pkg.A implements Intf { + } + + static class C extends B { + public void m() { System.out.println("In C.m()"); } + } + + public static void main(String[] args) { + new C().m(); + } +} diff --git a/test/runtime/VtableTests/pkg/A.java b/test/runtime/VtableTests/pkg/A.java new file mode 100644 index 000000000..a4b7f49e7 --- /dev/null +++ b/test/runtime/VtableTests/pkg/A.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg; + +public class A { + void m() { } +} -- cgit v1.2.3 From e9a754db0d944b540d017b24e47145abeb40bf0a Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 3 Sep 2019 06:41:37 +0100 Subject: 8141570: Fix Zero interpreter build for --disable-precompiled-headers Summary: Prepare Zero build for backport of JDK-8062808. Reviewed-by: sgehwolf --- make/linux/makefiles/zeroshark.make | 16 +++++++++++----- src/share/vm/runtime/java.cpp | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/make/linux/makefiles/zeroshark.make b/make/linux/makefiles/zeroshark.make index 4480740e0..de1fcb353 100644 --- a/make/linux/makefiles/zeroshark.make +++ b/make/linux/makefiles/zeroshark.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. # Copyright 2007, 2008 Red Hat, Inc. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # @@ -25,8 +25,16 @@ # Setup common to Zero (non-Shark) and Shark versions of VM -# override this from the main file because some version of llvm do not like -Wundef -WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wunused-function -Wunused-value +# Some versions of llvm do not like -Wundef +ifeq ($(JVM_VARIANT_ZEROSHARK), true) + WARNING_FLAGS += -Wno-undef +endif +# Suppress some warning flags that are normally turned on for hotspot, +# because some of the zero code has not been updated accordingly. +WARNING_FLAGS += -Wno-return-type \ + -Wno-format-nonliteral -Wno-format-security \ + -Wno-maybe-uninitialized + # If FDLIBM_CFLAGS is non-empty it holds CFLAGS needed to be passed to # the compiler so as to be able to produce optimized objects @@ -48,5 +56,3 @@ endif ifeq ($(ARCH_DATA_MODEL), 64) CFLAGS += -D_LP64=1 endif - -OPT_CFLAGS/compactingPermGenGen.o = -O1 diff --git a/src/share/vm/runtime/java.cpp b/src/share/vm/runtime/java.cpp index faec9bae9..721f74321 100644 --- a/src/share/vm/runtime/java.cpp +++ b/src/share/vm/runtime/java.cpp @@ -45,6 +45,7 @@ #include "runtime/arguments.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/compilationPolicy.hpp" +#include "runtime/deoptimization.hpp" #include "runtime/fprofiler.hpp" #include "runtime/init.hpp" #include "runtime/interfaceSupport.hpp" -- cgit v1.2.3 From 5c08fcd0f41d9e602f0fbb1ed3fe2b13d2d331f5 Mon Sep 17 00:00:00 2001 From: zgu Date: Tue, 3 Sep 2019 06:57:35 +0100 Subject: 8155951: VM crash in nsk/jvmti/RedefineClasses/StressRedefine: assert failed: Corrupted constant pool 8151066: assert(0 <= i && i < length()) failed: index out of bounds Summary: lock classes for redefinition because constant pool merging isn't thread safe, use method constant pool because constant pool merging doesn't make equivalent cpCaches because of invokedynamic Reviewed-by: shade, andrew --- src/share/vm/ci/ciStreams.cpp | 9 ++-- src/share/vm/ci/ciStreams.hpp | 4 +- src/share/vm/oops/instanceKlass.hpp | 5 ++ src/share/vm/prims/jvmtiRedefineClasses.cpp | 73 ++++++++++++++++++++++------- src/share/vm/prims/jvmtiRedefineClasses.hpp | 4 ++ src/share/vm/runtime/mutexLocker.cpp | 2 + src/share/vm/runtime/mutexLocker.hpp | 1 + 7 files changed, 74 insertions(+), 24 deletions(-) diff --git a/src/share/vm/ci/ciStreams.cpp b/src/share/vm/ci/ciStreams.cpp index 76520fdff..a4eaf4739 100644 --- a/src/share/vm/ci/ciStreams.cpp +++ b/src/share/vm/ci/ciStreams.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -361,14 +361,14 @@ int ciBytecodeStream::get_method_index() { ciMethod* ciBytecodeStream::get_method(bool& will_link, ciSignature* *declared_signature_result) { VM_ENTRY_MARK; ciEnv* env = CURRENT_ENV; - constantPoolHandle cpool(_method->get_Method()->constants()); + constantPoolHandle cpool(THREAD, _method->get_Method()->constants()); ciMethod* m = env->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder); will_link = m->is_loaded(); // Use the MethodType stored in the CP cache to create a signature // with correct types (in respect to class loaders). if (has_method_type()) { - ciSymbol* sig_sym = env->get_symbol(cpool->symbol_at(get_method_signature_index())); + ciSymbol* sig_sym = env->get_symbol(cpool->symbol_at(get_method_signature_index(cpool))); ciKlass* pool_holder = env->get_klass(cpool->pool_holder()); ciMethodType* method_type = get_method_type(); ciSignature* declared_signature = new (env->arena()) ciSignature(pool_holder, sig_sym, method_type); @@ -465,9 +465,8 @@ int ciBytecodeStream::get_method_holder_index() { // Get the constant pool index of the signature of the method // referenced by the current bytecode. Used for generating // deoptimization information. -int ciBytecodeStream::get_method_signature_index() { +int ciBytecodeStream::get_method_signature_index(const constantPoolHandle& cpool) { GUARDED_VM_ENTRY( - ConstantPool* cpool = _holder->get_instanceKlass()->constants(); const int method_index = get_method_index(); const int name_and_type_index = cpool->name_and_type_ref_index_at(method_index); return cpool->signature_ref_index_at(name_and_type_index); diff --git a/src/share/vm/ci/ciStreams.hpp b/src/share/vm/ci/ciStreams.hpp index 091aa1bdf..07e573b59 100644 --- a/src/share/vm/ci/ciStreams.hpp +++ b/src/share/vm/ci/ciStreams.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -264,7 +264,7 @@ public: ciMethodType* get_method_type(); ciKlass* get_declared_method_holder(); int get_method_holder_index(); - int get_method_signature_index(); + int get_method_signature_index(const constantPoolHandle& cpool); // Get the resolved references arrays from the constant pool ciObjArray* get_resolved_references(); diff --git a/src/share/vm/oops/instanceKlass.hpp b/src/share/vm/oops/instanceKlass.hpp index a5f2eb346..444eadd38 100644 --- a/src/share/vm/oops/instanceKlass.hpp +++ b/src/share/vm/oops/instanceKlass.hpp @@ -225,6 +225,7 @@ class InstanceKlass: public Klass { // _is_marked_dependent can be set concurrently, thus cannot be part of the // _misc_flags. bool _is_marked_dependent; // used for marking during flushing and deoptimization + bool _is_being_redefined; // used for locking redefinition bool _has_unloaded_dependent; enum { @@ -667,6 +668,10 @@ class InstanceKlass: public Klass { _nonstatic_oop_map_size = words; } + // Redefinition locking. Class can only be redefined by one thread at a time. + bool is_being_redefined() const { return _is_being_redefined; } + void set_is_being_redefined(bool value) { _is_being_redefined = value; } + // RedefineClasses() support for previous versions: void add_previous_version(instanceKlassHandle ikh, int emcp_method_count); diff --git a/src/share/vm/prims/jvmtiRedefineClasses.cpp b/src/share/vm/prims/jvmtiRedefineClasses.cpp index 0e194b6f4..aac5f088d 100644 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -67,6 +67,43 @@ VM_RedefineClasses::VM_RedefineClasses(jint class_count, _res = JVMTI_ERROR_NONE; } +static inline InstanceKlass* get_ik(jclass def) { + oop mirror = JNIHandles::resolve_non_null(def); + return InstanceKlass::cast(java_lang_Class::as_Klass(mirror)); +} + +// If any of the classes are being redefined, wait +// Parallel constant pool merging leads to indeterminate constant pools. +void VM_RedefineClasses::lock_classes() { + MutexLocker ml(RedefineClasses_lock); + bool has_redefined; + do { + has_redefined = false; + // Go through classes each time until none are being redefined. + for (int i = 0; i < _class_count; i++) { + if (get_ik(_class_defs[i].klass)->is_being_redefined()) { + RedefineClasses_lock->wait(); + has_redefined = true; + break; // for loop + } + } + } while (has_redefined); + for (int i = 0; i < _class_count; i++) { + get_ik(_class_defs[i].klass)->set_is_being_redefined(true); + } + RedefineClasses_lock->notify_all(); +} + +void VM_RedefineClasses::unlock_classes() { + MutexLocker ml(RedefineClasses_lock); + for (int i = 0; i < _class_count; i++) { + assert(get_ik(_class_defs[i].klass)->is_being_redefined(), + "should be being redefined to get here"); + get_ik(_class_defs[i].klass)->set_is_being_redefined(false); + } + RedefineClasses_lock->notify_all(); +} + bool VM_RedefineClasses::doit_prologue() { if (_class_count == 0) { _res = JVMTI_ERROR_NONE; @@ -89,12 +126,21 @@ bool VM_RedefineClasses::doit_prologue() { _res = JVMTI_ERROR_NULL_POINTER; return false; } + + oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass); + // classes for primitives and arrays cannot be redefined + // check here so following code can assume these classes are InstanceKlass + if (!is_modifiable_class(mirror)) { + _res = JVMTI_ERROR_UNMODIFIABLE_CLASS; + return false; + } } // Start timer after all the sanity checks; not quite accurate, but // better than adding a bunch of stop() calls. RC_TIMER_START(_timer_vm_op_prologue); + lock_classes(); // We first load new class versions in the prologue, because somewhere down the // call chain it is required that the current thread is a Java thread. _res = load_new_class_versions(Thread::current()); @@ -111,6 +157,7 @@ bool VM_RedefineClasses::doit_prologue() { // Free os::malloc allocated memory in load_new_class_version. os::free(_scratch_classes); RC_TIMER_STOP(_timer_vm_op_prologue); + unlock_classes(); return false; } @@ -170,6 +217,8 @@ void VM_RedefineClasses::doit() { } void VM_RedefineClasses::doit_epilogue() { + unlock_classes(); + // Free os::malloc allocated memory. os::free(_scratch_classes); @@ -961,14 +1010,7 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) { // versions are deleted. Constant pools are deallocated while merging // constant pools HandleMark hm(THREAD); - - oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass); - // classes for primitives cannot be redefined - if (!is_modifiable_class(mirror)) { - return JVMTI_ERROR_UNMODIFIABLE_CLASS; - } - Klass* the_class_oop = java_lang_Class::as_Klass(mirror); - instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop); + instanceKlassHandle the_class(THREAD, get_ik(_class_defs[i].klass)); Symbol* the_class_sym = the_class->name(); // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark @@ -3855,22 +3897,19 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass, HandleMark hm(THREAD); // make sure handles from this call are freed RC_TIMER_START(_timer_rsc_phase1); - instanceKlassHandle scratch_class(scratch_class_oop); - - oop the_class_mirror = JNIHandles::resolve_non_null(the_jclass); - Klass* the_class_oop = java_lang_Class::as_Klass(the_class_mirror); - instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop); + instanceKlassHandle scratch_class(THREAD, scratch_class_oop); + instanceKlassHandle the_class(THREAD, get_ik(the_jclass)); // Remove all breakpoints in methods of this class JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); - jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop); + jvmti_breakpoints.clearall_in_class_at_safepoint(the_class()); // Deoptimize all compiled code that depends on this class flush_dependent_code(the_class, THREAD); _old_methods = the_class->methods(); _new_methods = scratch_class->methods(); - _the_class_oop = the_class_oop; + _the_class_oop = the_class(); compute_added_deleted_matching_methods(); update_jmethod_ids(); @@ -4094,14 +4133,14 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass, RC_TRACE_WITH_THREAD(0x00000001, THREAD, ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)", the_class->external_name(), - java_lang_Class::classRedefinedCount(the_class_mirror), + java_lang_Class::classRedefinedCount(the_class->java_mirror()), os::available_memory() >> 10)); { ResourceMark rm(THREAD); Events::log_redefinition(THREAD, "redefined class name=%s, count=%d", the_class->external_name(), - java_lang_Class::classRedefinedCount(the_class_mirror)); + java_lang_Class::classRedefinedCount(the_class->java_mirror())); } RC_TIMER_STOP(_timer_rsc_phase2); diff --git a/src/share/vm/prims/jvmtiRedefineClasses.hpp b/src/share/vm/prims/jvmtiRedefineClasses.hpp index aab9d4549..167c01c31 100644 --- a/src/share/vm/prims/jvmtiRedefineClasses.hpp +++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp @@ -490,6 +490,10 @@ class VM_RedefineClasses: public VM_Operation { void flush_dependent_code(instanceKlassHandle k_h, TRAPS); + // lock classes to redefine since constant pool merging isn't thread safe. + void lock_classes(); + void unlock_classes(); + static void dump_methods(); // Check that there are no old or obsolete methods diff --git a/src/share/vm/runtime/mutexLocker.cpp b/src/share/vm/runtime/mutexLocker.cpp index f358c75ea..1f61967aa 100644 --- a/src/share/vm/runtime/mutexLocker.cpp +++ b/src/share/vm/runtime/mutexLocker.cpp @@ -125,6 +125,7 @@ Monitor* GCTaskManager_lock = NULL; Mutex* Management_lock = NULL; Monitor* Service_lock = NULL; Monitor* PeriodicTask_lock = NULL; +Monitor* RedefineClasses_lock = NULL; #ifdef INCLUDE_TRACE Mutex* JfrStacktrace_lock = NULL; @@ -279,6 +280,7 @@ void mutex_init() { def(ProfileVM_lock , Monitor, special, false); // used for profiling of the VMThread def(CompileThread_lock , Monitor, nonleaf+5, false ); def(PeriodicTask_lock , Monitor, nonleaf+5, true); + def(RedefineClasses_lock , Monitor, nonleaf+5, true); #ifdef INCLUDE_TRACE def(JfrMsg_lock , Monitor, leaf, true); diff --git a/src/share/vm/runtime/mutexLocker.hpp b/src/share/vm/runtime/mutexLocker.hpp index be86bac71..138e30e83 100644 --- a/src/share/vm/runtime/mutexLocker.hpp +++ b/src/share/vm/runtime/mutexLocker.hpp @@ -141,6 +141,7 @@ extern Mutex* MMUTracker_lock; // protects the MMU extern Mutex* Management_lock; // a lock used to serialize JVM management extern Monitor* Service_lock; // a lock used for service thread operation extern Monitor* PeriodicTask_lock; // protects the periodic task structure +extern Monitor* RedefineClasses_lock; // locks classes from parallel redefinition #ifdef INCLUDE_TRACE extern Mutex* JfrStacktrace_lock; // used to guard access to the JFR stacktrace table -- cgit v1.2.3 From 0784d8722bfae86783312ee7a96fd941db9d6535 Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 4 Sep 2019 17:48:48 +0100 Subject: 8147611: G1 - Missing memory barrier in start_cset_region_for_worker Reviewed-by: mgerdin, tschatzl --- src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index e69839c4d..aa6bbc81a 100644 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2790,6 +2790,7 @@ HeapRegion* G1CollectedHeap::start_cset_region_for_worker(uint worker_i) { // Previous workers starting region is valid // so let's iterate from there start_ind = (cs_size * (worker_i - 1)) / active_workers; + OrderAccess::loadload(); result = _worker_cset_start_region[worker_i - 1]; } -- cgit v1.2.3 From 57b71186393a5bdaa113661fdbc988a267e03613 Mon Sep 17 00:00:00 2001 From: zgu Date: Thu, 12 Sep 2019 15:15:22 -0400 Subject: 8178870: instrumentation.retransformClasses cause coredump Summary: Don't double-free cached class bytes on redefinition loading failure. Reviewed-by: sspitsyn, jiangli --- src/share/vm/prims/jvmtiRedefineClasses.cpp | 11 +- .../RedefineTests/RedefineDoubleDelete.java | 81 ++++++++++ .../RedefineTests/libRedefineDoubleDelete.c | 164 +++++++++++++++++++++ test/runtime/RedefineTests/test8178870.sh | 87 +++++++++++ 4 files changed, 340 insertions(+), 3 deletions(-) create mode 100644 test/runtime/RedefineTests/RedefineDoubleDelete.java create mode 100644 test/runtime/RedefineTests/libRedefineDoubleDelete.c create mode 100644 test/runtime/RedefineTests/test8178870.sh diff --git a/src/share/vm/prims/jvmtiRedefineClasses.cpp b/src/share/vm/prims/jvmtiRedefineClasses.cpp index aac5f088d..8b99b217d 100644 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -151,6 +151,11 @@ bool VM_RedefineClasses::doit_prologue() { ClassLoaderData* cld = _scratch_classes[i]->class_loader_data(); // Free the memory for this class at class unloading time. Not before // because CMS might think this is still live. + InstanceKlass* ik = get_ik(_class_defs[i].klass); + if (ik->get_cached_class_file() == ((InstanceKlass*)_scratch_classes[i])->get_cached_class_file()) { + // Don't double-free cached_class_file copied from the original class if error. + ((InstanceKlass*)_scratch_classes[i])->set_cached_class_file(NULL); + } cld->add_to_deallocate_list((InstanceKlass*)_scratch_classes[i]); } } @@ -4019,12 +4024,12 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass, // with them was cached on the scratch class, move to the_class. // Note: we still want to do this if nothing needed caching since it // should get cleared in the_class too. - if (the_class->get_cached_class_file_bytes() == 0) { + if (the_class->get_cached_class_file() == 0) { // the_class doesn't have a cache yet so copy it the_class->set_cached_class_file(scratch_class->get_cached_class_file()); } - else if (scratch_class->get_cached_class_file_bytes() != - the_class->get_cached_class_file_bytes()) { + else if (scratch_class->get_cached_class_file() != + the_class->get_cached_class_file()) { // The same class can be present twice in the scratch classes list or there // are multiple concurrent RetransformClasses calls on different threads. // In such cases we have to deallocate scratch_class cached_class_file. diff --git a/test/runtime/RedefineTests/RedefineDoubleDelete.java b/test/runtime/RedefineTests/RedefineDoubleDelete.java new file mode 100644 index 000000000..7b18b45f1 --- /dev/null +++ b/test/runtime/RedefineTests/RedefineDoubleDelete.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8178870 + * @summary Redefine class with CFLH twice to test deleting the cached_class_file + */ + +public class RedefineDoubleDelete { + + // Class gets a redefinition error because it adds a data member + public static String newB = + "class RedefineDoubleDelete$B {" + + " int count1 = 0;" + + "}"; + + public static String newerB = + "class RedefineDoubleDelete$B { " + + " int faa() { System.out.println(\"baa\"); return 2; }" + + "}"; + + // The ClassFileLoadHook for this class turns foo into faa and prints out faa. + static class B { + int faa() { System.out.println("foo"); return 1; } + } + + public static void main(String args[]) throws Exception { + + B b = new B(); + int val = b.faa(); + if (val != 1) { + throw new RuntimeException("return value wrong " + val); + } + + // Redefine B twice to get cached_class_file in both B scratch classes + try { + RedefineClassHelper.redefineClass(B.class, newB); + } catch (java.lang.UnsupportedOperationException e) { + // this is expected + } + try { + RedefineClassHelper.redefineClass(B.class, newB); + } catch (java.lang.UnsupportedOperationException e) { + // this is expected + } + + // Do a full GC. + System.gc(); + + // Redefine with a compatible class + RedefineClassHelper.redefineClass(B.class, newerB); + val = b.faa(); + if (val != 2) { + throw new RuntimeException("return value wrong " + val); + } + + // Do another full GC to clean things up. + System.gc(); + } +} diff --git a/test/runtime/RedefineTests/libRedefineDoubleDelete.c b/test/runtime/RedefineTests/libRedefineDoubleDelete.c new file mode 100644 index 000000000..d855e873a --- /dev/null +++ b/test/runtime/RedefineTests/libRedefineDoubleDelete.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include +#include "jvmti.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef JNI_ENV_ARG + +#ifdef __cplusplus +#define JNI_ENV_ARG(x, y) y +#define JNI_ENV_PTR(x) x +#else +#define JNI_ENV_ARG(x,y) x, y +#define JNI_ENV_PTR(x) (*x) +#endif + +#endif + +#define TranslateError(err) "JVMTI error" + +static jvmtiEnv *jvmti = NULL; + +static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved); + +JNIEXPORT +jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { + return JNI_VERSION_1_8; +} + + +static jint newClassDataLen = 0; +static unsigned char* newClassData = NULL; + +static jint +getBytecodes(jvmtiEnv *jvmti_env, + jint class_data_len, const unsigned char* class_data) { + int i; + jint res; + + newClassDataLen = class_data_len; + res = (*jvmti_env)->Allocate(jvmti_env, newClassDataLen, &newClassData); + if (res != JNI_OK) { + printf(" Unable to allocate bytes\n"); + return JNI_ERR; + } + for (i = 0; i < newClassDataLen; i++) { + newClassData[i] = class_data[i]; + // Rewrite oo in class to aa + if (i > 0 && class_data[i] == 'o' && class_data[i-1] == 'o') { + newClassData[i] = newClassData[i-1] = 'a'; + } + } + printf(" ... copied bytecode: %d bytes\n", (int)newClassDataLen); + return JNI_OK; +} + + +static void JNICALL +Callback_ClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv *env, + jclass class_being_redefined, + jobject loader, const char* name, jobject protection_domain, + jint class_data_len, const unsigned char* class_data, + jint *new_class_data_len, unsigned char** new_class_data) { + if (name != NULL && strcmp(name, "RedefineDoubleDelete$B") == 0) { + if (newClassData == NULL) { + jint res = getBytecodes(jvmti_env, class_data_len, class_data); + if (res == JNI_ERR) { + printf(">>> ClassFileLoadHook event: class name %s FAILED\n", name); + return; + } + // Only change for first CFLH event. + *new_class_data_len = newClassDataLen; + *new_class_data = newClassData; + } + printf(">>> ClassFileLoadHook event: class name %s\n", name); + } +} + +static +jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { + jint res, size; + jvmtiCapabilities caps; + jvmtiEventCallbacks callbacks; + jvmtiError err; + + res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), + JVMTI_VERSION_1_2); + if (res != JNI_OK || jvmti == NULL) { + printf(" Error: wrong result of a valid call to GetEnv!\n"); + return JNI_ERR; + } + + printf("Enabling following capabilities: can_generate_all_class_hook_events, " + "can_retransform_classes, can_redefine_classes"); + memset(&caps, 0, sizeof(caps)); + caps.can_generate_all_class_hook_events = 1; + caps.can_retransform_classes = 1; + caps.can_redefine_classes = 1; + printf("\n"); + + err = (*jvmti)->AddCapabilities(jvmti, &caps); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in AddCapabilites: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + size = (jint)sizeof(callbacks); + + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.ClassFileLoadHook = Callback_ClassFileLoadHook; + + err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in SetEventCallbacks: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + return JNI_OK; +} + +#ifdef __cplusplus +} +#endif diff --git a/test/runtime/RedefineTests/test8178870.sh b/test/runtime/RedefineTests/test8178870.sh new file mode 100644 index 000000000..4a90e2655 --- /dev/null +++ b/test/runtime/RedefineTests/test8178870.sh @@ -0,0 +1,87 @@ +#!/bin/sh + +# +# Copyright (c) 2019, Red Hat, Inc. All rights reserved. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +## @test test.sh +## @bug 8178870 +## @summary test instrumentation.retransformClasses +## @run shell test.sh + +if [ "${TESTSRC}" = "" ] +then + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" +fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh + +LIB_SRC=${TESTSRC}/../../testlibrary/ + +# set platform-dependent variables +OS=`uname -s` +echo "Testing on " $OS +case "$OS" in + Linux) + cc_cmd=`which gcc` + if [ "x$cc_cmd" == "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; + fi + ;; + Solaris) + cc_cmd=`which cc` + if [ "x$cc_cmd" == "x" ]; then + echo "WARNING: cc not found. Cannot execute test." 2>&1 + exit 0; + fi + ;; + *) + echo "Test passed. Only on Linux and Solaris" + exit 0; + ;; +esac + +THIS_DIR=. + +cp ${TESTSRC}/RedefineDoubleDelete.java ${THIS_DIR} +mkdir -p ${THIS_DIR}/classes +${TESTJAVA}/bin/javac -sourcepath ${LIB_SRC} -d ${THIS_DIR}/classes ${LIB_SRC}RedefineClassHelper.java +${TESTJAVA}/bin/javac -cp .:${THIS_DIR}/classes:${TESTJAVA}/lib/tools.jar -d ${THIS_DIR} RedefineDoubleDelete.java + +$cc_cmd -fPIC -shared -o ${THIS_DIR}${FS}libRedefineDoubleDelete.so \ + -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ + ${TESTSRC}/libRedefineDoubleDelete.c + +LD_LIBRARY_PATH=${THIS_DIR} +echo LD_LIBRARY_PATH = ${LD_LIBRARY_PATH} +export LD_LIBRARY_PATH + +# Install redefineagent.jar +${TESTJAVA}/bin${FS}java -cp ${THIS_DIR}/classes RedefineClassHelper + +echo +echo ${TESTJAVA}/bin/java -agentlib:RedefineDoubleDelete RedefineDoubleDelete +${TESTJAVA}/bin/java -cp .:${THIS_DIR}${FS}classes -javaagent:redefineagent.jar -agentlib:RedefineDoubleDelete RedefineDoubleDelete + -- cgit v1.2.3 From e72c9665f8d7cd778937840bacd5cbedf1e95714 Mon Sep 17 00:00:00 2001 From: zgu Date: Thu, 12 Sep 2019 15:29:50 -0400 Subject: 8217676: Upgrade libpng to 1.6.37 Reviewed-by: prr, jdv, kcr --- THIRD_PARTY_README | 153 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 91 insertions(+), 62 deletions(-) diff --git a/THIRD_PARTY_README b/THIRD_PARTY_README index 814e5f234..eddee26a0 100644 --- a/THIRD_PARTY_README +++ b/THIRD_PARTY_README @@ -1470,60 +1470,90 @@ included with JDK 8 and OpenJDK 8 source distributions. ------------------------------------------------------------------------------- -%% This notice is provided with respect to libpng 1.6.35, which may be +%% This notice is provided with respect to libpng 1.6.37, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- -This copy of the libpng notices is provided for your convenience. In case of -any discrepancy between this copy and the notices in the file png.h that is -included in the libpng distribution, the latter shall prevail. +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE +========================================= -COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: +PNG Reference Library License version 2 +--------------------------------------- -If you modify libpng you may insert additional notices immediately following -this sentence. + * Copyright (c) 1995-2019 The PNG Reference Library Authors. + * Copyright (c) 2018-2019 Cosmin Truta. + * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. + * Copyright (c) 1996-1997 Andreas Dilger. + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. -This code is released under the libpng license. +The software is supplied "as is", without warranty of any kind, +express or implied, including, without limitation, the warranties +of merchantability, fitness for a particular purpose, title, and +non-infringement. In no event shall the Copyright owners, or +anyone distributing the software, be liable for any damages or +other liability, whether in contract, tort or otherwise, arising +from, out of, or in connection with the software, or the use or +other dealings in the software, even if advised of the possibility +of such damage. -libpng versions 1.0.7, July 1, 2000 through 1.6.35, July 15, 2018 are +Permission is hereby granted to use, copy, modify, and distribute +this software, or portions hereof, for any purpose, without fee, +subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you + use this software in a product, an acknowledgment in the product + documentation would be appreciated, but is not required. + + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + + +PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) +----------------------------------------------------------------------- + +libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are derived from libpng-1.0.6, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors: - Simon-Pierre Cadieux - Eric S. Raymond - Mans Rullgard - Cosmin Truta - Gilles Vollant - James Yu - Mandar Sahastrabuddhe - Google Inc. - Vadim Barkov + Simon-Pierre Cadieux + Eric S. Raymond + Mans Rullgard + Cosmin Truta + Gilles Vollant + James Yu + Mandar Sahastrabuddhe + Google Inc. + Vadim Barkov and with the following additions to the disclaimer: - There is no warranty against interference with your enjoyment of the - library or against infringement. There is no warranty that our - efforts or the library will fulfill any of your particular purposes - or needs. This library is provided with all faults, and the entire - risk of satisfactory quality, performance, accuracy, and effort is with - the user. + There is no warranty against interference with your enjoyment of + the library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is + with the user. Some files in the "contrib" directory and some configure-generated -files that are distributed with libpng have other copyright owners and +files that are distributed with libpng have other copyright owners, and are released under other open source licenses. libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from libpng-0.96, and are distributed according to the same disclaimer and -license as libpng-0.96, with the following individuals added to the list -of Contributing Authors: +license as libpng-0.96, with the following individuals added to the +list of Contributing Authors: - Tom Lane - Glenn Randers-Pehrson - Willem van Schaik + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik libpng versions 0.89, June 1996, through 0.96, May 1997, are Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, @@ -1531,14 +1561,14 @@ and are distributed according to the same disclaimer and license as libpng-0.88, with the following individuals added to the list of Contributing Authors: - John Bowler - Kevin Bracey - Sam Bushell - Magnus Holmgren - Greg Roelofs - Tom Tanner + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner -Some files in the "scripts" directory have other copyright owners +Some files in the "scripts" directory have other copyright owners, but are released under this license. libpng versions 0.5, May 1995, through 0.88, January 1996, are @@ -1547,39 +1577,38 @@ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: - Andreas Dilger - Dave Martindale - Guy Eric Schalnat - Paul Schmidt - Tim Wegner - -The PNG Reference Library is supplied "AS IS". The Contributing Authors -and Group 42, Inc. disclaim all warranties, expressed or implied, -including, without limitation, the warranties of merchantability and of -fitness for any purpose. The Contributing Authors and Group 42, Inc. -assume no liability for direct, indirect, incidental, special, exemplary, -or consequential damages, which may result from the use of the PNG -Reference Library, even if advised of the possibility of such damage. + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing +Authors and Group 42, Inc. disclaim all warranties, expressed or +implied, including, without limitation, the warranties of +merchantability and of fitness for any purpose. The Contributing +Authors and Group 42, Inc. assume no liability for direct, indirect, +incidental, special, exemplary, or consequential damages, which may +result from the use of the PNG Reference Library, even if advised of +the possibility of such damage. Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: - 1. The origin of this source code must not be misrepresented. - - 2. Altered versions must be plainly marked as such and must not - be misrepresented as being the original source. + 1. The origin of this source code must not be misrepresented. - 3. This Copyright notice may not be removed or altered from any - source or altered source distribution. + 2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. -The Contributing Authors and Group 42, Inc. specifically permit, without -fee, and encourage the use of this source code as a component to -supporting the PNG file format in commercial products. If you use this -source code in a product, acknowledgment is not required but would be -appreciated. + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. -END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. +The Contributing Authors and Group 42, Inc. specifically permit, +without fee, and encourage the use of this source code as a component +to supporting the PNG file format in commercial products. If you use +this source code in a product, acknowledgment is not required but would +be appreciated. TRADEMARK: -- cgit v1.2.3 From bd83d7cf987b561bdf1cf1cb1cb52f2a786d0ae2 Mon Sep 17 00:00:00 2001 From: dsamersoff Date: Fri, 13 Jun 2014 05:10:44 -0700 Subject: 8038392: Generating prelink cache breaks JAVA 'jinfo' utility normal behaviour Summary: Better parsing of /proc/pid/maps in sa Reviewed-by: sspitsyn, sla --- agent/src/os/linux/ps_proc.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/agent/src/os/linux/ps_proc.c b/agent/src/os/linux/ps_proc.c index abf2d60fd..c4d6a9ecc 100644 --- a/agent/src/os/linux/ps_proc.c +++ b/agent/src/os/linux/ps_proc.c @@ -345,7 +345,7 @@ static bool add_new_thread(struct ps_prochandle* ph, pthread_t pthread_id, lwpid static bool read_lib_info(struct ps_prochandle* ph) { char fname[32]; - char buf[256]; + char buf[PATH_MAX]; FILE *fp = NULL; sprintf(fname, "/proc/%d/maps", ph->pid); @@ -355,10 +355,41 @@ static bool read_lib_info(struct ps_prochandle* ph) { return false; } - while(fgets_no_cr(buf, 256, fp)){ - char * word[6]; - int nwords = split_n_str(buf, 6, word, ' ', '\0'); - if (nwords > 5 && find_lib(ph, word[5]) == false) { + while(fgets_no_cr(buf, PATH_MAX, fp)){ + char * word[7]; + int nwords = split_n_str(buf, 7, word, ' ', '\0'); + + if (nwords < 6) { + // not a shared library entry. ignore. + continue; + } + + // SA does not handle the lines with patterns: + // "[stack]", "[heap]", "[vdso]", "[vsyscall]", etc. + if (word[5][0] == '[') { + // not a shared library entry. ignore. + continue; + } + + if (nwords > 6) { + // prelink altered mapfile when the program is running. + // Entries like one below have to be skipped + // /lib64/libc-2.15.so (deleted) + // SO name in entries like one below have to be stripped. + // /lib64/libpthread-2.15.so.#prelink#.EECVts + char *s = strstr(word[5],".#prelink#"); + if (s == NULL) { + // No prelink keyword. skip deleted library + print_debug("skip shared object %s deleted by prelink\n", word[5]); + continue; + } + + // Fall through + print_debug("rectifying shared object name %s changed by prelink\n", word[5]); + *s = 0; + } + + if (find_lib(ph, word[5]) == false) { intptr_t base; lib_info* lib; #ifdef _LP64 -- cgit v1.2.3 From 8db670fe084f4483e557d1a38690bcaf4814f475 Mon Sep 17 00:00:00 2001 From: valeriep Date: Wed, 26 Jun 2019 01:15:51 +0000 Subject: 8226607: Inconsistent info between pcsclite.md and MUSCLE headers Summary: Updated the info based on MUSCLE v1.8.24 Reviewed-by: ascarpino --- THIRD_PARTY_README | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/THIRD_PARTY_README b/THIRD_PARTY_README index eddee26a0..7dc54a057 100644 --- a/THIRD_PARTY_README +++ b/THIRD_PARTY_README @@ -2130,13 +2130,13 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice ------------------------------------------------------------------------------- -%% This notice is provided with respect to PC/SC Lite for Suse Linux v.1.1.1, +%% This notice is provided with respect to PC/SC Lite v1.8.24, which may be included with JRE 8, JDK 8, and OpenJDK 8 on Linux and Solaris. --- begin of LICENSE --- -Copyright (c) 1999-2004 David Corcoran -Copyright (c) 1999-2004 Ludovic Rousseau +Copyright (c) 1999-2003 David Corcoran +Copyright (c) 2001-2011 Ludovic Rousseau All rights reserved. Redistribution and use in source and binary forms, with or without @@ -2148,15 +2148,10 @@ are met: 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. All advertising materials mentioning features or use of this software - must display the following acknowledgement: - This product includes software developed by: - David Corcoran - http://www.linuxnet.com (MUSCLE) -4. The name of the author may not be used to endorse or promote products +3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. -Changes to this license can be made only by the copyright author with +Changes to this license can be made only by the copyright author with explicit written consent. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -- cgit v1.2.3 From e0f8cb77f27287f4c20f0ca5423806804b2726b0 Mon Sep 17 00:00:00 2001 From: zgu Date: Thu, 26 Sep 2019 06:56:38 +0100 Subject: 8231463: Fix runtime/RedefineTests/RedefineDoubleDelete.java test in 8u Reviewed-by: andrew --- .../RedefineTests/RedefineDoubleDelete.java | 4 + test/runtime/RedefineTests/test8178870.sh | 87 ---------------------- 2 files changed, 4 insertions(+), 87 deletions(-) delete mode 100644 test/runtime/RedefineTests/test8178870.sh diff --git a/test/runtime/RedefineTests/RedefineDoubleDelete.java b/test/runtime/RedefineTests/RedefineDoubleDelete.java index 7b18b45f1..1f4533f8e 100644 --- a/test/runtime/RedefineTests/RedefineDoubleDelete.java +++ b/test/runtime/RedefineTests/RedefineDoubleDelete.java @@ -24,7 +24,11 @@ /* * @test * @bug 8178870 + * @library /testlibrary * @summary Redefine class with CFLH twice to test deleting the cached_class_file + * @build RedefineClassHelper + * @run main RedefineClassHelper + * @run main/othervm -javaagent:redefineagent.jar RedefineDoubleDelete */ public class RedefineDoubleDelete { diff --git a/test/runtime/RedefineTests/test8178870.sh b/test/runtime/RedefineTests/test8178870.sh deleted file mode 100644 index 4a90e2655..000000000 --- a/test/runtime/RedefineTests/test8178870.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2019, Red Hat, Inc. All rights reserved. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -# - -## @test test.sh -## @bug 8178870 -## @summary test instrumentation.retransformClasses -## @run shell test.sh - -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -LIB_SRC=${TESTSRC}/../../testlibrary/ - -# set platform-dependent variables -OS=`uname -s` -echo "Testing on " $OS -case "$OS" in - Linux) - cc_cmd=`which gcc` - if [ "x$cc_cmd" == "x" ]; then - echo "WARNING: gcc not found. Cannot execute test." 2>&1 - exit 0; - fi - ;; - Solaris) - cc_cmd=`which cc` - if [ "x$cc_cmd" == "x" ]; then - echo "WARNING: cc not found. Cannot execute test." 2>&1 - exit 0; - fi - ;; - *) - echo "Test passed. Only on Linux and Solaris" - exit 0; - ;; -esac - -THIS_DIR=. - -cp ${TESTSRC}/RedefineDoubleDelete.java ${THIS_DIR} -mkdir -p ${THIS_DIR}/classes -${TESTJAVA}/bin/javac -sourcepath ${LIB_SRC} -d ${THIS_DIR}/classes ${LIB_SRC}RedefineClassHelper.java -${TESTJAVA}/bin/javac -cp .:${THIS_DIR}/classes:${TESTJAVA}/lib/tools.jar -d ${THIS_DIR} RedefineDoubleDelete.java - -$cc_cmd -fPIC -shared -o ${THIS_DIR}${FS}libRedefineDoubleDelete.so \ - -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ - ${TESTSRC}/libRedefineDoubleDelete.c - -LD_LIBRARY_PATH=${THIS_DIR} -echo LD_LIBRARY_PATH = ${LD_LIBRARY_PATH} -export LD_LIBRARY_PATH - -# Install redefineagent.jar -${TESTJAVA}/bin${FS}java -cp ${THIS_DIR}/classes RedefineClassHelper - -echo -echo ${TESTJAVA}/bin/java -agentlib:RedefineDoubleDelete RedefineDoubleDelete -${TESTJAVA}/bin/java -cp .:${THIS_DIR}${FS}classes -javaagent:redefineagent.jar -agentlib:RedefineDoubleDelete RedefineDoubleDelete - -- cgit v1.2.3 From 86da27e28a75deb6a47644be77398a968f4e6aad Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 15 Oct 2019 21:37:52 +0100 Subject: Added tag jdk8u232-ga for changeset 12177d88b89c --- .hgtags | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.hgtags b/.hgtags index 7b31328ff..a933d7c01 100644 --- a/.hgtags +++ b/.hgtags @@ -1307,3 +1307,13 @@ d690709cc3398f8cfd6ffebb89a229105fb3e69a jdk8u222-b04 55f693ba975d445d83a59cc32367ec4c2452b0c5 jdk8u222-b09 adfdce09acc32a691145a67792d47ab637159776 jdk8u222-b10 adfdce09acc32a691145a67792d47ab637159776 jdk8u222-ga +afa42cf8d060a12fe2fd24210cac6c46252fcd53 jdk8u232-b01 +c963a2881865f6fab5b49a31d22651e8e1b4bf46 jdk8u232-b02 +fa7fe6dae563edaae8a8bbe8ac4bd4fa942bde0c jdk8u232-b03 +921c5ee7965fdfde75f578ddda24d5cd16f124dc jdk8u232-b04 +b13d7942036329f64c77a93cffc25e1b52523a3c jdk8u232-b05 +fea2c7f50ce8e6aee1e946eaec7b834193747d82 jdk8u232-b06 +c751303497d539aa85c6373aa0fa85580d3f3044 jdk8u232-b07 +4170228e11e6313e948e6ddcae9af3eed06b1fbe jdk8u232-b08 +12177d88b89c12c14daa5ad681030d7551e8a5a0 jdk8u232-b09 +12177d88b89c12c14daa5ad681030d7551e8a5a0 jdk8u232-ga -- cgit v1.2.3