!17 Add feature and bug fix for jdk17
From: @neu-mobi Reviewed-by: @kuenking111 Signed-off-by: @kuenking111
This commit is contained in:
commit
7b395f63c7
539
8253495-CDS-generates-non-deterministic-outpu.patch
Normal file
539
8253495-CDS-generates-non-deterministic-outpu.patch
Normal 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
|
||||
|
||||
42
8296480-Fix-the-problem-that-the-TestPolicy.j.patch
Normal file
42
8296480-Fix-the-problem-that-the-TestPolicy.j.patch
Normal 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
|
||||
|
||||
40
8296485-BuildEEBasicConstraints.java-test-fai.patch
Normal file
40
8296485-BuildEEBasicConstraints.java-test-fai.patch
Normal 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
|
||||
|
||||
9987
Add-Fast-serializer-testcase.patch
Normal file
9987
Add-Fast-serializer-testcase.patch
Normal file
File diff suppressed because it is too large
Load Diff
104
Apply-TBI-barrier-patch-to-C1.patch
Normal file
104
Apply-TBI-barrier-patch-to-C1.patch
Normal 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
662
Fast-Serializer.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user