From da3a61161e64d9f66fbd42bff7b2410b5bf21089 Mon Sep 17 00:00:00 2001 From: kuenking111 Date: Fri, 10 Dec 2021 09:41:46 +0800 Subject: [PATCH 1/8] I4LWAN: Default timezone should return zone ID if /etc/localtime is valid but not canonicalization on linux --- ...id-but-not-canonicalization-on-linux.patch | 486 ++++++++++++++++++ openjdk-1.8.0.spec | 7 +- 2 files changed, 492 insertions(+), 1 deletion(-) create mode 100755 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch diff --git a/8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch b/8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch new file mode 100755 index 0000000..56e0f28 --- /dev/null +++ b/8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch @@ -0,0 +1,486 @@ +From 07654f80f1dc979b825c8c26c45e683547d20941 Mon Sep 17 00:00:00 2001 +From: s00478819 +Date: Mon, 25 Oct 2021 17:38:14 +0800 +Subject: [PATCH 1/4] 8273111: Default timezone should return zone ID if + /etc/localtime is valid but not canonicalization on linux + +--- + jdk/make/lib/ServiceabilityLibraries.gmk | 1 + + .../solaris/native/java/io/canonicalize_md.c | 144 +-------------- + jdk/src/solaris/native/java/io/path_util.c | 166 ++++++++++++++++++ + jdk/src/solaris/native/java/io/path_util.h | 31 ++++ + .../solaris/native/java/util/TimeZone_md.c | 61 +++---- + 5 files changed, 230 insertions(+), 173 deletions(-) + create mode 100644 jdk/src/solaris/native/java/io/path_util.c + create mode 100644 jdk/src/solaris/native/java/io/path_util.h + +diff --git a/jdk/make/lib/ServiceabilityLibraries.gmk b/jdk/make/lib/ServiceabilityLibraries.gmk +index 36b6c6811..2c80ffc00 100644 +--- a/jdk/make/lib/ServiceabilityLibraries.gmk ++++ b/jdk/make/lib/ServiceabilityLibraries.gmk +@@ -225,6 +225,7 @@ LIBINSTRUMENT_FILES := \ + PathCharsValidator.c \ + Reentrancy.c \ + Utilities.c \ ++ path_util.c \ + canonicalize_md.c + + LIBINSTRUMENT_DIR := $(JDK_OUTPUTDIR)/objs/libinstrument +diff --git a/jdk/src/solaris/native/java/io/canonicalize_md.c b/jdk/src/solaris/native/java/io/canonicalize_md.c +index cb8ce69c8..2bd1ef2cd 100644 +--- a/jdk/src/solaris/native/java/io/canonicalize_md.c ++++ b/jdk/src/solaris/native/java/io/canonicalize_md.c +@@ -33,154 +33,12 @@ + #include + #include + #include +-#if !defined(_ALLBSD_SOURCE) +-#include +-#endif ++#include "path_util.h" + + + /* Note: The comments in this file use the terminology + defined in the java.io.File class */ + +- +-/* Check the given name sequence to see if it can be further collapsed. +- Return zero if not, otherwise return the number of names in the sequence. */ +- +-static int +-collapsible(char *names) +-{ +- char *p = names; +- int dots = 0, n = 0; +- +- while (*p) { +- if ((p[0] == '.') && ((p[1] == '\0') +- || (p[1] == '/') +- || ((p[1] == '.') && ((p[2] == '\0') +- || (p[2] == '/'))))) { +- dots = 1; +- } +- n++; +- while (*p) { +- if (*p == '/') { +- p++; +- break; +- } +- p++; +- } +- } +- return (dots ? n : 0); +-} +- +- +-/* Split the names in the given name sequence, +- replacing slashes with nulls and filling in the given index array */ +- +-static void +-splitNames(char *names, char **ix) +-{ +- char *p = names; +- int i = 0; +- +- while (*p) { +- ix[i++] = p++; +- while (*p) { +- if (*p == '/') { +- *p++ = '\0'; +- break; +- } +- p++; +- } +- } +-} +- +- +-/* Join the names in the given name sequence, ignoring names whose index +- entries have been cleared and replacing nulls with slashes as needed */ +- +-static void +-joinNames(char *names, int nc, char **ix) +-{ +- int i; +- char *p; +- +- for (i = 0, p = names; i < nc; i++) { +- if (!ix[i]) continue; +- if (i > 0) { +- p[-1] = '/'; +- } +- if (p == ix[i]) { +- p += strlen(p) + 1; +- } else { +- char *q = ix[i]; +- while ((*p++ = *q++)); +- } +- } +- *p = '\0'; +-} +- +- +-/* Collapse "." and ".." names in the given path wherever possible. +- A "." name may always be eliminated; a ".." name may be eliminated if it +- follows a name that is neither "." nor "..". This is a syntactic operation +- that performs no filesystem queries, so it should only be used to cleanup +- after invoking the realpath() procedure. */ +- +-static void +-collapse(char *path) +-{ +- char *names = (path[0] == '/') ? path + 1 : path; /* Preserve first '/' */ +- int nc; +- char **ix; +- int i, j; +- char *p, *q; +- +- nc = collapsible(names); +- if (nc < 2) return; /* Nothing to do */ +- ix = (char **)alloca(nc * sizeof(char *)); +- splitNames(names, ix); +- +- for (i = 0; i < nc; i++) { +- int dots = 0; +- +- /* Find next occurrence of "." or ".." */ +- do { +- char *p = ix[i]; +- if (p[0] == '.') { +- if (p[1] == '\0') { +- dots = 1; +- break; +- } +- if ((p[1] == '.') && (p[2] == '\0')) { +- dots = 2; +- break; +- } +- } +- i++; +- } while (i < nc); +- if (i >= nc) break; +- +- /* At this point i is the index of either a "." or a "..", so take the +- appropriate action and then continue the outer loop */ +- if (dots == 1) { +- /* Remove this instance of "." */ +- ix[i] = 0; +- } +- else { +- /* If there is a preceding name, remove both that name and this +- instance of ".."; otherwise, leave the ".." as is */ +- for (j = i - 1; j >= 0; j--) { +- if (ix[j]) break; +- } +- if (j < 0) continue; +- ix[j] = 0; +- ix[i] = 0; +- } +- /* i will be incremented at the top of the loop */ +- } +- +- joinNames(names, nc, ix); +-} +- +- + /* Convert a pathname to canonical form. The input path is assumed to contain + no duplicate slashes. On Solaris we can use realpath() to do most of the + work, though once that's done we still must collapse any remaining "." and +diff --git a/jdk/src/solaris/native/java/io/path_util.c b/jdk/src/solaris/native/java/io/path_util.c +new file mode 100644 +index 000000000..8a533f812 +--- /dev/null ++++ b/jdk/src/solaris/native/java/io/path_util.c +@@ -0,0 +1,166 @@ ++/* ++ * Copyright (c) 2021, 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. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * 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 ++#if !defined(_ALLBSD_SOURCE) ++#include ++#endif ++#include "path_util.h" ++ ++/* Check the given name sequence to see if it can be further collapsed. ++ Return zero if not, otherwise return the number of names in the sequence. */ ++ ++static int ++collapsible(char *names) ++{ ++ char *p = names; ++ int dots = 0, n = 0; ++ ++ while (*p) { ++ if ((p[0] == '.') && ((p[1] == '\0') ++ || (p[1] == '/') ++ || ((p[1] == '.') && ((p[2] == '\0') ++ || (p[2] == '/'))))) { ++ dots = 1; ++ } ++ n++; ++ while (*p) { ++ if (*p == '/') { ++ p++; ++ break; ++ } ++ p++; ++ } ++ } ++ return (dots ? n : 0); ++} ++ ++/* Split the names in the given name sequence, ++ replacing slashes with nulls and filling in the given index array */ ++ ++static void ++splitNames(char *names, char **ix) ++{ ++ char *p = names; ++ int i = 0; ++ ++ while (*p) { ++ ix[i++] = p++; ++ while (*p) { ++ if (*p == '/') { ++ *p++ = '\0'; ++ break; ++ } ++ p++; ++ } ++ } ++} ++ ++/* Join the names in the given name sequence, ignoring names whose index ++ entries have been cleared and replacing nulls with slashes as needed */ ++ ++static void ++joinNames(char *names, int nc, char **ix) ++{ ++ int i; ++ char *p; ++ ++ for (i = 0, p = names; i < nc; i++) { ++ if (!ix[i]) continue; ++ if (i > 0) { ++ p[-1] = '/'; ++ } ++ if (p == ix[i]) { ++ p += strlen(p) + 1; ++ } else { ++ char *q = ix[i]; ++ while ((*p++ = *q++)); ++ } ++ } ++ *p = '\0'; ++} ++ ++/* Collapse "." and ".." names in the given path wherever possible. ++ A "." name may always be eliminated; a ".." name may be eliminated if it ++ follows a name that is neither "." nor "..". This is a syntactic operation ++ that performs no filesystem queries, so it should only be used to cleanup ++ after invoking the realpath() procedure. */ ++ ++void ++collapse(char *path) ++{ ++ char *names = (path[0] == '/') ? path + 1 : path; /* Preserve first '/' */ ++ int nc; ++ char **ix; ++ int i, j; ++ char *p, *q; ++ ++ nc = collapsible(names); ++ if (nc < 2) return; /* Nothing to do */ ++ ix = (char **)alloca(nc * sizeof(char *)); ++ splitNames(names, ix); ++ ++ for (i = 0; i < nc; i++) { ++ int dots = 0; ++ ++ /* Find next occurrence of "." or ".." */ ++ do { ++ char *p = ix[i]; ++ if (p[0] == '.') { ++ if (p[1] == '\0') { ++ dots = 1; ++ break; ++ } ++ if ((p[1] == '.') && (p[2] == '\0')) { ++ dots = 2; ++ break; ++ } ++ } ++ i++; ++ } while (i < nc); ++ if (i >= nc) break; ++ ++ /* At this point i is the index of either a "." or a "..", so take the ++ appropriate action and then continue the outer loop */ ++ if (dots == 1) { ++ /* Remove this instance of "." */ ++ ix[i] = 0; ++ } ++ else { ++ /* If there is a preceding name, remove both that name and this ++ instance of ".."; otherwise, leave the ".." as is */ ++ for (j = i - 1; j >= 0; j--) { ++ if (ix[j]) break; ++ } ++ if (j < 0) continue; ++ ix[j] = 0; ++ ix[i] = 0; ++ } ++ /* i will be incremented at the top of the loop */ ++ } ++ ++ joinNames(names, nc, ix); ++} +diff --git a/jdk/src/solaris/native/java/io/path_util.h b/jdk/src/solaris/native/java/io/path_util.h +new file mode 100644 +index 000000000..7b0fd5eb1 +--- /dev/null ++++ b/jdk/src/solaris/native/java/io/path_util.h +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (c) 2021, 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. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * 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. ++ */ ++ ++#ifndef PATH_UTIL_H ++#define PATH_UTIL_H ++ ++void collapse(char *path); ++ ++#endif +diff --git a/jdk/src/solaris/native/java/util/TimeZone_md.c b/jdk/src/solaris/native/java/util/TimeZone_md.c +index c183a723d..df1450e03 100644 +--- a/jdk/src/solaris/native/java/util/TimeZone_md.c ++++ b/jdk/src/solaris/native/java/util/TimeZone_md.c +@@ -41,6 +41,7 @@ + + #include "jvm.h" + #include "TimeZone_md.h" ++#include "path_util.h" + + static char *isFileIdentical(char* buf, size_t size, char *pathname); + +@@ -77,6 +78,33 @@ static const char *ETC_ENVIRONMENT_FILE = "/etc/environment"; + + #if defined(__linux__) || defined(MACOSX) || defined(__solaris__) + ++/* ++ * remove repeated path separators ('/') in the given 'path'. ++ */ ++static void ++removeDuplicateSlashes(char *path) ++{ ++ char *left = path; ++ char *right = path; ++ char *end = path + strlen(path); ++ ++ for (; right < end; right++) { ++ // Skip sequence of multiple path-separators. ++ while (*right == '/' && *(right + 1) == '/') { ++ right++; ++ } ++ ++ while (*right != '\0' && !(*right == '/' && *(right + 1) == '/')) { ++ *left++ = *right++; ++ } ++ ++ if (*right == '\0') { ++ *left = '\0'; ++ break; ++ } ++ } ++} ++ + /* + * Returns a pointer to the zone ID portion of the given zoneinfo file + * name, or NULL if the given string doesn't contain "zoneinfo/". +@@ -319,36 +347,9 @@ getPlatformTimeZoneID() + return NULL; + } + linkbuf[len] = '\0'; +- +- /* linkbuf may be a relative symlink or has more than one characters, like '.' and '/' , +- * which will cause the function call getZoneName return to an abnormal timeZone name. +- * For example, linkbuf is "../usr/share/zoneinfo//Asia/Shanghai", then the call of +- * getZoneName(linkbuf) will get "/Asia/Shanghai", not "Asia/Shanghai". +- * So we covert it to an absolute path by adding the file's (which is define by macro +- * DEFAULT_ZONEINFO_FILE) dirname and then call glibc's realpath API to canonicalize +- * the path. +- */ +- char abslinkbuf[2 * (PATH_MAX + 1)]; +- if (linkbuf[0] != '/') { +- if (sprintf(abslinkbuf, "%s/%s", DEFAULT_ZONEINFO_FILE_DIRNAME, linkbuf) < 0) { +- jio_fprintf(stderr, (const char *) "failed to generate absolute path\n"); +- return NULL; +- } +- } else { +- strncpy(abslinkbuf, linkbuf, len + 1); +- } +- +- /* canonicalize the path */ +- char resolvedpath[PATH_MAX + 1]; +- resolvedpath[PATH_MAX] = '\0'; +- char *path = realpath(abslinkbuf, resolvedpath); +- if (path == NULL) { +- jio_fprintf(stderr, (const char *) "failed to get real path, symlink is %s\n", +- abslinkbuf); +- return NULL; +- } +- +- tz = getZoneName(resolvedpath); ++ removeDuplicateSlashes(linkbuf); ++ collapse(linkbuf); ++ tz = getZoneName(linkbuf); + if (tz != NULL) { + tz = strdup(tz); + return tz; +-- +2.22.0 + diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index d826bac..ac3db90 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 1 +Release: 2 # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # and this change was brought into RHEL-4. java-1.5.0-ibm packages # also included the epoch in their virtual provides. This created a @@ -1116,6 +1116,7 @@ Patch218: 8143251-Thread-suspend-on-VM_G1IncCollectionPause-do.patch Patch219: G1Uncommit-Introduce-G1PeriodGCNotRetry-control-whet.patch Patch220: JDK-debug-version-crash-when-using-AppCDS.patch Patch221: 8183543-Aarch64-C2-compilation-often-fails-with-fail--last.patch +Patch222: 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch # 8u312 @@ -1582,6 +1583,7 @@ pushd %{top_level_dir_name} %patch219 -p1 %patch220 -p1 %patch221 -p1 +%patch222 -p1 popd # System library fixes @@ -2199,6 +2201,9 @@ require "copy_jdk_configs.lua" %endif %changelog +* Fri Dec 10 2021 kuenking111 - 1:1.8.0.312-b07.2 +- add 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch + * Tue Nov 23 2021 lijingwei - 1:1.8.0.312-b07.1 - correct spec file release number typo -- Gitee From fae61988d0f4a698b4f8b3fe6195fabb82615120 Mon Sep 17 00:00:00 2001 From: kuenking111 Date: Fri, 10 Dec 2021 11:06:08 +0800 Subject: [PATCH 2/8] I4LXAZ: 8233280 Remove GCLockerInvokesConcurrent relative logic for G1 --- ...okesConcurrent-relative-logic-for-G1.patch | 52 +++++++++++++++++++ openjdk-1.8.0.spec | 7 ++- 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100755 8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch diff --git a/8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch b/8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch new file mode 100755 index 0000000..2ad9973 --- /dev/null +++ b/8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch @@ -0,0 +1,52 @@ +From cf0e0f39908c8de21d69139e1144c2ad131c1140 Mon Sep 17 00:00:00 2001 +From: mashoubing +Date: Sun, 26 Sep 2021 17:30:48 +0800 +Subject: [PATCH 2/4] 8233280: Remove GCLockerInvokesConcurrent relative logic + for G1 + +--- + .../src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp | 4 ---- + .../src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp | 5 ++--- + 2 files changed, 2 insertions(+), 7 deletions(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +index 4f45bba52..060531901 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +@@ -2394,7 +2394,6 @@ bool G1CollectedHeap::is_user_requested_concurrent_full_gc(GCCause::Cause cause + + bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { + switch (cause) { +- case GCCause::_gc_locker: return GCLockerInvokesConcurrent; + case GCCause::_g1_humongous_allocation: return true; + case GCCause::_g1_periodic_collection: return true; + default: return is_user_requested_concurrent_full_gc(cause); +@@ -2583,9 +2582,6 @@ void G1CollectedHeap::collect(GCCause::Cause cause) { + gclog_or_tty->print_cr("Periodic GC is denied and not try !"); + return; + } +- if (GC_locker::is_active_and_needs_gc()) { +- GC_locker::stall_until_clear(); +- } + } + } + } else if (GC_locker::should_discard(cause, gc_count_before)) { +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +index d83e6cb65..3225967b3 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +@@ -354,9 +354,8 @@ private: + // It decides whether an explicit GC should start a concurrent cycle + // instead of doing a STW GC. Currently, a concurrent cycle is + // explicitly started if: +- // (a) cause == _gc_locker and +GCLockerInvokesConcurrent, or +- // (b) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent. +- // (c) cause == _g1_humongous_allocation ++ // (a) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent. ++ // (b) cause == _g1_humongous_allocation + bool should_do_concurrent_full_gc(GCCause::Cause cause); + + // Keeps track of how many "old marking cycles" (i.e., Full GCs or +-- +2.22.0 + diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index ac3db90..c63f8e8 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 2 +Release: 3 # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # and this change was brought into RHEL-4. java-1.5.0-ibm packages # also included the epoch in their virtual provides. This created a @@ -1117,6 +1117,7 @@ Patch219: G1Uncommit-Introduce-G1PeriodGCNotRetry-control-whet.patch Patch220: JDK-debug-version-crash-when-using-AppCDS.patch Patch221: 8183543-Aarch64-C2-compilation-often-fails-with-fail--last.patch Patch222: 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch +Patch223: 8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch # 8u312 @@ -1584,6 +1585,7 @@ pushd %{top_level_dir_name} %patch220 -p1 %patch221 -p1 %patch222 -p1 +%patch223 -p1 popd # System library fixes @@ -2201,6 +2203,9 @@ require "copy_jdk_configs.lua" %endif %changelog +* Fri Dec 10 2021 kuenking111 - 1:1.8.0.312-b07.3 +- add 8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch + * Fri Dec 10 2021 kuenking111 - 1:1.8.0.312-b07.2 - add 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch -- Gitee From 94419d5ddc34bf5f79a9a41c8ef0f3e3e831e626 Mon Sep 17 00:00:00 2001 From: kuenking111 Date: Fri, 10 Dec 2021 12:19:05 +0800 Subject: [PATCH 3/8] I4LXX3: G1Ucommit Refactor Trigger mechanism --- G1Ucommit-Refactor-Trigger-mechanism.patch | 630 +++++++++++++++++++++ openjdk-1.8.0.spec | 7 +- 2 files changed, 636 insertions(+), 1 deletion(-) create mode 100755 G1Ucommit-Refactor-Trigger-mechanism.patch diff --git a/G1Ucommit-Refactor-Trigger-mechanism.patch b/G1Ucommit-Refactor-Trigger-mechanism.patch new file mode 100755 index 0000000..99b7c20 --- /dev/null +++ b/G1Ucommit-Refactor-Trigger-mechanism.patch @@ -0,0 +1,630 @@ +From f6f0d05f65a35672f48f63d7e8f73a8c2f56d1c3 Mon Sep 17 00:00:00 2001 +From: mashoubing +Date: Wed, 25 Aug 2021 14:22:13 +0800 +Subject: [PATCH 4/4] G1Ucommit: Refactor Trigger mechanism + +--- + .../g1/concurrentG1RefineThread.cpp | 65 --------------- + .../g1/concurrentG1RefineThread.hpp | 1 - + .../gc_implementation/g1/concurrentMark.cpp | 2 +- + .../gc_implementation/g1/g1CollectedHeap.cpp | 51 ++++++++---- + .../gc_implementation/g1/g1CollectedHeap.hpp | 5 +- + .../g1/g1CollectorPolicy.cpp | 60 -------------- + .../g1/g1CollectorPolicy.hpp | 20 +---- + .../gc_implementation/g1/g1UncommitThread.cpp | 82 ++++++++++++++++++- + .../gc_implementation/g1/g1UncommitThread.hpp | 2 + + .../g1/heapRegionManager.cpp | 28 ++++--- + .../g1/heapRegionManager.hpp | 2 +- + .../g1/heapRegionManager.inline.hpp | 2 +- + 12 files changed, 142 insertions(+), 178 deletions(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp +index 98a43ba62..e4ec84895 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp +@@ -100,69 +100,6 @@ void ConcurrentG1RefineThread::sample_young_list_rs_lengths() { + } + } + +-bool ConcurrentG1RefineThread::should_start_periodic_gc() { +- // If we are currently in a concurrent mark we are going to uncommit memory soon. +- if (G1CollectedHeap::heap()->concurrent_mark()->cmThread()->during_cycle()) { +- if (G1UncommitLog) { +- gclog_or_tty->print_cr("Concurrent cycle in progress. Skipping."); +- } +- return false; +- } +- +- // Check if enough time has passed since the last GC. +- uintx time_since_last_gc; +- if ((time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc()) < G1PeriodicGCInterval) { +- if (G1UncommitLog) { +- gclog_or_tty->print_cr("Last GC occurred " UINTX_FORMAT "ms before which is below threshold " UINTX_FORMAT "ms. Skipping.", +- time_since_last_gc, G1PeriodicGCInterval); +- } +- return false; +- } +- +- return true; +-} +- +-void ConcurrentG1RefineThread::check_for_periodic_gc() { +- if (!G1Uncommit) { +- return; +- } +- +- assert(G1PeriodicGCInterval > 0, "just checking"); +- double recent_load = -1.0; +- G1CollectedHeap* g1h = G1CollectedHeap::heap(); +- G1CollectorPolicy* g1p = g1h->g1_policy(); +- if (G1PeriodicGCLoadThreshold) { +- // Sample process load and store it +- if (G1PeriodicGCProcessLoad) { +- recent_load = os::get_process_load() * 100; +- } +- if (recent_load < 0) { +- // Fallback to os load +- G1PeriodicGCProcessLoad = false; +- if (os::loadavg(&recent_load, 1) != -1) { +- static int cpu_count = os::active_processor_count(); +- assert(cpu_count > 0, "just checking"); +- recent_load = recent_load * 100 / cpu_count; +- } +- } +- if (recent_load >= 0) { +- g1p->add_os_load(recent_load); +- } +- } +- +- double now = os::elapsedTime(); +- if (now - _last_periodic_gc_attempt_s > G1PeriodicGCInterval / 1000.0) { +- if (G1UncommitLog) { +- recent_load < 0 ? gclog_or_tty->print_cr("Checking for periodic GC.") +- : gclog_or_tty->print_cr("Checking for periodic GC. Current load %1.2f. Heap total " UINT32_FORMAT " free " UINT32_FORMAT, recent_load, g1h->_hrm.length(), g1h->_hrm.num_free_regions()); +- } +- if (should_start_periodic_gc()) { +- g1p->set_periodic_gc(); +- } +- _last_periodic_gc_attempt_s = now; +- } +-} +- + void ConcurrentG1RefineThread::run_young_rs_sampling() { + DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); + _vtime_start = os::elapsedVTime(); +@@ -175,8 +112,6 @@ void ConcurrentG1RefineThread::run_young_rs_sampling() { + _vtime_accum = 0.0; + } + +- check_for_periodic_gc(); +- + MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); + if (_should_terminate) { + break; +diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp +index 8fa521371..6c712fd2d 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp +@@ -71,7 +71,6 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread { + void deactivate(); + + void check_for_periodic_gc(); +- bool should_start_periodic_gc(); + + public: + virtual void run(); +diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +index 447bee183..831ec94fa 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +@@ -1354,7 +1354,7 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) { + satb_mq_set.set_active_all_threads(false, /* new active value */ + true /* expected_active */); + +- g1h->extract_uncommit_list(); ++ g1h->shrink_heap_at_remark(); + if (VerifyDuringGC) { + HandleMark hm; // handle scope + Universe::heap()->prepare_for_verify(); +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +index 1f1042caa..6ee33fd05 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +@@ -1565,6 +1565,19 @@ void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { + void + G1CollectedHeap:: + resize_if_necessary_after_full_collection(size_t word_size) { ++ bool should_expand; ++ size_t resize_amount = full_collection_resize_amount(should_expand); ++ ++ if (resize_amount == 0) { ++ return; ++ } else if (should_expand) { ++ expand(resize_amount); ++ } else { ++ shrink(resize_amount); ++ } ++} ++ ++size_t G1CollectedHeap::full_collection_resize_amount(bool& expand) { + // Include the current allocation, if any, and bytes that will be + // pre-allocated to support collections, as "used". + const size_t capacity_after_gc = capacity(); +@@ -1630,8 +1643,8 @@ resize_if_necessary_after_full_collection(size_t word_size) { + ergo_format_byte_perc("min desired capacity"), + capacity_after_gc, used_after_gc, + minimum_desired_capacity, (double) MinHeapFreeRatio); +- expand(expand_bytes); +- ++ expand = true; ++ return expand_bytes; + // No expansion, now see if we want to shrink + } else if (capacity_after_gc > maximum_desired_capacity) { + // Capacity too large, compute shrinking size +@@ -1645,10 +1658,13 @@ resize_if_necessary_after_full_collection(size_t word_size) { + ergo_format_byte_perc("max desired capacity"), + capacity_after_gc, used_after_gc, + maximum_desired_capacity, (double) MaxHeapFreeRatio); +- shrink(shrink_bytes); ++ expand = false; ++ return shrink_bytes; + } +-} + ++ expand = true; ++ return 0; ++} + + HeapWord* + G1CollectedHeap::satisfy_failed_allocation(size_t word_size, +@@ -2185,12 +2201,6 @@ void G1CollectedHeap::stop() { + } + } + +-void G1CollectedHeap::check_trigger_periodic_gc() { +- if (g1_policy()->should_trigger_periodic_gc()) { +- collect(GCCause::_g1_periodic_collection); +- } +-} +- + void G1CollectedHeap::init_periodic_gc_thread() { + if (_uncommit_thread == NULL && G1Uncommit) { + PeriodicGC::start(); +@@ -2198,10 +2208,22 @@ void G1CollectedHeap::init_periodic_gc_thread() { + } + } + +-void G1CollectedHeap::extract_uncommit_list() { +- if (g1_policy()->can_extract_uncommit_list()) { +- uint count = _hrm.extract_uncommit_list(); +- g1_policy()->record_extract_uncommit_list(count); ++void G1CollectedHeap::shrink_heap_at_remark() { ++ if (!G1Uncommit) { ++ return; ++ } ++ ++ bool should_expand; ++ size_t resize_amount = full_collection_resize_amount(should_expand); ++ uint length = _hrm.length(); ++ ++ if (resize_amount > 0 && !should_expand) { ++ uint num_candidate_to_remove = (uint)(resize_amount / HeapRegion::GrainBytes); ++ uint count = _hrm.extract_uncommit_list(num_candidate_to_remove); ++ ++ gclog_or_tty->print(" [G1Uncommit list " UINT32_FORMAT ", remaining " UINT32_FORMAT ++ ", free list " UINT32_FORMAT "]", ++ count, length - count, _hrm.num_free_regions()); + } + } + +@@ -4037,7 +4059,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { + + + double pause_start_sec = os::elapsedTime(); +- g1_policy()->record_gc_start(pause_start_sec); + g1_policy()->phase_times()->note_gc_start(active_workers, mark_in_progress()); + log_gc_header(); + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +index 3225967b3..d0ec5a773 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +@@ -626,6 +626,8 @@ protected: + // and will be considered part of the used portion of the heap. + void resize_if_necessary_after_full_collection(size_t word_size); + ++ size_t full_collection_resize_amount(bool& expand); ++ + // Callback from VM_G1CollectForAllocation operation. + // This function does everything necessary/possible to satisfy a + // failed allocation request (including collection, expansion, etc.) +@@ -1026,9 +1028,8 @@ public: + + void set_refine_cte_cl_concurrency(bool concurrent); + +- void check_trigger_periodic_gc(); + void init_periodic_gc_thread(); +- void extract_uncommit_list(); ++ void shrink_heap_at_remark(); + + RefToScanQueue *task_queue(int i) const; + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +index 099762f2b..05ce59987 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +@@ -89,7 +89,6 @@ G1CollectorPolicy::G1CollectorPolicy() : + _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), + + _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)), +- _heap_size_seq(new TruncatedSeq(TruncatedSeqLength)), + _os_load_seq(new TruncatedSeq(TruncatedSeqLength)), + _gc_count_seq(new TruncatedSeq(TruncatedSeqLength)), + _prev_collection_pause_end_ms(0.0), +@@ -112,11 +111,9 @@ G1CollectorPolicy::G1CollectorPolicy() : + _pause_time_target_ms((double) MaxGCPauseMillis), + + _gcs_are_young(true), +- _periodic_gc(false), + _last_uncommit_attempt_s(0.0), + _os_load(-1.0), + _uncommit_start_time(0), +- _gc_count_cancel_extract(false), + _gc_count(0), + _gc_count_minute(0), + +@@ -160,7 +157,6 @@ G1CollectorPolicy::G1CollectorPolicy() : + _inc_cset_predicted_elapsed_time_ms(0.0), + _inc_cset_predicted_elapsed_time_ms_diffs(0.0), + _collection_pause_end_millis(os::javaTimeNanos() / NANOSECS_PER_MILLISEC), +- _extract_uncommit_list(0), + #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away + #pragma warning( disable:4355 ) // 'this' : used in base member initializer list + #endif // _MSC_VER +@@ -1211,8 +1207,6 @@ void G1CollectorPolicy::record_heap_size_info_at_start(bool full) { + _heap_capacity_bytes_before_gc = _g1->capacity(); + _heap_used_bytes_before_gc = _g1->used(); + _cur_collection_pause_used_regions_at_start = _g1->num_used_regions(); +- _heap_size_seq->add(_cur_collection_pause_used_regions_at_start); +- + _eden_capacity_bytes_before_gc = + (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc; + +@@ -1255,13 +1249,6 @@ void G1CollectorPolicy::print_detailed_heap_transition(bool full) { + EXT_SIZE_PARAMS(heap_used_bytes_after_gc), + EXT_SIZE_PARAMS(heap_capacity_bytes_after_gc)); + +- if (_extract_uncommit_list) { +- gclog_or_tty->print(" [Uncommit list " UINT32_FORMAT ", remaining " UINT32_FORMAT ", free list " UINT32_FORMAT "]", +- _extract_uncommit_list, +- _g1->_hrm.length(), +- _g1->_hrm.num_free_regions()); +- _extract_uncommit_list = 0; +- } + if (full) { + MetaspaceAux::print_metaspace_change(_metaspace_used_bytes_before_gc); + } +@@ -2175,53 +2162,6 @@ void G1CollectorPolicy::finalize_cset(double target_pause_time_ms, EvacuationInf + evacuation_info.set_collectionset_regions(cset_region_length()); + } + +-void G1CollectorPolicy::record_gc_start(double curr_sec) { +- if (_uncommit_start_time == 0) { +- _uncommit_start_time = curr_sec + G1UncommitDelay; +- } +- long curr = curr_sec / 60; +- if (curr > _gc_count_minute) { +- int diff = curr - _gc_count_minute; +- _gc_count_seq->add(_gc_count); +- for (int i = 1; i < diff; i++) { +- _gc_count_seq->add(0.0); +- } +- _gc_count_minute = curr; +- double gc_count_expected = get_new_prediction(_gc_count_seq); +- // Considering the test result, 15000 is an appropriate value for G1PeriodicGCInterval. +- _gc_count_cancel_extract = gc_count_expected > MIN2(4.0, 60000.0 / G1PeriodicGCInterval); +- _gc_count = 0; +- } +- _gc_count++; +-} +- +-bool G1CollectorPolicy::should_trigger_periodic_gc() { +- if (G1PeriodicGCLoadThreshold && _os_load > G1PeriodicGCLoadThreshold) { +- _periodic_gc = false; +- } else if (_periodic_gc) { +- _periodic_gc = false; +- return true; +- } +- return false; +-} +- +-bool G1CollectorPolicy::can_extract_uncommit_list() { +- double now = os::elapsedTime(); +- if (G1Uncommit && now > _uncommit_start_time) { +- if (G1PeriodicGCLoadThreshold && _os_load > G1PeriodicGCLoadThreshold) { +- return false; +- } +- G1CollectedHeap* g1h = G1CollectedHeap::heap(); +- if (!_gc_count_cancel_extract || now >= (g1h->millis_since_last_gc() + G1PeriodicGCInterval) / 1000.0) { +- if (now - _last_uncommit_attempt_s >= G1PeriodicGCInterval / 1000.0) { +- _last_uncommit_attempt_s = now; +- return true; +- } +- } +- } +- return false; +-} +- + void TraceGen0TimeData::record_start_collection(double time_to_stop_the_world_ms) { + if(TraceGen0Time) { + _all_stop_world_times_ms.add(time_to_stop_the_world_ms); +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp +index 1a0d20d6f..af5d5d57a 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp +@@ -244,7 +244,6 @@ private: + TruncatedSeq* _constant_other_time_ms_seq; + TruncatedSeq* _young_other_cost_per_region_ms_seq; + TruncatedSeq* _non_young_other_cost_per_region_ms_seq; +- TruncatedSeq* _heap_size_seq; + TruncatedSeq* _os_load_seq; + TruncatedSeq* _gc_count_seq; + +@@ -268,8 +267,6 @@ private: + + uint _free_regions_at_end_of_collection; + +- uint _extract_uncommit_list; +- + size_t _recorded_rs_lengths; + size_t _max_rs_lengths; + double _sigma; +@@ -308,19 +305,12 @@ private: + + size_t _gc_count; + long _gc_count_minute; +- bool _gc_count_cancel_extract; + +- volatile bool _periodic_gc; + double _last_uncommit_attempt_s; + volatile double _os_load; + double _uncommit_start_time; + public: + // Accessors +- +- void set_periodic_gc() { _periodic_gc = true; } +- bool can_extract_uncommit_list(); +- bool should_trigger_periodic_gc(); +- + void set_region_eden(HeapRegion* hr, int young_index_in_cset) { + hr->set_eden(); + hr->install_surv_rate_group(_short_lived_surv_rate_group); +@@ -346,16 +336,14 @@ public: + _max_rs_lengths = rs_lengths; + } + +- size_t predict_heap_size_seq() { +- return (size_t) get_new_prediction(_heap_size_seq); +- } +- + void add_os_load(double load) { + _os_load_seq->add(load); + _os_load = get_new_prediction(_os_load_seq); + } + +- void record_gc_start(double sec); ++ double os_load() { ++ return _os_load; ++ } + + size_t predict_rs_length_diff() { + return (size_t) get_new_prediction(_rs_length_diff_seq); +@@ -739,8 +727,6 @@ public: + void record_stop_world_start(); + void record_concurrent_pause(); + +- void record_extract_uncommit_list(uint count) { _extract_uncommit_list = count; } +- + // Record how much space we copied during a GC. This is typically + // called when a GC alloc region is being retired. + void record_bytes_copied_during_gc(size_t bytes) { +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp +index 37bdbdb69..503218917 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp +@@ -26,6 +26,9 @@ + + #include "gc_implementation/g1/g1UncommitThread.hpp" + #include "gc_implementation/g1/g1_globals.hpp" ++#include "gc_implementation/g1/g1Log.hpp" ++#include "gc_implementation/g1/g1CollectorPolicy.hpp" ++#include "gc_implementation/g1/concurrentMarkThread.hpp" + #include "runtime/javaCalls.hpp" + #include "runtime/os.hpp" + +@@ -104,9 +107,12 @@ void PeriodicGC::start() { + } + + void PeriodicGC::timer_thread_entry(JavaThread* thread, TRAPS) { ++ G1CollectedHeap* g1h = G1CollectedHeap::heap(); + while(!_should_terminate) { + assert(!SafepointSynchronize::is_at_safepoint(), "PeriodicGC timer thread is a JavaThread"); +- G1CollectedHeap::heap()->check_trigger_periodic_gc(); ++ if (check_for_periodic_gc()) { ++ g1h->collect(GCCause::_g1_periodic_collection); ++ } + + MutexLockerEx x(_monitor); + if (_should_terminate) { +@@ -116,6 +122,78 @@ void PeriodicGC::timer_thread_entry(JavaThread* thread, TRAPS) { + } + } + ++bool PeriodicGC::check_for_periodic_gc() { ++ if (!G1Uncommit) { ++ return false; ++ } ++ ++ return should_start_periodic_gc(); ++} ++ ++bool PeriodicGC::should_start_periodic_gc() { ++ G1CollectedHeap* g1h = G1CollectedHeap::heap(); ++ G1CollectorPolicy* g1p = g1h->g1_policy(); ++ // If we are currently in a concurrent mark we are going to uncommit memory soon. ++ if (g1h->concurrent_mark()->cmThread()->during_cycle()) { ++ if (G1UncommitLog && G1Log::finest()) { ++ gclog_or_tty->date_stamp(PrintGCDateStamps); ++ gclog_or_tty->stamp(PrintGCTimeStamps); ++ gclog_or_tty->print_cr("[G1Uncommit] Concurrent cycle in progress. Skipping."); ++ } ++ return false; ++ } ++ ++ // Check if enough time has passed since the last GC. ++ uintx time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc(); ++ if (time_since_last_gc < G1PeriodicGCInterval) { ++ if (G1UncommitLog && G1Log::finest()) { ++ gclog_or_tty->date_stamp(PrintGCDateStamps); ++ gclog_or_tty->stamp(PrintGCTimeStamps); ++ gclog_or_tty->print_cr("[G1Uncommit] Last GC occurred " UINTX_FORMAT "ms before which is below threshold" ++ UINTX_FORMAT "ms. Skipping.", time_since_last_gc, G1PeriodicGCInterval); ++ } ++ return false; ++ } ++ ++ // Collect load need G1PeriodicGCInterval time after previous GC's end ++ assert(G1PeriodicGCInterval > 0, "just checking"); ++ double recent_load = -1.0; ++ ++ if (G1PeriodicGCLoadThreshold) { ++ // Sample process load and store it ++ if (G1PeriodicGCProcessLoad) { ++ recent_load = os::get_process_load() * 100; ++ } ++ if (recent_load < 0) { ++ // Fallback to os load ++ G1PeriodicGCProcessLoad = false; ++ if (os::loadavg(&recent_load, 1) != -1) { ++ static int cpu_count = os::active_processor_count(); ++ assert(cpu_count > 0, "just checking"); ++ recent_load = recent_load * 100 / cpu_count; ++ } ++ } ++ if (recent_load >= 0) { ++ g1p->add_os_load(recent_load); ++ } ++ } ++ ++ if (G1UncommitLog) { ++ gclog_or_tty->date_stamp(PrintGCDateStamps); ++ gclog_or_tty->stamp(PrintGCTimeStamps); ++ recent_load < 0 ? gclog_or_tty->print_cr("[G1Uncommit] Checking for periodic GC.") ++ : gclog_or_tty->print_cr("[G1Uncommit] Checking for periodic GC. Current load %1.2f. " ++ "total regions: " UINT32_FORMAT" free regions: " UINT32_FORMAT, ++ recent_load, g1h->num_regions(), g1h->num_free_regions()); ++ } ++ ++ if (g1p->os_load() < G1PeriodicGCLoadThreshold || !G1PeriodicGCLoadThreshold) { ++ return true; ++ } ++ gclog_or_tty->print_cr("[G1Uncommit] Periodic GC request denied, skipping!"); ++ return false; ++} ++ + void PeriodicGC::stop() { + _should_terminate = true; + { +@@ -139,7 +217,7 @@ G1UncommitThread::G1UncommitThread() : + } + } + if (G1UncommitLog) { +- gclog_or_tty->print_cr("Periodic GC Thread start"); ++ gclog_or_tty->print_cr("[G1Uncommit] Periodic GC Thread start"); + } + } + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.hpp +index 883a9a418..6f1d5e35f 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.hpp +@@ -40,6 +40,8 @@ public: + static void start(); + static void stop(); + static bool has_error(TRAPS, const char* error); ++ static bool check_for_periodic_gc(); ++ static bool should_start_periodic_gc(); + }; + + class G1UncommitThread: public ConcurrentGCThread { +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp +index 56e2d32df..d31073f9f 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp +@@ -573,21 +573,23 @@ void HeapRegionManager::free_uncommit_list_memory() { + } + } + +-uint HeapRegionManager::extract_uncommit_list() +-{ ++uint HeapRegionManager::extract_uncommit_list(uint num_candidate_to_remove) { + assert_at_safepoint(true /* should_be_vm_thread */); ++ double start_up_sec = os::elapsedTime(); ++ if (start_up_sec < G1UncommitDelay) { ++ gclog_or_tty->date_stamp(PrintGCDateStamps); ++ gclog_or_tty->stamp(PrintGCTimeStamps); ++ gclog_or_tty->print_cr("start up seconds:%lf, less than G1UncommitDelay, will not uncommit.", start_up_sec); ++ return 0; ++ } ++ + if (!_uncommit_list_filled) { +- G1CollectedHeap* g1h = G1CollectedHeap::heap(); +- uint dest = ((G1CollectorPolicy*)g1h->collector_policy())->predict_heap_size_seq(); +- +- if (dest < _num_committed) { +- uint num_regions_to_remove = (_num_committed - dest) * G1UncommitPercent; +- if (num_regions_to_remove >= 1 && num_regions_to_remove < _free_list.length()) { +- int count = _free_list.move_regions_to(&_uncommit_list, num_regions_to_remove); +- OrderAccess::storestore(); +- _uncommit_list_filled = true; +- return count; +- } ++ uint num_regions_to_remove = num_candidate_to_remove * G1UncommitPercent; ++ if (num_regions_to_remove >= 1 && num_regions_to_remove < _free_list.length()) { ++ int count = _free_list.move_regions_to(&_uncommit_list, num_regions_to_remove); ++ OrderAccess::storestore(); ++ _uncommit_list_filled = true; ++ return count; + } + } + return 0; +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp +index 25f3a223f..3950d6280 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp +@@ -175,7 +175,7 @@ public: + G1RegionToSpaceMapper* cardtable, + G1RegionToSpaceMapper* card_counts); + +- uint extract_uncommit_list(); ++ uint extract_uncommit_list(uint num_candidate_to_remove); + void free_uncommit_list_memory(); + + // Return the "dummy" region used for G1AllocRegion. This is currently a hardwired +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp +index 68840d61e..50d0fa832 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp +@@ -40,8 +40,8 @@ inline HeapRegion* HeapRegionManager::addr_to_region(HeapWord* addr) const { + } + + inline HeapRegion* HeapRegionManager::at(uint index) const { +- assert(is_available(index), "pre-condition"); + HeapRegion* hr = _regions.get_by_index(index); ++ assert(hr->in_uncommit_list() || is_available(index), "pre-condition"); + assert(hr != NULL, "sanity"); + assert(hr->hrm_index() == index, "sanity"); + return hr; +-- +2.22.0 + diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index c63f8e8..f12b3e6 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 3 +Release: 4 # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # and this change was brought into RHEL-4. java-1.5.0-ibm packages # also included the epoch in their virtual provides. This created a @@ -1118,6 +1118,7 @@ Patch220: JDK-debug-version-crash-when-using-AppCDS.patch Patch221: 8183543-Aarch64-C2-compilation-often-fails-with-fail--last.patch Patch222: 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch Patch223: 8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch +Patch224: G1Ucommit-Refactor-Trigger-mechanism.patch # 8u312 @@ -1586,6 +1587,7 @@ pushd %{top_level_dir_name} %patch221 -p1 %patch222 -p1 %patch223 -p1 +%patch224 -p1 popd # System library fixes @@ -2203,6 +2205,9 @@ require "copy_jdk_configs.lua" %endif %changelog +* Fri Dec 10 2021 kuenking111 - 1:1.8.0.312-b07.4 +- add G1Ucommit-Refactor-Trigger-mechanism.patch + * Fri Dec 10 2021 kuenking111 - 1:1.8.0.312-b07.3 - add 8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch -- Gitee From d03e0f409e6db5da9036e90c3614a377c8bfc22a Mon Sep 17 00:00:00 2001 From: kuenking111 Date: Fri, 10 Dec 2021 15:48:24 +0800 Subject: [PATCH 4/8] I4LZJ1: G1 Full GC parallel mark --- G1-Full-GC-parallel-mark.patch | 1520 ++++++++++++++++++++++++++++++++ openjdk-1.8.0.spec | 7 +- 2 files changed, 1526 insertions(+), 1 deletion(-) create mode 100755 G1-Full-GC-parallel-mark.patch diff --git a/G1-Full-GC-parallel-mark.patch b/G1-Full-GC-parallel-mark.patch new file mode 100755 index 0000000..af8d22f --- /dev/null +++ b/G1-Full-GC-parallel-mark.patch @@ -0,0 +1,1520 @@ +From 2821582ff1191393781ccf93d46d9c31230c8a4a Mon Sep 17 00:00:00 2001 +From: mashoubing +Date: Mon, 11 Oct 2021 12:11:25 +0800 +Subject: [PATCH 3/4] G1: Full GC parallel mark + +--- + .../concurrentMarkSweepGeneration.cpp | 2 +- + .../g1/g1BlockOffsetTable.inline.hpp | 2 +- + .../gc_implementation/g1/g1CollectedHeap.cpp | 2 +- + .../vm/gc_implementation/g1/g1MarkSweep.cpp | 233 +++++++++++++----- + .../vm/gc_implementation/g1/g1MarkSweep.hpp | 9 +- + .../gc_implementation/g1/g1RootProcessor.cpp | 23 +- + .../gc_implementation/g1/g1RootProcessor.hpp | 9 +- + .../vm/gc_implementation/g1/g1StringDedup.cpp | 10 +- + .../vm/gc_implementation/g1/g1StringDedup.hpp | 4 +- + .../parallelScavenge/parallelScavengeHeap.cpp | 2 +- + .../parallelScavenge/psMarkSweep.cpp | 5 + + .../parallelScavenge/psMarkSweep.hpp | 33 +-- + .../parallelScavenge/psScavenge.cpp | 2 +- + .../vm/gc_implementation/shared/markSweep.cpp | 44 ++-- + .../vm/gc_implementation/shared/markSweep.hpp | 89 ++++--- + .../shared/markSweep.inline.hpp | 41 ++- + hotspot/src/share/vm/memory/genMarkSweep.cpp | 6 + + hotspot/src/share/vm/memory/genMarkSweep.hpp | 18 +- + hotspot/src/share/vm/memory/generation.cpp | 2 +- + .../vm/oops/instanceClassLoaderKlass.cpp | 6 +- + .../vm/oops/instanceClassLoaderKlass.hpp | 2 +- + hotspot/src/share/vm/oops/instanceKlass.cpp | 6 +- + hotspot/src/share/vm/oops/instanceKlass.hpp | 2 +- + .../src/share/vm/oops/instanceMirrorKlass.cpp | 10 +- + .../src/share/vm/oops/instanceMirrorKlass.hpp | 2 +- + .../src/share/vm/oops/instanceRefKlass.cpp | 18 +- + .../src/share/vm/oops/instanceRefKlass.hpp | 2 +- + hotspot/src/share/vm/oops/klass.hpp | 3 +- + hotspot/src/share/vm/oops/markOop.hpp | 2 +- + hotspot/src/share/vm/oops/objArrayKlass.cpp | 8 +- + hotspot/src/share/vm/oops/objArrayKlass.hpp | 6 +- + .../share/vm/oops/objArrayKlass.inline.hpp | 12 +- + hotspot/src/share/vm/oops/oop.hpp | 4 +- + hotspot/src/share/vm/oops/oop.inline.hpp | 4 +- + hotspot/src/share/vm/oops/typeArrayKlass.cpp | 2 +- + hotspot/src/share/vm/oops/typeArrayKlass.hpp | 2 +- + 36 files changed, 401 insertions(+), 226 deletions(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +index 3c3deab28..d31f9a54a 100644 +--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ++++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +@@ -2079,7 +2079,7 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) { + _intra_sweep_estimate.padded_average()); + } + +- GenMarkSweep::invoke_at_safepoint(_cmsGen->level(), ++ GenMarkSweep::the_gen_mark()->invoke_at_safepoint(_cmsGen->level(), + ref_processor(), clear_all_soft_refs); + #ifdef ASSERT + CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace(); +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp +index 912acdbe0..9a8cb877d 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp +@@ -51,7 +51,7 @@ G1BlockOffsetTable::block_start_const(const void* addr) const { + assert((index) < (_reserved.word_size() >> LogN_words), \ + err_msg("%s - index: "SIZE_FORMAT", _vs.committed_size: "SIZE_FORMAT, \ + msg, (index), (_reserved.word_size() >> LogN_words))); \ +- assert(!G1Uncommit && G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index)) || G1Uncommit, \ ++ assert((!G1Uncommit && G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index))) || G1Uncommit, \ + err_msg("Index "SIZE_FORMAT" corresponding to "PTR_FORMAT \ + " (%u) is not in committed area.", \ + (index), \ +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +index 060531901..1f1042caa 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +@@ -1371,7 +1371,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc, + // how reference processing currently works in G1. + + // Temporarily make discovery by the STW ref processor single threaded (non-MT). +- ReferenceProcessorMTDiscoveryMutator stw_rp_disc_ser(ref_processor_stw(), false); ++ ReferenceProcessorMTDiscoveryMutator stw_rp_disc_ser(ref_processor_stw(), G1ParallelFullGC); + + // Temporarily clear the STW ref processor's _is_alive_non_header field. + ReferenceProcessorIsAliveMutator stw_rp_is_alive_null(ref_processor_stw(), NULL); +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp +index 2a14b967a..9ab422405 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp +@@ -216,13 +216,17 @@ size_t G1RePrepareClosure::apply(oop obj) { + + bool G1MarkSweep::_parallel_prepare_compact = false; + bool G1MarkSweep::_parallel_adjust = false; ++bool G1MarkSweep::_parallel_mark = false; ++uint G1MarkSweep::_active_workers = 0; + + void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, + bool clear_all_softrefs) { + assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); +- uint active_workers = G1CollectedHeap::heap()->workers()->active_workers(); ++ ++ _active_workers = G1CollectedHeap::heap()->workers()->active_workers(); + + if (G1ParallelFullGC) { ++ _parallel_mark = true; + _parallel_prepare_compact = true; + _parallel_adjust = true; + } +@@ -238,6 +242,19 @@ void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, + assert(rp != NULL, "should be non-NULL"); + assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Precondition"); + ++ GenMarkSweep* marks = new GenMarkSweep[_active_workers]; ++ ++ if (!_parallel_mark) { ++ allocate_stacks(); ++ } else { ++ for (uint i = 0; i < _active_workers; i++) { ++ marks[i]._preserved_count_max = 0; ++ marks[i]._preserved_marks = NULL; ++ marks[i]._preserved_count = 0; ++ marks[i].set_worker_id(i); ++ } ++ } ++ + GenMarkSweep::_ref_processor = rp; + rp->setup_policy(clear_all_softrefs); + +@@ -248,30 +265,42 @@ void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, + + bool marked_for_unloading = false; + +- allocate_stacks(); +- + // We should save the marks of the currently locked biased monitors. + // The marking doesn't preserve the marks of biased objects. + BiasedLocking::preserve_marks(); + + { +- G1FullGCCompactionPoints cps(active_workers); ++ G1FullGCCompactionPoints cps(_active_workers); + +- mark_sweep_phase1(marked_for_unloading, clear_all_softrefs); ++ mark_sweep_phase1(marked_for_unloading, clear_all_softrefs, marks); + + mark_sweep_phase2(&cps); + + // Don't add any more derived pointers during phase3 + COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); + +- mark_sweep_phase3(); ++ mark_sweep_phase3(marks); + + mark_sweep_phase4(&cps); + } + +- GenMarkSweep::restore_marks(); ++ if (!_parallel_mark) { ++ GenMarkSweep::the_gen_mark()->restore_marks(); ++ } else { ++ for (uint i = 0; i < _active_workers; i++) { ++ marks[i].restore_marks(); ++ } ++ } ++ + BiasedLocking::restore_marks(); +- GenMarkSweep::deallocate_stacks(); ++ ++ if (!_parallel_mark) { ++ GenMarkSweep::the_gen_mark()->deallocate_stacks(); ++ } else { ++ for (uint i = 0; i < _active_workers; i++) { ++ marks[i].deallocate_stacks(); ++ } ++ } + + // "free at last gc" is calculated from these. + // CHF: cheating for now!!! +@@ -281,20 +310,62 @@ void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, + Threads::gc_epilogue(); + CodeCache::gc_epilogue(); + JvmtiExport::gc_epilogue(); +- + // refs processing: clean slate + GenMarkSweep::_ref_processor = NULL; + } + ++void G1MarkSweep::run_task(AbstractGangTask* task) { ++ G1CollectedHeap::heap()->workers()->run_task(task); ++} + + void G1MarkSweep::allocate_stacks() { +- GenMarkSweep::_preserved_count_max = 0; +- GenMarkSweep::_preserved_marks = NULL; +- GenMarkSweep::_preserved_count = 0; ++ GenMarkSweep::the_gen_mark()->_preserved_count_max = 0; ++ GenMarkSweep::the_gen_mark()->_preserved_marks = NULL; ++ GenMarkSweep::the_gen_mark()->_preserved_count = 0; + } + ++class G1FullGCMarkTask : public AbstractGangTask { ++protected: ++ G1RootProcessor _root_processor; ++ GenMarkSweep* _marks; ++ ++public: ++ G1FullGCMarkTask(GenMarkSweep* marks, uint active_workers) : ++ AbstractGangTask("G1 mark task"), ++ _root_processor(G1CollectedHeap::heap()), ++ _marks(marks) { ++ _root_processor.set_num_workers(active_workers); ++ } ++ virtual ~G1FullGCMarkTask() { } ++ ++ void work(uint worker_id) { ++ Ticks start = Ticks::now(); ++ ++ ResourceMark rm; ++ ++ MarkingCodeBlobClosure follow_code_closure(&_marks[worker_id].follow_root_closure, ++ !CodeBlobToOopClosure::FixRelocations); ++ { ++ ++ if (ClassUnloading) { ++ _root_processor.process_strong_roots(&_marks[worker_id].follow_root_closure, ++ &_marks[worker_id].follow_cld_closure, ++ &follow_code_closure, ++ worker_id); ++ } else { ++ _root_processor.process_all_roots_no_string_table(&_marks[worker_id].follow_root_closure, ++ &_marks[worker_id].follow_cld_closure, ++ &follow_code_closure); ++ } ++ _marks[worker_id].follow_stack(); ++ } ++ } ++}; ++ ++ + void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading, +- bool clear_all_softrefs) { ++ bool clear_all_softrefs, ++ GenMarkSweep* marks) { + // Recursively traverse all live objects and mark them + GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id()); + GenMarkSweep::trace(" 1"); +@@ -304,52 +375,87 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading, + // Need cleared claim bits for the roots processing + ClassLoaderDataGraph::clear_claimed_marks(); + +- MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations); +- { +- G1RootProcessor root_processor(g1h); +- if (ClassUnloading) { +- root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure, +- &GenMarkSweep::follow_cld_closure, +- &follow_code_closure); +- } else { +- root_processor.process_all_roots_no_string_table( +- &GenMarkSweep::follow_root_closure, +- &GenMarkSweep::follow_cld_closure, +- &follow_code_closure); ++ if (!_parallel_mark) { ++ ++ MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::the_gen_mark()->follow_root_closure, ++ !CodeBlobToOopClosure::FixRelocations); ++ { ++ G1RootProcessor root_processor(g1h); ++ if (ClassUnloading) { ++ root_processor.process_strong_roots(&GenMarkSweep::the_gen_mark()->follow_root_closure, ++ &GenMarkSweep::the_gen_mark()->follow_cld_closure, ++ &follow_code_closure); ++ } else { ++ root_processor.process_all_roots_no_string_table(&GenMarkSweep::the_gen_mark()->follow_root_closure, ++ &GenMarkSweep::the_gen_mark()->follow_cld_closure, ++ &follow_code_closure); ++ } + } +- } + +- // Process reference objects found during marking +- ReferenceProcessor* rp = GenMarkSweep::ref_processor(); +- assert(rp == g1h->ref_processor_stw(), "Sanity"); ++ // Process reference objects found during marking ++ ReferenceProcessor* rp = GenMarkSweep::ref_processor(); ++ assert(rp == g1h->ref_processor_stw(), "Sanity"); ++ ++ rp->setup_policy(clear_all_softrefs); ++ const ReferenceProcessorStats& stats = ++ rp->process_discovered_references(&GenMarkSweep::the_gen_mark()->is_alive, ++ &GenMarkSweep::the_gen_mark()->keep_alive, ++ &GenMarkSweep::the_gen_mark()->follow_stack_closure, ++ NULL, ++ gc_timer(), ++ gc_tracer()->gc_id()); ++ gc_tracer()->report_gc_reference_stats(stats); + +- rp->setup_policy(clear_all_softrefs); +- const ReferenceProcessorStats& stats = +- rp->process_discovered_references(&GenMarkSweep::is_alive, +- &GenMarkSweep::keep_alive, +- &GenMarkSweep::follow_stack_closure, +- NULL, +- gc_timer(), +- gc_tracer()->gc_id()); +- gc_tracer()->report_gc_reference_stats(stats); + ++ // This is the point where the entire marking should have completed. ++ assert(GenMarkSweep::the_gen_mark()->_marking_stack.is_empty(), "Marking should have completed"); + +- // This is the point where the entire marking should have completed. +- assert(GenMarkSweep::_marking_stack.is_empty(), "Marking should have completed"); ++ if (ClassUnloading) { ++ // Unload classes and purge the SystemDictionary. ++ bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::the_gen_mark()->is_alive); ++ // Unload nmethods. ++ CodeCache::do_unloading(&GenMarkSweep::the_gen_mark()->is_alive, purged_class); ++ // Prune dead klasses from subklass/sibling/implementor lists. ++ Klass::clean_weak_klass_links(&GenMarkSweep::the_gen_mark()->is_alive); ++ } ++ // Delete entries for dead interned string and clean up unreferenced symbols in symbol table. ++ G1CollectedHeap::heap()->unlink_string_and_symbol_table(&GenMarkSweep::the_gen_mark()->is_alive); ++ } else { ++ G1FullGCMarkTask task(marks, _active_workers); ++ FlexibleWorkGang* flexible = G1CollectedHeap::heap()->workers(); ++ SharedHeap::heap()->set_par_threads(_active_workers); ++ flexible->run_task(&task); ++ SharedHeap::heap()->set_par_threads(0); ++ ++ // Process reference objects found during marking ++ ReferenceProcessor* rp = MarkSweep::ref_processor(); ++ assert(rp == g1h->ref_processor_stw(), "Sanity"); + +- if (ClassUnloading) { ++ rp->setup_policy(clear_all_softrefs); + +- // Unload classes and purge the SystemDictionary. +- bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive); ++ const ReferenceProcessorStats& stats = ++ rp->process_discovered_references(&marks[0].is_alive, ++ &marks[0].keep_alive, ++ &marks[0].follow_stack_closure, ++ NULL, ++ gc_timer(), ++ gc_tracer()->gc_id()); ++ gc_tracer()->report_gc_reference_stats(stats); ++ ++ if (ClassUnloading) { + +- // Unload nmethods. +- CodeCache::do_unloading(&GenMarkSweep::is_alive, purged_class); ++ // Unload classes and purge the SystemDictionary. ++ bool purged_class = SystemDictionary::do_unloading(&marks[0].is_alive); + +- // Prune dead klasses from subklass/sibling/implementor lists. +- Klass::clean_weak_klass_links(&GenMarkSweep::is_alive); ++ // Unload nmethods. ++ CodeCache::do_unloading(&marks[0].is_alive, purged_class); ++ ++ // Prune dead klasses from subklass/sibling/implementor lists. ++ Klass::clean_weak_klass_links(&marks[0].is_alive); ++ } ++ // Delete entries for dead interned string and clean up unreferenced symbols in symbol table. ++ G1CollectedHeap::heap()->unlink_string_and_symbol_table(&marks[0].is_alive); + } +- // Delete entries for dead interned string and clean up unreferenced symbols in symbol table. +- G1CollectedHeap::heap()->unlink_string_and_symbol_table(&GenMarkSweep::is_alive); + + if (VerifyDuringGC) { + HandleMark hm; // handle scope +@@ -374,7 +480,7 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading, + } + } + +- gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive); ++ gc_tracer()->report_object_count_after_gc(&GenMarkSweep::the_gen_mark()->is_alive); + } + + +@@ -603,7 +709,7 @@ public: + } + }; + +-void G1MarkSweep::mark_sweep_phase3() { ++void G1MarkSweep::mark_sweep_phase3(GenMarkSweep* marks) { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + + // Adjust the pointers to reflect the new locations +@@ -613,33 +719,40 @@ void G1MarkSweep::mark_sweep_phase3() { + // Need cleared claim bits for the roots processing + ClassLoaderDataGraph::clear_claimed_marks(); + +- CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::adjust_pointer_closure, ++ CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure, + CodeBlobToOopClosure::FixRelocations); + { + G1RootProcessor root_processor(g1h); +- root_processor.process_all_roots(&GenMarkSweep::adjust_pointer_closure, +- &GenMarkSweep::adjust_cld_closure, ++ root_processor.process_all_roots(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure, ++ &GenMarkSweep::the_gen_mark()->adjust_cld_closure, + &adjust_code_closure); + } + + assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity"); +- g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_pointer_closure); ++ g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure); + + // Now adjust pointers in remaining weak roots. (All of which should + // have been cleared if they pointed to non-surviving objects.) +- JNIHandles::weak_oops_do(&GenMarkSweep::adjust_pointer_closure); +- JFR_ONLY(Jfr::weak_oops_do(&GenMarkSweep::adjust_pointer_closure)); ++ JNIHandles::weak_oops_do(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure); ++ JFR_ONLY(Jfr::weak_oops_do(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure)); + + if (G1StringDedup::is_enabled()) { +- G1StringDedup::oops_do(&GenMarkSweep::adjust_pointer_closure); ++ G1StringDedup::oops_do(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure); + } + +- GenMarkSweep::adjust_marks(); +- + if (!_parallel_adjust) { ++ GenMarkSweep::the_gen_mark()->adjust_marks(); + G1AdjustPointersClosure blk; + g1h->heap_region_iterate(&blk); + } else { ++ if (!_parallel_mark) { ++ GenMarkSweep::the_gen_mark()->adjust_marks(); ++ } else { ++ for (uint i = 0; i < _active_workers; i++) { ++ marks[i].adjust_marks(); ++ } ++ } ++ + G1FullGCAdjustTask task; + FlexibleWorkGang* flexible = G1CollectedHeap::heap()->workers(); + flexible->run_task(&task); +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp +index 82aa6b63e..0787cfe86 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp +@@ -75,16 +75,19 @@ class G1MarkSweep : AllStatic { + private: + static bool _parallel_prepare_compact; + static bool _parallel_adjust; ++ static bool _parallel_mark; ++ static uint _active_workers; + + private: +- ++ static void run_task(AbstractGangTask* task); + // Mark live objects + static void mark_sweep_phase1(bool& marked_for_deopt, +- bool clear_all_softrefs); ++ bool clear_all_softrefs, ++ GenMarkSweep* marks); + // Calculate new addresses + static void mark_sweep_phase2(G1FullGCCompactionPoints* cps); + // Update pointers +- static void mark_sweep_phase3(); ++ static void mark_sweep_phase3(GenMarkSweep* marks); + // Move objects to new positions + static void mark_sweep_phase4(G1FullGCCompactionPoints* cps); + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp +index 5b27a017a..6b0f8e8bd 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp +@@ -213,10 +213,11 @@ void G1RootProcessor::evacuate_roots(OopClosure* scan_non_heap_roots, + + void G1RootProcessor::process_strong_roots(OopClosure* oops, + CLDClosure* clds, +- CodeBlobClosure* blobs) { ++ CodeBlobClosure* blobs, ++ uint worker_id) { + +- process_java_roots(oops, clds, clds, NULL, blobs, NULL, 0); +- process_vm_roots(oops, NULL, NULL, 0); ++ process_java_roots(oops, clds, clds, NULL, blobs, NULL, worker_id); ++ process_vm_roots(oops, NULL, NULL, worker_id); + + _process_strong_tasks.all_tasks_completed(); + } +@@ -224,23 +225,25 @@ void G1RootProcessor::process_strong_roots(OopClosure* oops, + void G1RootProcessor::process_all_roots(OopClosure* oops, + CLDClosure* clds, + CodeBlobClosure* blobs, +- bool process_string_table) { ++ bool process_string_table, ++ uint worker_id) { + +- process_java_roots(oops, NULL, clds, clds, NULL, NULL, 0); +- process_vm_roots(oops, oops, NULL, 0); ++ process_java_roots(oops, NULL, clds, clds, NULL, NULL, worker_id); ++ process_vm_roots(oops, oops, NULL, worker_id); + + if (process_string_table) { +- process_string_table_roots(oops, NULL, 0); ++ process_string_table_roots(oops, NULL, worker_id); + } +- process_code_cache_roots(blobs, NULL, 0); ++ process_code_cache_roots(blobs, NULL, worker_id); + + _process_strong_tasks.all_tasks_completed(); + } + + void G1RootProcessor::process_all_roots(OopClosure* oops, + CLDClosure* clds, +- CodeBlobClosure* blobs) { +- process_all_roots(oops, clds, blobs, true); ++ CodeBlobClosure* blobs, ++ uint worker_id) { ++ process_all_roots(oops, clds, blobs, true, worker_id); + } + + void G1RootProcessor::process_all_roots_no_string_table(OopClosure* oops, +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp +index ad4e75ba3..8395ee2e4 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp +@@ -75,7 +75,8 @@ class G1RootProcessor : public StackObj { + void process_all_roots(OopClosure* oops, + CLDClosure* clds, + CodeBlobClosure* blobs, +- bool process_string_table); ++ bool process_string_table, ++ uint worker_id = 0); + + void process_java_roots(OopClosure* scan_non_heap_roots, + CLDClosure* thread_stack_clds, +@@ -114,12 +115,14 @@ public: + // Apply oops, clds and blobs to all strongly reachable roots in the system + void process_strong_roots(OopClosure* oops, + CLDClosure* clds, +- CodeBlobClosure* blobs); ++ CodeBlobClosure* blobs, ++ uint worker_id = 0); + + // Apply oops, clds and blobs to strongly and weakly reachable roots in the system + void process_all_roots(OopClosure* oops, + CLDClosure* clds, +- CodeBlobClosure* blobs); ++ CodeBlobClosure* blobs, ++ uint worker_id = 0); + + // Apply scan_rs to all locations in the union of the remembered sets for all + // regions in the collection set +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp +index bb960ee3a..804d1e141 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp +@@ -49,10 +49,10 @@ void G1StringDedup::stop() { + G1StringDedupThread::stop(); + } + +-bool G1StringDedup::is_candidate_from_mark(oop obj) { ++bool G1StringDedup::is_candidate_from_mark(oop obj, uint age) { + if (java_lang_String::is_instance(obj)) { + bool from_young = G1CollectedHeap::heap()->heap_region_containing_raw(obj)->is_young(); +- if (from_young && obj->age() < StringDeduplicationAgeThreshold) { ++ if (from_young && age < StringDeduplicationAgeThreshold) { + // Candidate found. String is being evacuated from young to old but has not + // reached the deduplication age threshold, i.e. has not previously been a + // candidate during its life in the young generation. +@@ -64,10 +64,10 @@ bool G1StringDedup::is_candidate_from_mark(oop obj) { + return false; + } + +-void G1StringDedup::enqueue_from_mark(oop java_string) { ++void G1StringDedup::enqueue_from_mark(oop java_string, uint age, uint worker_id) { + assert(is_enabled(), "String deduplication not enabled"); +- if (is_candidate_from_mark(java_string)) { +- G1StringDedupQueue::push(0 /* worker_id */, java_string); ++ if (is_candidate_from_mark(java_string, age)) { ++ G1StringDedupQueue::push(worker_id /* worker_id */, java_string); + } + } + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp +index 3792a667a..d14284b9a 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp +@@ -102,7 +102,7 @@ private: + + // Candidate selection policies, returns true if the given object is + // candidate for string deduplication. +- static bool is_candidate_from_mark(oop obj); ++ static bool is_candidate_from_mark(oop obj, uint age); + static bool is_candidate_from_evacuation(bool from_young, bool to_young, oop obj); + + public: +@@ -124,7 +124,7 @@ public: + // Enqueues a deduplication candidate for later processing by the deduplication + // thread. Before enqueuing, these functions apply the appropriate candidate + // selection policy to filters out non-candidates. +- static void enqueue_from_mark(oop java_string); ++ static void enqueue_from_mark(oop java_string, uint age, uint worker_id); + static void enqueue_from_evacuation(bool from_young, bool to_young, + unsigned int queue, oop java_string); + +diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp +index a8a87cc1b..74c15844b 100644 +--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp ++++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp +@@ -430,7 +430,7 @@ void ParallelScavengeHeap::do_full_collection(bool clear_all_soft_refs) { + bool maximum_compaction = clear_all_soft_refs; + PSParallelCompact::invoke(maximum_compaction); + } else { +- PSMarkSweep::invoke(clear_all_soft_refs); ++ PSMarkSweep::the_ps_mark()->invoke(clear_all_soft_refs); + } + } + +diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +index 2542ba1ca..4f8890f04 100644 +--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp ++++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +@@ -59,10 +59,15 @@ + + PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ++MarkSweep* PSMarkSweep::_the_ps_mark = NULL; + elapsedTimer PSMarkSweep::_accumulated_time; + jlong PSMarkSweep::_time_of_last_gc = 0; + CollectorCounters* PSMarkSweep::_counters = NULL; + ++void PSMarkSweep::ps_marksweep_init() { ++ PSMarkSweep::_the_ps_mark = new (ResourceObj::C_HEAP, mtGC) PSMarkSweep(); ++} ++ + void PSMarkSweep::initialize() { + MemRegion mr = Universe::heap()->reserved_region(); + _ref_processor = new ReferenceProcessor(mr); // a vanilla ref proc +diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp +index 46073f9e2..01666ea4d 100644 +--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp ++++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp +@@ -34,34 +34,36 @@ class PSYoungGen; + class PSOldGen; + + class PSMarkSweep : public MarkSweep { ++ friend void marksweep_init(); + private: + static elapsedTimer _accumulated_time; + static jlong _time_of_last_gc; // ms + static CollectorCounters* _counters; ++ static MarkSweep* _the_ps_mark; + + // Closure accessors +- static OopClosure* mark_and_push_closure() { return &MarkSweep::mark_and_push_closure; } +- static VoidClosure* follow_stack_closure() { return (VoidClosure*)&MarkSweep::follow_stack_closure; } +- static CLDClosure* follow_cld_closure() { return &MarkSweep::follow_cld_closure; } +- static OopClosure* adjust_pointer_closure() { return (OopClosure*)&MarkSweep::adjust_pointer_closure; } +- static CLDClosure* adjust_cld_closure() { return &MarkSweep::adjust_cld_closure; } +- static BoolObjectClosure* is_alive_closure() { return (BoolObjectClosure*)&MarkSweep::is_alive; } ++ OopClosure* mark_and_push_closure() { return &(MarkSweep::mark_and_push_closure); } ++ VoidClosure* follow_stack_closure() { return (VoidClosure*)&(MarkSweep::follow_stack_closure); } ++ CLDClosure* follow_cld_closure() { return &(MarkSweep::follow_cld_closure); } ++ OopClosure* adjust_pointer_closure() { return (OopClosure*)&(MarkSweep::adjust_pointer_closure); } ++ CLDClosure* adjust_cld_closure() { return &(MarkSweep::adjust_cld_closure); } ++ BoolObjectClosure* is_alive_closure() { return (BoolObjectClosure*)&(MarkSweep::is_alive); } + + debug_only(public:) // Used for PSParallelCompact debugging + // Mark live objects +- static void mark_sweep_phase1(bool clear_all_softrefs); ++ void mark_sweep_phase1(bool clear_all_softrefs); + // Calculate new addresses +- static void mark_sweep_phase2(); ++ void mark_sweep_phase2(); + debug_only(private:) // End used for PSParallelCompact debugging + // Update pointers +- static void mark_sweep_phase3(); ++ void mark_sweep_phase3(); + // Move objects to new positions +- static void mark_sweep_phase4(); ++ void mark_sweep_phase4(); + + debug_only(public:) // Used for PSParallelCompact debugging + // Temporary data structures for traversal and storing/restoring marks +- static void allocate_stacks(); +- static void deallocate_stacks(); ++ void allocate_stacks(); ++ void deallocate_stacks(); + static void set_ref_processor(ReferenceProcessor* rp) { // delete this method + _ref_processor = rp; + } +@@ -75,10 +77,13 @@ class PSMarkSweep : public MarkSweep { + + // Reset time since last full gc + static void reset_millis_since_last_gc(); ++ static void ps_marksweep_init(); + + public: +- static void invoke(bool clear_all_softrefs); +- static bool invoke_no_policy(bool clear_all_softrefs); ++ static inline PSMarkSweep* the_ps_mark() { return (PSMarkSweep*)_the_ps_mark; } ++ ++ void invoke(bool clear_all_softrefs); ++ bool invoke_no_policy(bool clear_all_softrefs); + + static void initialize(); + +diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +index 12e282eeb..670cd3e64 100644 +--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp ++++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +@@ -248,7 +248,7 @@ bool PSScavenge::invoke() { + if (UseParallelOldGC) { + full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs); + } else { +- full_gc_done = PSMarkSweep::invoke_no_policy(clear_all_softrefs); ++ full_gc_done = PSMarkSweep::the_ps_mark()->invoke_no_policy(clear_all_softrefs); + } + } + +diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp +index e2629b652..596207934 100644 +--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp ++++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp +@@ -24,10 +24,12 @@ + + #include "precompiled.hpp" + #include "compiler/compileBroker.hpp" ++#include "gc_implementation/parallelScavenge/psMarkSweep.hpp" + #include "gc_implementation/shared/gcTimer.hpp" + #include "gc_implementation/shared/gcTrace.hpp" + #include "gc_implementation/shared/markSweep.inline.hpp" + #include "gc_interface/collectedHeap.inline.hpp" ++#include "memory/genMarkSweep.hpp" + #include "oops/methodData.hpp" + #include "oops/objArrayKlass.inline.hpp" + #include "oops/oop.inline.hpp" +@@ -36,53 +38,41 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + + uint MarkSweep::_total_invocations = 0; + +-Stack MarkSweep::_marking_stack; +-Stack MarkSweep::_objarray_stack; +- +-Stack MarkSweep::_preserved_oop_stack; +-Stack MarkSweep::_preserved_mark_stack; +-size_t MarkSweep::_preserved_count = 0; +-size_t MarkSweep::_preserved_count_max = 0; +-PreservedMark* MarkSweep::_preserved_marks = NULL; + ReferenceProcessor* MarkSweep::_ref_processor = NULL; + STWGCTimer* MarkSweep::_gc_timer = NULL; + SerialOldTracer* MarkSweep::_gc_tracer = NULL; + +-MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; +- +-void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); } +-void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); } +- +-MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure; +-CLDToOopClosure MarkSweep::follow_cld_closure(&mark_and_push_closure); +-CLDToOopClosure MarkSweep::adjust_cld_closure(&adjust_pointer_closure); ++void MarkSweep::FollowRootClosure::do_oop(oop* p) { _mark->follow_root(p); } ++void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { _mark->follow_root(p); } + +-void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(p); } +-void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); } ++void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { _mark->mark_and_push(p); } ++void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { _mark->mark_and_push(p); } + + void MarkSweep::follow_class_loader(ClassLoaderData* cld) { + MarkSweep::follow_cld_closure.do_cld(cld); + } + ++MarkSweep* MarkSweep::the_mark() { ++ return GenMarkSweep::the_gen_mark(); ++} ++ + void MarkSweep::follow_stack() { + do { + while (!_marking_stack.is_empty()) { + oop obj = _marking_stack.pop(); + assert (obj->is_gc_marked(), "p must be marked"); +- obj->follow_contents(); ++ obj->follow_contents(this); + } + // Process ObjArrays one at a time to avoid marking stack bloat. + if (!_objarray_stack.is_empty()) { + ObjArrayTask task = _objarray_stack.pop(); + ObjArrayKlass* k = (ObjArrayKlass*)task.obj()->klass(); +- k->oop_follow_contents(task.obj(), task.index()); ++ k->oop_follow_contents(task.obj(), task.index(), this); + } + } while (!_marking_stack.is_empty() || !_objarray_stack.is_empty()); + } + +-MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure; +- +-void MarkSweep::FollowStackClosure::do_void() { follow_stack(); } ++void MarkSweep::FollowStackClosure::do_void() { _mark->follow_stack(); } + + // We preserve the mark which should be replaced at the end and the location + // that it will go. Note that the object that this markOop belongs to isn't +@@ -100,8 +90,6 @@ void MarkSweep::preserve_mark(oop obj, markOop mark) { + } + } + +-MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure; +- + void MarkSweep::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p); } + void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p); } + +@@ -143,18 +131,16 @@ void MarkSweep::restore_marks() { + } + } + +-MarkSweep::IsAliveClosure MarkSweep::is_alive; +- + bool MarkSweep::IsAliveClosure::do_object_b(oop p) { return p->is_gc_marked(); } + +-MarkSweep::KeepAliveClosure MarkSweep::keep_alive; +- + void MarkSweep::KeepAliveClosure::do_oop(oop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); } + void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); } + + void marksweep_init() { + MarkSweep::_gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer(); + MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer(); ++ PSMarkSweep::ps_marksweep_init(); ++ GenMarkSweep::gen_marksweep_init(); + } + + #ifndef PRODUCT +diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp +index 462643e2f..813a5aef7 100644 +--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp ++++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp +@@ -49,43 +49,55 @@ class STWGCTimer; + // declared at end + class PreservedMark; + +-class MarkSweep : AllStatic { ++class MarkSweep : public ResourceObj { + // + // Inline closure decls + // + class FollowRootClosure: public OopsInGenClosure { ++ MarkSweep* _mark; + public: ++ FollowRootClosure(MarkSweep* mark) : _mark(mark) { } + virtual void do_oop(oop* p); + virtual void do_oop(narrowOop* p); + }; + + class MarkAndPushClosure: public OopClosure { ++ MarkSweep* _mark; + public: ++ MarkAndPushClosure(MarkSweep* mark) : _mark(mark) { } + virtual void do_oop(oop* p); + virtual void do_oop(narrowOop* p); + }; + + class FollowStackClosure: public VoidClosure { ++ MarkSweep* _mark; + public: ++ FollowStackClosure(MarkSweep* mark) : _mark(mark) { } + virtual void do_void(); + }; + + class AdjustPointerClosure: public OopsInGenClosure { ++ MarkSweep* _mark; + public: ++ AdjustPointerClosure(MarkSweep* mark) : _mark(mark) { } + virtual void do_oop(oop* p); + virtual void do_oop(narrowOop* p); + }; + + // Used for java/lang/ref handling + class IsAliveClosure: public BoolObjectClosure { ++ MarkSweep* _mark; + public: ++ IsAliveClosure(MarkSweep* mark) : _mark(mark) { } + virtual bool do_object_b(oop p); + }; + + class KeepAliveClosure: public OopClosure { ++ MarkSweep* _mark; + protected: + template void do_oop_work(T* p); + public: ++ KeepAliveClosure(MarkSweep* mark) : _mark(mark) { } + virtual void do_oop(oop* p); + virtual void do_oop(narrowOop* p); + }; +@@ -106,37 +118,49 @@ class MarkSweep : AllStatic { + static uint _total_invocations; + + // Traversal stacks used during phase1 +- static Stack _marking_stack; +- static Stack _objarray_stack; ++ Stack _marking_stack; ++ Stack _objarray_stack; + + // Space for storing/restoring mark word +- static Stack _preserved_mark_stack; +- static Stack _preserved_oop_stack; +- static size_t _preserved_count; +- static size_t _preserved_count_max; +- static PreservedMark* _preserved_marks; ++ Stack _preserved_mark_stack; ++ Stack _preserved_oop_stack; ++ size_t _preserved_count; ++ size_t _preserved_count_max; ++ PreservedMark* _preserved_marks; + ++ uint _worker_id; + // Reference processing (used in ...follow_contents) + static ReferenceProcessor* _ref_processor; + + static STWGCTimer* _gc_timer; + static SerialOldTracer* _gc_tracer; + +- // Non public closures +- static KeepAliveClosure keep_alive; +- + // Debugging + static void trace(const char* msg) PRODUCT_RETURN; ++ bool par_mark(oop obj); + + public: ++ static MarkSweep* the_mark(); ++ KeepAliveClosure keep_alive; + // Public closures +- static IsAliveClosure is_alive; +- static FollowRootClosure follow_root_closure; +- static MarkAndPushClosure mark_and_push_closure; +- static FollowStackClosure follow_stack_closure; +- static CLDToOopClosure follow_cld_closure; +- static AdjustPointerClosure adjust_pointer_closure; +- static CLDToOopClosure adjust_cld_closure; ++ IsAliveClosure is_alive; ++ FollowRootClosure follow_root_closure; ++ MarkAndPushClosure mark_and_push_closure; ++ FollowStackClosure follow_stack_closure; ++ CLDToOopClosure follow_cld_closure; ++ AdjustPointerClosure adjust_pointer_closure; ++ CLDToOopClosure adjust_cld_closure; ++ ++ MarkSweep() : ++ is_alive(this), ++ follow_root_closure(this), ++ mark_and_push_closure(this), ++ follow_stack_closure(this), ++ follow_cld_closure(&mark_and_push_closure), ++ adjust_pointer_closure(this), ++ adjust_cld_closure(&adjust_pointer_closure), ++ keep_alive(this) ++ { } + + // Accessors + static uint total_invocations() { return _total_invocations; } +@@ -147,26 +171,23 @@ class MarkSweep : AllStatic { + static STWGCTimer* gc_timer() { return _gc_timer; } + static SerialOldTracer* gc_tracer() { return _gc_tracer; } + ++ void set_worker_id(uint worker_id) { _worker_id = worker_id; } + // Call backs for marking +- static void mark_object(oop obj); ++ bool mark_object(oop obj); + // Mark pointer and follow contents. Empty marking stack afterwards. +- template static inline void follow_root(T* p); ++ template inline void follow_root(T* p); + + // Check mark and maybe push on marking stack +- template static void mark_and_push(T* p); +- +- static inline void push_objarray(oop obj, size_t index); +- +- static void follow_stack(); // Empty marking stack. +- +- static void follow_klass(Klass* klass); +- +- static void follow_class_loader(ClassLoaderData* cld); +- +- static void preserve_mark(oop p, markOop mark); +- // Save the mark word so it can be restored later +- static void adjust_marks(); // Adjust the pointers in the preserved marks table +- static void restore_marks(); // Restore the marks that we saved in preserve_mark ++ template void mark_and_push(T* p); ++ ++ inline void push_objarray(oop obj, size_t index); ++ void follow_stack(); // Empty marking st ++ void follow_klass(Klass* klass); ++ void follow_class_loader(ClassLoaderData* cld); ++ void preserve_mark(oop p, markOop mark); ++ // Save the mark word so it can be restored later ++ void adjust_marks(); // Adjust the pointers in the preserved marks table ++ void restore_marks(); // Restore the marks that we saved in preserve_mark + + template static inline void adjust_pointer(T* p); + }; +diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp +index c08e7a637..f9ede2487 100644 +--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp ++++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp +@@ -34,22 +34,43 @@ + #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" + #endif // INCLUDE_ALL_GCS + +-inline void MarkSweep::mark_object(oop obj) { ++inline bool MarkSweep::par_mark(oop obj) { ++ markOop origin = obj->mark(); ++ markOop target = markOopDesc::prototype()->set_marked(); ++ void* res = Atomic::cmpxchg_ptr(target, obj->mark_addr(), origin); ++ if (res == origin) { ++ return true; ++ } else { ++ return false; ++ } ++} ++ ++inline bool MarkSweep::mark_object(oop obj) { ++ markOop mark = obj->mark(); + #if INCLUDE_ALL_GCS + if (G1StringDedup::is_enabled()) { + // We must enqueue the object before it is marked + // as we otherwise can't read the object's age. +- G1StringDedup::enqueue_from_mark(obj); ++ uint age = 0; ++ if (mark->has_displaced_mark_helper()) { ++ age = mark->displaced_mark_helper()->age(); ++ } else { ++ age = mark->age(); ++ } ++ ++ G1StringDedup::enqueue_from_mark(obj, age, _worker_id); + } + #endif + // some marks may contain information we need to preserve so we store them away + // and overwrite the mark. We'll restore it at the end of markSweep. +- markOop mark = obj->mark(); +- obj->set_mark(markOopDesc::prototype()->set_marked()); ++ if (mark->is_marked() || !par_mark(obj)) { ++ return false; ++ } + + if (mark->must_be_preserved(obj)) { + preserve_mark(obj, mark); + } ++ return true; + } + + inline void MarkSweep::follow_klass(Klass* klass) { +@@ -64,8 +85,9 @@ template inline void MarkSweep::follow_root(T* p) { + if (!oopDesc::is_null(heap_oop)) { + oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); + if (!obj->mark()->is_marked()) { +- mark_object(obj); +- obj->follow_contents(); ++ if (mark_object(obj)) { ++ obj->follow_contents(this); ++ } + } + } + follow_stack(); +@@ -77,8 +99,9 @@ template inline void MarkSweep::mark_and_push(T* p) { + if (!oopDesc::is_null(heap_oop)) { + oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); + if (!obj->mark()->is_marked()) { +- mark_object(obj); +- _marking_stack.push(obj); ++ if (mark_object(obj)) { ++ _marking_stack.push(obj); ++ } + } + } + } +@@ -108,7 +131,7 @@ template inline void MarkSweep::adjust_pointer(T* p) { + } + + template inline void MarkSweep::KeepAliveClosure::do_oop_work(T* p) { +- mark_and_push(p); ++ _mark->mark_and_push(p); + } + + #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_MARKSWEEP_INLINE_HPP +diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp +index c5dc4947c..132703d5a 100644 +--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp ++++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp +@@ -52,6 +52,12 @@ + #include "utilities/copy.hpp" + #include "utilities/events.hpp" + ++GenMarkSweep* GenMarkSweep::_the_gen_mark = NULL; ++ ++void GenMarkSweep::gen_marksweep_init() { ++ GenMarkSweep::_the_gen_mark = new (ResourceObj::C_HEAP, mtGC) GenMarkSweep(); ++} ++ + void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, bool clear_all_softrefs) { + guarantee(level == 1, "We always collect both old and young."); + assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); +diff --git a/hotspot/src/share/vm/memory/genMarkSweep.hpp b/hotspot/src/share/vm/memory/genMarkSweep.hpp +index b6147ab5b..76d4ae1a2 100644 +--- a/hotspot/src/share/vm/memory/genMarkSweep.hpp ++++ b/hotspot/src/share/vm/memory/genMarkSweep.hpp +@@ -30,24 +30,28 @@ + class GenMarkSweep : public MarkSweep { + friend class VM_MarkSweep; + friend class G1MarkSweep; ++ friend void marksweep_init(); ++ static GenMarkSweep* _the_gen_mark; ++ static void gen_marksweep_init(); + public: +- static void invoke_at_safepoint(int level, ReferenceProcessor* rp, ++ static inline GenMarkSweep* the_gen_mark() { return _the_gen_mark; } ++ void invoke_at_safepoint(int level, ReferenceProcessor* rp, + bool clear_all_softrefs); + + private: + + // Mark live objects +- static void mark_sweep_phase1(int level, bool clear_all_softrefs); ++ void mark_sweep_phase1(int level, bool clear_all_softrefs); + // Calculate new addresses +- static void mark_sweep_phase2(); ++ void mark_sweep_phase2(); + // Update pointers +- static void mark_sweep_phase3(int level); ++ void mark_sweep_phase3(int level); + // Move objects to new positions +- static void mark_sweep_phase4(); ++ void mark_sweep_phase4(); + + // Temporary data structures for traversal and storing/restoring marks +- static void allocate_stacks(); +- static void deallocate_stacks(); ++ void allocate_stacks(); ++ void deallocate_stacks(); + }; + + #endif // SHARE_VM_MEMORY_GENMARKSWEEP_HPP +diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp +index 9d6c926e1..4e9848bb9 100644 +--- a/hotspot/src/share/vm/memory/generation.cpp ++++ b/hotspot/src/share/vm/memory/generation.cpp +@@ -648,7 +648,7 @@ void OneContigSpaceCardGeneration::collect(bool full, + SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer(); + gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start()); + +- GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs); ++ GenMarkSweep::the_gen_mark()->invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs); + + gc_timer->register_gc_end(); + +diff --git a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp +index 131ecbfb0..bb35ffd38 100644 +--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp ++++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp +@@ -114,14 +114,14 @@ ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARD + ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m) + ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m) + +-void InstanceClassLoaderKlass::oop_follow_contents(oop obj) { +- InstanceKlass::oop_follow_contents(obj); ++void InstanceClassLoaderKlass::oop_follow_contents(oop obj, MarkSweep* mark) { ++ InstanceKlass::oop_follow_contents(obj, mark); + ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj); + + // We must NULL check here, since the class loader + // can be found before the loader data has been set up. + if(loader_data != NULL) { +- MarkSweep::follow_class_loader(loader_data); ++ mark->follow_class_loader(loader_data); + } + } + +diff --git a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp +index 309ebf96c..47abfed45 100644 +--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp ++++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp +@@ -71,7 +71,7 @@ public: + #endif // INCLUDE_ALL_GCS + + // Garbage collection +- void oop_follow_contents(oop obj); ++ void oop_follow_contents(oop obj, MarkSweep* mark); + + // Parallel Scavenge and Parallel Old + PARALLEL_GC_DECLS +diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp +index c1707bf8b..895fbbf07 100644 +--- a/hotspot/src/share/vm/oops/instanceKlass.cpp ++++ b/hotspot/src/share/vm/oops/instanceKlass.cpp +@@ -2280,12 +2280,12 @@ template void assert_nothing(T *p) {} + } \ + } + +-void InstanceKlass::oop_follow_contents(oop obj) { ++void InstanceKlass::oop_follow_contents(oop obj, MarkSweep* mark) { + assert(obj != NULL, "can't follow the content of NULL object"); +- MarkSweep::follow_klass(obj->klass()); ++ mark->follow_klass(obj->klass()); + InstanceKlass_OOP_MAP_ITERATE( \ + obj, \ +- MarkSweep::mark_and_push(p), \ ++ mark->mark_and_push(p), \ + assert_is_in_closed_subset) + } + +diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp +index 3d6f85911..39d2c580c 100644 +--- a/hotspot/src/share/vm/oops/instanceKlass.hpp ++++ b/hotspot/src/share/vm/oops/instanceKlass.hpp +@@ -1013,7 +1013,7 @@ class InstanceKlass: public Klass { + #endif // INCLUDE_JVMTI + + // Garbage collection +- void oop_follow_contents(oop obj); ++ void oop_follow_contents(oop obj, MarkSweep* mark); + int oop_adjust_pointers(oop obj); + + void clean_weak_instanceklass_links(BoolObjectClosure* is_alive); +diff --git a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp +index 82c804108..fdf2e42af 100644 +--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp ++++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp +@@ -150,8 +150,8 @@ template void assert_nothing(T *p) {} + } + + +-void InstanceMirrorKlass::oop_follow_contents(oop obj) { +- InstanceKlass::oop_follow_contents(obj); ++void InstanceMirrorKlass::oop_follow_contents(oop obj, MarkSweep* mark) { ++ InstanceKlass::oop_follow_contents(obj, mark); + + // Follow the klass field in the mirror. + Klass* klass = java_lang_Class::as_Klass(obj); +@@ -164,9 +164,9 @@ void InstanceMirrorKlass::oop_follow_contents(oop obj) { + // the call to follow_class_loader is made when the class loader itself + // is handled. + if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) { +- MarkSweep::follow_class_loader(klass->class_loader_data()); ++ mark->follow_class_loader(klass->class_loader_data()); + } else { +- MarkSweep::follow_klass(klass); ++ mark->follow_klass(klass); + } + } else { + // If klass is NULL then this a mirror for a primitive type. +@@ -177,7 +177,7 @@ void InstanceMirrorKlass::oop_follow_contents(oop obj) { + + InstanceMirrorKlass_OOP_ITERATE( \ + start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ +- MarkSweep::mark_and_push(p), \ ++ mark->mark_and_push(p), \ + assert_is_in_closed_subset) + } + +diff --git a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp +index b861639ee..759f7d074 100644 +--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp ++++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp +@@ -89,7 +89,7 @@ class InstanceMirrorKlass: public InstanceKlass { + + // Garbage collection + int oop_adjust_pointers(oop obj); +- void oop_follow_contents(oop obj); ++ void oop_follow_contents(oop obj, MarkSweep* mark); + + // Parallel Scavenge and Parallel Old + PARALLEL_GC_DECLS +diff --git a/hotspot/src/share/vm/oops/instanceRefKlass.cpp b/hotspot/src/share/vm/oops/instanceRefKlass.cpp +index a14989314..2c3fe7496 100644 +--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp ++++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp +@@ -48,7 +48,7 @@ + PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + + template +-void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { ++void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj, MarkSweep* mark) { + T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); + T heap_oop = oopDesc::load_heap_oop(referent_addr); + debug_only( +@@ -61,7 +61,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { + if (!referent->is_gc_marked() && + MarkSweep::ref_processor()->discover_reference(obj, ref->reference_type())) { + // reference was discovered, referent will be traversed later +- ref->InstanceKlass::oop_follow_contents(obj); ++ ref->InstanceKlass::oop_follow_contents(obj, mark); + debug_only( + if(TraceReferenceGC && PrintGCDetails) { + gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, (void *)obj); +@@ -75,7 +75,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { + gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, (void *)obj); + } + ) +- MarkSweep::mark_and_push(referent_addr); ++ mark->mark_and_push(referent_addr); + } + } + T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); +@@ -91,7 +91,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { + INTPTR_FORMAT, discovered_addr); + } + ) +- MarkSweep::mark_and_push(discovered_addr); ++ mark->mark_and_push(discovered_addr); + } + } else { + #ifdef ASSERT +@@ -111,15 +111,15 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { + gclog_or_tty->print_cr(" Process next as normal " INTPTR_FORMAT, next_addr); + } + ) +- MarkSweep::mark_and_push(next_addr); +- ref->InstanceKlass::oop_follow_contents(obj); ++ mark->mark_and_push(next_addr); ++ ref->InstanceKlass::oop_follow_contents(obj, mark); + } + +-void InstanceRefKlass::oop_follow_contents(oop obj) { ++void InstanceRefKlass::oop_follow_contents(oop obj, MarkSweep* mark) { + if (UseCompressedOops) { +- specialized_oop_follow_contents(this, obj); ++ specialized_oop_follow_contents(this, obj, mark); + } else { +- specialized_oop_follow_contents(this, obj); ++ specialized_oop_follow_contents(this, obj, mark); + } + } + +diff --git a/hotspot/src/share/vm/oops/instanceRefKlass.hpp b/hotspot/src/share/vm/oops/instanceRefKlass.hpp +index 3140977b4..4a15c4c75 100644 +--- a/hotspot/src/share/vm/oops/instanceRefKlass.hpp ++++ b/hotspot/src/share/vm/oops/instanceRefKlass.hpp +@@ -65,7 +65,7 @@ class InstanceRefKlass: public InstanceKlass { + + // Garbage collection + int oop_adjust_pointers(oop obj); +- void oop_follow_contents(oop obj); ++ void oop_follow_contents(oop obj, MarkSweep* mark); + + // Parallel Scavenge and Parallel Old + PARALLEL_GC_DECLS +diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp +index b7588abd0..f70587eab 100644 +--- a/hotspot/src/share/vm/oops/klass.hpp ++++ b/hotspot/src/share/vm/oops/klass.hpp +@@ -93,6 +93,7 @@ class klassVtable; + class ParCompactionManager; + class KlassSizeStats; + class fieldDescriptor; ++class MarkSweep; + + class Klass : public Metadata { + friend class VMStructs; +@@ -538,7 +539,7 @@ protected: + virtual const char* signature_name() const; + + // garbage collection support +- virtual void oop_follow_contents(oop obj) = 0; ++ virtual void oop_follow_contents(oop obj, MarkSweep* mark) = 0; + virtual int oop_adjust_pointers(oop obj) = 0; + + // Parallel Scavenge and Parallel Old +diff --git a/hotspot/src/share/vm/oops/markOop.hpp b/hotspot/src/share/vm/oops/markOop.hpp +index 649217c88..a80c99be4 100644 +--- a/hotspot/src/share/vm/oops/markOop.hpp ++++ b/hotspot/src/share/vm/oops/markOop.hpp +@@ -102,8 +102,8 @@ class ObjectMonitor; + class JavaThread; + + class markOopDesc: public oopDesc { +- private: + // Conversion ++ public: + uintptr_t value() const { return (uintptr_t) this; } + + public: +diff --git a/hotspot/src/share/vm/oops/objArrayKlass.cpp b/hotspot/src/share/vm/oops/objArrayKlass.cpp +index 8049209bf..19abfbd5a 100644 +--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp ++++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp +@@ -454,13 +454,13 @@ void ObjArrayKlass::initialize(TRAPS) { + a, p, low, high, do_oop) \ + } + +-void ObjArrayKlass::oop_follow_contents(oop obj) { ++void ObjArrayKlass::oop_follow_contents(oop obj, MarkSweep* mark) { + assert (obj->is_array(), "obj must be array"); +- MarkSweep::follow_klass(obj->klass()); ++ mark->follow_klass(obj->klass()); + if (UseCompressedOops) { +- objarray_follow_contents(obj, 0); ++ objarray_follow_contents(obj, 0, mark); + } else { +- objarray_follow_contents(obj, 0); ++ objarray_follow_contents(obj, 0, mark); + } + } + +diff --git a/hotspot/src/share/vm/oops/objArrayKlass.hpp b/hotspot/src/share/vm/oops/objArrayKlass.hpp +index cfe31e86e..ab3cbc61c 100644 +--- a/hotspot/src/share/vm/oops/objArrayKlass.hpp ++++ b/hotspot/src/share/vm/oops/objArrayKlass.hpp +@@ -104,9 +104,9 @@ class ObjArrayKlass : public ArrayKlass { + void initialize(TRAPS); + + // Garbage collection +- void oop_follow_contents(oop obj); +- inline void oop_follow_contents(oop obj, int index); +- template inline void objarray_follow_contents(oop obj, int index); ++ void oop_follow_contents(oop obj, MarkSweep* mark); ++ inline void oop_follow_contents(oop obj, int index, MarkSweep* mark); ++ template inline void objarray_follow_contents(oop obj, int index, MarkSweep* mark); + + int oop_adjust_pointers(oop obj); + +diff --git a/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp b/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp +index e082df55a..96637bad7 100644 +--- a/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp ++++ b/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp +@@ -33,16 +33,16 @@ + #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" + #endif // INCLUDE_ALL_GCS + +-void ObjArrayKlass::oop_follow_contents(oop obj, int index) { ++void ObjArrayKlass::oop_follow_contents(oop obj, int index, MarkSweep* mark) { + if (UseCompressedOops) { +- objarray_follow_contents(obj, index); ++ objarray_follow_contents(obj, index, mark); + } else { +- objarray_follow_contents(obj, index); ++ objarray_follow_contents(obj, index, mark); + } + } + + template +-void ObjArrayKlass::objarray_follow_contents(oop obj, int index) { ++void ObjArrayKlass::objarray_follow_contents(oop obj, int index, MarkSweep* mark) { + objArrayOop a = objArrayOop(obj); + const size_t len = size_t(a->length()); + const size_t beg_index = size_t(index); +@@ -56,11 +56,11 @@ void ObjArrayKlass::objarray_follow_contents(oop obj, int index) { + + // Push the non-NULL elements of the next stride on the marking stack. + for (T* e = beg; e < end; e++) { +- MarkSweep::mark_and_push(e); ++ mark->mark_and_push(e); + } + + if (end_index < len) { +- MarkSweep::push_objarray(a, end_index); // Push the continuation. ++ mark->push_objarray(a, end_index); // Push the continuation. + } + } + +diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp +index a5c1d69bf..f452e7473 100644 +--- a/hotspot/src/share/vm/oops/oop.hpp ++++ b/hotspot/src/share/vm/oops/oop.hpp +@@ -56,6 +56,8 @@ class CMSIsAliveClosure; + class PSPromotionManager; + class ParCompactionManager; + ++class MarkSweep; ++ + class oopDesc { + friend class VMStructs; + private: +@@ -298,7 +300,7 @@ class oopDesc { + bool is_gc_marked() const; + // Apply "MarkSweep::mark_and_push" to (the address of) every non-NULL + // reference field in "this". +- void follow_contents(void); ++ void follow_contents(MarkSweep* mark); + + #if INCLUDE_ALL_GCS + // Parallel Scavenge +diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp +index ed37d0558..6407f830f 100644 +--- a/hotspot/src/share/vm/oops/oop.inline.hpp ++++ b/hotspot/src/share/vm/oops/oop.inline.hpp +@@ -655,9 +655,9 @@ inline bool oopDesc::is_unlocked_oop() const { + } + #endif // PRODUCT + +-inline void oopDesc::follow_contents(void) { ++inline void oopDesc::follow_contents(MarkSweep* mark) { + assert (is_gc_marked(), "should be marked"); +- klass()->oop_follow_contents(this); ++ klass()->oop_follow_contents(this, mark); + } + + // Used by scavengers +diff --git a/hotspot/src/share/vm/oops/typeArrayKlass.cpp b/hotspot/src/share/vm/oops/typeArrayKlass.cpp +index d69267d42..f17524e4b 100644 +--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp ++++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp +@@ -204,7 +204,7 @@ int TypeArrayKlass::oop_size(oop obj) const { + return t->object_size(); + } + +-void TypeArrayKlass::oop_follow_contents(oop obj) { ++void TypeArrayKlass::oop_follow_contents(oop obj, MarkSweep* mark) { + assert(obj->is_typeArray(),"must be a type array"); + // Performance tweak: We skip iterating over the klass pointer since we + // know that Universe::TypeArrayKlass never moves. +diff --git a/hotspot/src/share/vm/oops/typeArrayKlass.hpp b/hotspot/src/share/vm/oops/typeArrayKlass.hpp +index cf363fc76..c5cdd7000 100644 +--- a/hotspot/src/share/vm/oops/typeArrayKlass.hpp ++++ b/hotspot/src/share/vm/oops/typeArrayKlass.hpp +@@ -77,7 +77,7 @@ class TypeArrayKlass : public ArrayKlass { + int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr); + + // Garbage collection +- void oop_follow_contents(oop obj); ++ void oop_follow_contents(oop obj, MarkSweep* mark); + int oop_adjust_pointers(oop obj); + + // Parallel Scavenge and Parallel Old +-- +2.22.0 + diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index f12b3e6..af7fc81 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 4 +Release: 5 # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # and this change was brought into RHEL-4. java-1.5.0-ibm packages # also included the epoch in their virtual provides. This created a @@ -1119,6 +1119,7 @@ Patch221: 8183543-Aarch64-C2-compilation-often-fails-with-fail--last.patch Patch222: 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch Patch223: 8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch Patch224: G1Ucommit-Refactor-Trigger-mechanism.patch +Patch225: G1-Full-GC-parallel-mark.patch # 8u312 @@ -1588,6 +1589,7 @@ pushd %{top_level_dir_name} %patch222 -p1 %patch223 -p1 %patch224 -p1 +%patch225 -p1 popd # System library fixes @@ -2205,6 +2207,9 @@ require "copy_jdk_configs.lua" %endif %changelog +* Fri Dec 10 2021 kuenking111 - 1:1.8.0.312-b07.5 +- add G1-Full-GC-parallel-mark.patch + * Fri Dec 10 2021 kuenking111 - 1:1.8.0.312-b07.4 - add G1Ucommit-Refactor-Trigger-mechanism.patch -- Gitee From db5be6ea9220d5a92406ed82597af1b7c6cecce2 Mon Sep 17 00:00:00 2001 From: kuenking111 Date: Fri, 10 Dec 2021 17:01:23 +0800 Subject: [PATCH 5/8] I4M09Y: G1Uncommit add G1UncommitLog limit before G1Uncommit --- ...1UncommitLog-limit-before-G1Uncommit.patch | 67 +++++++++++++++++++ openjdk-1.8.0.spec | 7 +- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100755 G1Uncommit-add-G1UncommitLog-limit-before-G1Uncommit.patch diff --git a/G1Uncommit-add-G1UncommitLog-limit-before-G1Uncommit.patch b/G1Uncommit-add-G1UncommitLog-limit-before-G1Uncommit.patch new file mode 100755 index 0000000..7902cd9 --- /dev/null +++ b/G1Uncommit-add-G1UncommitLog-limit-before-G1Uncommit.patch @@ -0,0 +1,67 @@ +From 309b16c487fa42fc65781da3ccf79af67f142ee9 Mon Sep 17 00:00:00 2001 +From: mashoubing +Date: Mon, 6 Dec 2021 16:05:39 +0800 +Subject: [PATCH] G1Uncommit: add G1UncommitLog limit before G1Uncommit log + message +--- + .../src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp | 8 +++++--- + .../share/vm/gc_implementation/g1/g1UncommitThread.cpp | 4 +++- + .../share/vm/gc_implementation/g1/heapRegionManager.cpp | 8 +++++--- + 3 files changed, 13 insertions(+), 7 deletions(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +index 6ee33fd05..f7266c9c4 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +@@ -2221,9 +2221,11 @@ void G1CollectedHeap::shrink_heap_at_remark() { + uint num_candidate_to_remove = (uint)(resize_amount / HeapRegion::GrainBytes); + uint count = _hrm.extract_uncommit_list(num_candidate_to_remove); + +- gclog_or_tty->print(" [G1Uncommit list " UINT32_FORMAT ", remaining " UINT32_FORMAT +- ", free list " UINT32_FORMAT "]", +- count, length - count, _hrm.num_free_regions()); ++ if (G1UncommitLog) { ++ gclog_or_tty->print(" [G1Uncommit list " UINT32_FORMAT ", remaining " UINT32_FORMAT ++ ", free list " UINT32_FORMAT "]", ++ count, length - count, _hrm.num_free_regions()); ++ } + } + } + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp +index 503218917..280313b69 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp +@@ -190,7 +190,9 @@ bool PeriodicGC::should_start_periodic_gc() { + if (g1p->os_load() < G1PeriodicGCLoadThreshold || !G1PeriodicGCLoadThreshold) { + return true; + } +- gclog_or_tty->print_cr("[G1Uncommit] Periodic GC request denied, skipping!"); ++ if (G1UncommitLog) { ++ gclog_or_tty->print_cr("[G1Uncommit] Periodic GC request denied, skipping!"); ++ } + return false; + } + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp +index d31073f9f..83513b3b8 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp +@@ -577,9 +577,11 @@ uint HeapRegionManager::extract_uncommit_list(uint num_candidate_to_remove) { + assert_at_safepoint(true /* should_be_vm_thread */); + double start_up_sec = os::elapsedTime(); + if (start_up_sec < G1UncommitDelay) { +- gclog_or_tty->date_stamp(PrintGCDateStamps); +- gclog_or_tty->stamp(PrintGCTimeStamps); +- gclog_or_tty->print_cr("start up seconds:%lf, less than G1UncommitDelay, will not uncommit.", start_up_sec); ++ if (G1UncommitLog) { ++ gclog_or_tty->date_stamp(PrintGCDateStamps); ++ gclog_or_tty->stamp(PrintGCTimeStamps); ++ gclog_or_tty->print_cr("start up seconds:%lf, less than G1UncommitDelay, will not uncommit.", start_up_sec); ++ } + return 0; + } + +-- +2.22.0 + diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index af7fc81..058558f 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 5 +Release: 6 # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # and this change was brought into RHEL-4. java-1.5.0-ibm packages # also included the epoch in their virtual provides. This created a @@ -1120,6 +1120,7 @@ Patch222: 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-b Patch223: 8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch Patch224: G1Ucommit-Refactor-Trigger-mechanism.patch Patch225: G1-Full-GC-parallel-mark.patch +Patch226: G1Uncommit-add-G1UncommitLog-limit-before-G1Uncommit.patch # 8u312 @@ -1590,6 +1591,7 @@ pushd %{top_level_dir_name} %patch223 -p1 %patch224 -p1 %patch225 -p1 +%patch226 -p1 popd # System library fixes @@ -2207,6 +2209,9 @@ require "copy_jdk_configs.lua" %endif %changelog +* Fri Dec 10 2021 kuenking111 - 1:1.8.0.312-b07.6 +- add G1Uncommit-add-G1UncommitLog-limit-before-G1Uncommit.patch + * Fri Dec 10 2021 kuenking111 - 1:1.8.0.312-b07.5 - add G1-Full-GC-parallel-mark.patch -- Gitee From 2a00fd80ac0adb6081722ae41fc294cfe27723ba Mon Sep 17 00:00:00 2001 From: kuenking111 Date: Thu, 16 Dec 2021 15:16:06 +0800 Subject: [PATCH 6/8] I4MTUJ: Delete expired certificate --- ...e-expired-certificate-globalsignr2ca.patch | 121 ++++++++++++++++++ openjdk-1.8.0.spec | 11 +- 2 files changed, 130 insertions(+), 2 deletions(-) create mode 100755 Delete-expired-certificate-globalsignr2ca.patch diff --git a/Delete-expired-certificate-globalsignr2ca.patch b/Delete-expired-certificate-globalsignr2ca.patch new file mode 100755 index 0000000..8b771ad --- /dev/null +++ b/Delete-expired-certificate-globalsignr2ca.patch @@ -0,0 +1,121 @@ +From d64c9b5f69fa307c1fdc44ce8e2a063e805400b8 Mon Sep 17 00:00:00 2001 +From: zhangyipeng +Date: Wed, 15 Dec 2021 18:26:13 +0800 +Subject: [PATCH 2/2] Delete expired certificate + +--- + jdk/make/data/cacerts/globalsignr2ca | 29 ------------------- + jdk/make/data/cacerts/identrustdstx3 | 27 ----------------- + .../security/lib/cacerts/VerifyCACerts.java | 8 ++--- + 3 files changed, 2 insertions(+), 62 deletions(-) + delete mode 100644 jdk/make/data/cacerts/globalsignr2ca + delete mode 100644 jdk/make/data/cacerts/identrustdstx3 + +diff --git a/jdk/make/data/cacerts/globalsignr2ca b/jdk/make/data/cacerts/globalsignr2ca +deleted file mode 100644 +index 746d1fab9..000000000 +--- a/jdk/make/data/cacerts/globalsignr2ca ++++ /dev/null +@@ -1,29 +0,0 @@ +-Owner: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2 +-Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2 +-Serial number: 400000000010f8626e60d +-Valid from: Fri Dec 15 08:00:00 GMT 2006 until: Wed Dec 15 08:00:00 GMT 2021 +-Signature algorithm name: SHA1withRSA +-Subject Public Key Algorithm: 2048-bit RSA key +-Version: 3 +------BEGIN CERTIFICATE----- +-MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +-A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +-Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +-MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +-A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +-hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +-v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +-eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +-tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +-C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +-zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +-mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +-V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +-bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +-3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +-J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +-291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +-ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +-AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +-TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +------END CERTIFICATE----- +diff --git a/jdk/make/data/cacerts/identrustdstx3 b/jdk/make/data/cacerts/identrustdstx3 +deleted file mode 100644 +index 87a0d0c4f..000000000 +--- a/jdk/make/data/cacerts/identrustdstx3 ++++ /dev/null +@@ -1,27 +0,0 @@ +-Owner: CN=DST Root CA X3, O=Digital Signature Trust Co. +-Issuer: CN=DST Root CA X3, O=Digital Signature Trust Co. +-Serial number: 44afb080d6a327ba893039862ef8406b +-Valid from: Sat Sep 30 21:12:19 GMT 2000 until: Thu Sep 30 14:01:15 GMT 2021 +-Signature algorithm name: SHA1withRSA +-Subject Public Key Algorithm: 2048-bit RSA key +-Version: 3 +------BEGIN CERTIFICATE----- +-MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +-MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +-DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +-PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +-Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +-AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +-rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +-OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +-xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +-7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +-aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +-SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +-ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +-AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +-R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +-JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +-Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +------END CERTIFICATE----- +diff --git a/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java b/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java +index e4fc63ad7..f46355e8c 100644 +--- a/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java ++++ b/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java +@@ -53,12 +53,12 @@ public class VerifyCACerts { + + File.separator + "security" + File.separator + "cacerts"; + + // The numbers of certs now. +- private static final int COUNT = 86; ++ private static final int COUNT = 84; + + // SHA-256 of cacerts, can be generated with + // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 + private static final String CHECKSUM +- = "A5:00:71:02:B4:8B:AC:BE:64:34:0A:F2:DF:9D:F7:75:9D:05:84:7E:F6:EA:48:F0:64:36:29:8C:E7:A2:2D:63"; ++ = "D3:05:21:64:FA:D7:CD:29:E8:CB:57:E7:47:ED:79:9B:47:D8:0E:75:2D:CA:83:BB:86:AF:D9:43:FD:3E:17:85"; + + // map of cert alias to SHA-256 fingerprint + @SuppressWarnings("serial") +@@ -139,8 +139,6 @@ public class VerifyCACerts { + "49:E7:A4:42:AC:F0:EA:62:87:05:00:54:B5:25:64:B6:50:E4:F4:9E:42:E3:48:D6:AA:38:E0:39:E9:57:B1:C1"); + put("dtrustclass3ca2ev [jdk]", + "EE:C5:49:6B:98:8C:E9:86:25:B9:34:09:2E:EC:29:08:BE:D0:B0:F3:16:C2:D4:73:0C:84:EA:F1:F3:D3:48:81"); +- put("identrustdstx3 [jdk]", +- "06:87:26:03:31:A7:24:03:D9:09:F1:05:E6:9B:CF:0D:32:E1:BD:24:93:FF:C6:D9:20:6D:11:BC:D6:77:07:39"); + put("identrustpublicca [jdk]", + "30:D0:89:5A:9A:44:8A:26:20:91:63:55:22:D1:F5:20:10:B5:86:7A:CA:E1:2C:78:EF:95:8F:D4:F4:38:9F:2F"); + put("identrustcommercial [jdk]", +@@ -209,8 +207,6 @@ public class VerifyCACerts { + "17:9F:BC:14:8A:3D:D0:0F:D2:4E:A1:34:58:CC:43:BF:A7:F5:9C:81:82:D7:83:A5:13:F6:EB:EC:10:0C:89:24"); + put("globalsigneccrootcar4 [jdk]", + "BE:C9:49:11:C2:95:56:76:DB:6C:0A:55:09:86:D7:6E:3B:A0:05:66:7C:44:2C:97:62:B4:FB:B7:73:DE:22:8C"); +- put("globalsignr2ca [jdk]", +- "CA:42:DD:41:74:5F:D0:B8:1E:B9:02:36:2C:F9:D8:BF:71:9D:A1:BD:1B:1E:FC:94:6F:5B:4C:99:F4:2C:1B:9E"); + put("teliasonerarootcav1 [jdk]", + "DD:69:36:FE:21:F8:F0:77:C1:23:A1:A5:21:C1:22:24:F7:22:55:B7:3E:03:A7:26:06:93:E8:A2:4B:0F:A3:89"); + put("globalsignrootcar6 [jdk]", +-- +2.22.0 + diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index 058558f..6eaccef 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 6 +Release: 7 # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # and this change was brought into RHEL-4. java-1.5.0-ibm packages # also included the epoch in their virtual provides. This created a @@ -1115,14 +1115,17 @@ Patch217: 8202142-jfr-event-io-TestInstrumentation-is-unstable.patch Patch218: 8143251-Thread-suspend-on-VM_G1IncCollectionPause-do.patch Patch219: G1Uncommit-Introduce-G1PeriodGCNotRetry-control-whet.patch Patch220: JDK-debug-version-crash-when-using-AppCDS.patch + +# 8u312 Patch221: 8183543-Aarch64-C2-compilation-often-fails-with-fail--last.patch Patch222: 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch Patch223: 8233280-Remove-GCLockerInvokesConcurrent-relative-logic-for-G1.patch Patch224: G1Ucommit-Refactor-Trigger-mechanism.patch Patch225: G1-Full-GC-parallel-mark.patch Patch226: G1Uncommit-add-G1UncommitLog-limit-before-G1Uncommit.patch +Patch227: Delete-expired-certificate-globalsignr2ca.patch -# 8u312 +# 8u322 ############################################# # @@ -1592,6 +1595,7 @@ pushd %{top_level_dir_name} %patch224 -p1 %patch225 -p1 %patch226 -p1 +%patch227 -p1 popd # System library fixes @@ -2209,6 +2213,9 @@ require "copy_jdk_configs.lua" %endif %changelog +* Thu Dec 16 2021 kuenking111 - 1:1.8.0.312-b07.7 +- add Delete-expired-certificate-globalsignr2ca.patch + * Fri Dec 10 2021 kuenking111 - 1:1.8.0.312-b07.6 - add G1Uncommit-add-G1UncommitLog-limit-before-G1Uncommit.patch -- Gitee From 2c57e9bb0cc6540004f23d75b63781c2200b4c90 Mon Sep 17 00:00:00 2001 From: kuenking111 Date: Mon, 20 Dec 2021 12:16:45 +0800 Subject: [PATCH 7/8] I4N9PE: add wrap_memcpy to libsaproc --- add-wrap_memcpy-to-libsaproc.patch | 27 +++++++++++++++++++++++++++ openjdk-1.8.0.spec | 7 ++++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100755 add-wrap_memcpy-to-libsaproc.patch diff --git a/add-wrap_memcpy-to-libsaproc.patch b/add-wrap_memcpy-to-libsaproc.patch new file mode 100755 index 0000000..a4d5204 --- /dev/null +++ b/add-wrap_memcpy-to-libsaproc.patch @@ -0,0 +1,27 @@ +From: zhangyipeng +Date: Thu, 4 Mar 2021 11:10:07 +0800 +Subject: add wrap_memcpy to libsaproc + +--- + hotspot/make/linux/makefiles/saproc.make | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hotspot/make/linux/makefiles/saproc.make b/hotspot/make/linux/makefiles/saproc.make +index dfeb254da..258585366 100644 +--- a/hotspot/make/linux/makefiles/saproc.make ++++ b/hotspot/make/linux/makefiles/saproc.make +@@ -46,6 +46,11 @@ SASRCFILES = $(SASRCDIR)/salibelf.c \ + $(SASRCDIR)/LinuxDebuggerLocal.c \ + $(AGENT_DIR)/src/share/native/sadis.c + ++# wrap memcpy ++ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86) ++ SASRCFILES += $(HOTSPOT_TOPDIR)/src/os_cpu/linux_x86/vm/memcpy.cpp ++endif ++ + -include $(HS_ALT_MAKE)/linux/makefiles/saproc.make + + SAMAPFILE = $(SASRCDIR)/mapfile +-- +2.19.0 + diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index 6eaccef..79fc2dc 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 7 +Release: 8 # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # and this change was brought into RHEL-4. java-1.5.0-ibm packages # also included the epoch in their virtual provides. This created a @@ -1124,6 +1124,7 @@ Patch224: G1Ucommit-Refactor-Trigger-mechanism.patch Patch225: G1-Full-GC-parallel-mark.patch Patch226: G1Uncommit-add-G1UncommitLog-limit-before-G1Uncommit.patch Patch227: Delete-expired-certificate-globalsignr2ca.patch +Patch228: add-wrap_memcpy-to-libsaproc.patch # 8u322 @@ -1596,6 +1597,7 @@ pushd %{top_level_dir_name} %patch225 -p1 %patch226 -p1 %patch227 -p1 +%patch228 -p1 popd # System library fixes @@ -2213,6 +2215,9 @@ require "copy_jdk_configs.lua" %endif %changelog +* Mon Dec 20 2021 kuenking111 - 1:1.8.0.312-b07.8 +- add wrap_memcpy to libsaproc + * Thu Dec 16 2021 kuenking111 - 1:1.8.0.312-b07.7 - add Delete-expired-certificate-globalsignr2ca.patch -- Gitee From f60435498095fe3c7c1064cd751818654d003f1c Mon Sep 17 00:00:00 2001 From: kuenking111 Date: Mon, 20 Dec 2021 20:27:35 +0800 Subject: [PATCH 8/8] I4N9PR: downgrade the symver of fcntl64 --- downgrade-the-symver-of-fcntl64.patch | 26 ++++++++++++++++++++++++++ openjdk-1.8.0.spec | 7 ++++++- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100755 downgrade-the-symver-of-fcntl64.patch diff --git a/downgrade-the-symver-of-fcntl64.patch b/downgrade-the-symver-of-fcntl64.patch new file mode 100755 index 0000000..9d21dad --- /dev/null +++ b/downgrade-the-symver-of-fcntl64.patch @@ -0,0 +1,26 @@ +From: zhangyipeng +Date: Thu, 4 Mar 2021 09:38:42 +0800 + +--- + jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c b/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c +index 9b3ff8194..bb9be2ccb 100644 +--- a/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c ++++ b/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c +@@ -63,6 +63,11 @@ + #include "sun_nio_ch_FileDispatcherImpl.h" + #include "java_lang_Long.h" + ++#if defined(aarch64) ++ __asm__(".symver fcntl64,fcntl@GLIBC_2.17"); ++#elif defined(amd64) ++ __asm__(".symver fcntl64,fcntl@GLIBC_2.2.5"); ++#endif + static int preCloseFD = -1; /* File descriptor to which we dup other fd's + before closing them for real */ + +-- +2.19.0 + diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index 79fc2dc..cfda2a4 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 8 +Release: 9 # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # and this change was brought into RHEL-4. java-1.5.0-ibm packages # also included the epoch in their virtual provides. This created a @@ -1125,6 +1125,7 @@ Patch225: G1-Full-GC-parallel-mark.patch Patch226: G1Uncommit-add-G1UncommitLog-limit-before-G1Uncommit.patch Patch227: Delete-expired-certificate-globalsignr2ca.patch Patch228: add-wrap_memcpy-to-libsaproc.patch +Patch229: downgrade-the-symver-of-fcntl64.patch # 8u322 @@ -1598,6 +1599,7 @@ pushd %{top_level_dir_name} %patch226 -p1 %patch227 -p1 %patch228 -p1 +%patch229 -p1 popd # System library fixes @@ -2215,6 +2217,9 @@ require "copy_jdk_configs.lua" %endif %changelog +* Mon Dec 20 2021 kuenking111 - 1:1.8.0.312-b07.9 +- add downgrade-the-symver-of-fcntl64.patch + * Mon Dec 20 2021 kuenking111 - 1:1.8.0.312-b07.8 - add wrap_memcpy to libsaproc -- Gitee