Add several enhancement patches
This commit is contained in:
parent
8b13547351
commit
ecb324beca
115
8210461-AArch64-Math.cos-intrinsic-gives-incorrect-results.patch
Normal file
115
8210461-AArch64-Math.cos-intrinsic-gives-incorrect-results.patch
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
From 723ae2c317eabdd65836df0bf6677cc2cf00e219 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhanggaofeng <zhanggaofeng9@huawei.com>
|
||||||
|
Date: Fri, 7 Aug 2020 18:49:17 +0000
|
||||||
|
Subject: [PATCH 16/20] 8210461: AArch64: Math.cos intrinsic gives incorrect
|
||||||
|
results
|
||||||
|
|
||||||
|
DTS/AR: DTS2020080710179
|
||||||
|
Summary: hotspot: backport JDK-8210461 and enable sin/cos stub
|
||||||
|
LLT: NA
|
||||||
|
Patch Type: backport
|
||||||
|
Bug url: https://bugs.openjdk.java.net/browse/JDK-8210461
|
||||||
|
---
|
||||||
|
.../aarch64/macroAssembler_aarch64_trig.cpp | 2 +-
|
||||||
|
.../cpu/aarch64/stubGenerator_aarch64.cpp | 6 ++-
|
||||||
|
.../intrinsics/mathexact/Test8210461.java | 54 +++++++++++++++++++
|
||||||
|
3 files changed, 59 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 test/hotspot/jtreg/compiler/intrinsics/mathexact/Test8210461.java
|
||||||
|
|
||||||
|
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp
|
||||||
|
index 694c3b5eb..7e1a16635 100644
|
||||||
|
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp
|
||||||
|
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp
|
||||||
|
@@ -1004,7 +1004,7 @@ void MacroAssembler::generate__kernel_rem_pio2(address two_over_pi, address pio2
|
||||||
|
br(LT, Z_IS_LESS_THAN_TWO24B);
|
||||||
|
fmuld(v1, v18, v17); // twon24*z
|
||||||
|
frintzd(v1, v1); // v1 = (double)(int)(v1)
|
||||||
|
- fmaddd(v2, v10, v1, v18);
|
||||||
|
+ fmsubd(v2, v10, v1, v18);
|
||||||
|
fcvtzdw(tmp3, v1); // (int)fw
|
||||||
|
fcvtzdw(tmp2, v2); // double to int
|
||||||
|
strw(tmp2, Address(iqBase, jz, Address::lsl(2)));
|
||||||
|
diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
|
||||||
|
index ac7eb8480..0310463ac 100644
|
||||||
|
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
|
||||||
|
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
|
||||||
|
@@ -5694,12 +5694,14 @@ class StubGenerator: public StubCodeGenerator {
|
||||||
|
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) {
|
||||||
|
// disabled pending fix and retest of generated code via JDK-8210461
|
||||||
|
- // StubRoutines::_dsin = generate_dsin_dcos(/* isCos = */ false);
|
||||||
|
+ // fixed in JDK-8210461
|
||||||
|
+ StubRoutines::_dsin = generate_dsin_dcos(/* isCos = */ false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
|
||||||
|
// disabled pending fix and retest of generated code via JDK-8210461
|
||||||
|
- // StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true);
|
||||||
|
+ // fixed in JDK-8210461
|
||||||
|
+ StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/test/hotspot/jtreg/compiler/intrinsics/mathexact/Test8210461.java b/test/hotspot/jtreg/compiler/intrinsics/mathexact/Test8210461.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..2fb4b59a0
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/hotspot/jtreg/compiler/intrinsics/mathexact/Test8210461.java
|
||||||
|
@@ -0,0 +1,54 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
+ * Copyright (c) 2018, Cavium (by BELLSOFT). All rights reserved.
|
||||||
|
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
+ *
|
||||||
|
+ * This code is free software; you can redistribute it and/or modify it
|
||||||
|
+ * under the terms of the GNU General Public License version 2 only, as
|
||||||
|
+ * published by the Free Software Foundation.
|
||||||
|
+ *
|
||||||
|
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
+ * accompanied this code).
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU General Public License version
|
||||||
|
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
+ *
|
||||||
|
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
+ * or visit www.oracle.com if you need additional information or have any
|
||||||
|
+ * questions.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * @test
|
||||||
|
+ * @bug 8210461
|
||||||
|
+ * @summary Math cos instrinsic returns incorrect result for large value
|
||||||
|
+ *
|
||||||
|
+ * @run main/othervm compiler.intrinsics.math.Test8210461
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+package compiler.intrinsics.math;
|
||||||
|
+
|
||||||
|
+import java.util.Arrays;
|
||||||
|
+
|
||||||
|
+public class Test8210461 {
|
||||||
|
+ private static final double[] testCases = new double[] {
|
||||||
|
+ 1647100.0d,
|
||||||
|
+ 16471000.0d,
|
||||||
|
+ 164710000.0d
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ public static void main(String[] args) {
|
||||||
|
+ Arrays.stream(testCases).forEach(Test8210461::test);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static void test(double arg) {
|
||||||
|
+ double strictResult = StrictMath.cos(arg);
|
||||||
|
+ double mathResult = Math.cos(arg);
|
||||||
|
+ if (Math.abs(strictResult - mathResult) > Math.ulp(strictResult))
|
||||||
|
+ throw new AssertionError(mathResult + " while expecting " + strictResult);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.19.0
|
||||||
|
|
||||||
4311
8210473-JEP-345-NUMA-Aware-Memory-Allocation-for-G1.patch
Normal file
4311
8210473-JEP-345-NUMA-Aware-Memory-Allocation-for-G1.patch
Normal file
File diff suppressed because it is too large
Load Diff
956
NUMA-Aware-Implementation-humongous-region.patch
Normal file
956
NUMA-Aware-Implementation-humongous-region.patch
Normal file
@ -0,0 +1,956 @@
|
|||||||
|
diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp
|
||||||
|
index 0fcfe4e96..a0ecfd393 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp
|
||||||
|
@@ -34,6 +34,7 @@
|
||||||
|
// Forward declarations
|
||||||
|
class G1BlockOffsetTable;
|
||||||
|
class G1ContiguousSpace;
|
||||||
|
+class G1RegionToSpaceMapper;
|
||||||
|
|
||||||
|
// This implementation of "G1BlockOffsetTable" divides the covered region
|
||||||
|
// into "N"-word subregions (where "N" = 2^"LogN". An array with an entry
|
||||||
|
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
|
||||||
|
index 3bb5b56e8..a987377ae 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
|
||||||
|
@@ -343,7 +343,8 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) {
|
||||||
|
} else {
|
||||||
|
// Policy: Try only empty regions (i.e. already committed first). Maybe we
|
||||||
|
// are lucky enough to find some.
|
||||||
|
- first = _hrm.find_contiguous_only_empty(obj_regions);
|
||||||
|
+ uint node_index = _numa->is_humongous_region_enabled() ? _numa->index_of_current_thread() : G1NUMA::AnyNodeIndex;
|
||||||
|
+ first = _hrm.find_contiguous_only_empty(obj_regions, node_index);
|
||||||
|
if (first != G1_NO_HRM_INDEX) {
|
||||||
|
_hrm.allocate_free_regions_starting_at(first, obj_regions);
|
||||||
|
}
|
||||||
|
@@ -353,14 +354,15 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) {
|
||||||
|
// Policy: We could not find enough regions for the humongous object in the
|
||||||
|
// free list. Look through the heap to find a mix of free and uncommitted regions.
|
||||||
|
// If so, try expansion.
|
||||||
|
- first = _hrm.find_contiguous_empty_or_unavailable(obj_regions);
|
||||||
|
+ uint node_index = _numa->is_humongous_region_enabled() ? _numa->index_of_current_thread() : G1NUMA::AnyNodeIndex;
|
||||||
|
+ first = _hrm.find_contiguous_empty_or_unavailable(obj_regions, node_index);
|
||||||
|
if (first != G1_NO_HRM_INDEX) {
|
||||||
|
// We found something. Make sure these regions are committed, i.e. expand
|
||||||
|
// the heap. Alternatively we could do a defragmentation GC.
|
||||||
|
log_debug(gc, ergo, heap)("Attempt heap expansion (humongous allocation request failed). Allocation request: " SIZE_FORMAT "B",
|
||||||
|
word_size * HeapWordSize);
|
||||||
|
|
||||||
|
- _hrm.expand_at(first, obj_regions, workers());
|
||||||
|
+ _hrm.expand_at(first, obj_regions, workers(), node_index);
|
||||||
|
g1_policy()->record_new_heap_size(num_regions());
|
||||||
|
|
||||||
|
#ifdef ASSERT
|
||||||
|
@@ -4823,7 +4825,7 @@ public:
|
||||||
|
HeapRegionSet* old_set, HeapRegionManager* hrm) :
|
||||||
|
_free_list_only(free_list_only),
|
||||||
|
_old_set(old_set), _hrm(hrm), _total_used(0) {
|
||||||
|
- assert(_hrm.num_free_regions() == 0, "pre-condition");
|
||||||
|
+ assert(_hrm->num_free_regions() == 0, "pre-condition");
|
||||||
|
if (!free_list_only) {
|
||||||
|
assert(_old_set->is_empty(), "pre-condition");
|
||||||
|
}
|
||||||
|
diff --git a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp
|
||||||
|
index 71342b4d2..22fd0bd95 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp
|
||||||
|
@@ -777,7 +777,7 @@ class G1CheckCSetFastTableClosure : public HeapRegionClosure {
|
||||||
|
|
||||||
|
bool G1HeapVerifier::check_cset_fast_test() {
|
||||||
|
G1CheckCSetFastTableClosure cl;
|
||||||
|
- _g1h->_hrm->iterate(&cl);
|
||||||
|
+ _g1h->_hrm.iterate(&cl);
|
||||||
|
return !cl.failures();
|
||||||
|
}
|
||||||
|
#endif // PRODUCT
|
||||||
|
diff --git a/src/hotspot/share/gc/g1/g1NUMA.cpp b/src/hotspot/share/gc/g1/g1NUMA.cpp
|
||||||
|
index 95d9d8c15..fada40f13 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/g1NUMA.cpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/g1NUMA.cpp
|
||||||
|
@@ -42,6 +42,8 @@ size_t G1NUMA::page_size() const {
|
||||||
|
|
||||||
|
bool G1NUMA::is_enabled() const { return num_active_nodes() > 1; }
|
||||||
|
|
||||||
|
+bool G1NUMA::is_humongous_region_enabled() const { return UseNUMAHumongous && num_active_nodes() > 1; }
|
||||||
|
+
|
||||||
|
G1NUMA* G1NUMA::create() {
|
||||||
|
guarantee(_inst == NULL, "Should be called once.");
|
||||||
|
_inst = new G1NUMA();
|
||||||
|
@@ -203,7 +205,7 @@ uint G1NUMA::index_for_region(HeapRegion* hr) const {
|
||||||
|
// * Page #: |-----0----||-----1----||-----2----||-----3----||-----4----||-----5----||-----6----||-----7----|
|
||||||
|
// * HeapRegion #: |-#0-||-#1-||-#2-||-#3-||-#4-||-#5-||-#6-||-#7-||-#8-||-#9-||#10-||#11-||#12-||#13-||#14-||#15-|
|
||||||
|
// * NUMA node #: |----#0----||----#1----||----#2----||----#3----||----#0----||----#1----||----#2----||----#3----|
|
||||||
|
-void G1NUMA::request_memory_on_node(void* aligned_address, size_t size_in_bytes, uint region_index) {
|
||||||
|
+void G1NUMA::request_memory_on_node(void* aligned_address, size_t size_in_bytes, uint region_index, uint node) {
|
||||||
|
if (!is_enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -212,7 +214,7 @@ void G1NUMA::request_memory_on_node(void* aligned_address, size_t size_in_bytes,
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- uint node_index = preferred_node_index_for_index(region_index);
|
||||||
|
+ uint node_index = node == G1NUMA::AnyNodeIndex ? preferred_node_index_for_index(region_index) : node;
|
||||||
|
|
||||||
|
assert(is_aligned(aligned_address, page_size()), "Given address (" PTR_FORMAT ") should be aligned.", p2i(aligned_address));
|
||||||
|
assert(is_aligned(size_in_bytes, page_size()), "Given size (" SIZE_FORMAT ") should be aligned.", size_in_bytes);
|
||||||
|
diff --git a/src/hotspot/share/gc/g1/g1NUMA.hpp b/src/hotspot/share/gc/g1/g1NUMA.hpp
|
||||||
|
index 2bfad205b..56889057f 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/g1NUMA.hpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/g1NUMA.hpp
|
||||||
|
@@ -89,6 +89,8 @@ public:
|
||||||
|
|
||||||
|
bool is_enabled() const;
|
||||||
|
|
||||||
|
+ bool is_humongous_region_enabled() const;
|
||||||
|
+
|
||||||
|
int numa_id(int index) const;
|
||||||
|
|
||||||
|
// Returns memory node ids
|
||||||
|
@@ -113,7 +115,7 @@ public:
|
||||||
|
uint index_for_region(HeapRegion* hr) const;
|
||||||
|
|
||||||
|
// Requests the given memory area to be located at the given node index.
|
||||||
|
- void request_memory_on_node(void* aligned_address, size_t size_in_bytes, uint region_index);
|
||||||
|
+ void request_memory_on_node(void* aligned_address, size_t size_in_bytes, uint region_index, uint node = AnyNodeIndex);
|
||||||
|
|
||||||
|
// Returns maximum search depth which is used to limit heap region search iterations.
|
||||||
|
// The number of active nodes, page size and heap region size are considered.
|
||||||
|
diff --git a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp
|
||||||
|
index dba2d1734..67595e05b 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp
|
||||||
|
@@ -69,7 +69,7 @@ class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper {
|
||||||
|
guarantee(alloc_granularity >= page_size, "allocation granularity smaller than commit granularity");
|
||||||
|
}
|
||||||
|
|
||||||
|
- virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) {
|
||||||
|
+ virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang, uint node) {
|
||||||
|
const size_t start_page = (size_t)start_idx * _pages_per_region;
|
||||||
|
const size_t size_in_pages = num_regions * _pages_per_region;
|
||||||
|
bool zero_filled = _storage.commit(start_page, size_in_pages);
|
||||||
|
@@ -77,7 +77,7 @@ class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper {
|
||||||
|
for (uint region_index = start_idx; region_index < start_idx + num_regions; region_index++ ) {
|
||||||
|
void* address = _storage.page_start(region_index * _pages_per_region);
|
||||||
|
size_t size_in_bytes = _storage.page_size() * _pages_per_region;
|
||||||
|
- G1NUMA::numa()->request_memory_on_node(address, size_in_bytes, region_index);
|
||||||
|
+ G1NUMA::numa()->request_memory_on_node(address, size_in_bytes, region_index, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (AlwaysPreTouch) {
|
||||||
|
@@ -125,7 +125,7 @@ class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
|
||||||
|
_refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + align_up(rs.size(), page_size)), page_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
- virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) {
|
||||||
|
+ virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang, uint node) {
|
||||||
|
size_t const NoPage = ~(size_t)0;
|
||||||
|
|
||||||
|
size_t first_committed = NoPage;
|
||||||
|
diff --git a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp
|
||||||
|
index 30f7bf54c..6b396c8e3 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp
|
||||||
|
@@ -25,6 +25,7 @@
|
||||||
|
#ifndef SHARE_VM_GC_G1_G1REGIONTOSPACEMAPPER_HPP
|
||||||
|
#define SHARE_VM_GC_G1_G1REGIONTOSPACEMAPPER_HPP
|
||||||
|
|
||||||
|
+#include "gc/g1/g1NUMA.hpp"
|
||||||
|
#include "gc/g1/g1PageBasedVirtualSpace.hpp"
|
||||||
|
#include "memory/allocation.hpp"
|
||||||
|
#include "utilities/debug.hpp"
|
||||||
|
@@ -72,7 +73,7 @@ class G1RegionToSpaceMapper : public CHeapObj<mtGC> {
|
||||||
|
return _commit_map.at(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
- virtual void commit_regions(uint start_idx, size_t num_regions = 1, WorkGang* pretouch_workers = NULL) = 0;
|
||||||
|
+ virtual void commit_regions(uint start_idx, size_t num_regions = 1, WorkGang* pretouch_workers = NULL, uint node = G1NUMA::AnyNodeIndex) = 0;
|
||||||
|
virtual void uncommit_regions(uint start_idx, size_t num_regions = 1) = 0;
|
||||||
|
|
||||||
|
// Creates an appropriate G1RegionToSpaceMapper for the given parameters.
|
||||||
|
diff --git a/src/hotspot/share/gc/g1/heapRegionManager.cpp b/src/hotspot/share/gc/g1/heapRegionManager.cpp
|
||||||
|
index 10a0d58a5..9dc86eb21 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/heapRegionManager.cpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp
|
||||||
|
@@ -37,6 +37,11 @@
|
||||||
|
#include "runtime/orderAccess.hpp"
|
||||||
|
#include "utilities/bitMap.inline.hpp"
|
||||||
|
|
||||||
|
+// Avoid allocating too many humongous regions in the same node
|
||||||
|
+// at most (humongous regions already allocated)/ BALANCE_FACTOR_FOR_HUMONGOUS
|
||||||
|
+// if this threshold is exceeded, fallback to the original scheme
|
||||||
|
+const int BALANCE_FACTOR_FOR_HUMONGOUS = 2;
|
||||||
|
+
|
||||||
|
class MasterFreeRegionListChecker : public HeapRegionSetChecker {
|
||||||
|
public:
|
||||||
|
void check_mt_safety() {
|
||||||
|
@@ -134,23 +139,23 @@ HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) {
|
||||||
|
assert(reserved().contains(mr), "invariant");
|
||||||
|
return g1h->new_heap_region(hrm_index, mr);
|
||||||
|
}
|
||||||
|
-
|
||||||
|
-void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkGang* pretouch_gang) {
|
||||||
|
+
|
||||||
|
+void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkGang* pretouch_gang, uint node) {
|
||||||
|
guarantee(num_regions > 0, "Must commit more than zero regions");
|
||||||
|
guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
|
||||||
|
|
||||||
|
_num_committed += (uint)num_regions;
|
||||||
|
|
||||||
|
- _heap_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||||
|
+ _heap_mapper->commit_regions(index, num_regions, pretouch_gang, node);
|
||||||
|
|
||||||
|
// Also commit auxiliary data
|
||||||
|
- _prev_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||||
|
- _next_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||||
|
+ _prev_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang, node);
|
||||||
|
+ _next_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang, node);
|
||||||
|
|
||||||
|
- _bot_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||||
|
- _cardtable_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||||
|
+ _bot_mapper->commit_regions(index, num_regions, pretouch_gang, node);
|
||||||
|
+ _cardtable_mapper->commit_regions(index, num_regions, pretouch_gang, node);
|
||||||
|
|
||||||
|
- _card_counts_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||||
|
+ _card_counts_mapper->commit_regions(index, num_regions, pretouch_gang, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
|
||||||
|
@@ -185,9 +190,22 @@ void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
|
||||||
|
_card_counts_mapper->uncommit_regions(start, num_regions);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void HeapRegionManager::make_regions_available(uint start, uint num_regions, WorkGang* pretouch_gang) {
|
||||||
|
+void HeapRegionManager::make_regions_available(uint start, uint num_regions, WorkGang* pretouch_gang, uint node) {
|
||||||
|
guarantee(num_regions > 0, "No point in calling this for zero regions");
|
||||||
|
- commit_regions(start, num_regions, pretouch_gang);
|
||||||
|
+ if (node != G1NUMA::AnyNodeIndex) {
|
||||||
|
+ G1NUMA* numa = G1NUMA::numa();
|
||||||
|
+ guarantee(numa->is_humongous_region_enabled(), "NUMA Humongous should be enabled in calling this");
|
||||||
|
+ guarantee(node < numa->num_active_nodes(), "node should be less than active nodes");
|
||||||
|
+ uint sum = 0;
|
||||||
|
+ for (uint i = 0; i < numa->num_active_nodes(); i++) {
|
||||||
|
+ sum += _humongous.count(i);
|
||||||
|
+ }
|
||||||
|
+ uint regionsOnThisNode = _humongous.count(node);
|
||||||
|
+ if (BALANCE_FACTOR_FOR_HUMONGOUS * regionsOnThisNode > sum + num_regions) {
|
||||||
|
+ node = G1NUMA::AnyNodeIndex;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ commit_regions(start, num_regions, pretouch_gang, node);
|
||||||
|
for (uint i = start; i < start + num_regions; i++) {
|
||||||
|
if (_regions.get_by_index(i) == NULL) {
|
||||||
|
HeapRegion* new_hr = new_heap_region(i);
|
||||||
|
@@ -209,7 +227,10 @@ void HeapRegionManager::make_regions_available(uint start, uint num_regions, Wor
|
||||||
|
MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
|
||||||
|
|
||||||
|
hr->initialize(mr);
|
||||||
|
- hr->set_node_index(G1NUMA::numa()->index_for_region(hr));
|
||||||
|
+ hr->set_node_index(node == G1NUMA::AnyNodeIndex ? G1NUMA::numa()->index_for_region(hr) : node);
|
||||||
|
+ if (node != G1NUMA::AnyNodeIndex) {
|
||||||
|
+ _humongous.add(hr);
|
||||||
|
+ }
|
||||||
|
insert_into_free_list(at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -236,7 +257,7 @@ uint HeapRegionManager::expand_by(uint num_regions, WorkGang* pretouch_workers)
|
||||||
|
return expand_at(0, num_regions, pretouch_workers);
|
||||||
|
}
|
||||||
|
|
||||||
|
-uint HeapRegionManager::expand_at(uint start, uint num_regions, WorkGang* pretouch_workers) {
|
||||||
|
+uint HeapRegionManager::expand_at(uint start, uint num_regions, WorkGang* pretouch_workers, uint node) {
|
||||||
|
if (num_regions == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -250,7 +271,7 @@ uint HeapRegionManager::expand_at(uint start, uint num_regions, WorkGang* pretou
|
||||||
|
while (expanded < num_regions &&
|
||||||
|
(num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
|
||||||
|
uint to_expand = MIN2(num_regions - expanded, num_last_found);
|
||||||
|
- make_regions_available(idx_last_found, to_expand, pretouch_workers);
|
||||||
|
+ make_regions_available(idx_last_found, to_expand, pretouch_workers, node);
|
||||||
|
expanded += to_expand;
|
||||||
|
cur = idx_last_found + num_last_found + 1;
|
||||||
|
}
|
||||||
|
@@ -288,7 +309,7 @@ bool HeapRegionManager::is_on_preferred_index(uint region_index, uint preferred_
|
||||||
|
return region_node_index == preferred_node_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
-uint HeapRegionManager::find_contiguous(size_t num, bool empty_only) {
|
||||||
|
+uint HeapRegionManager::find_contiguous(size_t num, bool empty_only, uint node) {
|
||||||
|
uint found = 0;
|
||||||
|
size_t length_found = 0;
|
||||||
|
uint cur = 0;
|
||||||
|
@@ -297,7 +318,12 @@ uint HeapRegionManager::find_contiguous(size_t num, bool empty_only) {
|
||||||
|
HeapRegion* hr = _regions.get_by_index(cur);
|
||||||
|
if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) {
|
||||||
|
// This region is a potential candidate for allocation into.
|
||||||
|
- length_found++;
|
||||||
|
+ if (node != G1NUMA::AnyNodeIndex && hr != NULL && hr->node_index() != node) {
|
||||||
|
+ length_found = 0;
|
||||||
|
+ found = cur + 1;
|
||||||
|
+ } else {
|
||||||
|
+ length_found++;
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
// This region is not a candidate. The next region is the next possible one.
|
||||||
|
found = cur + 1;
|
||||||
|
@@ -306,13 +332,35 @@ uint HeapRegionManager::find_contiguous(size_t num, bool empty_only) {
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (node != G1NUMA::AnyNodeIndex && length_found != num) {
|
||||||
|
+ found = 0;
|
||||||
|
+ length_found = 0;
|
||||||
|
+ cur = 0;
|
||||||
|
+ while (length_found < num && cur < max_length()) {
|
||||||
|
+ HeapRegion* hr = _regions.get_by_index(cur);
|
||||||
|
+ if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) {
|
||||||
|
+ // This region is a potential candidate for allocation into.
|
||||||
|
+ length_found++;
|
||||||
|
+ } else {
|
||||||
|
+ // This region is not a candidate. The next region is the next possible one.
|
||||||
|
+ found = cur + 1;
|
||||||
|
+ length_found = 0;
|
||||||
|
+ }
|
||||||
|
+ cur++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (length_found == num) {
|
||||||
|
+ G1NUMA* numa = G1NUMA::numa();
|
||||||
|
for (uint i = found; i < (found + num); i++) {
|
||||||
|
HeapRegion* hr = _regions.get_by_index(i);
|
||||||
|
// sanity check
|
||||||
|
guarantee((!empty_only && !is_available(i)) || (is_available(i) && hr != NULL && hr->is_empty()),
|
||||||
|
"Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT
|
||||||
|
" that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr));
|
||||||
|
+ if (numa->is_humongous_region_enabled() && hr != NULL && hr->node_index() < numa->num_active_nodes()) {
|
||||||
|
+ numa->update_statistics(G1NUMAStats::NewRegionAlloc, node, hr->node_index());
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
} else {
|
||||||
|
diff --git a/src/hotspot/share/gc/g1/heapRegionManager.hpp b/src/hotspot/share/gc/g1/heapRegionManager.hpp
|
||||||
|
index 216fcbc92..3edc1a9fb 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/heapRegionManager.hpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/heapRegionManager.hpp
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
#define SHARE_VM_GC_G1_HEAPREGIONMANAGER_HPP
|
||||||
|
|
||||||
|
#include "gc/g1/g1BiasedArray.hpp"
|
||||||
|
+#include "gc/g1/g1NUMA.hpp"
|
||||||
|
#include "gc/g1/g1RegionToSpaceMapper.hpp"
|
||||||
|
#include "gc/g1/heapRegionSet.hpp"
|
||||||
|
#include "services/memoryUsage.hpp"
|
||||||
|
@@ -81,7 +82,7 @@ class HeapRegionManager: public CHeapObj<mtGC> {
|
||||||
|
G1RegionToSpaceMapper* _card_counts_mapper;
|
||||||
|
|
||||||
|
FreeRegionList _free_list;
|
||||||
|
-
|
||||||
|
+ G1RegionsOnNodes _humongous;
|
||||||
|
// Each bit in this bitmap indicates that the corresponding region is available
|
||||||
|
// for allocation.
|
||||||
|
CHeapBitMap _available_map;
|
||||||
|
@@ -95,10 +96,10 @@ class HeapRegionManager: public CHeapObj<mtGC> {
|
||||||
|
HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); }
|
||||||
|
HeapWord* heap_end() const {return _regions.end_address_mapped(); }
|
||||||
|
|
||||||
|
- void make_regions_available(uint index, uint num_regions = 1, WorkGang* pretouch_gang = NULL);
|
||||||
|
+ void make_regions_available(uint index, uint num_regions = 1, WorkGang* pretouch_gang = NULL, uint node = G1NUMA::AnyNodeIndex);
|
||||||
|
|
||||||
|
// Pass down commit calls to the VirtualSpace.
|
||||||
|
- void commit_regions(uint index, size_t num_regions = 1, WorkGang* pretouch_gang = NULL);
|
||||||
|
+ void commit_regions(uint index, size_t num_regions = 1, WorkGang* pretouch_gang = NULL, uint node = G1NUMA::AnyNodeIndex);
|
||||||
|
void uncommit_regions(uint index, size_t num_regions = 1);
|
||||||
|
|
||||||
|
// Notify other data structures about change in the heap layout.
|
||||||
|
@@ -108,7 +109,7 @@ class HeapRegionManager: public CHeapObj<mtGC> {
|
||||||
|
// the index of the first region or G1_NO_HRM_INDEX if the search was unsuccessful.
|
||||||
|
// If only_empty is true, only empty regions are considered.
|
||||||
|
// Searches from bottom to top of the heap, doing a first-fit.
|
||||||
|
- uint find_contiguous(size_t num, bool only_empty);
|
||||||
|
+ uint find_contiguous(size_t num, bool only_empty, uint node = G1NUMA::AnyNodeIndex);
|
||||||
|
// Finds the next sequence of unavailable regions starting from start_idx. Returns the
|
||||||
|
// length of the sequence found. If this result is zero, no such sequence could be found,
|
||||||
|
// otherwise res_idx indicates the start index of these regions.
|
||||||
|
@@ -212,17 +213,17 @@ public:
|
||||||
|
// Makes sure that the regions from start to start+num_regions-1 are available
|
||||||
|
// for allocation. Returns the number of regions that were committed to achieve
|
||||||
|
// this.
|
||||||
|
- uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers);
|
||||||
|
+ uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers, uint node = G1NUMA::AnyNodeIndex);
|
||||||
|
|
||||||
|
// Try to expand on the given node index.
|
||||||
|
virtual uint expand_on_preferred_node(uint node_index);
|
||||||
|
|
||||||
|
// Find a contiguous set of empty regions of length num. Returns the start index of
|
||||||
|
// that set, or G1_NO_HRM_INDEX.
|
||||||
|
- uint find_contiguous_only_empty(size_t num) { return find_contiguous(num, true); }
|
||||||
|
+ uint find_contiguous_only_empty(size_t num, uint node = G1NUMA::AnyNodeIndex) { return find_contiguous(num, true, node); }
|
||||||
|
// Find a contiguous set of empty or unavailable regions of length num. Returns the
|
||||||
|
// start index of that set, or G1_NO_HRM_INDEX.
|
||||||
|
- uint find_contiguous_empty_or_unavailable(size_t num) { return find_contiguous(num, false); }
|
||||||
|
+ uint find_contiguous_empty_or_unavailable(size_t num, uint node = G1NUMA::AnyNodeIndex) { return find_contiguous(num, false, node); }
|
||||||
|
|
||||||
|
HeapRegion* next_region_in_heap(const HeapRegion* r) const;
|
||||||
|
|
||||||
|
diff --git a/src/hotspot/share/gc/g1/heapRegionSet.hpp b/src/hotspot/share/gc/g1/heapRegionSet.hpp
|
||||||
|
index a495269da..71b89668a 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/heapRegionSet.hpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/heapRegionSet.hpp
|
||||||
|
@@ -53,6 +53,7 @@ class HeapRegionSetChecker : public CHeapObj<mtGC> {
|
||||||
|
public:
|
||||||
|
// Verify MT safety for this HeapRegionSet.
|
||||||
|
virtual void check_mt_safety() = 0;
|
||||||
|
+ virtual bool is_correct_type(HeapRegion *hr) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Base class for all the classes that represent heap region sets. It
|
||||||
|
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
|
||||||
|
index fe7a5eff3..ce62c7ac7 100644
|
||||||
|
--- a/src/hotspot/share/runtime/globals.hpp
|
||||||
|
+++ b/src/hotspot/share/runtime/globals.hpp
|
||||||
|
@@ -299,6 +299,10 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G);
|
||||||
|
product(bool, UseNUMAInterleaving, false, \
|
||||||
|
"Interleave memory across NUMA nodes if available") \
|
||||||
|
\
|
||||||
|
+ experimental(bool, UseNUMAHumongous, false, \
|
||||||
|
+ "Allocate Humongous Regions in the same node if available" \
|
||||||
|
+ "Only used if UseNUMA is enabled.") \
|
||||||
|
+ \
|
||||||
|
product(size_t, NUMAInterleaveGranularity, 2*M, \
|
||||||
|
"Granularity to use for NUMA interleaving on Windows OS") \
|
||||||
|
range(os::vm_allocation_granularity(), NOT_LP64(2*G) LP64_ONLY(8192*G)) \
|
||||||
|
diff --git a/test/jtreg-ext/com/huawei/openjdk/numa/TestNUMAARMIO.java b/test/jtreg-ext/com/huawei/openjdk/numa/TestNUMAARMIO.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..4394b5bbb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/jtreg-ext/com/huawei/openjdk/numa/TestNUMAARMIO.java
|
||||||
|
@@ -0,0 +1,127 @@
|
||||||
|
+/*
|
||||||
|
+*Copyright (c) Huawei Technologies Co., Ltd. 2012-2019. All rights reserved.
|
||||||
|
+*/
|
||||||
|
+package com.huawei.openjdk.numa;
|
||||||
|
+/**
|
||||||
|
+ * @test TestNUMAARMIO
|
||||||
|
+ * @key gc
|
||||||
|
+ * @modules java.base/jdk.internal.misc
|
||||||
|
+ * @library /test/lib
|
||||||
|
+ * @build sun.hotspot.WhiteBox
|
||||||
|
+ * @build com.huawei.openjdk.numa.TestNUMAAbstract
|
||||||
|
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
+ * @run main/othervm -Xlog:gc*=info -Xms8G -Xmx8G -XX:+UseNUMA com.huawei.openjdk.numa.TestNUMAARMIO 100 80000 80000 0 7 10000 10000 +UseNUMA -Xms16G -Xmx16G 70
|
||||||
|
+ * @summary open NUMA-Aware,test mermoy allocate and copy
|
||||||
|
+ * @author wangruishun
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * @test TestNUMAARMIO
|
||||||
|
+ * @key gc
|
||||||
|
+ * @modules java.base/jdk.internal.misc
|
||||||
|
+ * @library /test/lib
|
||||||
|
+ * @build sun.hotspot.WhiteBox
|
||||||
|
+ * @build com.huawei.openjdk.numa.TestNUMAAbstract
|
||||||
|
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
+ * @run main/othervm -Xlog:gc*=info -Xms8G -Xmx8G -XX:-UseNUMA com.huawei.openjdk.numa.TestNUMAARMIO 100 80000 80000 0 7 10000 10000 -UseNUMA -Xms16G -Xmx16G 70
|
||||||
|
+ * @summary close NUMA-Aware,test mermoy allocate and copy
|
||||||
|
+ * @author wangruishun
|
||||||
|
+ */
|
||||||
|
+import jdk.test.lib.Asserts.*;
|
||||||
|
+import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
+import jdk.test.lib.process.ProcessTools;
|
||||||
|
+
|
||||||
|
+import java.util.ArrayList;
|
||||||
|
+import java.util.List;
|
||||||
|
+import java.util.Random;
|
||||||
|
+import java.util.concurrent.CountDownLatch;
|
||||||
|
+import java.util.concurrent.TimeUnit;
|
||||||
|
+import java.util.regex.Matcher;
|
||||||
|
+import java.util.regex.Pattern;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+public class TestNUMAARMIO {
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ public static void main(String[] args) throws Exception {
|
||||||
|
+ if (!TestNUMAAbstract.checkArgs(args)) {
|
||||||
|
+ System.err.println("[param error] please check your param");
|
||||||
|
+ throw new RuntimeException("args error!");
|
||||||
|
+ }
|
||||||
|
+ String flagStr = args[10];
|
||||||
|
+ float flag = Float.parseFloat(flagStr);
|
||||||
|
+ OutputAnalyzer output = TestNUMAAbstract.executeClass(args,ExeTest.class);
|
||||||
|
+ System.out.println(output.getStdout());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ private static class ExeTest {
|
||||||
|
+
|
||||||
|
+ public static void main(String[] args) throws Exception {
|
||||||
|
+ int threadNum = Integer.valueOf(args[0]).intValue();
|
||||||
|
+ int minStore = Integer.valueOf(args[1]).intValue();
|
||||||
|
+ int maxStore = Integer.valueOf(args[2]).intValue();
|
||||||
|
+ int minThreadSleep = Integer.valueOf(args[3]).intValue();
|
||||||
|
+ int maxThreadSleep = Integer.valueOf(args[4]).intValue();
|
||||||
|
+ int minObjCount = Integer.valueOf(args[5]).intValue();
|
||||||
|
+ int maxObjCount = Integer.valueOf(args[6]).intValue();
|
||||||
|
+ long starTime = System.currentTimeMillis();
|
||||||
|
+ System.out.println("***********star time*************:" + starTime);
|
||||||
|
+ final CountDownLatch mDoneSignal = new CountDownLatch(threadNum);
|
||||||
|
+ //create thread
|
||||||
|
+ List<Thread> threadList = TestNUMAAbstract.createNUMABindThread(threadNum, minStore, maxStore, minThreadSleep, maxThreadSleep, minObjCount, maxObjCount,mDoneSignal,new TestNUMAAbstract(){
|
||||||
|
+ @Override
|
||||||
|
+ void threadRun(int minObjCount, int maxObjCount, int minStore, int maxStore, CountDownLatch mDoneSignal, int minThreadSleep, int maxThreadSleep) {
|
||||||
|
+ int randomObjNum = TestNUMAAbstract.randomNum(minObjCount, maxObjCount);
|
||||||
|
+ int count = 0;
|
||||||
|
+ while (count < randomObjNum) {
|
||||||
|
+ int randomStore = TestNUMAAbstract.randomNum(minStore, maxStore);
|
||||||
|
+ int[] arr = new int[randomStore];
|
||||||
|
+ //allocate mermory
|
||||||
|
+ for (int i = 0; i < arr.length; i++) {
|
||||||
|
+ arr[i] = i;
|
||||||
|
+ }
|
||||||
|
+ //copy mermory
|
||||||
|
+ int[] tem = new int[randomStore];
|
||||||
|
+ for (int i = 0; i < arr.length; i++) {
|
||||||
|
+ tem[i] = arr[i];
|
||||||
|
+ }
|
||||||
|
+ count++;
|
||||||
|
+ }
|
||||||
|
+ mDoneSignal.countDown();
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ TestNUMAAbstract.runNUMABindThread(threadList);
|
||||||
|
+ mDoneSignal.await();
|
||||||
|
+ long endTime = System.currentTimeMillis();
|
||||||
|
+ System.out.println("***********end time*************" + endTime);
|
||||||
|
+ System.out.println(String.format("Total thread count:%s", threadNum));
|
||||||
|
+ System.out.println(String.format("Min thread sleep:%s(um)", minThreadSleep));
|
||||||
|
+ System.out.println(String.format("Max thread sleep:%s(um)", maxThreadSleep));
|
||||||
|
+ System.out.println(String.format("Min RAM,int array length:%s", minStore));
|
||||||
|
+ System.out.println(String.format("Max RAM,int array length:%s", maxStore));
|
||||||
|
+ System.out.println(String.format("Min count of Obj:%s", minObjCount));
|
||||||
|
+ System.out.println(String.format("Max count of Obj:%s", maxObjCount));
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ double objTotalCount = threadNum*minObjCount;
|
||||||
|
+ double totalArm = objTotalCount*minStore*4;
|
||||||
|
+ //byte to KB
|
||||||
|
+ totalArm = totalArm/1024;
|
||||||
|
+ //KB to MB
|
||||||
|
+ totalArm = totalArm/1024;
|
||||||
|
+ System.out.println(String.format("allocate total ARM:%sMB", totalArm));
|
||||||
|
+ System.out.println(String.format("copy total ARM:%sMB", totalArm));
|
||||||
|
+ System.out.println("exe time:" + (endTime - starTime));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff --git a/test/jtreg-ext/com/huawei/openjdk/numa/TestNUMAAbstract.java b/test/jtreg-ext/com/huawei/openjdk/numa/TestNUMAAbstract.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..31eb393f6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/jtreg-ext/com/huawei/openjdk/numa/TestNUMAAbstract.java
|
||||||
|
@@ -0,0 +1,178 @@
|
||||||
|
+/*
|
||||||
|
+* Copyright (c) Huawei Technologies Co., Ltd. 2012-2019. All rights
|
||||||
|
+reserved.
|
||||||
|
+*/
|
||||||
|
+package com.huawei.openjdk.numa;
|
||||||
|
+
|
||||||
|
+import java.util.ArrayList;
|
||||||
|
+import java.util.List;
|
||||||
|
+import java.util.Random;
|
||||||
|
+import java.util.concurrent.CountDownLatch;
|
||||||
|
+
|
||||||
|
+import jdk.test.lib.Asserts.*;
|
||||||
|
+
|
||||||
|
+import jdk.test.lib.Platform;
|
||||||
|
+import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
+import jdk.test.lib.process.ProcessTools;
|
||||||
|
+import sun.hotspot.WhiteBox;
|
||||||
|
+/**
|
||||||
|
+ * @summary Utility class.
|
||||||
|
+ * @author wangruishun
|
||||||
|
+ */
|
||||||
|
+public class TestNUMAAbstract {
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ private static final int ARGS_LEN_LIMIT = 11;
|
||||||
|
+
|
||||||
|
+ void threadRun(int minObjCount,int maxObjCount,int minStore,int maxStore,CountDownLatch mDoneSignal,int minThreadSleep, int maxThreadSleep){
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+ /**
|
||||||
|
+ * get random from closed interval
|
||||||
|
+ *
|
||||||
|
+ * @param minNum min
|
||||||
|
+ * @param maxNum max
|
||||||
|
+ * @return random
|
||||||
|
+ */
|
||||||
|
+ public static int randomNum(int minNum, int maxNum) {
|
||||||
|
+ if (minNum == maxNum) {
|
||||||
|
+ return minNum;
|
||||||
|
+ }
|
||||||
|
+ Random random = new Random();
|
||||||
|
+ int randomNum = random.nextInt((maxNum - minNum) + 1) + minNum;
|
||||||
|
+ return randomNum;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * start all thread
|
||||||
|
+ * @param createNUMABindThread thread list
|
||||||
|
+ */
|
||||||
|
+ public static void runNUMABindThread(List<Thread> createNUMABindThread) {
|
||||||
|
+ for (Thread thread : createNUMABindThread) {
|
||||||
|
+ try {
|
||||||
|
+ thread.start();
|
||||||
|
+ } catch (Exception e) {
|
||||||
|
+ e.printStackTrace();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * create thread and The execution content is provided by the caller
|
||||||
|
+ *
|
||||||
|
+ * @param maxThreadNum maxThreadNum
|
||||||
|
+ * @param minStore minStore
|
||||||
|
+ * @param maxStore maxStore
|
||||||
|
+ * @param minThreadSleep minThreadSleep
|
||||||
|
+ * @param maxThreadSleep maxThreadSleep
|
||||||
|
+ * @param minObjCount minObjCount
|
||||||
|
+ * @param maxObjCount maxObjCount
|
||||||
|
+ * @return list
|
||||||
|
+ */
|
||||||
|
+ public static List<Thread> createNUMABindThread(int maxThreadNum, int minStore, int maxStore, int minThreadSleep, int maxThreadSleep, int minObjCount, int maxObjCount, CountDownLatch mDoneSignal,TestNUMAAbstract testNUMAAbstract) {
|
||||||
|
+ System.gc();
|
||||||
|
+ System.out.println("-------init gc over ------------");
|
||||||
|
+ System.out.println(String.format("args[0]:Total thread count:%s", maxThreadNum));
|
||||||
|
+ System.out.println(String.format("args[1]:Min thread sleep:%s(um)", minThreadSleep));
|
||||||
|
+ System.out.println(String.format("args[2]:Max thread sleep:%s(um)", maxThreadSleep));
|
||||||
|
+ System.out.println(String.format("args[3]:Min RAM,int array length:%s", minStore));
|
||||||
|
+ System.out.println(String.format("args[4]:Max RAM,int array length:%s", maxStore));
|
||||||
|
+ System.out.println(String.format("args[5]:Min count of Obj:%s", minObjCount));
|
||||||
|
+ System.out.println(String.format("args[6]:Max count of Obj:%s", maxObjCount));
|
||||||
|
+ List<Thread> list = new ArrayList<>();
|
||||||
|
+ int i = 0;
|
||||||
|
+ while (i < maxThreadNum) {
|
||||||
|
+ Thread createObj = new TestNUMABindThread(minStore, maxStore, minThreadSleep, maxThreadSleep, minObjCount, maxObjCount, mDoneSignal,testNUMAAbstract);
|
||||||
|
+ list.add(createObj);
|
||||||
|
+ i++;
|
||||||
|
+ }
|
||||||
|
+ return list;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * execute class
|
||||||
|
+ *
|
||||||
|
+ * @param args the param of main
|
||||||
|
+ * @param exeClass calss name
|
||||||
|
+ * @throws Exception
|
||||||
|
+ */
|
||||||
|
+ public static OutputAnalyzer executeClass(String[] args,Class exeClass) throws Exception {
|
||||||
|
+ final String[] arguments = {
|
||||||
|
+ "-Xbootclasspath/a:.",
|
||||||
|
+ "-XX:" + args[7],
|
||||||
|
+ args[8],
|
||||||
|
+ args[9],
|
||||||
|
+ "-Xlog:gc*=info",
|
||||||
|
+ exeClass.getName(),
|
||||||
|
+ args[0],
|
||||||
|
+ args[1],
|
||||||
|
+ args[2],
|
||||||
|
+ args[3],
|
||||||
|
+ args[4],
|
||||||
|
+ args[5],
|
||||||
|
+ args[6]
|
||||||
|
+ };
|
||||||
|
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(arguments);
|
||||||
|
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||||
|
+ output.shouldHaveExitValue(0);
|
||||||
|
+ return output;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * param check
|
||||||
|
+ * @param args
|
||||||
|
+ * @return
|
||||||
|
+ */
|
||||||
|
+ public static boolean checkArgs(String[] args) {
|
||||||
|
+ if (args == null || args.length != ARGS_LEN_LIMIT) {
|
||||||
|
+ System.out.println("args[0]:Total thread count");
|
||||||
|
+ System.out.println("args[1]:Min thread sleep(um)");
|
||||||
|
+ System.out.println("args[2]:Max thread sleep(um)");
|
||||||
|
+ System.out.println("args[3]:Min RAM,int array length");
|
||||||
|
+ System.out.println("args[4]:Max RAM,int array length");
|
||||||
|
+ System.out.println("args[5]:Min count of Obj");
|
||||||
|
+ System.out.println("args[6]:Max count of Obj");
|
||||||
|
+ System.out.println("args[7]:NUMA is open,+UseNUMA/-UseNUMA");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class TestNUMABindThread extends Thread {
|
||||||
|
+ private int minStore;
|
||||||
|
+ private int maxStore;
|
||||||
|
+ private int minThreadSleep;
|
||||||
|
+ private int maxThreadSleep;
|
||||||
|
+ private int minObjCount;
|
||||||
|
+ private int maxObjCount;
|
||||||
|
+ private CountDownLatch mDoneSignal;
|
||||||
|
+ private TestNUMAAbstract testNUMAAbstract;
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * @param minStore min store
|
||||||
|
+ * @param maxStore max store
|
||||||
|
+ * @param minThreadSleep sleep time(um)
|
||||||
|
+ * @param maxThreadSleep sleep time(um)
|
||||||
|
+ * @param minObjCount the count of obj in one thread
|
||||||
|
+ * @param maxObjCount the count of obj in one thread
|
||||||
|
+ */
|
||||||
|
+ public TestNUMABindThread(int minStore, int maxStore, int minThreadSleep, int maxThreadSleep, int minObjCount, int maxObjCount, CountDownLatch mDoneSignal, TestNUMAAbstract testNUMAAbstract) {
|
||||||
|
+ this.minStore = minStore;
|
||||||
|
+ this.maxStore = maxStore;
|
||||||
|
+ this.minThreadSleep = minThreadSleep;
|
||||||
|
+ this.maxThreadSleep = maxThreadSleep;
|
||||||
|
+ this.minObjCount = minObjCount;
|
||||||
|
+ this.maxObjCount = maxObjCount;
|
||||||
|
+ this.mDoneSignal = mDoneSignal;
|
||||||
|
+ this.testNUMAAbstract = testNUMAAbstract;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void run() {
|
||||||
|
+ testNUMAAbstract.threadRun(minObjCount, maxObjCount, minStore, maxStore, mDoneSignal,minThreadSleep,maxThreadSleep);
|
||||||
|
+ mDoneSignal.countDown();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
\ No newline at end of file
|
||||||
|
diff --git a/test/jtreg-ext/com/huawei/openjdk/numa/TestNUMAAllocate.java b/test/jtreg-ext/com/huawei/openjdk/numa/TestNUMAAllocate.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..a00e6dad4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/jtreg-ext/com/huawei/openjdk/numa/TestNUMAAllocate.java
|
||||||
|
@@ -0,0 +1,208 @@
|
||||||
|
+/*
|
||||||
|
+* Copyright (c) Huawei Technologies Co., Ltd. 2012-2019. All rights
|
||||||
|
+reserved.
|
||||||
|
+*/
|
||||||
|
+package com.huawei.openjdk.numa;
|
||||||
|
+/**
|
||||||
|
+ * @test TestNUMAAllocate
|
||||||
|
+ * @key gc
|
||||||
|
+ * @modules java.base/jdk.internal.misc
|
||||||
|
+ * @library /test/lib
|
||||||
|
+ * @build sun.hotspot.WhiteBox
|
||||||
|
+ * @build com.huawei.openjdk.numa.TestNUMAAbstract
|
||||||
|
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
+ * @run main/othervm -Xlog:gc*=info -Xms8G -Xmx8G -XX:+UseNUMA com.huawei.openjdk.numa.TestNUMAAllocate 1500 77000 80000 0 7 10000 10000 +UseNUMA -Xms8G -Xmx8G 70
|
||||||
|
+ * @summary opem NUMA-Aware,Memory allocate distribution ratio exceeds 70%
|
||||||
|
+ * @author wangruishun
|
||||||
|
+ */
|
||||||
|
+/**
|
||||||
|
+ * @test TestNUMAAllocate
|
||||||
|
+ * @key gc
|
||||||
|
+ * @modules java.base/jdk.internal.misc
|
||||||
|
+ * @library /test/lib
|
||||||
|
+ * @build sun.hotspot.WhiteBox
|
||||||
|
+ * @build com.huawei.openjdk.numa.TestNUMAAbstract
|
||||||
|
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
+ * @run main/othervm -Xlog:gc*=info -Xms16G -Xmx16G -XX:+UseNUMA com.huawei.openjdk.numa.TestNUMAAllocate 1 6000000 9000000 0 0 100 100 +UseNUMA -Xms8G -Xmx16G 20
|
||||||
|
+ * @summary opem NUMA-Aware,Memory allocate distribution ratio exceeds 20%,one thread Humongous.
|
||||||
|
+ * @author wangruishun
|
||||||
|
+ */
|
||||||
|
+/**
|
||||||
|
+ * @test TestNUMAAllocate
|
||||||
|
+ * @key gc
|
||||||
|
+ * @modules java.base/jdk.internal.misc
|
||||||
|
+ * @library /test/lib
|
||||||
|
+ * @build sun.hotspot.WhiteBox
|
||||||
|
+ * @build com.huawei.openjdk.numa.TestNUMAAbstract
|
||||||
|
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
+ * @run main/othervm -Xlog:gc*=info -Xms16G -Xmx16G -XX:+UseNUMA com.huawei.openjdk.numa.TestNUMAAllocate 5 800000 1000000 0 7 100 100 +UseNUMA -Xms256M -Xmx16G 45
|
||||||
|
+ * @summary opem NUMA-Aware,Memory allocate distribution ratio exceeds 45%,5 thread,Humongous
|
||||||
|
+ * @author wangruishun
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * @test TestNUMAAllocate
|
||||||
|
+ * @key gc
|
||||||
|
+ * @modules java.base/jdk.internal.misc
|
||||||
|
+ * @library /test/lib
|
||||||
|
+ * @build sun.hotspot.WhiteBox
|
||||||
|
+ * @build com.huawei.openjdk.numa.TestNUMAAbstract
|
||||||
|
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
+ * @run main/othervm -Xlog:gc*=info -Xms16G -Xmx16G -XX:+UseNUMA com.huawei.openjdk.numa.TestNUMAAllocate 5 800000 1000000 0 7 100 100 +UseNUMA -Xms256M -Xmx16G 45
|
||||||
|
+ * @summary opem NUMA-Aware,Memory allocate distribution ratio exceeds 45%,5 thread,Humongous
|
||||||
|
+ * @author wangruishun
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * @test TestNUMAAllocate
|
||||||
|
+ * @key gc
|
||||||
|
+ * @modules java.base/jdk.internal.misc
|
||||||
|
+ * @library /test/lib
|
||||||
|
+ * @build sun.hotspot.WhiteBox
|
||||||
|
+ * @build com.huawei.openjdk.numa.TestNUMAAbstract
|
||||||
|
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
+ * @run main/othervm -Xlog:gc*=info -Xms8G -Xmx8G -XX:+UseNUMA com.huawei.openjdk.numa.TestNUMAAllocate 120 77000 80000 0 7 150 150 +UseNUMA -Xms8G -Xmx8G 70
|
||||||
|
+ * @summary opem NUMA-Aware,Memory allocate distribution ratio exceeds 70%
|
||||||
|
+ * @author wangruishun
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+import java.util.ArrayList;
|
||||||
|
+import java.util.List;
|
||||||
|
+import java.util.Random;
|
||||||
|
+import java.util.concurrent.CountDownLatch;
|
||||||
|
+import java.util.concurrent.TimeUnit;
|
||||||
|
+import java.util.regex.Matcher;
|
||||||
|
+import java.util.regex.Pattern;
|
||||||
|
+
|
||||||
|
+import jdk.test.lib.Asserts.*;
|
||||||
|
+
|
||||||
|
+import jdk.test.lib.Platform;
|
||||||
|
+import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
+import jdk.test.lib.process.ProcessTools;
|
||||||
|
+import sun.hotspot.WhiteBox;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+public class TestNUMAAllocate{
|
||||||
|
+
|
||||||
|
+ private static final int ARGS_LEN_LIMIT = 11;
|
||||||
|
+
|
||||||
|
+ public static void main(String[] args) throws Exception {
|
||||||
|
+ if (!TestNUMAAbstract.checkArgs(args)) {
|
||||||
|
+ System.err.println("[param error] please check your param");
|
||||||
|
+ throw new RuntimeException("args error!");
|
||||||
|
+ }
|
||||||
|
+ //ratio
|
||||||
|
+ String flagStr = args[10];
|
||||||
|
+ float flag = Float.parseFloat(flagStr);
|
||||||
|
+ //execute program and get stdout
|
||||||
|
+ OutputAnalyzer output = TestNUMAAbstract.executeClass(args,GClogTest.class);
|
||||||
|
+ //check print
|
||||||
|
+ checkPattern(".*Placement match ratio:*", output.getStdout(),flag);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Check if the string matches
|
||||||
|
+ *
|
||||||
|
+ * @param pattern string
|
||||||
|
+ * @param what string
|
||||||
|
+ * @param flag ratio
|
||||||
|
+ * @throws Exception
|
||||||
|
+ */
|
||||||
|
+ private static void checkPattern(String pattern, String what, float flag) throws Exception {
|
||||||
|
+ String[] arr = what.split(System.lineSeparator());
|
||||||
|
+ boolean isMatch = false;
|
||||||
|
+ float maxPercent = 0f;
|
||||||
|
+ for (String line : arr) {
|
||||||
|
+ Pattern r = Pattern.compile(pattern);
|
||||||
|
+ Matcher m = r.matcher(line);
|
||||||
|
+ if (m.find()) {
|
||||||
|
+ isMatch = true;
|
||||||
|
+ Float percentLine = getPercentByLog(line);
|
||||||
|
+ if (percentLine > maxPercent) {
|
||||||
|
+ maxPercent = percentLine;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ System.out.println(String.format("NUMA percent:%s", maxPercent));
|
||||||
|
+ if (!isMatch) {
|
||||||
|
+ throw new RuntimeException("Could not find pattern " + pattern + " in output");
|
||||||
|
+ }
|
||||||
|
+ if (maxPercent < flag) {
|
||||||
|
+ throw new RuntimeException("MUMA Seems to fail to start ");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * get ration by gclog
|
||||||
|
+ *
|
||||||
|
+ * @param line
|
||||||
|
+ * @return
|
||||||
|
+ */
|
||||||
|
+ private static Float getPercentByLog(String line) {
|
||||||
|
+ if (null == line || "".equals(line)) {
|
||||||
|
+ return 0f;
|
||||||
|
+ }
|
||||||
|
+ //[1.631s][info][gc,heap,numa ] GC(23) Placement match ratio: 5% 555/10618 (0: 62% 243/392, 1: 53% 265/498, 2: 100% 11/11, 3: 100% 36/36)
|
||||||
|
+ Pattern pattern = Pattern.compile(".\\d%|[1-9]*%|100%");
|
||||||
|
+ Matcher matcher = pattern.matcher(line);
|
||||||
|
+ Float percent = 0f;
|
||||||
|
+ if(matcher.find()){
|
||||||
|
+ String percentStr = matcher.group(0);
|
||||||
|
+ percentStr = percentStr.substring(0,percentStr.length()-1);
|
||||||
|
+ percent = Float.parseFloat(percentStr);
|
||||||
|
+ }
|
||||||
|
+ return percent;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ private static class GClogTest {
|
||||||
|
+ public static void main(String[] args) throws Exception {
|
||||||
|
+ int threadNum = Integer.valueOf(args[0]).intValue();
|
||||||
|
+ int minStore = Integer.valueOf(args[1]).intValue();
|
||||||
|
+ int maxStore = Integer.valueOf(args[2]).intValue();
|
||||||
|
+ int minThreadSleep = Integer.valueOf(args[3]).intValue();
|
||||||
|
+ int maxThreadSleep = Integer.valueOf(args[4]).intValue();
|
||||||
|
+ int minObjCount = Integer.valueOf(args[5]).intValue();
|
||||||
|
+ int maxObjCount = Integer.valueOf(args[6]).intValue();
|
||||||
|
+ long starTime = System.currentTimeMillis();
|
||||||
|
+ System.out.println("***********star time*************:" + starTime);
|
||||||
|
+ final CountDownLatch mDoneSignal = new CountDownLatch(threadNum);
|
||||||
|
+ List<Thread> threadList = TestNUMAAbstract.createNUMABindThread(threadNum, minStore, maxStore, minThreadSleep, maxThreadSleep, minObjCount, maxObjCount,mDoneSignal,new TestNUMAAbstract(){
|
||||||
|
+ @Override
|
||||||
|
+ void threadRun(int minObjCount, int maxObjCount, int minStore, int maxStore, CountDownLatch mDoneSignal, int minThreadSleep, int maxThreadSleep) {
|
||||||
|
+ int randomObjNum = TestNUMAAbstract.randomNum(minObjCount, maxObjCount);
|
||||||
|
+ int count = 0;
|
||||||
|
+ while (count < randomObjNum) {
|
||||||
|
+ int randomStore = TestNUMAAbstract.randomNum(minStore, maxStore);
|
||||||
|
+ int[] arr = new int[randomStore];
|
||||||
|
+ int[] tem = new int[1];
|
||||||
|
+ for (int i = 0; i < arr.length; i++) {
|
||||||
|
+ tem[0] = arr[i];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ count++;
|
||||||
|
+ try {
|
||||||
|
+ int threadSleep = TestNUMAAbstract.randomNum(minThreadSleep, maxThreadSleep);
|
||||||
|
+ TimeUnit.MICROSECONDS.sleep(threadSleep);
|
||||||
|
+ } catch (InterruptedException e) {
|
||||||
|
+ e.printStackTrace();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ mDoneSignal.countDown();
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
+ TestNUMAAbstract.runNUMABindThread(threadList);
|
||||||
|
+ mDoneSignal.await();
|
||||||
|
+ long endTime = System.currentTimeMillis();
|
||||||
|
+ System.out.println("***********end time*************" + endTime);
|
||||||
|
+ System.out.println("***********result time*************" + (starTime - endTime));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
From 1e483c1a6ed3f4a32f658031594c5a89ff955260 Mon Sep 17 00:00:00 2001
|
||||||
|
From: mashoubing <mashoubing1@huawei.com>
|
||||||
|
Date: Tue, 18 Aug 2020 19:17:27 +0800
|
||||||
|
Subject: [PATCH 20/20] ZGC: in c1 load barrier d0 and d1 registers miss
|
||||||
|
restoring
|
||||||
|
|
||||||
|
DTS/AR: DTS2020072712733
|
||||||
|
Summary: <gc>: <load barrier need to save and restore float registers correctly>
|
||||||
|
LLT:
|
||||||
|
Patch Type: huawei
|
||||||
|
Bug url: https://gitlab.huawei.com/huaweijdk/jdk11u-dev/issues/857
|
||||||
|
---
|
||||||
|
src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp
|
||||||
|
index 4ce56895a..92b4d4335 100644
|
||||||
|
--- a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp
|
||||||
|
+++ b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp
|
||||||
|
@@ -309,7 +309,7 @@ void ZBarrierSetAssembler::generate_c1_load_barrier_runtime_stub(StubAssembler*
|
||||||
|
|
||||||
|
__ pop(save_regs, sp);
|
||||||
|
|
||||||
|
- for (int i = 30; i >0; i -= 2) {
|
||||||
|
+ for (int i = 30; i >= 0; i -= 2) {
|
||||||
|
__ ldpd(as_FloatRegister(i), as_FloatRegister(i + 1), Address(__ post(sp, 16)));
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.19.0
|
||||||
|
|
||||||
@ -1,628 +0,0 @@
|
|||||||
commit cbbef85e20818d23651e553ad9915ec8225a3456
|
|
||||||
Author: hexuejin <hexuejin2@huawei.com>
|
|
||||||
Date: Thu May 28 11:04:16 2020 +0800
|
|
||||||
|
|
||||||
Add FastSerializer
|
|
||||||
|
|
||||||
DTS/AR: AR.SR.IREQ02369011.001.001
|
|
||||||
Summary:<core-libs>: Add FastSerializer
|
|
||||||
LLT: jtreg
|
|
||||||
Patch Type: huawei
|
|
||||||
Bug url: NA
|
|
||||||
|
|
||||||
diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp
|
|
||||||
index 2f14e01ce..2f7f96aee 100644
|
|
||||||
--- a/src/hotspot/share/prims/unsafe.cpp
|
|
||||||
+++ b/src/hotspot/share/prims/unsafe.cpp
|
|
||||||
@@ -1019,6 +1019,11 @@ UNSAFE_ENTRY(jint, Unsafe_GetLoadAverage0(JNIEnv *env, jobject unsafe, jdoubleAr
|
|
||||||
} UNSAFE_END
|
|
||||||
|
|
||||||
|
|
||||||
+UNSAFE_ENTRY(jboolean, Unsafe_GetUseFastSerializer(JNIEnv *env, jobject unsafe)) {
|
|
||||||
+ return UseFastSerializer;
|
|
||||||
+}
|
|
||||||
+UNSAFE_END
|
|
||||||
+
|
|
||||||
/// JVM_RegisterUnsafeMethods
|
|
||||||
|
|
||||||
#define ADR "J"
|
|
||||||
@@ -1102,6 +1107,7 @@ static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = {
|
|
||||||
{CC "fullFence", CC "()V", FN_PTR(Unsafe_FullFence)},
|
|
||||||
|
|
||||||
{CC "isBigEndian0", CC "()Z", FN_PTR(Unsafe_isBigEndian0)},
|
|
||||||
+ {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)},
|
|
||||||
{CC "unalignedAccess0", CC "()Z", FN_PTR(Unsafe_unalignedAccess0)}
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
|
|
||||||
index 1e2408b4b..7fc3c1fb7 100644
|
|
||||||
--- a/src/hotspot/share/runtime/globals.hpp
|
|
||||||
+++ b/src/hotspot/share/runtime/globals.hpp
|
|
||||||
@@ -2670,6 +2670,10 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G);
|
|
||||||
JFR_ONLY(product(ccstr, StartFlightRecording, NULL, \
|
|
||||||
"Start flight recording with options")) \
|
|
||||||
\
|
|
||||||
+ experimental(bool, UseFastSerializer, false, \
|
|
||||||
+ "Cache-based serialization.It is extremely fast, but it can only" \
|
|
||||||
+ "be effective in certain scenarios.") \
|
|
||||||
+ \
|
|
||||||
experimental(bool, UseFastUnorderedTimeStamps, false, \
|
|
||||||
"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 3386b1a08..d71d44a98 100644
|
|
||||||
--- a/src/java.base/share/classes/java/io/ObjectInputStream.java
|
|
||||||
+++ b/src/java.base/share/classes/java/io/ObjectInputStream.java
|
|
||||||
@@ -295,6 +295,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 */
|
|
||||||
@@ -320,6 +337,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.
|
|
||||||
@@ -333,6 +353,33 @@ 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.
|
|
||||||
+ */
|
|
||||||
+ private static final boolean fastSerializerEscapeMode = java.security.AccessController.doPrivileged(
|
|
||||||
+ new sun.security.action.GetBooleanAction(
|
|
||||||
+ "fastSerializerEscapeMode")).booleanValue();
|
|
||||||
+
|
|
||||||
+ /**
|
|
||||||
+ * value of "printFastSerializer" property,
|
|
||||||
+ * as true or false for printing FastSerializer logs.
|
|
||||||
+ */
|
|
||||||
+ private static final boolean printFastSerializer = java.security.AccessController.doPrivileged(
|
|
||||||
+ new sun.security.action.GetBooleanAction(
|
|
||||||
+ "printFastSerializer")).booleanValue();
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* Creates an ObjectInputStream that reads from the specified InputStream.
|
|
||||||
* A serialization stream header is read from the stream and verified.
|
|
||||||
@@ -410,6 +457,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
|
|
||||||
@@ -698,11 +748,20 @@ public class ObjectInputStream
|
|
||||||
vlist.register(obj, prio);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /**
|
|
||||||
+ * Cache the class meta during serialization.
|
|
||||||
+ * Only used in FastSerilizer.
|
|
||||||
+ */
|
|
||||||
+ protected 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</code> is
|
|
||||||
* <code>annotateClass</code>. This method will be invoked only once for
|
|
||||||
* each unique class in the stream. This method can be implemented by
|
|
||||||
@@ -741,18 +800,33 @@ 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;
|
|
||||||
+
|
|
||||||
}
|
|
||||||
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* Returns a proxy class that implements the interfaces named in a proxy
|
|
||||||
* class descriptor; subclasses may implement this method to read custom
|
|
||||||
@@ -924,9 +998,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));
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -940,6 +1038,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
|
|
||||||
@@ -950,6 +1053,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;
|
|
||||||
@@ -1946,10 +2072,12 @@ public class ObjectInputStream
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectStreamClass desc = new ObjectStreamClass();
|
|
||||||
+
|
|
||||||
int descHandle = handles.assign(unshared ? unsharedMarker : desc);
|
|
||||||
passHandle = NULL_HANDLE;
|
|
||||||
|
|
||||||
ObjectStreamClass readDesc;
|
|
||||||
+
|
|
||||||
try {
|
|
||||||
readDesc = readClassDescriptor();
|
|
||||||
} catch (ClassNotFoundException ex) {
|
|
||||||
@@ -1976,17 +2104,40 @@ public class ObjectInputStream
|
|
||||||
|
|
||||||
skipCustomData();
|
|
||||||
|
|
||||||
- try {
|
|
||||||
- totalObjectRefs++;
|
|
||||||
- depth++;
|
|
||||||
- desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
|
|
||||||
- } finally {
|
|
||||||
- depth--;
|
|
||||||
+ totalObjectRefs++;
|
|
||||||
+ depth++;
|
|
||||||
+
|
|
||||||
+ 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));
|
|
||||||
+ } 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2873,7 +3024,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 135e5645a..8935e61dc 100644
|
|
||||||
--- a/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
|
||||||
+++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
|
||||||
@@ -36,6 +36,7 @@ import java.util.StringJoiner;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import static java.io.ObjectStreamClass.processQueue;
|
|
||||||
+import jdk.internal.misc.Unsafe;
|
|
||||||
import sun.reflect.misc.ReflectUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
@@ -174,6 +175,25 @@ public class ObjectOutputStream
|
|
||||||
new ReferenceQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
+ 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 */
|
|
||||||
@@ -192,7 +212,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,22 @@ 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.
|
|
||||||
+ */
|
|
||||||
+ private static final boolean printFastSerializer = java.security.AccessController.doPrivileged(
|
|
||||||
+ new sun.security.action.GetBooleanAction(
|
|
||||||
+ "printFastSerializer")).booleanValue();
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* Creates an ObjectOutputStream that writes to the specified OutputStream.
|
|
||||||
* This constructor writes the serialization stream header to the
|
|
||||||
@@ -328,6 +363,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
|
|
||||||
@@ -636,7 +674,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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -651,6 +693,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</code> method). If this
|
|
||||||
@@ -668,7 +713,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);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
@@ -1276,9 +1328,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);
|
|
||||||
}
|
|
||||||
@@ -1291,8 +1355,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 17739cdc7..a5d7d2d75 100644
|
|
||||||
--- a/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
|
||||||
+++ b/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
|
||||||
@@ -270,6 +270,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
|
|
||||||
+ */
|
|
||||||
+ public 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.
|
|
||||||
@@ -560,6 +594,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.
|
|
||||||
*/
|
|
||||||
@@ -746,6 +789,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/java/io/ObjectStreamConstants.java b/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
|
||||||
index 43a480ce4..96157782a 100644
|
|
||||||
--- a/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
|
||||||
+++ b/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
|
||||||
@@ -38,6 +38,11 @@ public interface ObjectStreamConstants {
|
|
||||||
*/
|
|
||||||
static final short STREAM_MAGIC = (short)0xaced;
|
|
||||||
|
|
||||||
+ /**
|
|
||||||
+ * Magic number that is written to the stream header when using fastserilizer.
|
|
||||||
+ */
|
|
||||||
+ static final short STREAM_MAGIC_FAST = (short)0xdeca;
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* Version number that is written to the stream header.
|
|
||||||
*/
|
|
||||||
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 031b5aae5..d78caabdc 100644
|
|
||||||
--- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
|
|
||||||
+++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
|
|
||||||
@@ -3703,7 +3703,7 @@ public final class Unsafe {
|
|
||||||
private static long convEndian(boolean big, long n) { return big == BE ? 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);
|
|
||||||
21
fix-compile-error-without-disable-precompiled-headers.patch
Normal file
21
fix-compile-error-without-disable-precompiled-headers.patch
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
diff --git a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp
|
||||||
|
index 6b396c8e3..7eddfd69c 100644
|
||||||
|
--- a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp
|
||||||
|
+++ b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp
|
||||||
|
@@ -25,7 +25,6 @@
|
||||||
|
#ifndef SHARE_VM_GC_G1_G1REGIONTOSPACEMAPPER_HPP
|
||||||
|
#define SHARE_VM_GC_G1_G1REGIONTOSPACEMAPPER_HPP
|
||||||
|
|
||||||
|
-#include "gc/g1/g1NUMA.hpp"
|
||||||
|
#include "gc/g1/g1PageBasedVirtualSpace.hpp"
|
||||||
|
#include "memory/allocation.hpp"
|
||||||
|
#include "utilities/debug.hpp"
|
||||||
|
@@ -73,7 +72,7 @@ class G1RegionToSpaceMapper : public CHeapObj<mtGC> {
|
||||||
|
return _commit_map.at(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
- virtual void commit_regions(uint start_idx, size_t num_regions = 1, WorkGang* pretouch_workers = NULL, uint node = G1NUMA::AnyNodeIndex) = 0;
|
||||||
|
+ virtual void commit_regions(uint start_idx, size_t num_regions = 1, WorkGang* pretouch_workers = NULL, uint node = UINT_MAX - 1) = 0;
|
||||||
|
virtual void uncommit_regions(uint start_idx, size_t num_regions = 1) = 0;
|
||||||
|
|
||||||
|
// Creates an appropriate G1RegionToSpaceMapper for the given parameters.
|
||||||
@ -1,88 +0,0 @@
|
|||||||
From cd63946e80ceb3f9de8a1ee02b38548c06cf532a Mon Sep 17 00:00:00 2001
|
|
||||||
Date: Thu, 23 Jul 2020 16:40:31 +0800
|
|
||||||
Subject: [PATCH] fix jck failure on FastSerializer
|
|
||||||
|
|
||||||
Summary: <core-libs>: <fix jck failure on FastSerializer>
|
|
||||||
LLT: jck
|
|
||||||
Bug url: NA
|
|
||||||
---
|
|
||||||
src/java.base/share/classes/java/io/ObjectInputStream.java | 7 ++++++-
|
|
||||||
src/java.base/share/classes/java/io/ObjectOutputStream.java | 5 +++++
|
|
||||||
src/java.base/share/classes/java/io/ObjectStreamClass.java | 2 +-
|
|
||||||
src/java.base/share/classes/java/io/ObjectStreamConstants.java | 5 -----
|
|
||||||
4 files changed, 12 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java
|
|
||||||
index d71d44a..a48e50c 100644
|
|
||||||
--- a/src/java.base/share/classes/java/io/ObjectInputStream.java
|
|
||||||
+++ b/src/java.base/share/classes/java/io/ObjectInputStream.java
|
|
||||||
@@ -381,6 +381,11 @@ public class ObjectInputStream
|
|
||||||
"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 ObjectInputStream that reads from the specified InputStream.
|
|
||||||
* A serialization stream header is read from the stream and verified.
|
|
||||||
* This constructor will block until the corresponding ObjectOutputStream
|
|
||||||
@@ -752,7 +757,7 @@ public class ObjectInputStream
|
|
||||||
* Cache the class meta during serialization.
|
|
||||||
* Only used in FastSerilizer.
|
|
||||||
*/
|
|
||||||
- protected static ConcurrentHashMap<String,Class<?>> nameToClass = new ConcurrentHashMap<>();
|
|
||||||
+ private static ConcurrentHashMap<String,Class<?>> nameToClass = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the local class equivalent of the specified stream class
|
|
||||||
diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
|
||||||
index 8935e61..0e54763 100644
|
|
||||||
--- a/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
|
||||||
+++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
|
||||||
@@ -251,6 +251,11 @@ public class ObjectOutputStream
|
|
||||||
"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
|
|
||||||
* underlying stream; callers may wish to flush the stream immediately to
|
|
||||||
diff --git a/src/java.base/share/classes/java/io/ObjectStreamClass.java b/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
|
||||||
index a5d7d2d..e37a784 100644
|
|
||||||
--- a/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
|
||||||
+++ b/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
|
||||||
@@ -280,7 +280,7 @@ public class ObjectStreamClass implements Serializable {
|
|
||||||
*
|
|
||||||
* @return the flags for this class described by this descriptor
|
|
||||||
*/
|
|
||||||
- public byte getFlags(Object serialStream) {
|
|
||||||
+ byte getFlags(Object serialStream) {
|
|
||||||
byte flags = 0;
|
|
||||||
if (externalizable) {
|
|
||||||
flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
|
|
||||||
diff --git a/src/java.base/share/classes/java/io/ObjectStreamConstants.java b/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
|
||||||
index 9615778..43a480c 100644
|
|
||||||
--- a/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
|
||||||
+++ b/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
|
||||||
@@ -39,11 +39,6 @@ public interface ObjectStreamConstants {
|
|
||||||
static final short STREAM_MAGIC = (short)0xaced;
|
|
||||||
|
|
||||||
/**
|
|
||||||
- * Magic number that is written to the stream header when using fastserilizer.
|
|
||||||
- */
|
|
||||||
- static final short STREAM_MAGIC_FAST = (short)0xdeca;
|
|
||||||
-
|
|
||||||
- /**
|
|
||||||
* Version number that is written to the stream header.
|
|
||||||
*/
|
|
||||||
static final short STREAM_VERSION = 5;
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
|
|
||||||
@ -735,7 +735,7 @@ Provides: java-src%{?1} = %{epoch}:%{version}-%{release}
|
|||||||
|
|
||||||
Name: java-%{javaver}-%{origin}
|
Name: java-%{javaver}-%{origin}
|
||||||
Version: %{newjavaver}.%{buildver}
|
Version: %{newjavaver}.%{buildver}
|
||||||
Release: 3
|
Release: 4
|
||||||
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
|
# 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
|
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
|
||||||
# also included the epoch in their virtual provides. This created a
|
# also included the epoch in their virtual provides. This created a
|
||||||
@ -815,10 +815,15 @@ Patch26: ZGC-aarch64-fix-system-call-number-of-memfd_create.patch
|
|||||||
Patch27: ZGC-aarch64-fix-not-using-load-store-Pre-index.patch
|
Patch27: ZGC-aarch64-fix-not-using-load-store-Pre-index.patch
|
||||||
Patch28: address-s-offset-may-exceed-the-limit-of-ldrw-instru.patch
|
Patch28: address-s-offset-may-exceed-the-limit-of-ldrw-instru.patch
|
||||||
Patch29: ZGC-reuse-entries-of-ResolvedMethodTable.patch
|
Patch29: ZGC-reuse-entries-of-ResolvedMethodTable.patch
|
||||||
Patch30: fast-serializer-jdk11.patch
|
|
||||||
Patch31: fix-jck-failure-on-FastSerializer.patch
|
|
||||||
Patch32: 8240360-NativeLibraryEvent-has-wrong-library-name-on-linux.patch
|
Patch32: 8240360-NativeLibraryEvent-has-wrong-library-name-on-linux.patch
|
||||||
|
|
||||||
|
# 11.0.8
|
||||||
|
Patch33: 8210473-JEP-345-NUMA-Aware-Memory-Allocation-for-G1.patch
|
||||||
|
Patch34: 8210461-AArch64-Math.cos-intrinsic-gives-incorrect-results.patch
|
||||||
|
Patch35: NUMA-Aware-Implementation-humongous-region.patch
|
||||||
|
Patch36: ZGC-in-c1-load-barrier-d0-and-d1-registers-miss-restoring.patch
|
||||||
|
Patch37: fix-compile-error-without-disable-precompiled-headers.patch
|
||||||
|
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
BuildRequires: alsa-lib-devel
|
BuildRequires: alsa-lib-devel
|
||||||
BuildRequires: binutils
|
BuildRequires: binutils
|
||||||
@ -1066,9 +1071,12 @@ pushd %{top_level_dir_name}
|
|||||||
%patch27 -p1
|
%patch27 -p1
|
||||||
%patch28 -p1
|
%patch28 -p1
|
||||||
%patch29 -p1
|
%patch29 -p1
|
||||||
%patch30 -p1
|
|
||||||
%patch31 -p1
|
|
||||||
%patch32 -p1
|
%patch32 -p1
|
||||||
|
%patch33 -p1
|
||||||
|
%patch34 -p1
|
||||||
|
%patch35 -p1
|
||||||
|
%patch36 -p1
|
||||||
|
%patch37 -p1
|
||||||
popd # openjdk
|
popd # openjdk
|
||||||
|
|
||||||
%patch1000
|
%patch1000
|
||||||
@ -1571,6 +1579,15 @@ require "copy_jdk_configs.lua"
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Aug 31 2020 jdkboy <guoge1@huawei.com> - 1:11.0.8.10-4
|
||||||
|
- Add 8210473-JEP-345-NUMA-Aware-Memory-Allocation-for-G1.patch
|
||||||
|
- Add 8210461-AArch64-Math.cos-intrinsic-gives-incorrect-results.patch
|
||||||
|
- Add NUMA-Aware-Implementation-humongous-region.patch
|
||||||
|
- Add ZGC-in-c1-load-barrier-d0-and-d1-registers-miss-restoring.patch
|
||||||
|
- Add fix-compile-error-without-disable-precompiled-headers.patch
|
||||||
|
- Remove fast-serializer-jdk11.patch
|
||||||
|
- Remove fix-jck-failure-on-FastSerializer.patch
|
||||||
|
|
||||||
* Tue Aug 25 2020 noah <hedongbo@huawei.com> - 1:11.0.8.10-3
|
* Tue Aug 25 2020 noah <hedongbo@huawei.com> - 1:11.0.8.10-3
|
||||||
- add fix-jck-failure-on-FastSerializer.patch
|
- add fix-jck-failure-on-FastSerializer.patch
|
||||||
- add 8240360-NativeLibraryEvent-has-wrong-library-name-on-linux.patch
|
- add 8240360-NativeLibraryEvent-has-wrong-library-name-on-linux.patch
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user