!17 Add feature and bug fix for jdk17

From: @neu-mobi 
Reviewed-by: @kuenking111 
Signed-off-by: @kuenking111
This commit is contained in:
openeuler-ci-bot 2023-01-10 01:28:53 +00:00 committed by Gitee
commit 7b395f63c7
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
7 changed files with 11399 additions and 9 deletions

View File

@ -0,0 +1,539 @@
From dfe3a75cf5c911a68ccd187c57f7d0d1f30f65f9 Mon Sep 17 00:00:00 2001
Date: Wed, 4 Jan 2023 20:41:20 +0800
Subject: 8253495: CDS generates non-deterministic output
---
make/GenerateLinkOptData.gmk | 7 +-
.../build/tools/classlist/SortClasslist.java | 79 +++++++++++++++++++
make/scripts/compare.sh | 8 +-
src/hotspot/share/cds/archiveBuilder.cpp | 5 +-
src/hotspot/share/cds/archiveUtils.hpp | 5 +-
src/hotspot/share/cds/heapShared.cpp | 8 +-
src/hotspot/share/gc/shared/collectedHeap.cpp | 18 ++++-
src/hotspot/share/gc/shared/collectedHeap.hpp | 1 +
src/hotspot/share/prims/jvm.cpp | 20 +++++
src/hotspot/share/runtime/os.cpp | 19 ++++-
test/hotspot/jtreg/ProblemList.txt | 1 -
.../jtreg/runtime/cds/DeterministicDump.java | 10 ++-
.../cds/appcds/javaldr/LockDuringDump.java | 4 +-
.../appcds/javaldr/LockDuringDumpAgent.java | 16 +++-
test/lib/jdk/test/lib/cds/CDSOptions.java | 33 ++++++--
15 files changed, 202 insertions(+), 32 deletions(-)
create mode 100644 make/jdk/src/classes/build/tools/classlist/SortClasslist.java
diff --git a/make/GenerateLinkOptData.gmk b/make/GenerateLinkOptData.gmk
index 0de28d643..5dd766c8c 100644
--- a/make/GenerateLinkOptData.gmk
+++ b/make/GenerateLinkOptData.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 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
@@ -88,7 +88,10 @@ $(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXECUTABLE_SUFFIX) $(CLASSLIST
$(CAT) $(LINK_OPT_DIR)/stderr $(JLI_TRACE_FILE) ; \
exit $$exitcode \
)
- $(GREP) -v HelloClasslist $@.raw.2 > $@
+ $(GREP) -v HelloClasslist $@.raw.2 > $@.raw.3
+ $(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java \
+ -cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
+ build.tools.classlist.SortClasslist $@.raw.3 > $@
# The jli trace is created by the same recipe as classlist. By declaring these
# dependencies, make will correctly rebuild both jli trace and classlist
diff --git a/make/jdk/src/classes/build/tools/classlist/SortClasslist.java b/make/jdk/src/classes/build/tools/classlist/SortClasslist.java
new file mode 100644
index 000000000..cf9e55a7b
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/classlist/SortClasslist.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.
+ */
+
+/**
+ * This application is meant to be run to create a classlist file representing
+ * common use.
+ *
+ * The classlist is produced by adding -XX:DumpLoadedClassList=classlist
+ */
+package build.tools.classlist;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.Scanner;
+
+/**
+ * The classlist generated by build.tools.classlist.HelloClasslist
+ * may have non-deterministic contents, affected by Java thread execution order.
+ * SortClasslist sorts the file to make the JDK image's contents more deterministic.
+ */
+public class SortClasslist {
+ public static void main(String args[]) throws FileNotFoundException {
+ ArrayList<String> classes = new ArrayList<>();
+ ArrayList<String> lambdas = new ArrayList<>();
+
+ FileInputStream fis = new FileInputStream(args[0]);
+ Scanner scanner = new Scanner(fis);
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ if (line.startsWith("#")) {
+ // Comments -- print them first without sorting. These appear only at the top
+ // of the file.
+ System.out.println(line);
+ } else if (line.startsWith("@")) {
+ // @lambda-form-invoker, @lambda-proxy, etc.
+ lambdas.add(line);
+ } else {
+ classes.add(line);
+ }
+ }
+
+ Collections.sort(classes);
+ Collections.sort(lambdas);
+
+ for (String s : classes) {
+ System.out.println(s);
+ }
+ for (String s : lambdas) {
+ System.out.println(s);
+ }
+ }
+}
diff --git a/make/scripts/compare.sh b/make/scripts/compare.sh
index 42886573f..3075f9a82 100644
--- a/make/scripts/compare.sh
+++ b/make/scripts/compare.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2022, 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
@@ -324,7 +324,7 @@ compare_general_files() {
! -name "*.cpl" ! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \
! -name "*.lib" ! -name "*.jmod" ! -name "*.exe" \
! -name "*.obj" ! -name "*.o" ! -name "jspawnhelper" ! -name "*.a" \
- ! -name "*.tar.gz" ! -name "*.jsa" ! -name "gtestLauncher" \
+ ! -name "*.tar.gz" ! -name "classes_nocoops.jsa" ! -name "gtestLauncher" \
! -name "*.map" \
| $GREP -v "./bin/" | $SORT | $FILTER)
@@ -356,8 +356,8 @@ compare_general_files() {
"
$CAT $OTHER_DIR/$f | eval "$SVG_FILTER" > $OTHER_FILE
$CAT $THIS_DIR/$f | eval "$SVG_FILTER" > $THIS_FILE
- elif [[ "$f" = *"/lib/classlist" ]] || [ "$SUFFIX" = "jar_contents" ]; then
- # The classlist files may have some lines in random order
+ elif [ "$SUFFIX" = "jar_contents" ]; then
+ # The jar_contents files may have some lines in random order
OTHER_FILE=$WORK_DIR/$f.other
THIS_FILE=$WORK_DIR/$f.this
$MKDIR -p $(dirname $OTHER_FILE) $(dirname $THIS_FILE)
diff --git a/src/hotspot/share/cds/archiveBuilder.cpp b/src/hotspot/share/cds/archiveBuilder.cpp
index 699926fcf..8e12cdabb 100644
--- a/src/hotspot/share/cds/archiveBuilder.cpp
+++ b/src/hotspot/share/cds/archiveBuilder.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022, 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
@@ -540,7 +540,8 @@ ArchiveBuilder::FollowMode ArchiveBuilder::get_follow_mode(MetaspaceClosure::Ref
if (MetaspaceShared::is_in_shared_metaspace(obj)) {
// Don't dump existing shared metadata again.
return point_to_it;
- } else if (ref->msotype() == MetaspaceObj::MethodDataType) {
+ } else if (ref->msotype() == MetaspaceObj::MethodDataType ||
+ ref->msotype() == MetaspaceObj::MethodCountersType) {
return set_to_null;
} else {
if (ref->msotype() == MetaspaceObj::ClassType) {
diff --git a/src/hotspot/share/cds/archiveUtils.hpp b/src/hotspot/share/cds/archiveUtils.hpp
index cdb3d99ab..6d8e0b43a 100644
--- a/src/hotspot/share/cds/archiveUtils.hpp
+++ b/src/hotspot/share/cds/archiveUtils.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022, 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
@@ -30,6 +30,7 @@
#include "memory/virtualspace.hpp"
#include "utilities/bitMap.hpp"
#include "utilities/exceptions.hpp"
+#include "utilities/macros.hpp"
class BootstrapInfo;
class ReservedSpace;
@@ -142,7 +143,7 @@ public:
char* expand_top_to(char* newtop);
char* allocate(size_t num_bytes);
- void append_intptr_t(intptr_t n, bool need_to_mark = false);
+ void append_intptr_t(intptr_t n, bool need_to_mark = false) NOT_CDS_RETURN;
char* base() const { return _base; }
char* top() const { return _top; }
diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp
index 3e50dd750..fd3d199f8 100644
--- a/src/hotspot/share/cds/heapShared.cpp
+++ b/src/hotspot/share/cds/heapShared.cpp
@@ -454,7 +454,7 @@ KlassSubGraphInfo* HeapShared::init_subgraph_info(Klass* k, bool is_full_module_
bool created;
Klass* relocated_k = ArchiveBuilder::get_relocated_klass(k);
KlassSubGraphInfo* info =
- _dump_time_subgraph_info_table->put_if_absent(relocated_k, KlassSubGraphInfo(relocated_k, is_full_module_graph),
+ _dump_time_subgraph_info_table->put_if_absent(k, KlassSubGraphInfo(relocated_k, is_full_module_graph),
&created);
assert(created, "must not initialize twice");
return info;
@@ -462,8 +462,7 @@ KlassSubGraphInfo* HeapShared::init_subgraph_info(Klass* k, bool is_full_module_
KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
assert(DumpSharedSpaces, "dump time only");
- Klass* relocated_k = ArchiveBuilder::get_relocated_klass(k);
- KlassSubGraphInfo* info = _dump_time_subgraph_info_table->get(relocated_k);
+ KlassSubGraphInfo* info = _dump_time_subgraph_info_table->get(k);
assert(info != NULL, "must have been initialized");
return info;
}
@@ -624,7 +623,8 @@ struct CopyKlassSubGraphInfoToArchive : StackObj {
(ArchivedKlassSubGraphInfoRecord*)ArchiveBuilder::ro_region_alloc(sizeof(ArchivedKlassSubGraphInfoRecord));
record->init(&info);
- unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary((address)klass);
+ Klass* relocated_k = ArchiveBuilder::get_relocated_klass(klass);
+ unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary((address)relocated_k);
u4 delta = ArchiveBuilder::current()->any_to_offset_u4(record);
_writer->add(hash, delta);
}
diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp
index 96b3eb946..5a2cb0e51 100644
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2022, 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
@@ -405,6 +405,11 @@ size_t CollectedHeap::filler_array_min_size() {
return align_object_size(filler_array_hdr_size()); // align to MinObjAlignment
}
+void CollectedHeap::zap_filler_array_with(HeapWord* start, size_t words, juint value) {
+ Copy::fill_to_words(start + filler_array_hdr_size(),
+ words - filler_array_hdr_size(), value);
+}
+
#ifdef ASSERT
void CollectedHeap::fill_args_check(HeapWord* start, size_t words)
{
@@ -415,8 +420,7 @@ void CollectedHeap::fill_args_check(HeapWord* start, size_t words)
void CollectedHeap::zap_filler_array(HeapWord* start, size_t words, bool zap)
{
if (ZapFillerObjects && zap) {
- Copy::fill_to_words(start + filler_array_hdr_size(),
- words - filler_array_hdr_size(), 0XDEAFBABE);
+ zap_filler_array_with(start, words, 0XDEAFBABE);
}
}
#endif // ASSERT
@@ -433,7 +437,13 @@ CollectedHeap::fill_with_array(HeapWord* start, size_t words, bool zap)
ObjArrayAllocator allocator(Universe::intArrayKlassObj(), words, (int)len, /* do_zero */ false);
allocator.initialize(start);
- DEBUG_ONLY(zap_filler_array(start, words, zap);)
+ if (DumpSharedSpaces) {
+ // This array is written into the CDS archive. Make sure it
+ // has deterministic contents.
+ zap_filler_array_with(start, words, 0);
+ } else {
+ DEBUG_ONLY(zap_filler_array(start, words, zap);)
+ }
}
void
diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp
index 10baf8749..8d1087ed3 100644
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp
@@ -143,6 +143,7 @@ class CollectedHeap : public CHeapObj<mtInternal> {
static inline size_t filler_array_hdr_size();
static inline size_t filler_array_min_size();
+ static inline void zap_filler_array_with(HeapWord* start, size_t words, juint value);
DEBUG_ONLY(static void fill_args_check(HeapWord* start, size_t words);)
DEBUG_ONLY(static void zap_filler_array(HeapWord* start, size_t words, bool zap = true);)
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
index 8baba8c38..9057cc072 100644
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -2852,6 +2852,26 @@ static void thread_entry(JavaThread* thread, TRAPS) {
JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
+#if INCLUDE_CDS
+ if (DumpSharedSpaces) {
+ // During java -Xshare:dump, if we allow multiple Java threads to
+ // execute in parallel, symbols and classes may be loaded in
+ // random orders which will make the resulting CDS archive
+ // non-deterministic.
+ //
+ // Lucikly, during java -Xshare:dump, it's important to run only
+ // the code in the main Java thread (which is NOT started here) that
+ // creates the module graph, etc. It's safe to not start the other
+ // threads which are launched by class static initializers
+ // (ReferenceHandler, FinalizerThread and CleanerImpl).
+ if (log_is_enabled(Info, cds)) {
+ ResourceMark rm;
+ oop t = JNIHandles::resolve_non_null(jthread);
+ log_info(cds)("JVM_StartThread() ignored: %s", t->klass()->external_name());
+ }
+ return;
+ }
+#endif
JavaThread *native_thread = NULL;
// We cannot hold the Threads_lock when we throw an exception,
diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp
index bb6cea80e..bd5ab658c 100644
--- a/src/hotspot/share/runtime/os.cpp
+++ b/src/hotspot/share/runtime/os.cpp
@@ -674,6 +674,15 @@ static bool has_reached_max_malloc_test_peak(size_t alloc_size) {
return false;
}
+#ifdef ASSERT
+static void break_if_ptr_caught(void* ptr) {
+ if (p2i(ptr) == (intptr_t)MallocCatchPtr) {
+ log_warning(malloc, free)("ptr caught: " PTR_FORMAT, p2i(ptr));
+ breakpoint();
+ }
+}
+#endif // ASSERT
+
void* os::malloc(size_t size, MEMFLAGS flags) {
return os::malloc(size, flags, CALLER_PC);
}
@@ -746,7 +755,15 @@ void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
#endif
// we do not track guard memory
- return MemTracker::record_malloc((address)ptr, size, memflags, stack, level);
+ void* const inner_ptr = MemTracker::record_malloc((address)ptr, size, memflags, stack, level);
+ if (DumpSharedSpaces) {
+ // Need to deterministically fill all the alignment gaps in C++ structures.
+ ::memset(inner_ptr, 0, size);
+ } else {
+ DEBUG_ONLY(::memset(inner_ptr, uninitBlockPad, size);)
+ }
+ DEBUG_ONLY(break_if_ptr_caught(inner_ptr);)
+ return inner_ptr;
}
void* os::realloc(void *memblock, size_t size, MEMFLAGS flags) {
diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index 5d43b504f..ebc29f736 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -86,7 +86,6 @@ gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8241293 macosx-x64
# :hotspot_runtime
runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP_JFR.java 8253437 windows-x64
-runtime/cds/DeterministicDump.java 8253495 generic-all
runtime/InvocationTests/invokevirtualTests.java#current-int 8271125 generic-all
runtime/InvocationTests/invokevirtualTests.java#current-comp 8271125 generic-all
runtime/InvocationTests/invokevirtualTests.java#old-int 8271125 generic-all
diff --git a/test/hotspot/jtreg/runtime/cds/DeterministicDump.java b/test/hotspot/jtreg/runtime/cds/DeterministicDump.java
index 9cdba1fa9..6e8ccffce 100644
--- a/test/hotspot/jtreg/runtime/cds/DeterministicDump.java
+++ b/test/hotspot/jtreg/runtime/cds/DeterministicDump.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022, 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
@@ -54,6 +54,11 @@ public class DeterministicDump {
baseArgs.add("-Xmx128M");
if (Platform.is64bit()) {
+ if (!compressed) {
+ System.out.println("CDS archives with uncompressed oops are still non-deterministic");
+ System.out.println("See https://bugs.openjdk.java.net/browse/JDK-8282828");
+ return;
+ }
// These options are available only on 64-bit.
String sign = (compressed) ? "+" : "-";
baseArgs.add("-XX:" + sign + "UseCompressedOops");
@@ -78,9 +83,12 @@ public class DeterministicDump {
static String dump(ArrayList<String> args, String... more) throws Exception {
String logName = "SharedArchiveFile" + (id++);
String archiveName = logName + ".jsa";
+ String mapName = logName + ".map";
CDSOptions opts = (new CDSOptions())
.addPrefix("-Xlog:cds=debug")
+ .addPrefix("-Xlog:cds+map=trace:file=" + mapName + ":none:filesize=0")
.setArchiveName(archiveName)
+ .addSuffix(args)
.addSuffix(more);
CDSTestUtils.createArchiveAndCheck(opts);
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/LockDuringDump.java b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/LockDuringDump.java
index d60e0d11a..5dc8dbc08 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/LockDuringDump.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/LockDuringDump.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022, 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
@@ -70,7 +70,7 @@ public class LockDuringDump {
TestCommon.testDump(appJar, TestCommon.list(LockDuringDumpApp.class.getName()),
"-XX:+UnlockDiagnosticVMOptions",
agentArg, agentArg2, biasedLock);
- if (i != 0) {
+ if (i != 0 && !out.getStdout().contains("LockDuringDumpAgent timeout")) {
out.shouldContain("Let's hold the lock on the literal string");
}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/LockDuringDumpAgent.java b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/LockDuringDumpAgent.java
index 5e053d83e..57db61e93 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/LockDuringDumpAgent.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/LockDuringDumpAgent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022, 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
@@ -51,9 +51,21 @@ public class LockDuringDumpAgent implements Runnable {
static void waitForThreadStart() {
try {
+ long started = System.currentTimeMillis();
+ long timeout = 10000;
+ synchronized (LITERAL) {
+ Thread.sleep(1);
+ }
synchronized (lock) {
while (!threadStarted) {
- lock.wait();
+ lock.wait(timeout);
+ long elapsed = System.currentTimeMillis() - started;
+ if (elapsed >= timeout) {
+ System.out.println("This JVM may decide to not launch any Java threads during -Xshare:dump.");
+ System.out.println("This is OK because no string objects could be in a locked state during heap dump.");
+ System.out.println("LockDuringDumpAgent timeout after " + elapsed + " ms");
+ return;
+ }
}
System.out.println("Thread has started");
}
diff --git a/test/lib/jdk/test/lib/cds/CDSOptions.java b/test/lib/jdk/test/lib/cds/CDSOptions.java
index 2fa949dc4..1138b7757 100644
--- a/test/lib/jdk/test/lib/cds/CDSOptions.java
+++ b/test/lib/jdk/test/lib/cds/CDSOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, 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
@@ -46,24 +46,43 @@ public class CDSOptions {
public CDSOptions addPrefix(String... prefix) {
- for (String s : prefix) this.prefix.add(s);
+ for (String s : prefix) {
+ this.prefix.add(s);
+ }
return this;
}
public CDSOptions addPrefix(String prefix[], String... extra) {
- for (String s : prefix) this.prefix.add(s);
- for (String s : extra) this.prefix.add(s);
+ for (String s : prefix) {
+ this.prefix.add(s);
+ }
+ for (String s : extra) {
+ this.prefix.add(s);
+ }
+ return this;
+ }
+
+ public CDSOptions addSuffix(ArrayList<String> suffix) {
+ for (String s : suffix) {
+ this.suffix.add(s);
+ }
return this;
}
public CDSOptions addSuffix(String... suffix) {
- for (String s : suffix) this.suffix.add(s);
+ for (String s : suffix) {
+ this.suffix.add(s);
+ }
return this;
}
public CDSOptions addSuffix(String suffix[], String... extra) {
- for (String s : suffix) this.suffix.add(s);
- for (String s : extra) this.suffix.add(s);
+ for (String s : suffix) {
+ this.suffix.add(s);
+ }
+ for (String s : extra) {
+ this.suffix.add(s);
+ }
return this;
}
--
2.37.0

View File

@ -0,0 +1,42 @@
From c40df7ed8cb6d6c0f687c1d68071729fab7c1b2d Mon Sep 17 00:00:00 2001
Date: Wed, 4 Jan 2023 20:42:04 +0800
Subject: 8296480: Fix the problem that the TestPolicy.java
case fails because the certificate expires.
---
.../java/security/cert/pkix/policyChanges/TestPolicy.java | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/test/jdk/java/security/cert/pkix/policyChanges/TestPolicy.java b/test/jdk/java/security/cert/pkix/policyChanges/TestPolicy.java
index a92eee2c5..de2f94d27 100644
--- a/test/jdk/java/security/cert/pkix/policyChanges/TestPolicy.java
+++ b/test/jdk/java/security/cert/pkix/policyChanges/TestPolicy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2022, 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
@@ -34,6 +34,7 @@
*/
import java.io.*;
+import java.text.DateFormat;
import java.util.*;
import java.security.Security;
@@ -97,6 +98,10 @@ public class TestPolicy {
params.setRevocationEnabled(false);
params.setInitialPolicies(testCase.initialPolicies);
+ // Certs expired on 7th Nov 2022
+ params.setDate(DateFormat.getDateInstance(DateFormat.MEDIUM,
+ Locale.US).parse("June 01, 2022"));
+
CertPath path = factory.generateCertPath(Arrays.asList(new X509Certificate[] {ee, ca}));
PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)validator.validate(path, params);
--
2.37.0

View File

@ -0,0 +1,40 @@
From 59bc22bb9d2cdcc7d12d163c30432bd8c9d2c976 Mon Sep 17 00:00:00 2001
Date: Wed, 4 Jan 2023 20:44:46 +0800
Subject: 8296485: BuildEEBasicConstraints.java test fails
with SunCertPathBuilderException
---
.../targetConstraints/BuildEEBasicConstraints.java | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java b/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java
index c7cc90f95..edb68cf29 100644
--- a/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java
+++ b/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java
@@ -45,9 +45,11 @@ import java.security.cert.PKIXCertPathBuilderResult;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.security.cert.X509CertSelector;
+import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
import jdk.test.lib.security.CertUtils;
public final class BuildEEBasicConstraints {
@@ -65,6 +67,11 @@ public final class BuildEEBasicConstraints {
PKIXBuilderParameters params = new PKIXBuilderParameters
(Collections.singleton(anchor), sel);
params.setRevocationEnabled(false);
+
+ // Certs expired on 7th Nov 2022
+ params.setDate(DateFormat.getDateInstance(DateFormat.MEDIUM,
+ Locale.US).parse("June 01, 2022"));
+
X509Certificate eeCert = CertUtils.getCertFromFile("ee.cer");
X509Certificate caCert = CertUtils.getCertFromFile("ca.cer");
ArrayList<X509Certificate> certs = new ArrayList<X509Certificate>();
--
2.37.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
From cfa76d24fb8fdee972a0e9a35479bceb288ca59e Mon Sep 17 00:00:00 2001
Date: Wed, 4 Jan 2023 20:46:49 +0800
Subject: Apply TBI barrier patch to C1
---
.../gc/z/zBarrierSetAssembler_aarch64.cpp | 14 ++++++----
src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad | 28 ++++++++++++++++---
2 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp
index cafd4e58f..41f047f2c 100644
--- a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp
@@ -212,11 +212,8 @@ static void change_immediate(uint32_t& instr, uint32_t imm, uint32_t start, uint
void ZBarrierSetAssembler::patch_barrier_relocation(address addr) {
uint32_t* const patch_addr = (uint32_t*)addr;
- // The next 3 insns should be movz, andr, cbnz.
- assert(nativeInstruction_at(addr)->is_movz() &&
- Instruction_aarch64::extract(*(patch_addr + 1), 30, 24) == 0b0001010 &&
- Instruction_aarch64::extract(*(patch_addr + 2), 31, 24) == 0b10110101,
- "wrong insns in barrier patch");
+ // The next insn should be movz.
+ assert(nativeInstruction_at(addr)->is_movz(), "wrong insn in barrier patch");
change_immediate(*patch_addr, (uint16_t) (ZAddressBadMask >> 48), 5, 20);
OrderAccess::fence();
@@ -232,7 +229,12 @@ void ZBarrierSetAssembler::generate_c1_load_barrier_test(LIR_Assembler* ce,
LIR_Opr ref) const {
assert_different_registers(rscratch1, rthread, ref->as_register());
- __ ldr(rscratch1, address_bad_mask_from_thread(rthread));
+ if (UseTBI) {
+ __ relocate(barrier_Relocation::spec());
+ __ movz(rscratch1, barrier_Relocation::unpatched, 48);
+ } else {
+ __ ldr(rscratch1, address_bad_mask_from_thread(rthread));
+ }
__ tst(ref->as_register(), rscratch1);
}
diff --git a/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad b/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad
index 426a1cc2a..4dc54c280 100644
--- a/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad
+++ b/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad
@@ -113,7 +113,12 @@ instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newva
__ cset($res$$Register, Assembler::EQ);
if (barrier_data() != ZLoadBarrierElided) {
Label good;
- __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ if (UseTBI) {
+ __ relocate(barrier_Relocation::spec());
+ __ movz(rscratch1, barrier_Relocation::unpatched, 48);
+ } else {
+ __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ }
__ andr(rscratch1, rscratch1, rscratch2);
__ cbz(rscratch1, good);
z_load_barrier_slow_path(_masm, this, Address($mem$$Register), rscratch2 /* ref */, rscratch1 /* tmp */);
@@ -145,7 +150,12 @@ instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
__ cset($res$$Register, Assembler::EQ);
if (barrier_data() != ZLoadBarrierElided) {
Label good;
- __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ if (UseTBI) {
+ __ relocate(barrier_Relocation::spec());
+ __ movz(rscratch1, barrier_Relocation::unpatched, 48);
+ } else {
+ __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ }
__ andr(rscratch1, rscratch1, rscratch2);
__ cbz(rscratch1, good);
z_load_barrier_slow_path(_masm, this, Address($mem$$Register), rscratch2 /* ref */, rscratch1 /* tmp */ );
@@ -174,7 +184,12 @@ instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
false /* acquire */, true /* release */, false /* weak */, $res$$Register);
if (barrier_data() != ZLoadBarrierElided) {
Label good;
- __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ if (UseTBI) {
+ __ relocate(barrier_Relocation::spec());
+ __ movz(rscratch1, barrier_Relocation::unpatched, 48);
+ } else {
+ __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ }
__ andr(rscratch1, rscratch1, $res$$Register);
__ cbz(rscratch1, good);
z_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, rscratch1 /* tmp */);
@@ -202,7 +217,12 @@ instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
true /* acquire */, true /* release */, false /* weak */, $res$$Register);
if (barrier_data() != ZLoadBarrierElided) {
Label good;
- __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ if (UseTBI) {
+ __ relocate(barrier_Relocation::spec());
+ __ movz(rscratch1, barrier_Relocation::unpatched, 48);
+ } else {
+ __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ }
__ andr(rscratch1, rscratch1, $res$$Register);
__ cbz(rscratch1, good);
z_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, rscratch1 /* tmp */);
--
2.37.0

662
Fast-Serializer.patch Normal file
View File

@ -0,0 +1,662 @@
From 2286646981811c818e7da61a806426d38481218b Mon Sep 17 00:00:00 2001
Date: Wed, 4 Jan 2023 20:45:23 +0800
Subject: Fast Serializer
---
src/hotspot/share/prims/unsafe.cpp | 5 +
src/hotspot/share/runtime/globals.hpp | 4 +
.../classes/java/io/ObjectInputStream.java | 222 +++++++++++++++---
.../classes/java/io/ObjectOutputStream.java | 83 ++++++-
.../classes/java/io/ObjectStreamClass.java | 81 +++++++
.../classes/jdk/internal/misc/Unsafe.java | 2 +-
6 files changed, 355 insertions(+), 42 deletions(-)
diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp
index ee6c218f5..97f36a2db 100644
--- a/src/hotspot/share/prims/unsafe.cpp
+++ b/src/hotspot/share/prims/unsafe.cpp
@@ -870,6 +870,10 @@ UNSAFE_ENTRY(jint, Unsafe_GetLoadAverage0(JNIEnv *env, jobject unsafe, jdoubleAr
return ret;
} UNSAFE_END
+UNSAFE_ENTRY(jboolean, Unsafe_GetUseFastSerializer(JNIEnv *env, jobject unsafe)) {
+ return UseFastSerializer;
+}
+UNSAFE_END
/// JVM_RegisterUnsafeMethods
@@ -951,6 +955,7 @@ static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = {
{CC "loadFence", CC "()V", FN_PTR(Unsafe_LoadFence)},
{CC "storeFence", CC "()V", FN_PTR(Unsafe_StoreFence)},
{CC "fullFence", CC "()V", FN_PTR(Unsafe_FullFence)},
+ {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)},
};
#undef CC
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index 8c61e6a05..6852f1ac3 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -2071,6 +2071,10 @@ const intx ObjectAlignmentInBytes = 8;
JFR_ONLY(product(ccstr, StartFlightRecording, NULL, \
"Start flight recording with options")) \
\
+ product(bool, UseFastSerializer, false, EXPERIMENTAL, \
+ "Cache-based serialization.It is extremely fast, but it" \
+ "can only be effective in certain scenarios.") \
+ \
product(bool, UseFastUnorderedTimeStamps, false, EXPERIMENTAL, \
"Use platform unstable time where supported for timestamps only") \
\
diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java
index b3e063b3d..1cf3a38c8 100644
--- a/src/java.base/share/classes/java/io/ObjectInputStream.java
+++ b/src/java.base/share/classes/java/io/ObjectInputStream.java
@@ -41,6 +41,7 @@ import java.security.PrivilegedExceptionAction;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
import jdk.internal.access.SharedSecrets;
import jdk.internal.event.DeserializationEvent;
@@ -312,6 +313,23 @@ public class ObjectInputStream
filterLogger = (filterLog.isLoggable(Logger.Level.DEBUG)
|| filterLog.isLoggable(Logger.Level.TRACE)) ? filterLog : null;
}
+
+ /*
+ * Logger for FastSerializer.
+ * Setup the FastSerializer logger if it is set to DEBUG.
+ * (Assuming it will not change).
+ */
+ static final System.Logger fastSerLogger;
+
+ static {
+ if (printFastSerializer) {
+ Logger fastSerLog = System.getLogger("fastSerializer");
+ fastSerLogger = (fastSerLog.isLoggable(Logger.Level.DEBUG))
+ ? fastSerLog : null;
+ } else {
+ fastSerLogger = null;
+ }
+ }
}
/** filter stream for handling block data conversion */
@@ -337,6 +355,9 @@ public class ObjectInputStream
/** if true, invoke resolveObject() */
private boolean enableResolve;
+ /** Used to get the commandline option: useFastSerializer */
+ private static final Unsafe UNSAFE = Unsafe.getUnsafe();
+
/**
* Context during upcalls to class-defined readObject methods; holds
* object currently being deserialized and descriptor for current class.
@@ -350,6 +371,40 @@ public class ObjectInputStream
*/
private ObjectInputFilter serialFilter;
+ /**
+ * value of "useFastSerializer" property
+ */
+ private static final boolean defaultFastSerializer = UNSAFE.getUseFastSerializer();
+
+ /**
+ * true or false for open FastSerilizer
+ * May be changed in readStreamHeader
+ */
+ private boolean useFastSerializer = defaultFastSerializer;
+
+ /**
+ * Value of "fastSerializerEscapeMode" property. It can be turned on
+ * when useFastSerializer is true.
+ */
+ @SuppressWarnings("removal")
+ private static final boolean fastSerializerEscapeMode = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetBooleanAction(
+ "fastSerializerEscapeMode")).booleanValue();
+
+ /**
+ * Magic number that is written to the stream header when using fastserilizer.
+ */
+ private static final short STREAM_MAGIC_FAST = (short)0xdeca;
+
+ /**
+ * value of "printFastSerializer" property,
+ * as true or false for printing FastSerializer logs.
+ */
+ @SuppressWarnings("removal")
+ private static final boolean printFastSerializer = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetBooleanAction(
+ "printFastSerializer")).booleanValue();
+
/**
* True if the stream-specific filter has been set; initially false.
*/
@@ -437,6 +492,9 @@ public class ObjectInputStream
* transitively so that a complete equivalent graph of objects is
* reconstructed by readObject.
*
+ * The difference between fastSerialzation and default serialization is the
+ * descriptor serialization. The data serialization is same with each other.
+ *
* <p>The root object is completely restored when all of its fields and the
* objects it references are completely restored. At this point the object
* validation callbacks are executed in order based on their registered
@@ -726,11 +784,20 @@ public class ObjectInputStream
vlist.register(obj, prio);
}
+ /**
+ * Cache the class meta during serialization.
+ * Only used in FastSerilizer.
+ */
+ private static ConcurrentHashMap<String,Class<?>> nameToClass = new ConcurrentHashMap<>();
+
/**
* Load the local class equivalent of the specified stream class
* description. Subclasses may implement this method to allow classes to
* be fetched from an alternate source.
*
+ * When fastSerializer is turned on, fields of desc will be null except
+ * name. When resolveClass is override, this may cause null pointer exception.
+ *
* <p>The corresponding method in {@code ObjectOutputStream} is
* {@code annotateClass}. This method will be invoked only once for
* each unique class in the stream. This method can be implemented by
@@ -769,16 +836,29 @@ public class ObjectInputStream
throws IOException, ClassNotFoundException
{
String name = desc.getName();
- try {
- return Class.forName(name, false, latestUserDefinedLoader());
- } catch (ClassNotFoundException ex) {
- Class<?> cl = primClasses.get(name);
+ Class<?> cl = null;
+
+ if (useFastSerializer) {
+ cl = nameToClass.get(name);
if (cl != null) {
return cl;
- } else {
+ }
+ }
+
+ try {
+ cl = Class.forName(name, false, latestUserDefinedLoader());
+ } catch (ClassNotFoundException ex) {
+ cl = primClasses.get(name);
+ if (cl == null) {
throw ex;
}
}
+
+ if (useFastSerializer) {
+ nameToClass.put(name, cl);
+ }
+
+ return cl;
}
/**
@@ -953,9 +1033,33 @@ public class ObjectInputStream
{
short s0 = bin.readShort();
short s1 = bin.readShort();
- if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
- throw new StreamCorruptedException(
- String.format("invalid stream header: %04X%04X", s0, s1));
+ if (useFastSerializer) {
+ if (s0 != STREAM_MAGIC_FAST || s1 != STREAM_VERSION) {
+ if (s0 != STREAM_MAGIC) {
+ throw new StreamCorruptedException(
+ String.format("invalid stream header: %04X%04X, and FastSerializer is activated", s0, s1));
+ }
+
+ if (!fastSerializerEscapeMode) {
+ throw new StreamCorruptedException(
+ String.format("invalid stream header: %04X%04X.Fast serialization does not support " +
+ "original serialized files", s0, s1));
+ }
+
+ // Escape to default serialization
+ useFastSerializer = false;
+ if (Logging.fastSerLogger != null) {
+ Logging.fastSerLogger.log(Logger.Level.DEBUG, "[Deserialize]: Escape and disable FastSerializer");
+ }
+ }
+ } else if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
+ if (s0 == STREAM_MAGIC_FAST && s1 == STREAM_VERSION) {
+ throw new StreamCorruptedException(
+ String.format("invalid stream header: %04X%04X, and it is a FastSerializer stream", s0, s1));
+ } else {
+ throw new StreamCorruptedException(
+ String.format("invalid stream header: %04X%04X", s0, s1));
+ }
}
}
@@ -969,6 +1073,11 @@ public class ObjectInputStream
* this method reads class descriptors according to the format defined in
* the Object Serialization specification.
*
+ * In fastSerialize mode, the descriptor is obtained by lookup method. And
+ * the resolveClass method is called here to get the classmeta. Since the
+ * descriptor is obtained by lookup, the descriptor is same as localdesc.
+ * So we cann't distinguish the receiver desc and local desc.
+ *
* @return the class descriptor read
* @throws IOException If an I/O error has occurred.
* @throws ClassNotFoundException If the Class of a serialized object used
@@ -979,6 +1088,29 @@ public class ObjectInputStream
protected ObjectStreamClass readClassDescriptor()
throws IOException, ClassNotFoundException
{
+ // fastSerializer
+ if (useFastSerializer) {
+ String name = readUTF();
+ Class<?> cl = null;
+ ObjectStreamClass desc = new ObjectStreamClass(name);
+ try {
+ // In order to match this method, we add an annotateClass method in
+ // writeClassDescriptor.
+ cl = resolveClass(desc);
+ } catch (ClassNotFoundException ex) {
+ // resolveClass is just used to obtain Class which required by lookup method
+ // and it will be called again later, so we don't throw ClassNotFoundException here.
+ return desc;
+ }
+ if (cl != null) {
+ // This desc is localDesc. It may be different from the descriptor
+ // obtained from the stream.
+ desc = ObjectStreamClass.lookup(cl, true);
+ }
+ return desc;
+ }
+
+ // Default deserialization. If the Class cannot be found, throw ClassNotFoundException.
ObjectStreamClass desc = new ObjectStreamClass();
desc.readNonProxy(this);
return desc;
@@ -2045,41 +2177,63 @@ public class ObjectInputStream
skipCustomData();
- try {
- totalObjectRefs++;
- depth++;
- desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
+ totalObjectRefs++;
+ depth++;
- if (cl != null) {
- // Check that serial filtering has been done on the local class descriptor's superclass,
- // in case it does not appear in the stream.
-
- // Find the next super descriptor that has a local class descriptor.
- // Descriptors for which there is no local class are ignored.
- ObjectStreamClass superLocal = null;
- for (ObjectStreamClass sDesc = desc.getSuperDesc(); sDesc != null; sDesc = sDesc.getSuperDesc()) {
- if ((superLocal = sDesc.getLocalDesc()) != null) {
- break;
+ if (useFastSerializer) {
+ desc.initNonProxyFast(readDesc, resolveEx);
+ ObjectStreamClass superDesc = desc.getSuperDesc();
+ long originDepth = depth - 1;
+ // Since desc is obtained from the lookup method, we will lose the depth and
+ // totalObjectRefs of superDesc. So we add a loop here to compute the depth
+ // and objectRef of superDesc.
+ while (superDesc != null && superDesc.forClass() != null) {
+ filterCheck(superDesc.forClass(), -1);
+ superDesc = superDesc.getSuperDesc();
+ totalObjectRefs++;
+ depth++;
+ }
+ depth = originDepth;
+ } else {
+ try {
+ desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
+
+ if (cl != null) {
+ // Check that serial filtering has been done on the local class descriptor's superclass,
+ // in case it does not appear in the stream.
+ // Find the next super descriptor that has a local class descriptor.
+ // Descriptors for which there is no local class are ignored.
+ ObjectStreamClass superLocal = null;
+ for (ObjectStreamClass sDesc = desc.getSuperDesc(); sDesc != null; sDesc = sDesc.getSuperDesc()) {
+ if ((superLocal = sDesc.getLocalDesc()) != null) {
+ break;
+ }
}
- }
- // Scan local descriptor superclasses for a match with the local descriptor of the super found above.
- // For each super descriptor before the match, invoke the serial filter on the class.
- // The filter is invoked for each class that has not already been filtered
- // but would be filtered if the instance had been serialized by this Java runtime.
- for (ObjectStreamClass lDesc = desc.getLocalDesc().getSuperDesc();
- lDesc != null && lDesc != superLocal;
- lDesc = lDesc.getSuperDesc()) {
- filterCheck(lDesc.forClass(), -1);
+ // Scan local descriptor superclasses for a match with the local descriptor of the super found above.
+ // For each super descriptor before the match, invoke the serial filter on the class.
+ // The filter is invoked for each class that has not already been filtered
+ // but would be filtered if the instance had been serialized by this Java runtime.
+ for (ObjectStreamClass lDesc = desc.getLocalDesc().getSuperDesc();
+ lDesc != null && lDesc != superLocal;
+ lDesc = lDesc.getSuperDesc()) {
+ filterCheck(lDesc.forClass(), -1);
+ }
}
+ } finally {
+ depth--;
}
- } finally {
- depth--;
}
handles.finish(descHandle);
passHandle = descHandle;
+ if (Logging.fastSerLogger != null) {
+ Logging.fastSerLogger.log(Logger.Level.DEBUG,
+ "[Deserialize] useFastSerializer:{0}, Class name:{1}, SerialVersionUID:{2}, flags:{3}",
+ useFastSerializer, desc.getName(), desc.getSerialVersionUID(), desc.getFlags(this));
+ }
+
return desc;
}
@@ -2946,8 +3100,6 @@ public class ObjectInputStream
}
}
- private static final Unsafe UNSAFE = Unsafe.getUnsafe();
-
/**
* Performs a "freeze" action, required to adhere to final field semantics.
*
diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java
index be52df020..f855d6ee4 100644
--- a/src/java.base/share/classes/java/io/ObjectOutputStream.java
+++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
+import jdk.internal.misc.Unsafe;
import sun.reflect.misc.ReflectUtil;
/**
@@ -173,6 +174,25 @@ public class ObjectOutputStream
};
}
+ private static class Logging {
+ /*
+ * Logger for FastSerializer.
+ * Setup the FastSerializer logger if it is set to DEBUG.
+ * (Assuming it will not change).
+ */
+ static final System.Logger fastSerLogger;
+
+ static {
+ if (printFastSerializer) {
+ System.Logger fastSerLog = System.getLogger("fastSerializer");
+ fastSerLogger = (fastSerLog.isLoggable(System.Logger.Level.DEBUG))
+ ? fastSerLog : null;
+ } else {
+ fastSerLogger = null;
+ }
+ }
+ }
+
/** filter stream for handling block data conversion */
private final BlockDataOutputStream bout;
/** obj -> wire handle map */
@@ -191,7 +211,6 @@ public class ObjectOutputStream
private final boolean enableOverride;
/** if true, invoke replaceObject() */
private boolean enableReplace;
-
// values below valid only during upcalls to writeObject()/writeExternal()
/**
* Context during upcalls to class-defined writeObject methods; holds
@@ -215,6 +234,28 @@ public class ObjectOutputStream
new sun.security.action.GetBooleanAction(
"sun.io.serialization.extendedDebugInfo")).booleanValue();
+ private static final Unsafe UNSAFE = Unsafe.getUnsafe();
+
+ /**
+ * Value of "UseFastSerializer" property, The fastSerializer is turned
+ * on when it is true.
+ */
+ private static final boolean useFastSerializer = UNSAFE.getUseFastSerializer();
+
+ /**
+ * value of "printFastSerializer" property,
+ * as true or false for printing FastSerializer logs.
+ */
+ @SuppressWarnings("removal")
+ private static final boolean printFastSerializer = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetBooleanAction(
+ "printFastSerializer")).booleanValue();
+
+ /**
+ * Magic number that is written to the stream header when using fastserilizer.
+ */
+ private static final short STREAM_MAGIC_FAST = (short)0xdeca;
+
/**
* Creates an ObjectOutputStream that writes to the specified OutputStream.
* This constructor writes the serialization stream header to the
@@ -329,6 +370,9 @@ public class ObjectOutputStream
* object are written transitively so that a complete equivalent graph of
* objects can be reconstructed by an ObjectInputStream.
*
+ * The difference between fastSerialzation and default serialization is the
+ * descriptor serialization. The data serialization is same with each other.
+ *
* <p>Exceptions are thrown for problems with the OutputStream and for
* classes that should not be serialized. All exceptions are fatal to the
* OutputStream, which is left in an indeterminate state, and it is up to
@@ -638,7 +682,11 @@ public class ObjectOutputStream
* stream
*/
protected void writeStreamHeader() throws IOException {
- bout.writeShort(STREAM_MAGIC);
+ if (useFastSerializer) {
+ bout.writeShort(STREAM_MAGIC_FAST);
+ } else {
+ bout.writeShort(STREAM_MAGIC);
+ }
bout.writeShort(STREAM_VERSION);
}
@@ -653,6 +701,9 @@ public class ObjectOutputStream
* By default, this method writes class descriptors according to the format
* defined in the Object Serialization specification.
*
+ * In fastSerializer mode, we will only write the classname to the stream.
+ * The annotateClass is used to match the resolveClass in readClassDescriptor.
+ *
* <p>Note that this method will only be called if the ObjectOutputStream
* is not using the old serialization stream format (set by calling
* ObjectOutputStream's {@code useProtocolVersion} method). If this
@@ -670,7 +721,14 @@ public class ObjectOutputStream
protected void writeClassDescriptor(ObjectStreamClass desc)
throws IOException
{
- desc.writeNonProxy(this);
+ if (useFastSerializer) {
+ writeUTF(desc.getName());
+ // The annotateClass is used to match the resolveClass called in
+ // readClassDescriptor.
+ annotateClass(desc.forClass());
+ } else {
+ desc.writeNonProxy(this);
+ }
}
/**
@@ -1278,9 +1336,21 @@ public class ObjectOutputStream
bout.writeByte(TC_CLASSDESC);
handles.assign(unshared ? null : desc);
+ if (Logging.fastSerLogger != null) {
+ Logging.fastSerLogger.log(System.Logger.Level.DEBUG,
+ "[Serialize] useFastSerializer:{0}, Class name:{1}, SerialVersionUID:{2}, flags:{3}, protocol:{4}",
+ useFastSerializer, desc.getName(), desc.getSerialVersionUID(), desc.getFlags(this), protocol);
+ }
+
if (protocol == PROTOCOL_VERSION_1) {
// do not invoke class descriptor write hook with old protocol
- desc.writeNonProxy(this);
+ if (useFastSerializer) {
+ // only write name and annotate class when using FastSerializer
+ writeUTF(desc.getName());
+ annotateClass(desc.forClass());
+ } else {
+ desc.writeNonProxy(this);
+ }
} else {
writeClassDescriptor(desc);
}
@@ -1293,8 +1363,9 @@ public class ObjectOutputStream
annotateClass(cl);
bout.setBlockDataMode(false);
bout.writeByte(TC_ENDBLOCKDATA);
-
- writeClassDesc(desc.getSuperDesc(), false);
+ if (!useFastSerializer) {
+ writeClassDesc(desc.getSuperDesc(), false);
+ }
}
/**
diff --git a/src/java.base/share/classes/java/io/ObjectStreamClass.java b/src/java.base/share/classes/java/io/ObjectStreamClass.java
index afb3d8447..08488d19c 100644
--- a/src/java.base/share/classes/java/io/ObjectStreamClass.java
+++ b/src/java.base/share/classes/java/io/ObjectStreamClass.java
@@ -295,6 +295,40 @@ public class ObjectStreamClass implements Serializable {
return suid.longValue();
}
+ /**
+ * Return the flags for this class described by this descriptor. The flags
+ * means a set of bit masks for ObjectStreamClass, which indicate the status
+ * of SC_WRITE_METHOD, SC_SERIALIZABLE, SC_EXTERNALIZABLE, SC_BLOCK_DATA and
+ * SC_ENUM.
+ *
+ * @param serialStream ObjectOutputStream or ObjectInputStream
+ *
+ * @return the flags for this class described by this descriptor
+ */
+ byte getFlags(Object serialStream) {
+ byte flags = 0;
+ if (externalizable) {
+ flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
+ if (serialStream instanceof ObjectOutputStream) {
+ int protocol = ((ObjectOutputStream)serialStream).getProtocolVersion();
+ if (protocol != ObjectStreamConstants.PROTOCOL_VERSION_1) {
+ flags |= ObjectStreamConstants.SC_BLOCK_DATA;
+ }
+ } else if (serialStream instanceof ObjectInputStream) {
+ flags |= ObjectStreamConstants.SC_BLOCK_DATA;
+ }
+ } else if (serializable) {
+ flags |= ObjectStreamConstants.SC_SERIALIZABLE;
+ }
+ if (hasWriteObjectData) {
+ flags |= ObjectStreamConstants.SC_WRITE_METHOD;
+ }
+ if (isEnum) {
+ flags |= ObjectStreamConstants.SC_ENUM;
+ }
+ return flags;
+ }
+
/**
* Return the class in the local VM that this version is mapped to. Null
* is returned if there is no corresponding local class.
@@ -467,6 +501,15 @@ public class ObjectStreamClass implements Serializable {
ObjectStreamClass() {
}
+ /**
+ * Create a blank class descriptor with name. It is only used
+ * in fastSerialize path.
+ * @param name class name
+ */
+ ObjectStreamClass(String name) {
+ this.name = name;
+ }
+
/**
* Creates a PermissionDomain that grants no permission.
*/
@@ -661,6 +704,44 @@ public class ObjectStreamClass implements Serializable {
initialized = true;
}
+ /**
+ * Initializes class descriptor representing a non-proxy class.
+ * Used in fast serialization mode.
+ */
+ void initNonProxyFast(ObjectStreamClass model,
+ ClassNotFoundException resolveEx)
+ {
+ this.cl = model.cl;
+ this.resolveEx = resolveEx;
+ this.superDesc = model.superDesc;
+ name = model.name;
+ this.suid = model.suid;
+ isProxy = false;
+ isEnum = model.isEnum;
+ serializable = model.serializable;
+ externalizable = model.externalizable;
+ hasBlockExternalData = model.hasBlockExternalData;
+ hasWriteObjectData = model.hasWriteObjectData;
+ fields = model.fields;
+ primDataSize = model.primDataSize;
+ numObjFields = model.numObjFields;
+
+ writeObjectMethod = model.writeObjectMethod;
+ readObjectMethod = model.readObjectMethod;
+ readObjectNoDataMethod = model.readObjectNoDataMethod;
+ writeReplaceMethod = model.writeReplaceMethod;
+ readResolveMethod = model.readResolveMethod;
+ if (deserializeEx == null) {
+ deserializeEx = model.deserializeEx;
+ }
+ domains = model.domains;
+ cons = model.cons;
+ fieldRefl = model.fieldRefl;
+ localDesc = model;
+
+ initialized = true;
+ }
+
/**
* Reads non-proxy class descriptor information from given input stream.
* The resulting class descriptor is not fully functional; it can only be
diff --git a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
index 22aa09c9d..b6e7978a5 100644
--- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
+++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
@@ -3811,7 +3811,7 @@ public final class Unsafe {
private static long convEndian(boolean big, long n) { return big == BIG_ENDIAN ? n : Long.reverseBytes(n) ; }
-
+ public native boolean getUseFastSerializer();
private native long allocateMemory0(long bytes);
private native long reallocateMemory0(long address, long bytes);
private native void freeMemory0(long address);
--
2.37.0

View File

@ -56,7 +56,7 @@
# in alternatives those are slaves and master, very often triplicated by man pages
# in files all masters and slaves are ghosted
# the ghosts are here to allow installation via query like `dnf install /usr/bin/java`
# you can list those files, with appropriate sections: cat *.spec | grep -e --install -e --slave -e post_
# you can list those files, with appropriate sections: cat *.spec | grep -e --install -e --slave -e post_
# TODO - fix those hardcoded lists via single list
# those files ,must *NOT* be ghosted for *slowdebug* packages
# FIXME - if you are moving jshell or jlink or simialr, always modify all three sections
@ -157,7 +157,7 @@
%global vendor_version_string 21.9
%global securityver 5
# buildjdkver is usually same as %%{majorver},
# but in time of bootstrap of next jdk, it is majorver-1,
# but in time of bootstrap of next jdk, it is majorver-1,
# and this it is better to change it here, on single place
%global buildjdkver 17
# We don't add any LTS designator for STS packages (Fedora and EPEL).
@ -297,7 +297,7 @@ alternatives \\
--slave %{_mandir}/man1/keytool.1$ext keytool.1$ext \\
%{_mandir}/man1/keytool-%{uniquesuffix -- %{?1}}.1$ext \\
--slave %{_mandir}/man1/rmiregistry.1$ext rmiregistry.1$ext \\
%{_mandir}/man1/rmiregistry-%{uniquesuffix -- %{?1}}.1$ext
%{_mandir}/man1/rmiregistry-%{uniquesuffix -- %{?1}}.1$ext
for X in %{origin} %{javaver} ; do
alternatives --install %{_jvmdir}/jre-"$X" jre_"$X" %{_jvmdir}/%{sdkdir -- %{?1}} $PRIORITY --family %{name}.%{_arch}
@ -415,7 +415,7 @@ alternatives \\
--slave %{_mandir}/man1/jstatd.1$ext jstatd.1$ext \\
%{_mandir}/man1/jstatd-%{uniquesuffix -- %{?1}}.1$ext \\
--slave %{_mandir}/man1/serialver.1$ext serialver.1$ext \\
%{_mandir}/man1/serialver-%{uniquesuffix -- %{?1}}.1$ext
%{_mandir}/man1/serialver-%{uniquesuffix -- %{?1}}.1$ext
for X in %{origin} %{javaver} ; do
alternatives \\
@ -885,7 +885,7 @@ Provides: java-src%{?1} = %{epoch}:%{version}-%{release}
Name: java-%{javaver}-%{origin}
Version: %{newjavaver}.%{buildver}
Release: 0
Release: 1
# 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
@ -973,6 +973,14 @@ Patch16: Clean-up-JDK17-codeDEX-fix-Non-static-numa_node_dist.patch
Patch17: 8290705_fix_StringConcat_validate_mem_flow_asserts_with_unexpected_userStoreI.patch
Patch18: Apply-TBI-to-ZGC-of-JDK17.patch
# 17.0.5
Patch19: 8253495-CDS-generates-non-deterministic-outpu.patch
Patch20: 8296480-Fix-the-problem-that-the-TestPolicy.j.patch
Patch21: 8296485-BuildEEBasicConstraints.java-test-fai.patch
Patch22: Fast-Serializer.patch
Patch23: Apply-TBI-barrier-patch-to-C1.patch
Patch24: Add-Fast-serializer-testcase.patch
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: alsa-lib-devel
@ -1446,7 +1454,7 @@ done
# Make sure gdb can do a backtrace based on line numbers on libjvm.so
# javaCalls.cpp:58 should map to:
# http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/ff3b27e6bcc2/src/share/vm/runtime/javaCalls.cpp#l58
# http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/ff3b27e6bcc2/src/share/vm/runtime/javaCalls.cpp#l58
# Using line number 1 might cause build problems. See:
gdb -q "$JAVA_HOME/bin/java" <<EOF | tee gdb.out
handle SIGSEGV pass nostop noprint
@ -1580,9 +1588,9 @@ popd
# end moving files to /etc
# stabilize permissions
find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/ -name "*.so" -exec chmod 755 {} \; ;
find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/ -type d -exec chmod 755 {} \; ;
find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/legal -type f -exec chmod 644 {} \; ;
find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/ -name "*.so" -exec chmod 755 {} \; ;
find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/ -type d -exec chmod 755 {} \; ;
find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/legal -type f -exec chmod 644 {} \; ;
# end, dual install
done
@ -1758,6 +1766,14 @@ cjc.mainProgram(arg)
%changelog
* Thu Jan 5 2023 neu-mobi <liuyulong.work@qq.com> - 1:17.0.5.8-0.1
- add 8253495-CDS-generates-non-deterministic-outpu.patch
- add 8296480-Fix-the-problem-that-the-TestPolicy.j.patch
- add 8296485-BuildEEBasicConstraints.java-test-fai.patch
- add Fast-Serializer.patch
- add Apply-TBI-barrier-patch-to-C1.patch
- add Add-Fast-serializer-testcase.patch
* Wed Oct 19 2022 kuenking111 <wangkun49@huawei.com> - 1:17.0.5.8-0.rolling
- modified add-version-txt.patch
- add jdk17.0.5-ga