Update to aarch64-shenandoah-jdk8u-8u262-b10
- add 8144993-Elide-redundant-memory-barrier-after-AllocationNode.patch - add 8223504-improve-performance-of-forall-loops-by-better.patch - add add-vm-option-BoxTypeCachedMax-for-Integer-and-Long-cache.patch - add 8080289-8040213-8189067-move-the-store-out-of-the-loop.patch - add fast-serializer-jdk8.patch - add 8182397-race-in-field-updates.patch - add --with-company-name="Boole" - remove fix-incorrect-offset-for-oop-field-with-weak-memory-.patch
This commit is contained in:
parent
d163614241
commit
28a397092a
687
8080289-8040213-8189067-move-the-store-out-of-the-loop.patch
Normal file
687
8080289-8040213-8189067-move-the-store-out-of-the-loop.patch
Normal file
@ -0,0 +1,687 @@
|
||||
From c2d7c271a60a6892bbbf7a2d585aa5b50c85bef1 Mon Sep 17 00:00:00 2001
|
||||
From: sunjianye <sunjianye@huawei.com>
|
||||
Date: Sat, 23 May 2020 17:40:00 +0800
|
||||
Subject: [PATCH] 8080289 8040213 8189067: move the store out of the loop
|
||||
|
||||
DTS/AR: AR.SR.IREQ02373832.002.001
|
||||
Summary: <superWord> : move the store out of the loop
|
||||
LLT: NA
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8080289 https://bugs.openjdk.java.net/browse/JDK-8040213 https://bugs.openjdk.java.net/browse/JDK-8189067
|
||||
---
|
||||
hotspot/src/share/vm/opto/loopnode.cpp | 2 +-
|
||||
hotspot/src/share/vm/opto/loopnode.hpp | 4 +-
|
||||
hotspot/src/share/vm/opto/loopopts.cpp | 191 +++++++++++
|
||||
hotspot/src/share/vm/opto/memnode.cpp | 58 ++--
|
||||
hotspot/src/share/vm/opto/phaseX.hpp | 9 +-
|
||||
.../loopopts/TestMoveStoresOutOfLoops.java | 310 ++++++++++++++++++
|
||||
6 files changed, 545 insertions(+), 29 deletions(-)
|
||||
create mode 100644 hotspot/test/compiler/loopopts/TestMoveStoresOutOfLoops.java
|
||||
|
||||
diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp
|
||||
index 0a44d7ede..7ab9bf893 100644
|
||||
--- a/hotspot/src/share/vm/opto/loopnode.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/loopnode.cpp
|
||||
@@ -1192,7 +1192,7 @@ void CountedLoopEndNode::dump_spec(outputStream *st) const {
|
||||
//=============================================================================
|
||||
//------------------------------is_member--------------------------------------
|
||||
// Is 'l' a member of 'this'?
|
||||
-int IdealLoopTree::is_member( const IdealLoopTree *l ) const {
|
||||
+bool IdealLoopTree::is_member(const IdealLoopTree *l) const {
|
||||
while( l->_nest > _nest ) l = l->_parent;
|
||||
return l == this;
|
||||
}
|
||||
diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp
|
||||
index 558b10504..21995dda6 100644
|
||||
--- a/hotspot/src/share/vm/opto/loopnode.hpp
|
||||
+++ b/hotspot/src/share/vm/opto/loopnode.hpp
|
||||
@@ -371,7 +371,7 @@ public:
|
||||
{ }
|
||||
|
||||
// Is 'l' a member of 'this'?
|
||||
- int is_member( const IdealLoopTree *l ) const; // Test for nested membership
|
||||
+ bool is_member(const IdealLoopTree *l) const; // Test for nested membership
|
||||
|
||||
// Set loop nesting depth. Accumulate has_call bits.
|
||||
int set_nest( uint depth );
|
||||
@@ -1075,6 +1075,8 @@ private:
|
||||
bool split_up( Node *n, Node *blk1, Node *blk2 );
|
||||
void sink_use( Node *use, Node *post_loop );
|
||||
Node *place_near_use( Node *useblock ) const;
|
||||
+ Node* try_move_store_before_loop(Node* n, Node *n_ctrl);
|
||||
+ void try_move_store_after_loop(Node* n);
|
||||
|
||||
bool _created_loop_node;
|
||||
public:
|
||||
diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp
|
||||
index 62273d86d..ec244e363 100644
|
||||
--- a/hotspot/src/share/vm/opto/loopopts.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/loopopts.cpp
|
||||
@@ -673,6 +673,190 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) {
|
||||
return iff->in(1);
|
||||
}
|
||||
|
||||
+#ifdef ASSERT
|
||||
+static void enqueue_cfg_uses(Node* m, Unique_Node_List& wq) {
|
||||
+ for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) {
|
||||
+ Node* u = m->fast_out(i);
|
||||
+ if (u->is_CFG()) {
|
||||
+ if (u->Opcode() == Op_NeverBranch) {
|
||||
+ u = ((NeverBranchNode*)u)->proj_out(0);
|
||||
+ enqueue_cfg_uses(u, wq);
|
||||
+ } else {
|
||||
+ wq.push(u);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+// Try moving a store out of a loop, right before the loop
|
||||
+Node* PhaseIdealLoop::try_move_store_before_loop(Node* n, Node *n_ctrl) {
|
||||
+ // Store has to be first in the loop body
|
||||
+ IdealLoopTree *n_loop = get_loop(n_ctrl);
|
||||
+ if (n->is_Store() && n_loop != _ltree_root && n_loop->is_loop()) {
|
||||
+ assert(n->in(0), "store should have control set");
|
||||
+ Node* address = n->in(MemNode::Address);
|
||||
+ Node* value = n->in(MemNode::ValueIn);
|
||||
+ Node* mem = n->in(MemNode::Memory);
|
||||
+ IdealLoopTree* address_loop = get_loop(get_ctrl(address));
|
||||
+ IdealLoopTree* value_loop = get_loop(get_ctrl(value));
|
||||
+
|
||||
+ // - address and value must be loop invariant
|
||||
+ // - memory must be a memory Phi for the loop
|
||||
+ // - Store must be the only store on this memory slice in the
|
||||
+ // loop: if there's another store following this one then value
|
||||
+ // written at iteration i by the second store could be overwritten
|
||||
+ // at iteration i+n by the first store: it's not safe to move the
|
||||
+ // first store out of the loop
|
||||
+ // - nothing must observe the Phi memory: it guarantees no read
|
||||
+ // before the store and no early exit out of the loop
|
||||
+ // With those conditions, we are also guaranteed the store post
|
||||
+ // dominates the loop head. Otherwise there would be extra Phi
|
||||
+ // involved between the loop's Phi and the store.
|
||||
+
|
||||
+ if (!n_loop->is_member(address_loop) &&
|
||||
+ !n_loop->is_member(value_loop) &&
|
||||
+ mem->is_Phi() && mem->in(0) == n_loop->_head &&
|
||||
+ mem->outcnt() == 1 &&
|
||||
+ mem->in(LoopNode::LoopBackControl) == n) {
|
||||
+
|
||||
+#ifdef ASSERT
|
||||
+ // Verify that store's control does post dominate loop entry and
|
||||
+ // that there's no early exit of the loop before the store.
|
||||
+ bool ctrl_ok = false;
|
||||
+ {
|
||||
+ // Follow control from loop head until n, we exit the loop or
|
||||
+ // we reach the tail
|
||||
+ ResourceMark rm;
|
||||
+ Unique_Node_List wq;
|
||||
+ wq.push(n_loop->_head);
|
||||
+ assert(n_loop->_tail != NULL, "need a tail");
|
||||
+ for (uint next = 0; next < wq.size(); ++next) {
|
||||
+ Node *m = wq.at(next);
|
||||
+ if (m == n->in(0)) {
|
||||
+ ctrl_ok = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ assert(!has_ctrl(m), "should be CFG");
|
||||
+ if (!n_loop->is_member(get_loop(m)) || m == n_loop->_tail) {
|
||||
+ ctrl_ok = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ enqueue_cfg_uses(m, wq);
|
||||
+ }
|
||||
+ }
|
||||
+ assert(ctrl_ok, "bad control");
|
||||
+#endif
|
||||
+
|
||||
+ // move the Store
|
||||
+ _igvn.replace_input_of(mem, LoopNode::LoopBackControl, mem);
|
||||
+ _igvn.replace_input_of(n, 0, n_loop->_head->in(LoopNode::EntryControl));
|
||||
+ _igvn.replace_input_of(n, MemNode::Memory, mem->in(LoopNode::EntryControl));
|
||||
+ // Disconnect the phi now. An empty phi can confuse other
|
||||
+ // optimizations in this pass of loop opts.
|
||||
+ _igvn.replace_node(mem, mem->in(LoopNode::EntryControl));
|
||||
+ n_loop->_body.yank(mem);
|
||||
+
|
||||
+ IdealLoopTree* new_loop = get_loop(n->in(0));
|
||||
+ set_ctrl_and_loop(n, n->in(0));
|
||||
+
|
||||
+ return n;
|
||||
+ }
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+// Try moving a store out of a loop, right after the loop
|
||||
+void PhaseIdealLoop::try_move_store_after_loop(Node* n) {
|
||||
+ if (n->is_Store()) {
|
||||
+ assert(n->in(0), "store should have control set");
|
||||
+ Node *n_ctrl = get_ctrl(n);
|
||||
+ IdealLoopTree *n_loop = get_loop(n_ctrl);
|
||||
+ // Store must be in a loop
|
||||
+ if (n_loop != _ltree_root && !n_loop->_irreducible) {
|
||||
+ Node* address = n->in(MemNode::Address);
|
||||
+ Node* value = n->in(MemNode::ValueIn);
|
||||
+ IdealLoopTree* address_loop = get_loop(get_ctrl(address));
|
||||
+ // address must be loop invariant
|
||||
+ if (!n_loop->is_member(address_loop)) {
|
||||
+ // Store must be last on this memory slice in the loop and
|
||||
+ // nothing in the loop must observe it
|
||||
+ Node* phi = NULL;
|
||||
+ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
|
||||
+ Node* u = n->fast_out(i);
|
||||
+ if (has_ctrl(u)) { // control use?
|
||||
+ IdealLoopTree *u_loop = get_loop(get_ctrl(u));
|
||||
+ if (!n_loop->is_member(u_loop)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (u->is_Phi() && u->in(0) == n_loop->_head) {
|
||||
+ assert(_igvn.type(u) == Type::MEMORY, "bad phi");
|
||||
+ assert(phi == NULL, "already found");
|
||||
+ phi = u;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ phi = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (phi != NULL) {
|
||||
+ // Nothing in the loop before the store (next iteration)
|
||||
+ // must observe the stored value
|
||||
+ bool mem_ok = true;
|
||||
+ {
|
||||
+ ResourceMark rm;
|
||||
+ Unique_Node_List wq;
|
||||
+ wq.push(phi);
|
||||
+ for (uint next = 0; next < wq.size() && mem_ok; ++next) {
|
||||
+ Node *m = wq.at(next);
|
||||
+ for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax && mem_ok; i++) {
|
||||
+ Node* u = m->fast_out(i);
|
||||
+ if (u->is_Store() || u->is_Phi()) {
|
||||
+ if (u != n) {
|
||||
+ wq.push(u);
|
||||
+ mem_ok = (wq.size() <= 10);
|
||||
+ }
|
||||
+ } else {
|
||||
+ mem_ok = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (mem_ok) {
|
||||
+ // Move the store out of the loop if the LCA of all
|
||||
+ // users (except for the phi) is outside the loop.
|
||||
+ Node* hook = new (C) Node(1);
|
||||
+ _igvn.rehash_node_delayed(phi);
|
||||
+ int count = phi->replace_edge(n, hook);
|
||||
+ assert(count > 0, "inconsistent phi");
|
||||
+
|
||||
+ // Compute latest point this store can go
|
||||
+ Node* lca = get_late_ctrl(n, get_ctrl(n));
|
||||
+ if (n_loop->is_member(get_loop(lca))) {
|
||||
+ // LCA is in the loop - bail out
|
||||
+ _igvn.replace_node(hook, n);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Move store out of the loop
|
||||
+ _igvn.replace_node(hook, n->in(MemNode::Memory));
|
||||
+ _igvn.replace_input_of(n, 0, lca);
|
||||
+ set_ctrl_and_loop(n, lca);
|
||||
+
|
||||
+ // Disconnect the phi now. An empty phi can confuse other
|
||||
+ // optimizations in this pass of loop opts..
|
||||
+ if (phi->in(LoopNode::LoopBackControl) == phi) {
|
||||
+ _igvn.replace_node(phi, phi->in(LoopNode::EntryControl));
|
||||
+ n_loop->_body.yank(phi);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
//------------------------------split_if_with_blocks_pre-----------------------
|
||||
// Do the real work in a non-recursive function. Data nodes want to be
|
||||
// cloned in the pre-order so they can feed each other nicely.
|
||||
@@ -703,6 +887,11 @@ Node *PhaseIdealLoop::split_if_with_blocks_pre( Node *n ) {
|
||||
Node *n_ctrl = get_ctrl(n);
|
||||
if( !n_ctrl ) return n; // Dead node
|
||||
|
||||
+ Node* res = try_move_store_before_loop(n, n_ctrl);
|
||||
+ if (res != NULL) {
|
||||
+ return n;
|
||||
+ }
|
||||
+
|
||||
// Attempt to remix address expressions for loop invariants
|
||||
Node *m = remix_address_expressions( n );
|
||||
if( m ) return m;
|
||||
@@ -1057,6 +1246,8 @@ void PhaseIdealLoop::split_if_with_blocks_post( Node *n ) {
|
||||
}
|
||||
}
|
||||
|
||||
+ try_move_store_after_loop(n);
|
||||
+
|
||||
// Check for Opaque2's who's loop has disappeared - who's input is in the
|
||||
// same loop nest as their output. Remove 'em, they are no longer useful.
|
||||
if( n_op == Op_Opaque2 &&
|
||||
diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp
|
||||
index 3ecbe1ce0..1bab75927 100644
|
||||
--- a/hotspot/src/share/vm/opto/memnode.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/memnode.cpp
|
||||
@@ -2313,33 +2313,39 @@ Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// unsafe if I have intervening uses... Also disallowed for StoreCM
|
||||
// since they must follow each StoreP operation. Redundant StoreCMs
|
||||
// are eliminated just before matching in final_graph_reshape.
|
||||
- if (mem->is_Store() && mem->in(MemNode::Address)->eqv_uncast(address) &&
|
||||
- mem->Opcode() != Op_StoreCM) {
|
||||
- // Looking at a dead closed cycle of memory?
|
||||
- assert(mem != mem->in(MemNode::Memory), "dead loop in StoreNode::Ideal");
|
||||
-
|
||||
- assert(Opcode() == mem->Opcode() ||
|
||||
- phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw ||
|
||||
- (is_mismatched_access() || mem->as_Store()->is_mismatched_access()),
|
||||
- "no mismatched stores, except on raw memory");
|
||||
-
|
||||
- if (mem->outcnt() == 1 && // check for intervening uses
|
||||
- mem->as_Store()->memory_size() <= this->memory_size()) {
|
||||
- // If anybody other than 'this' uses 'mem', we cannot fold 'mem' away.
|
||||
- // For example, 'mem' might be the final state at a conditional return.
|
||||
- // Or, 'mem' might be used by some node which is live at the same time
|
||||
- // 'this' is live, which might be unschedulable. So, require exactly
|
||||
- // ONE user, the 'this' store, until such time as we clone 'mem' for
|
||||
- // each of 'mem's uses (thus making the exactly-1-user-rule hold true).
|
||||
- if (can_reshape) { // (%%% is this an anachronism?)
|
||||
- set_req_X(MemNode::Memory, mem->in(MemNode::Memory),
|
||||
- phase->is_IterGVN());
|
||||
- } else {
|
||||
- // It's OK to do this in the parser, since DU info is always accurate,
|
||||
- // and the parser always refers to nodes via SafePointNode maps.
|
||||
- set_req(MemNode::Memory, mem->in(MemNode::Memory));
|
||||
+ {
|
||||
+ Node* st = mem;
|
||||
+ // If Store 'st' has more than one use, we cannot fold 'st' away.
|
||||
+ // For example, 'st' might be the final state at a conditional
|
||||
+ // return. Or, 'st' might be used by some node which is live at
|
||||
+ // the same time 'st' is live, which might be unschedulable. So,
|
||||
+ // require exactly ONE user until such time as we clone 'mem' for
|
||||
+ // each of 'mem's uses (thus making the exactly-1-user-rule hold
|
||||
+ // true).
|
||||
+ while (st->is_Store() && st->outcnt() == 1 && st->Opcode() != Op_StoreCM) {
|
||||
+ // Looking at a dead closed cycle of memory?
|
||||
+ assert(st != st->in(MemNode::Memory), "dead loop in StoreNode::Ideal");
|
||||
+ assert(Opcode() == st->Opcode() ||
|
||||
+ st->Opcode() == Op_StoreVector ||
|
||||
+ Opcode() == Op_StoreVector ||
|
||||
+ phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw ||
|
||||
+ (Opcode() == Op_StoreL && st->Opcode() == Op_StoreI), // expanded ClearArrayNode
|
||||
+ err_msg_res("no mismatched stores, except on raw memory: %s %s", NodeClassNames[Opcode()], NodeClassNames[st->Opcode()]));
|
||||
+
|
||||
+ if (st->in(MemNode::Address)->eqv_uncast(address) &&
|
||||
+ st->as_Store()->memory_size() <= this->memory_size()) {
|
||||
+ Node* use = st->raw_out(0);
|
||||
+ phase->igvn_rehash_node_delayed(use);
|
||||
+ if (can_reshape) {
|
||||
+ use->set_req_X(MemNode::Memory, st->in(MemNode::Memory), phase->is_IterGVN());
|
||||
+ } else {
|
||||
+ // It's OK to do this in the parser, since DU info is always accurate,
|
||||
+ // and the parser always refers to nodes via SafePointNode maps.
|
||||
+ use->set_req(MemNode::Memory, st->in(MemNode::Memory));
|
||||
+ }
|
||||
+ return this;
|
||||
}
|
||||
- return this;
|
||||
+ st = st->in(MemNode::Memory);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/hotspot/src/share/vm/opto/phaseX.hpp b/hotspot/src/share/vm/opto/phaseX.hpp
|
||||
index 332b1175d..852a1c295 100644
|
||||
--- a/hotspot/src/share/vm/opto/phaseX.hpp
|
||||
+++ b/hotspot/src/share/vm/opto/phaseX.hpp
|
||||
@@ -327,6 +327,9 @@ public:
|
||||
const Type* limit_type) const
|
||||
{ ShouldNotCallThis(); return NULL; }
|
||||
|
||||
+ // Delayed node rehash if this is an IGVN phase
|
||||
+ virtual void igvn_rehash_node_delayed(Node* n) {}
|
||||
+
|
||||
virtual PhaseIterGVN *is_IterGVN() { return 0; }
|
||||
|
||||
#ifndef PRODUCT
|
||||
@@ -495,7 +498,11 @@ public:
|
||||
_worklist.push(n);
|
||||
}
|
||||
|
||||
- // Replace ith edge of "n" with "in"
|
||||
+ void igvn_rehash_node_delayed(Node* n) {
|
||||
+ rehash_node_delayed(n);
|
||||
+ }
|
||||
+
|
||||
+ // Replace ith edge of "n" with "in"
|
||||
void replace_input_of(Node* n, int i, Node* in) {
|
||||
rehash_node_delayed(n);
|
||||
n->set_req(i, in);
|
||||
diff --git a/hotspot/test/compiler/loopopts/TestMoveStoresOutOfLoops.java b/hotspot/test/compiler/loopopts/TestMoveStoresOutOfLoops.java
|
||||
new file mode 100644
|
||||
index 000000000..4eea5d5e4
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/compiler/loopopts/TestMoveStoresOutOfLoops.java
|
||||
@@ -0,0 +1,310 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
+ *
|
||||
+ * This code is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/**
|
||||
+ * @test
|
||||
+ * @bug 8080289
|
||||
+ * @summary Sink stores out of loops if possible
|
||||
+ * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:+PrintCompilation -XX:CompileCommand=dontinline,TestMoveStoresOutOfLoops::test* TestMoveStoresOutOfLoops
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+import java.lang.reflect.*;
|
||||
+import java.util.*;
|
||||
+import java.util.function.*;
|
||||
+
|
||||
+public class TestMoveStoresOutOfLoops {
|
||||
+
|
||||
+ private static long[] array = new long[10];
|
||||
+ private static long[] array2 = new long[10];
|
||||
+ private static boolean[] array3 = new boolean[1000];
|
||||
+ private static byte[] byte_array = new byte[10];
|
||||
+
|
||||
+ // Array store should be moved out of the loop, value stored
|
||||
+ // should be 999, the loop should be eliminated
|
||||
+ static void test_after_1(int idx) {
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ array[idx] = i;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Array store can't be moved out of loop because of following
|
||||
+ // non loop invariant array access
|
||||
+ static void test_after_2(int idx) {
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ array[idx] = i;
|
||||
+ array2[i%10] = i;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Array store can't be moved out of loop because of following
|
||||
+ // use
|
||||
+ static void test_after_3(int idx) {
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ array[idx] = i;
|
||||
+ if (array[0] == -1) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Array store can't be moved out of loop because of preceding
|
||||
+ // use
|
||||
+ static void test_after_4(int idx) {
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ if (array[0] == -2) {
|
||||
+ break;
|
||||
+ }
|
||||
+ array[idx] = i;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // All array stores should be moved out of the loop, one after
|
||||
+ // the other
|
||||
+ static void test_after_5(int idx) {
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ array[idx] = i;
|
||||
+ array[idx+1] = i;
|
||||
+ array[idx+2] = i;
|
||||
+ array[idx+3] = i;
|
||||
+ array[idx+4] = i;
|
||||
+ array[idx+5] = i;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Array store can be moved after the loop but needs to be
|
||||
+ // cloned on both exit paths
|
||||
+ static void test_after_6(int idx) {
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ array[idx] = i;
|
||||
+ if (array3[i]) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Optimize out redundant stores
|
||||
+ static void test_stores_1(int ignored) {
|
||||
+ array[0] = 0;
|
||||
+ array[1] = 1;
|
||||
+ array[2] = 2;
|
||||
+ array[0] = 0;
|
||||
+ array[1] = 1;
|
||||
+ array[2] = 2;
|
||||
+ }
|
||||
+
|
||||
+ static void test_stores_2(int idx) {
|
||||
+ array[idx+0] = 0;
|
||||
+ array[idx+1] = 1;
|
||||
+ array[idx+2] = 2;
|
||||
+ array[idx+0] = 0;
|
||||
+ array[idx+1] = 1;
|
||||
+ array[idx+2] = 2;
|
||||
+ }
|
||||
+
|
||||
+ static void test_stores_3(int idx) {
|
||||
+ byte_array[idx+0] = 0;
|
||||
+ byte_array[idx+1] = 1;
|
||||
+ byte_array[idx+2] = 2;
|
||||
+ byte_array[idx+0] = 0;
|
||||
+ byte_array[idx+1] = 1;
|
||||
+ byte_array[idx+2] = 2;
|
||||
+ }
|
||||
+
|
||||
+ // Array store can be moved out of the loop before the loop header
|
||||
+ static void test_before_1(int idx) {
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ array[idx] = 999;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Array store can't be moved out of the loop before the loop
|
||||
+ // header because there's more than one store on this slice
|
||||
+ static void test_before_2(int idx) {
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ array[idx] = 999;
|
||||
+ array[i%2] = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Array store can't be moved out of the loop before the loop
|
||||
+ // header because of use before store
|
||||
+ static int test_before_3(int idx) {
|
||||
+ int res = 0;
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ res += array[i%10];
|
||||
+ array[idx] = 999;
|
||||
+ }
|
||||
+ return res;
|
||||
+ }
|
||||
+
|
||||
+ // Array store can't be moved out of the loop before the loop
|
||||
+ // header because of possible early exit
|
||||
+ static void test_before_4(int idx) {
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ if (idx / (i+1) > 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+ array[idx] = 999;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Array store can't be moved out of the loop before the loop
|
||||
+ // header because it doesn't postdominate the loop head
|
||||
+ static void test_before_5(int idx) {
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ if (i % 2 == 0) {
|
||||
+ array[idx] = 999;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Array store can be moved out of the loop before the loop header
|
||||
+ static int test_before_6(int idx) {
|
||||
+ int res = 0;
|
||||
+ for (int i = 0; i < 1000; i++) {
|
||||
+ if (i%2 == 1) {
|
||||
+ res *= 2;
|
||||
+ } else {
|
||||
+ res++;
|
||||
+ }
|
||||
+ array[idx] = 999;
|
||||
+ }
|
||||
+ return res;
|
||||
+ }
|
||||
+
|
||||
+ final HashMap<String,Method> tests = new HashMap<>();
|
||||
+ {
|
||||
+ for (Method m : this.getClass().getDeclaredMethods()) {
|
||||
+ if (m.getName().matches("test_(before|after|stores)_[0-9]+")) {
|
||||
+ assert(Modifier.isStatic(m.getModifiers())) : m;
|
||||
+ tests.put(m.getName(), m);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ boolean success = true;
|
||||
+ void doTest(String name, Runnable init, Function<String, Boolean> check) throws Exception {
|
||||
+ Method m = tests.get(name);
|
||||
+ for (int i = 0; i < 20000; i++) {
|
||||
+ init.run();
|
||||
+ m.invoke(null, 0);
|
||||
+ success = success && check.apply(name);
|
||||
+ if (!success) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static void array_init() {
|
||||
+ array[0] = -1;
|
||||
+ }
|
||||
+
|
||||
+ static boolean array_check(String name) {
|
||||
+ boolean success = true;
|
||||
+ if (array[0] != 999) {
|
||||
+ success = false;
|
||||
+ System.out.println(name + " failed: array[0] = " + array[0]);
|
||||
+ }
|
||||
+ return success;
|
||||
+ }
|
||||
+
|
||||
+ static void array_init2() {
|
||||
+ for (int i = 0; i < 6; i++) {
|
||||
+ array[i] = -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static boolean array_check2(String name) {
|
||||
+ boolean success = true;
|
||||
+ for (int i = 0; i < 6; i++) {
|
||||
+ if (array[i] != 999) {
|
||||
+ success = false;
|
||||
+ System.out.println(name + " failed: array[" + i + "] = " + array[i]);
|
||||
+ }
|
||||
+ }
|
||||
+ return success;
|
||||
+ }
|
||||
+
|
||||
+ static void array_init3() {
|
||||
+ for (int i = 0; i < 3; i++) {
|
||||
+ array[i] = -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static boolean array_check3(String name) {
|
||||
+ boolean success = true;
|
||||
+ for (int i = 0; i < 3; i++) {
|
||||
+ if (array[i] != i) {
|
||||
+ success = false;
|
||||
+ System.out.println(name + " failed: array[" + i + "] = " + array[i]);
|
||||
+ }
|
||||
+ }
|
||||
+ return success;
|
||||
+ }
|
||||
+
|
||||
+ static void array_init4() {
|
||||
+ for (int i = 0; i < 3; i++) {
|
||||
+ byte_array[i] = -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static boolean array_check4(String name) {
|
||||
+ boolean success = true;
|
||||
+ for (int i = 0; i < 3; i++) {
|
||||
+ if (byte_array[i] != i) {
|
||||
+ success = false;
|
||||
+ System.out.println(name + " failed: byte_array[" + i + "] = " + byte_array[i]);
|
||||
+ }
|
||||
+ }
|
||||
+ return success;
|
||||
+ }
|
||||
+
|
||||
+ static public void main(String[] args) throws Exception {
|
||||
+ TestMoveStoresOutOfLoops test = new TestMoveStoresOutOfLoops();
|
||||
+ test.doTest("test_after_1", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+ test.doTest("test_after_2", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+ test.doTest("test_after_3", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+ test.doTest("test_after_4", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+ test.doTest("test_after_5", TestMoveStoresOutOfLoops::array_init2, TestMoveStoresOutOfLoops::array_check2);
|
||||
+ test.doTest("test_after_6", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+ array3[999] = true;
|
||||
+ test.doTest("test_after_6", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+
|
||||
+ test.doTest("test_stores_1", TestMoveStoresOutOfLoops::array_init3, TestMoveStoresOutOfLoops::array_check3);
|
||||
+ test.doTest("test_stores_2", TestMoveStoresOutOfLoops::array_init3, TestMoveStoresOutOfLoops::array_check3);
|
||||
+ test.doTest("test_stores_3", TestMoveStoresOutOfLoops::array_init4, TestMoveStoresOutOfLoops::array_check4);
|
||||
+
|
||||
+ test.doTest("test_before_1", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+ test.doTest("test_before_2", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+ test.doTest("test_before_3", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+ test.doTest("test_before_4", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+ test.doTest("test_before_5", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+ test.doTest("test_before_6", TestMoveStoresOutOfLoops::array_init, TestMoveStoresOutOfLoops::array_check);
|
||||
+
|
||||
+ if (!test.success) {
|
||||
+ throw new RuntimeException("Some tests failed");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -0,0 +1,258 @@
|
||||
From e938b66397096f88ef40f4fc3522a543f938267d Mon Sep 17 00:00:00 2001
|
||||
From: sunjianye <sunjianye@huawei.com>
|
||||
Date: Sat, 23 May 2020 18:10:45 +0800
|
||||
Subject: [PATCH] 8144993:Elide redundant memory barrier after AllocationNode
|
||||
and JDK:8139758
|
||||
|
||||
DTS/AR: AR.SR.IREQ02373832.002.001
|
||||
Summary: <C2> : Elide redundant memory barrier after AllocationNode
|
||||
LLT: NA
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8144993 https://bugs.openjdk.java.net/browse/JDK-8139758
|
||||
---
|
||||
hotspot/src/share/vm/opto/callnode.cpp | 18 ++++
|
||||
hotspot/src/share/vm/opto/callnode.hpp | 8 ++
|
||||
hotspot/src/share/vm/opto/macro.cpp | 17 ++-
|
||||
hotspot/src/share/vm/opto/parse1.cpp | 8 ++
|
||||
hotspot/src/share/vm/opto/parse3.cpp | 5 +-
|
||||
.../stable/TestStableMemoryBarrier.java | 102 ++++++++++++++++++
|
||||
6 files changed, 151 insertions(+), 7 deletions(-)
|
||||
create mode 100644 hotspot/test/compiler/stable/TestStableMemoryBarrier.java
|
||||
|
||||
diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp
|
||||
index 418f69f60..4ba29841c 100644
|
||||
--- a/hotspot/src/share/vm/opto/callnode.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/callnode.cpp
|
||||
@@ -1293,6 +1293,7 @@ AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype,
|
||||
init_flags(Flag_is_macro);
|
||||
_is_scalar_replaceable = false;
|
||||
_is_non_escaping = false;
|
||||
+ _is_allocation_MemBar_redundant = false;
|
||||
Node *topnode = C->top();
|
||||
|
||||
init_req( TypeFunc::Control , ctrl );
|
||||
@@ -1307,6 +1308,23 @@ AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype,
|
||||
C->add_macro_node(this);
|
||||
}
|
||||
|
||||
+void AllocateNode::compute_MemBar_redundancy(ciMethod* initializer)
|
||||
+{
|
||||
+ assert(initializer != NULL &&
|
||||
+ initializer->is_initializer() &&
|
||||
+ !initializer->is_static(),
|
||||
+ "unexpected initializer method");
|
||||
+ BCEscapeAnalyzer* analyzer = initializer->get_bcea();
|
||||
+ if (analyzer == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Allocation node is first parameter in its initializer
|
||||
+ if (analyzer->is_arg_stack(0) || analyzer->is_arg_local(0)) {
|
||||
+ _is_allocation_MemBar_redundant = true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
//=============================================================================
|
||||
Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
if (remove_dead_region(phase, can_reshape)) return this;
|
||||
diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp
|
||||
index f01bc1ec2..4aa46e492 100644
|
||||
--- a/hotspot/src/share/vm/opto/callnode.hpp
|
||||
+++ b/hotspot/src/share/vm/opto/callnode.hpp
|
||||
@@ -848,6 +848,8 @@ public:
|
||||
// Result of Escape Analysis
|
||||
bool _is_scalar_replaceable;
|
||||
bool _is_non_escaping;
|
||||
+ // True when MemBar for new is redundant with MemBar at initialzer exit
|
||||
+ bool _is_allocation_MemBar_redundant;
|
||||
|
||||
virtual uint size_of() const; // Size is bigger
|
||||
AllocateNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio,
|
||||
@@ -915,6 +917,12 @@ public:
|
||||
return _is_non_escaping || (((init = initialization()) != NULL) && init->does_not_escape());
|
||||
}
|
||||
#endif
|
||||
+ // If object doesn't escape in <.init> method and there is memory barrier
|
||||
+ // inserted at exit of its <.init>, memory barrier for new is not necessary.
|
||||
+ // Inovke this method when MemBar at exit of initializer and post-dominate
|
||||
+ // allocation node.
|
||||
+ void compute_MemBar_redundancy(ciMethod* initializer);
|
||||
+ bool is_allocation_MemBar_redundant() { return _is_allocation_MemBar_redundant; }
|
||||
};
|
||||
|
||||
//------------------------------AllocateArray---------------------------------
|
||||
diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp
|
||||
index 3c13f973f..628ee6656 100644
|
||||
--- a/hotspot/src/share/vm/opto/macro.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/macro.cpp
|
||||
@@ -1402,11 +1402,20 @@ void PhaseMacroExpand::expand_allocate_common(
|
||||
|
||||
// If initialization is performed by an array copy, any required
|
||||
// MemBarStoreStore was already added. If the object does not
|
||||
- // escape no need for a MemBarStoreStore. Otherwise we need a
|
||||
- // MemBarStoreStore so that stores that initialize this object
|
||||
- // can't be reordered with a subsequent store that makes this
|
||||
- // object accessible by other threads.
|
||||
+ // escape no need for a MemBarStoreStore. If the object does not
|
||||
+ // escape in its initializer and memory barrier (MemBarStoreStore or
|
||||
+ // stronger) is already added at exit of initializer, also no need
|
||||
+ // for a MemBarStoreStore. Otherwise we need a MemBarStoreStore
|
||||
+ // so that stores that initialize this object can't be reordered
|
||||
+ // with a subsequent store that makes this object accessible by
|
||||
+ // other threads.
|
||||
+ // Other threads include java threads and JVM internal threads
|
||||
+ // (for example concurrent GC threads). Current concurrent GC
|
||||
+ // implementation: CMS and G1 will not scan newly created object,
|
||||
+ // so it's safe to skip storestore barrier when allocation does
|
||||
+ // not escape.
|
||||
if ( AARCH64_ONLY ( !alloc->does_not_escape_thread() &&
|
||||
+ !alloc->is_allocation_MemBar_redundant() &&
|
||||
(init == NULL ||
|
||||
!init->is_complete_with_arraycopy()) )
|
||||
NOT_AARCH64 ( init == NULL ||
|
||||
diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp
|
||||
index 2d6daa159..da0c6dd68 100644
|
||||
--- a/hotspot/src/share/vm/opto/parse1.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/parse1.cpp
|
||||
@@ -973,6 +973,14 @@ void Parse::do_exits() {
|
||||
// exceptional returns, since they cannot publish normally.
|
||||
//
|
||||
_exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final());
|
||||
+
|
||||
+ // If Memory barrier is created for final fields write
|
||||
+ // and allocation node does not escape the initialize method,
|
||||
+ // then barrier introduced by allocation node can be removed.
|
||||
+ if (DoEscapeAnalysis && alloc_with_final()) {
|
||||
+ AllocateNode *alloc = AllocateNode::Ideal_allocation(alloc_with_final(), &_gvn);
|
||||
+ alloc->compute_MemBar_redundancy(method());
|
||||
+ }
|
||||
#ifndef PRODUCT
|
||||
if (PrintOpto && (Verbose || WizardMode)) {
|
||||
method()->print_name();
|
||||
diff --git a/hotspot/src/share/vm/opto/parse3.cpp b/hotspot/src/share/vm/opto/parse3.cpp
|
||||
index abcfc2a48..0e085275f 100644
|
||||
--- a/hotspot/src/share/vm/opto/parse3.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/parse3.cpp
|
||||
@@ -359,9 +359,8 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) {
|
||||
set_wrote_final(true);
|
||||
// Preserve allocation ptr to create precedent edge to it in membar
|
||||
// generated on exit from constructor.
|
||||
- if (C->eliminate_boxing() &&
|
||||
- adr_type->isa_oopptr() && adr_type->is_oopptr()->is_ptr_to_boxed_value() &&
|
||||
- AllocateNode::Ideal_allocation(obj, &_gvn) != NULL) {
|
||||
+ // Can't bind stable with its allocation, only record allocation for final field.
|
||||
+ if (field->is_final() && AllocateNode::Ideal_allocation(obj, &_gvn) != NULL) {
|
||||
set_alloc_with_final(obj);
|
||||
}
|
||||
}
|
||||
diff --git a/hotspot/test/compiler/stable/TestStableMemoryBarrier.java b/hotspot/test/compiler/stable/TestStableMemoryBarrier.java
|
||||
new file mode 100644
|
||||
index 000000000..c9724f54f
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/compiler/stable/TestStableMemoryBarrier.java
|
||||
@@ -0,0 +1,102 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
+ *
|
||||
+ * This code is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation. Oracle designates this
|
||||
+ * particular file as subject to the "Classpath" exception as provided
|
||||
+ * by Oracle in the LICENSE file that accompanied this code.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * @test TestStableMemoryBarrier
|
||||
+ * @bug 8139758
|
||||
+ * @summary tests memory barrier correctly inserted for stable fields
|
||||
+ * @library /testlibrary /testlibrary/whitebox
|
||||
+ * @build TestStableMemoryBarrier StableConfiguration sun.hotspot.WhiteBox
|
||||
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||
+ * @run main ClassFileInstaller
|
||||
+ * java/lang/invoke/StableConfiguration
|
||||
+ * java/lang/invoke/TestStableMemoryBarrier
|
||||
+ * java/lang/invoke/TestStableMemoryBarrier$NotDominate
|
||||
+ *
|
||||
+ * @run main/othervm -Xbootclasspath/a:.
|
||||
+ * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
|
||||
+ * -XX:-TieredCompilation
|
||||
+ * -XX:+FoldStableValues
|
||||
+ * -XX:CompileOnly=::testCompile
|
||||
+ * java.lang.invoke.TestStableMemoryBarrier
|
||||
+ *
|
||||
+ * @author hui.shi@linaro.org
|
||||
+ */
|
||||
+
|
||||
+package java.lang.invoke;
|
||||
+
|
||||
+import java.lang.reflect.InvocationTargetException;
|
||||
+
|
||||
+public class TestStableMemoryBarrier {
|
||||
+
|
||||
+ public static void main(String[] args) throws Exception {
|
||||
+ run(NotDominate.class);
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ /* ====================================================
|
||||
+ * Stable field initialized in method, but its allocation
|
||||
+ * doesn't dominate MemBar Release at the end of method.
|
||||
+ */
|
||||
+
|
||||
+ static class NotDominate{
|
||||
+ public @Stable int v;
|
||||
+ public static int[] array = new int[100];
|
||||
+ public static NotDominate testCompile(int n) {
|
||||
+ if ((n % 2) == 0) return null;
|
||||
+ // add a loop here, trigger PhaseIdealLoop::verify_dominance
|
||||
+ for (int i = 0; i < 100; i++) {
|
||||
+ array[i] = n;
|
||||
+ }
|
||||
+ NotDominate nm = new NotDominate();
|
||||
+ nm.v = n;
|
||||
+ return nm;
|
||||
+ }
|
||||
+
|
||||
+ public static void test() throws Exception {
|
||||
+ for (int i = 0; i < 1000000; i++)
|
||||
+ testCompile(i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void run(Class<?> test) {
|
||||
+ Throwable ex = null;
|
||||
+ System.out.print(test.getName()+": ");
|
||||
+ try {
|
||||
+ test.getMethod("test").invoke(null);
|
||||
+ } catch (InvocationTargetException e) {
|
||||
+ ex = e.getCause();
|
||||
+ } catch (Throwable e) {
|
||||
+ ex = e;
|
||||
+ } finally {
|
||||
+ if (ex == null) {
|
||||
+ System.out.println("PASSED");
|
||||
+ } else {
|
||||
+ System.out.println("FAILED");
|
||||
+ ex.printStackTrace(System.out);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -15,10 +15,10 @@ Bug url: https://bugs.openjdk.java.net/browse/JDK-8182397
|
||||
create mode 100644 hotspot/test/runtime/CreateMirror/ArraysNewInstanceBug.java
|
||||
|
||||
diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp
|
||||
index cd28c758d0..e010c77cd1 100644
|
||||
index 86cb361c..4db165d4 100644
|
||||
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp
|
||||
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp
|
||||
@@ -573,6 +573,7 @@ void java_lang_Class::initialize_mirror_fields(KlassHandle k,
|
||||
@@ -575,6 +575,7 @@ void java_lang_Class::initialize_mirror_fields(KlassHandle k,
|
||||
|
||||
void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
Handle protection_domain, TRAPS) {
|
||||
@ -26,7 +26,7 @@ index cd28c758d0..e010c77cd1 100644
|
||||
assert(k->java_mirror() == NULL, "should only assign mirror once");
|
||||
// Use this moment of initialization to cache modifier_flags also,
|
||||
// to support Class.getModifiers(). Instance classes recalculate
|
||||
@@ -585,11 +586,10 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
@@ -587,11 +588,10 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
if (SystemDictionary::Class_klass_loaded()) {
|
||||
// Allocate mirror (java.lang.Class instance)
|
||||
Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK);
|
||||
@ -40,7 +40,7 @@ index cd28c758d0..e010c77cd1 100644
|
||||
|
||||
InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
|
||||
assert(oop_size(mirror()) == mk->instance_size(k), "should have been set");
|
||||
@@ -598,21 +598,21 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
@@ -600,21 +600,21 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
|
||||
// It might also have a component mirror. This mirror must already exist.
|
||||
if (k->oop_is_array()) {
|
||||
@ -67,8 +67,8 @@ index cd28c758d0..e010c77cd1 100644
|
||||
} else {
|
||||
assert(k->oop_is_instance(), "Must be");
|
||||
|
||||
@@ -631,10 +631,13 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
assert(oopDesc::equals(class_loader(), k->class_loader()), "should be same");
|
||||
@@ -633,10 +633,13 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
assert(class_loader() == k->class_loader(), "should be same");
|
||||
set_class_loader(mirror(), class_loader());
|
||||
|
||||
- // Setup indirection from klass->mirror last
|
||||
@ -84,7 +84,7 @@ index cd28c758d0..e010c77cd1 100644
|
||||
}
|
||||
} else {
|
||||
if (fixup_mirror_list() == NULL) {
|
||||
@@ -715,7 +718,7 @@ oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, Basic
|
||||
@@ -716,7 +719,7 @@ oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, Basic
|
||||
if (type != T_VOID) {
|
||||
Klass* aklass = Universe::typeArrayKlassObj(type);
|
||||
assert(aklass != NULL, "correct bootstrap");
|
||||
@ -93,7 +93,7 @@ index cd28c758d0..e010c77cd1 100644
|
||||
}
|
||||
#ifdef ASSERT
|
||||
InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(SystemDictionary::Class_klass());
|
||||
@@ -812,9 +815,9 @@ Klass* java_lang_Class::array_klass(oop java_class) {
|
||||
@@ -813,9 +816,9 @@ Klass* java_lang_Class::array_klass(oop java_class) {
|
||||
}
|
||||
|
||||
|
||||
@ -106,7 +106,7 @@ index cd28c758d0..e010c77cd1 100644
|
||||
|
||||
|
||||
diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp
|
||||
index 51879658c7..d9e65f9014 100644
|
||||
index 51879658..d9e65f90 100644
|
||||
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp
|
||||
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp
|
||||
@@ -281,7 +281,7 @@ class java_lang_Class : AllStatic {
|
||||
@ -119,10 +119,10 @@ index 51879658c7..d9e65f9014 100644
|
||||
static int klass_offset_in_bytes() { return _klass_offset; }
|
||||
static int array_klass_offset_in_bytes() { return _array_klass_offset; }
|
||||
diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp
|
||||
index c8d1f99183..c9bcf96d1c 100644
|
||||
index 5e598b4b..a703a54e 100644
|
||||
--- a/hotspot/src/share/vm/oops/oop.hpp
|
||||
+++ b/hotspot/src/share/vm/oops/oop.hpp
|
||||
@@ -243,6 +243,8 @@ class oopDesc {
|
||||
@@ -203,6 +203,8 @@ class oopDesc {
|
||||
Metadata* metadata_field(int offset) const;
|
||||
void metadata_field_put(int offset, Metadata* value);
|
||||
|
||||
@ -132,11 +132,11 @@ index c8d1f99183..c9bcf96d1c 100644
|
||||
void byte_field_put(int offset, jbyte contents);
|
||||
|
||||
diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
index 5d47e3f4dc..16d2870d79 100644
|
||||
index a76b8506..d4c4d75c 100644
|
||||
--- a/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
@@ -393,6 +393,10 @@ inline void oopDesc::metadata_field_put(int offset, Metadata* value) {
|
||||
}
|
||||
@@ -373,6 +373,10 @@ inline void oopDesc::metadata_field_put(int offset, Metadata* value) {
|
||||
*metadata_field_addr(offset) = value;
|
||||
}
|
||||
|
||||
+void oopDesc::release_metadata_field_put(int offset, Metadata* value) {
|
||||
@ -144,11 +144,11 @@ index 5d47e3f4dc..16d2870d79 100644
|
||||
+}
|
||||
+
|
||||
inline void oopDesc::obj_field_put_raw(int offset, oop value) {
|
||||
if (UseShenandoahGC) {
|
||||
oop p = bs()->write_barrier(this);
|
||||
UseCompressedOops ?
|
||||
encode_store_heap_oop(obj_field_addr<narrowOop>(offset), value) :
|
||||
diff --git a/hotspot/test/runtime/CreateMirror/ArraysNewInstanceBug.java b/hotspot/test/runtime/CreateMirror/ArraysNewInstanceBug.java
|
||||
new file mode 100644
|
||||
index 0000000000..870e8ea94b
|
||||
index 00000000..870e8ea9
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/runtime/CreateMirror/ArraysNewInstanceBug.java
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
79
8223504-improve-performance-of-forall-loops-by-better.patch
Normal file
79
8223504-improve-performance-of-forall-loops-by-better.patch
Normal file
@ -0,0 +1,79 @@
|
||||
From c1d5b7c044ba418848c98d36ec21358a1dac568e Mon Sep 17 00:00:00 2001
|
||||
From: sunjianye <sunjianye@huawei.com>
|
||||
Date: Sat, 23 May 2020 17:18:39 +0800
|
||||
Subject: [PATCH] 8223504:improve performance of forall loops by better
|
||||
inlining of "iterator()" methods
|
||||
|
||||
DTS/AR: AR.SR.IREQ02373832.002.001
|
||||
Summary: <C2> : improve performance of forall loops by better inlining of "iterator()" methods
|
||||
LLT: NA
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8223504
|
||||
---
|
||||
hotspot/src/share/vm/classfile/systemDictionary.hpp | 3 +++
|
||||
hotspot/src/share/vm/classfile/vmSymbols.hpp | 2 ++
|
||||
hotspot/src/share/vm/opto/bytecodeInfo.cpp | 9 ++++++++-
|
||||
3 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp
|
||||
index 57a9d669b..956b50313 100644
|
||||
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp
|
||||
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp
|
||||
@@ -196,6 +196,9 @@ class Ticks;
|
||||
do_klass(Short_klass, java_lang_Short, Pre ) \
|
||||
do_klass(Integer_klass, java_lang_Integer, Pre ) \
|
||||
do_klass(Long_klass, java_lang_Long, Pre ) \
|
||||
+ \
|
||||
+ /* force inline of iterators */ \
|
||||
+ do_klass(Iterator_klass, java_util_Iterator, Pre ) \
|
||||
/*end*/
|
||||
|
||||
|
||||
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
|
||||
index 46f2e2d8b..acc33fcc2 100644
|
||||
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
|
||||
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
|
||||
@@ -121,6 +121,8 @@
|
||||
template(sun_misc_Launcher_AppClassLoader, "sun/misc/Launcher$AppClassLoader") \
|
||||
template(sun_misc_Launcher_ExtClassLoader, "sun/misc/Launcher$ExtClassLoader") \
|
||||
\
|
||||
+ template(java_util_Iterator, "java/util/Iterator") \
|
||||
+ \
|
||||
/* Java runtime version access */ \
|
||||
template(sun_misc_Version, "sun/misc/Version") \
|
||||
template(java_runtime_name_name, "java_runtime_name") \
|
||||
diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp
|
||||
index d16b5631b..06a30b94a 100644
|
||||
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -75,6 +75,8 @@ InlineTree::InlineTree(Compile* c,
|
||||
* Return true when EA is ON and a java constructor is called or
|
||||
* a super constructor is called from an inlined java constructor.
|
||||
* Also return true for boxing methods.
|
||||
+ * Also return true for methods returning Iterator (including Iterable::iterator())
|
||||
+ * that is essential for forall-loops performance.
|
||||
*/
|
||||
static bool is_init_with_ea(ciMethod* callee_method,
|
||||
ciMethod* caller_method, Compile* C) {
|
||||
@@ -92,6 +94,11 @@ static bool is_init_with_ea(ciMethod* callee_method,
|
||||
if (C->eliminate_boxing() && callee_method->is_boxing_method()) {
|
||||
return true;
|
||||
}
|
||||
+ ciType *retType = callee_method->signature()->return_type();
|
||||
+ ciKlass *iter = C->env()->Iterator_klass();
|
||||
+ if (retType->is_loaded() && iter->is_loaded() && retType->is_subtype_of(iter)) {
|
||||
+ return true;
|
||||
+ }
|
||||
return false;
|
||||
}
|
||||
|
||||
--
|
||||
2.19.1
|
||||
|
||||
Binary file not shown.
166
add-vm-option-BoxTypeCachedMax-for-Integer-and-Long-cache.patch
Normal file
166
add-vm-option-BoxTypeCachedMax-for-Integer-and-Long-cache.patch
Normal file
@ -0,0 +1,166 @@
|
||||
From b5c192bb3dc57021996545b0bac822d73c75ec19 Mon Sep 17 00:00:00 2001
|
||||
From: sunjianye <sunjianye@huawei.com>
|
||||
Date: Thu, 23 Apr 2020 16:12:34 +0800
|
||||
Subject: [PATCH] add vm option BoxTypeCachedMax for Integer and Long cache
|
||||
|
||||
DTS/AR: AR.SR.IREQ02373832.002.001
|
||||
Summary: < JDK> : add vm option BoxTypeCachedMax for Integer and Long cache
|
||||
LLT: NA
|
||||
Patch Type: huawei
|
||||
Bug url: NA
|
||||
---
|
||||
hotspot/src/share/vm/opto/c2_globals.hpp | 3 ++
|
||||
hotspot/src/share/vm/runtime/arguments.cpp | 23 ++++++++++++
|
||||
hotspot/src/share/vm/runtime/arguments.hpp | 3 ++
|
||||
jdk/src/share/classes/java/lang/Long.java | 43 ++++++++++++++++++----
|
||||
4 files changed, 65 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp
|
||||
index 4b6a87508..3f2d286b2 100644
|
||||
--- a/hotspot/src/share/vm/opto/c2_globals.hpp
|
||||
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp
|
||||
@@ -470,6 +470,9 @@
|
||||
product(intx, AutoBoxCacheMax, 128, \
|
||||
"Sets max value cached by the java.lang.Integer autobox cache") \
|
||||
\
|
||||
+ product(intx, BoxTypeCachedMax, 128, \
|
||||
+ "Sets max value cached by the java.lang.Long and Integer autobox cache") \
|
||||
+ \
|
||||
experimental(bool, AggressiveUnboxing, false, \
|
||||
"Control optimizations for aggressive boxing elimination") \
|
||||
\
|
||||
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
|
||||
index 63b39c4ba..75ef29b9b 100644
|
||||
--- a/hotspot/src/share/vm/runtime/arguments.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
|
||||
@@ -2194,6 +2194,24 @@ void Arguments::set_bytecode_flags() {
|
||||
}
|
||||
}
|
||||
|
||||
+// set Integer and Long box type cached MAX num flag : -XX:BoxTypeCachedMax=<size>
|
||||
+void Arguments::set_boxtype_cached_max_flags() {
|
||||
+ int size = 1024;
|
||||
+ char buffer[size];
|
||||
+ jio_snprintf(buffer, size, "java.lang.Long.LongCache.high=" INTX_FORMAT, BoxTypeCachedMax);
|
||||
+ add_property(buffer);
|
||||
+
|
||||
+ if (AggressiveOpts || !FLAG_IS_DEFAULT(AutoBoxCacheMax)) {
|
||||
+ if (FLAG_IS_DEFAULT(AutoBoxCacheMax)) {
|
||||
+ FLAG_SET_DEFAULT(AutoBoxCacheMax, 20000);
|
||||
+ }
|
||||
+ jio_snprintf(buffer, size, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
|
||||
+ } else {
|
||||
+ jio_snprintf(buffer, size, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, BoxTypeCachedMax);
|
||||
+ }
|
||||
+ add_property(buffer);
|
||||
+}
|
||||
+
|
||||
// Aggressive optimization flags -XX:+AggressiveOpts
|
||||
void Arguments::set_aggressive_opts_flags() {
|
||||
#ifdef COMPILER2
|
||||
@@ -2846,6 +2864,8 @@ bool Arguments::check_vm_args_consistency() {
|
||||
// Check the minimum number of compiler threads
|
||||
status &=verify_min_value(CICompilerCount, min_number_of_compiler_threads, "CICompilerCount");
|
||||
|
||||
+ status &= verify_min_value(BoxTypeCachedMax, 1, "BoxTypeCachedMax");
|
||||
+
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -4336,6 +4356,9 @@ jint Arguments::apply_ergo() {
|
||||
// Set bytecode rewriting flags
|
||||
set_bytecode_flags();
|
||||
|
||||
+ // Set Integer and Long cached max
|
||||
+ set_boxtype_cached_max_flags();
|
||||
+
|
||||
// Set flags if Aggressive optimization flags (-XX:+AggressiveOpts) enabled.
|
||||
set_aggressive_opts_flags();
|
||||
|
||||
diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp
|
||||
index a5cd59ea6..6f7ff138f 100644
|
||||
--- a/hotspot/src/share/vm/runtime/arguments.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/arguments.hpp
|
||||
@@ -386,6 +386,9 @@ class Arguments : AllStatic {
|
||||
// System properties
|
||||
static bool add_property(const char* prop);
|
||||
|
||||
+ // set Integer and Long box type cached MAX num
|
||||
+ static void set_boxtype_cached_max_flags();
|
||||
+
|
||||
// Aggressive optimization flags.
|
||||
static void set_aggressive_opts_flags();
|
||||
|
||||
diff --git a/jdk/src/share/classes/java/lang/Long.java b/jdk/src/share/classes/java/lang/Long.java
|
||||
index 9e21cb853..d56f4c6be 100644
|
||||
--- a/jdk/src/share/classes/java/lang/Long.java
|
||||
+++ b/jdk/src/share/classes/java/lang/Long.java
|
||||
@@ -804,13 +804,43 @@ public final class Long extends Number implements Comparable<Long> {
|
||||
}
|
||||
|
||||
private static class LongCache {
|
||||
+ static final int low;
|
||||
+ static final int high;
|
||||
+
|
||||
private LongCache(){}
|
||||
|
||||
- static final Long cache[] = new Long[-(-128) + 127 + 1];
|
||||
+ static final Long cache[];
|
||||
|
||||
static {
|
||||
- for(int i = 0; i < cache.length; i++)
|
||||
- cache[i] = new Long(i - 128);
|
||||
+
|
||||
+ String longCacheHighPropValue =
|
||||
+ sun.misc.VM.getSavedProperty("java.lang.Long.LongCache.high");
|
||||
+ if (longCacheHighPropValue != null) {
|
||||
+ // high value may be configured by property
|
||||
+ int h = 0;
|
||||
+ try {
|
||||
+ int i = Integer.parseInt(longCacheHighPropValue);
|
||||
+ i = Math.max(i, 128);
|
||||
+ // Maximum array size is Integer.MAX_VALUE
|
||||
+ h = Math.min(i, Integer.MAX_VALUE/2 -1);
|
||||
+ } catch( NumberFormatException nfe) {
|
||||
+ // If the property cannot be parsed into an int, ignore it.
|
||||
+ }
|
||||
+ high = h;
|
||||
+ low = -h+1;
|
||||
+ cache = new Long[(high - low) + 1];
|
||||
+ int j = low;
|
||||
+ for(int k = 0; k < cache.length; k++)
|
||||
+ cache[k] = new Long(j++);
|
||||
+
|
||||
+ } else {
|
||||
+ low = -128;
|
||||
+ high = 127;
|
||||
+ cache = new Long[(high - low) + 1];
|
||||
+ int j = low;
|
||||
+ for(int k = 0; k < cache.length; k++)
|
||||
+ cache[k] = new Long(j++);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,10 +863,8 @@ public final class Long extends Number implements Comparable<Long> {
|
||||
* @since 1.5
|
||||
*/
|
||||
public static Long valueOf(long l) {
|
||||
- final int offset = 128;
|
||||
- if (l >= -128 && l <= 127) { // will cache
|
||||
- return LongCache.cache[(int)l + offset];
|
||||
- }
|
||||
+ if (l >= LongCache.low && l <= LongCache.high)
|
||||
+ return LongCache.cache[(int) l + (-LongCache.low)];
|
||||
return new Long(l);
|
||||
}
|
||||
|
||||
@@ -1617,4 +1645,5 @@ public final class Long extends Number implements Comparable<Long> {
|
||||
|
||||
/** use serialVersionUID from JDK 1.0.2 for interoperability */
|
||||
@Native private static final long serialVersionUID = 4290774380558885855L;
|
||||
+
|
||||
}
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -94,7 +94,7 @@ index df886e88f4..c0c7b7bdb3 100644
|
||||
|
||||
+company_name =
|
||||
+ifneq ($(COMPANY_NAME),N/A)
|
||||
+ company_name=($(COMPANY_NAME))
|
||||
+ company_name=$(COMPANY_NAME)
|
||||
+endif
|
||||
+
|
||||
$(JDK_OUTPUTDIR)/gensrc/sun/misc/Version.java \
|
||||
@ -127,7 +127,7 @@ index 32e2586e79..022c142810 100644
|
||||
/* Second line: runtime version (ie, libraries). */
|
||||
|
||||
- ps.print(java_runtime_name + " (build " + java_runtime_version);
|
||||
+ ps.print(java_runtime_name + " " + company_name + "(build " + java_runtime_version);
|
||||
+ ps.print(java_runtime_name + " " + company_name + " " + "(build " + java_runtime_version);
|
||||
|
||||
if (java_profile_name.length() > 0) {
|
||||
// profile name
|
||||
@ -137,7 +137,7 @@ index 32e2586e79..022c142810 100644
|
||||
String java_vm_info = System.getProperty("java.vm.info");
|
||||
- ps.println(java_vm_name + " (build " + java_vm_version + ", " +
|
||||
- java_vm_info + ")");
|
||||
+ ps.println(java_vm_name + " " + company_name + "(build " + java_vm_version + ", " +
|
||||
+ ps.println(java_vm_name + " " + company_name + " " + "(build " + java_vm_version + ", " +
|
||||
+ java_vm_info + ")");
|
||||
}
|
||||
|
||||
|
||||
679
fast-serializer-jdk8.patch
Normal file
679
fast-serializer-jdk8.patch
Normal file
@ -0,0 +1,679 @@
|
||||
commit 3ece3b6a87e4bf61a1f786c12d796012becce313
|
||||
Author: hexuejin <hexuejin2@huawei.com>
|
||||
Date: Thu May 28 10:30:20 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/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp
|
||||
index cdb72c0d5..d50041635 100644
|
||||
--- a/hotspot/src/share/vm/prims/unsafe.cpp
|
||||
+++ b/hotspot/src/share/vm/prims/unsafe.cpp
|
||||
@@ -1361,6 +1361,10 @@ UNSAFE_ENTRY(void, Unsafe_PrefetchWrite(JNIEnv* env, jclass ignored, jobject obj
|
||||
Prefetch::write(addr, (intx)offset);
|
||||
UNSAFE_END
|
||||
|
||||
+UNSAFE_ENTRY(jboolean, Unsafe_GetUseFastSerializer(JNIEnv *env, jobject unsafe)) {
|
||||
+ return UseFastSerializer;
|
||||
+}
|
||||
+UNSAFE_END
|
||||
|
||||
/// JVM_RegisterUnsafeMethods
|
||||
|
||||
@@ -1447,7 +1451,8 @@ static JNINativeMethod methods_140[] = {
|
||||
{CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)},
|
||||
{CC "monitorEnter", CC "(" OBJ ")V", FN_PTR(Unsafe_MonitorEnter)},
|
||||
{CC "monitorExit", CC "(" OBJ ")V", FN_PTR(Unsafe_MonitorExit)},
|
||||
- {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)}
|
||||
+ {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)},
|
||||
+ {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)}
|
||||
};
|
||||
|
||||
// These are the methods prior to the JSR 166 changes in 1.5.0
|
||||
@@ -1493,8 +1498,8 @@ static JNINativeMethod methods_141[] = {
|
||||
{CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)},
|
||||
{CC "monitorEnter", CC "(" OBJ ")V", FN_PTR(Unsafe_MonitorEnter)},
|
||||
{CC "monitorExit", CC "(" OBJ ")V", FN_PTR(Unsafe_MonitorExit)},
|
||||
- {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)}
|
||||
-
|
||||
+ {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)},
|
||||
+ {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)}
|
||||
};
|
||||
|
||||
// These are the methods prior to the JSR 166 changes in 1.6.0
|
||||
@@ -1548,7 +1553,8 @@ static JNINativeMethod methods_15[] = {
|
||||
{CC "compareAndSwapInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)},
|
||||
{CC "compareAndSwapLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)},
|
||||
{CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
|
||||
- {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)}
|
||||
+ {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
|
||||
+ {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)}
|
||||
|
||||
};
|
||||
|
||||
@@ -1606,7 +1612,8 @@ static JNINativeMethod methods_16[] = {
|
||||
{CC "putOrderedInt", CC "(" OBJ "JI)V", FN_PTR(Unsafe_SetOrderedInt)},
|
||||
{CC "putOrderedLong", CC "(" OBJ "JJ)V", FN_PTR(Unsafe_SetOrderedLong)},
|
||||
{CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
|
||||
- {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)}
|
||||
+ {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
|
||||
+ {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)}
|
||||
};
|
||||
|
||||
// These are the methods for 1.8.0
|
||||
@@ -1662,7 +1669,8 @@ static JNINativeMethod methods_18[] = {
|
||||
{CC "putOrderedInt", CC "(" OBJ "JI)V", FN_PTR(Unsafe_SetOrderedInt)},
|
||||
{CC "putOrderedLong", CC "(" OBJ "JJ)V", FN_PTR(Unsafe_SetOrderedLong)},
|
||||
{CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
|
||||
- {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)}
|
||||
+ {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
|
||||
+ {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)}
|
||||
};
|
||||
|
||||
JNINativeMethod loadavg_method[] = {
|
||||
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
index 2e6ff26ed..0a6ebfae1 100644
|
||||
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
@@ -553,6 +553,10 @@ class CommandLineFlags {
|
||||
"Enable normal processing of flags relating to experimental " \
|
||||
"features") \
|
||||
\
|
||||
+ experimental(bool, UseFastSerializer, false, \
|
||||
+ "Cache-based serialization.It is extremely fast, but it can only" \
|
||||
+ "be effective in certain scenarios.") \
|
||||
+ \
|
||||
product(bool, JavaMonitorsInStackTrace, true, \
|
||||
"Print information about Java monitor locks when the stacks are" \
|
||||
"dumped") \
|
||||
diff --git a/jdk/src/share/classes/java/io/ObjectInputStream.java b/jdk/src/share/classes/java/io/ObjectInputStream.java
|
||||
index 5d30f2a01..b67f01719 100644
|
||||
--- a/jdk/src/share/classes/java/io/ObjectInputStream.java
|
||||
+++ b/jdk/src/share/classes/java/io/ObjectInputStream.java
|
||||
@@ -49,6 +49,7 @@ import sun.misc.SharedSecrets;
|
||||
import sun.misc.JavaOISAccess;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
import sun.security.action.GetBooleanAction;
|
||||
+import sun.misc.Unsafe;
|
||||
|
||||
/**
|
||||
* An ObjectInputStream deserializes primitive data and objects previously
|
||||
@@ -284,6 +285,22 @@ public class ObjectInputStream
|
||||
traceLogger = (filterLog != null &&
|
||||
filterLog.isLoggable(PlatformLogger.Level.FINER)) ? filterLog : null;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * Logger for FastSerializer.
|
||||
+ * Setup the FastSerializer logger if it is set to FINE
|
||||
+ * (Assuming it will not change).
|
||||
+ */
|
||||
+ private static final PlatformLogger fastSerLogger;
|
||||
+ static {
|
||||
+ if (printFastSerializer) {
|
||||
+ PlatformLogger fastSerLog = PlatformLogger.getLogger("fastSerializer");
|
||||
+ fastSerLogger = (fastSerLog != null &&
|
||||
+ fastSerLog.isLoggable(PlatformLogger.Level.FINE)) ? fastSerLog : null;
|
||||
+ } else {
|
||||
+ fastSerLogger = null;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/** filter stream for handling block data conversion */
|
||||
@@ -312,6 +329,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.
|
||||
@@ -325,6 +345,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.
|
||||
@@ -396,6 +443,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
|
||||
@@ -670,11 +720,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
|
||||
@@ -715,16 +774,27 @@ public class ObjectInputStream
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
String name = desc.getName();
|
||||
+ Class<?> cl = null;
|
||||
+
|
||||
+ if (useFastSerializer) {
|
||||
+ cl = nameToClass.get(name);
|
||||
+ if (cl != null) {
|
||||
+ return cl;
|
||||
+ }
|
||||
+ }
|
||||
try {
|
||||
- return Class.forName(name, false, latestUserDefinedLoader());
|
||||
+ cl = Class.forName(name, false, latestUserDefinedLoader());
|
||||
} catch (ClassNotFoundException ex) {
|
||||
- Class<?> cl = primClasses.get(name);
|
||||
- if (cl != null) {
|
||||
- return cl;
|
||||
- } else {
|
||||
+ cl = primClasses.get(name);
|
||||
+ if (cl == null) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
+ if (useFastSerializer) {
|
||||
+ nameToClass.put(name, cl);
|
||||
+ }
|
||||
+
|
||||
+ return cl;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -894,9 +964,34 @@ 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.fine("[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));
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -910,6 +1005,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
|
||||
@@ -920,6 +1020,27 @@ 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) {
|
||||
+ 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;
|
||||
@@ -1935,17 +2056,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.fine(
|
||||
+ "[Deserialize] useFastSerializer:{0}, Class name:{1}, SerialVersionUID:{2}, flags:{3}",
|
||||
+ useFastSerializer, desc.getName(), desc.getSerialVersionUID(), desc.getFlags(this));
|
||||
+ }
|
||||
+
|
||||
return desc;
|
||||
}
|
||||
|
||||
@@ -2334,21 +2478,25 @@ public class ObjectInputStream
|
||||
desc.setPrimFieldValues(obj, primVals);
|
||||
}
|
||||
|
||||
- int objHandle = passHandle;
|
||||
- ObjectStreamField[] fields = desc.getFields(false);
|
||||
- Object[] objVals = new Object[desc.getNumObjFields()];
|
||||
- int numPrimFields = fields.length - objVals.length;
|
||||
- for (int i = 0; i < objVals.length; i++) {
|
||||
- ObjectStreamField f = fields[numPrimFields + i];
|
||||
- objVals[i] = readObject0(Object.class, f.isUnshared());
|
||||
- if (f.getField() != null) {
|
||||
- handles.markDependency(objHandle, passHandle);
|
||||
+ Object[] objVals = null;
|
||||
+ int numObjFields = desc.getNumObjFields();
|
||||
+ if (numObjFields > 0) {
|
||||
+ int objHandle = passHandle;
|
||||
+ ObjectStreamField[] fields = desc.getFields(false);
|
||||
+ objVals = new Object[numObjFields];
|
||||
+ int numPrimFields = fields.length - objVals.length;
|
||||
+ for (int i = 0; i < objVals.length; i++) {
|
||||
+ ObjectStreamField f = fields[numPrimFields + i];
|
||||
+ objVals[i] = readObject0(Object.class, f.isUnshared());
|
||||
+ if (f.getField() != null) {
|
||||
+ handles.markDependency(objHandle, passHandle);
|
||||
+ }
|
||||
}
|
||||
+ if (obj != null) {
|
||||
+ desc.setObjFieldValues(obj, objVals);
|
||||
+ }
|
||||
+ passHandle = objHandle;
|
||||
}
|
||||
- if (obj != null) {
|
||||
- desc.setObjFieldValues(obj, objVals);
|
||||
- }
|
||||
- passHandle = objHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/jdk/src/share/classes/java/io/ObjectOutputStream.java b/jdk/src/share/classes/java/io/ObjectOutputStream.java
|
||||
index 6d29e3a1f..3890efc3e 100644
|
||||
--- a/jdk/src/share/classes/java/io/ObjectOutputStream.java
|
||||
+++ b/jdk/src/share/classes/java/io/ObjectOutputStream.java
|
||||
@@ -37,6 +37,8 @@ import java.util.concurrent.ConcurrentMap;
|
||||
import static java.io.ObjectStreamClass.processQueue;
|
||||
import java.io.SerialCallbackContext;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
+import sun.misc.Unsafe;
|
||||
+import sun.util.logging.PlatformLogger;
|
||||
|
||||
/**
|
||||
* An ObjectOutputStream writes primitive data types and graphs of Java objects
|
||||
@@ -173,6 +175,24 @@ public class ObjectOutputStream
|
||||
new ReferenceQueue<>();
|
||||
}
|
||||
|
||||
+ private static class Logging {
|
||||
+ /*
|
||||
+ * Logger for FastSerializer.
|
||||
+ * Setup the FastSerializer logger if it is set to FINE.
|
||||
+ * (Assuming it will not change).
|
||||
+ */
|
||||
+ static final PlatformLogger fastSerLogger;
|
||||
+ static {
|
||||
+ if (printFastSerializer) {
|
||||
+ PlatformLogger fastSerLog = PlatformLogger.getLogger("fastSerializer");
|
||||
+ fastSerLogger = (fastSerLog != null &&
|
||||
+ fastSerLog.isLoggable(PlatformLogger.Level.FINE)) ? fastSerLog : null;
|
||||
+ } else {
|
||||
+ fastSerLogger = null;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/** filter stream for handling block data conversion */
|
||||
private final BlockDataOutputStream bout;
|
||||
/** obj -> wire handle map */
|
||||
@@ -214,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
|
||||
@@ -327,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
|
||||
@@ -633,7 +672,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);
|
||||
}
|
||||
|
||||
@@ -648,6 +691,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
|
||||
@@ -665,7 +711,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);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1275,9 +1328,21 @@ public class ObjectOutputStream
|
||||
bout.writeByte(TC_CLASSDESC);
|
||||
handles.assign(unshared ? null : desc);
|
||||
|
||||
+ if (Logging.fastSerLogger != null) {
|
||||
+ Logging.fastSerLogger.fine(
|
||||
+ "[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,7 +1356,9 @@ public class ObjectOutputStream
|
||||
bout.setBlockDataMode(false);
|
||||
bout.writeByte(TC_ENDBLOCKDATA);
|
||||
|
||||
- writeClassDesc(desc.getSuperDesc(), false);
|
||||
+ if (!useFastSerializer) {
|
||||
+ writeClassDesc(desc.getSuperDesc(), false);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/jdk/src/share/classes/java/io/ObjectStreamClass.java b/jdk/src/share/classes/java/io/ObjectStreamClass.java
|
||||
index 64453b25a..fce3c3475 100644
|
||||
--- a/jdk/src/share/classes/java/io/ObjectStreamClass.java
|
||||
+++ b/jdk/src/share/classes/java/io/ObjectStreamClass.java
|
||||
@@ -280,6 +280,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.
|
||||
@@ -570,6 +604,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.
|
||||
*/
|
||||
@@ -756,6 +799,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/jdk/src/share/classes/java/io/ObjectStreamConstants.java b/jdk/src/share/classes/java/io/ObjectStreamConstants.java
|
||||
index 23f72b436..59179a6ec 100644
|
||||
--- a/jdk/src/share/classes/java/io/ObjectStreamConstants.java
|
||||
+++ b/jdk/src/share/classes/java/io/ObjectStreamConstants.java
|
||||
@@ -38,6 +38,11 @@ public interface ObjectStreamConstants {
|
||||
*/
|
||||
final static 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/jdk/src/share/classes/sun/misc/Unsafe.java b/jdk/src/share/classes/sun/misc/Unsafe.java
|
||||
index 99e465802..92fb01669 100644
|
||||
--- a/jdk/src/share/classes/sun/misc/Unsafe.java
|
||||
+++ b/jdk/src/share/classes/sun/misc/Unsafe.java
|
||||
@@ -433,6 +433,8 @@ public final class Unsafe {
|
||||
/** @see #putByte(long, byte) */
|
||||
public native void putDouble(long address, double x);
|
||||
|
||||
+ public native boolean getUseFastSerializer();
|
||||
+
|
||||
/**
|
||||
* Fetches a native pointer from a given memory address. If the address is
|
||||
* zero, or does not point into a block obtained from {@link
|
||||
@ -1,37 +0,0 @@
|
||||
From 7c73365615f00951272310db44dec2939b91b48e Mon Sep 17 00:00:00 2001
|
||||
Date: Wed, 19 Feb 2020 19:09:39 +0000
|
||||
Subject: [PATCH] fix incorrect offset for oop field with weak memory model
|
||||
|
||||
Summary: <interpreter>: add loadload membar in fast_storefield and fast_accessfield to avoid loading a incorrect offset
|
||||
LLT: N/A
|
||||
Bug url: N/A
|
||||
---
|
||||
hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp
|
||||
index 5a619566ae..aa9545ee9c 100644
|
||||
--- a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp
|
||||
+++ b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp
|
||||
@@ -2922,6 +2922,8 @@ void TemplateTable::fast_storefield(TosState state)
|
||||
// access constant pool cache
|
||||
__ get_cache_and_index_at_bcp(r2, r1, 1);
|
||||
|
||||
+ __ membar(MacroAssembler::LoadLoad);
|
||||
+
|
||||
// test for volatile with r3
|
||||
__ ldrw(r3, Address(r2, in_bytes(base +
|
||||
ConstantPoolCacheEntry::flags_offset())));
|
||||
@@ -3013,6 +3015,9 @@ void TemplateTable::fast_accessfield(TosState state)
|
||||
|
||||
// access constant pool cache
|
||||
__ get_cache_and_index_at_bcp(r2, r1, 1);
|
||||
+
|
||||
+ __ membar(MacroAssembler::LoadLoad);
|
||||
+
|
||||
__ ldr(r1, Address(r2, in_bytes(ConstantPoolCache::base_offset() +
|
||||
ConstantPoolCacheEntry::f2_offset())));
|
||||
__ ldrw(r3, Address(r2, in_bytes(ConstantPoolCache::base_offset() +
|
||||
--
|
||||
2.12.3
|
||||
|
||||
154
generate_source_tarball.sh
Executable file
154
generate_source_tarball.sh
Executable file
@ -0,0 +1,154 @@
|
||||
#!/bin/bash
|
||||
# Generates the 'source tarball' for JDK 8 projects.
|
||||
#
|
||||
# Example:
|
||||
# When used from local repo set REPO_ROOT pointing to file:// with your repo
|
||||
# If your local repo follows upstream forests conventions, it may be enough to set OPENJDK_URL
|
||||
# If you want to use a local copy of patch PR3756, set the path to it in the PR3756 variable
|
||||
#
|
||||
# In any case you have to set PROJECT_NAME REPO_NAME and VERSION. eg:
|
||||
# PROJECT_NAME=jdk8u OR aarch64-port
|
||||
# REPO_NAME=jdk8u60 OR jdk8u60
|
||||
# VERSION=jdk8u60-b27 OR aarch64-jdk8u65-b17 OR for head, keyword 'tip' should do the job there
|
||||
#
|
||||
# They are used to create correct name and are used in construction of sources url (unless REPO_ROOT is set)
|
||||
|
||||
# This script creates a single source tarball out of the repository
|
||||
# based on the given tag and removes code not allowed in fedora/rhel. For
|
||||
# consistency, the source tarball will always contain 'openjdk' as the top
|
||||
# level folder, name is created, based on parameter
|
||||
#
|
||||
|
||||
if [ ! "x$PR3756" = "x" ] ; then
|
||||
if [ ! -f "$PR3756" ] ; then
|
||||
echo "You have specified PR3756 as $PR3756 but it does not exists. exiting"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
set -e
|
||||
|
||||
OPENJDK_URL_DEFAULT=http://hg.openjdk.java.net
|
||||
COMPRESSION_DEFAULT=xz
|
||||
# jdk is last for its size
|
||||
REPOS_DEFAULT="hotspot corba jaxws jaxp langtools nashorn jdk"
|
||||
|
||||
if [ "x$1" = "xhelp" ] ; then
|
||||
echo -e "Behaviour may be specified by setting the following variables:\n"
|
||||
echo "VERSION - the version of the specified OpenJDK project"
|
||||
echo "PROJECT_NAME -- the name of the OpenJDK project being archived (optional; only needed by defaults)"
|
||||
echo "REPO_NAME - the name of the OpenJDK repository (optional; only needed by defaults)"
|
||||
echo "OPENJDK_URL - the URL to retrieve code from (optional; defaults to ${OPENJDK_URL_DEFAULT})"
|
||||
echo "COMPRESSION - the compression type to use (optional; defaults to ${COMPRESSION_DEFAULT})"
|
||||
echo "FILE_NAME_ROOT - name of the archive, minus extensions (optional; defaults to PROJECT_NAME-REPO_NAME-VERSION)"
|
||||
echo "REPO_ROOT - the location of the Mercurial repository to archive (optional; defaults to OPENJDK_URL/PROJECT_NAME/REPO_NAME)"
|
||||
echo "PR3756 - the path to the PR3756 patch to apply (optional; downloaded if unavailable)"
|
||||
echo "REPOS - specify the repositories to use (optional; defaults to ${REPOS_DEFAULT})"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
|
||||
if [ "x$VERSION" = "x" ] ; then
|
||||
echo "No VERSION specified"
|
||||
exit -2
|
||||
fi
|
||||
echo "Version: ${VERSION}"
|
||||
|
||||
# REPO_NAME is only needed when we default on REPO_ROOT and FILE_NAME_ROOT
|
||||
if [ "x$FILE_NAME_ROOT" = "x" -o "x$REPO_ROOT" = "x" ] ; then
|
||||
if [ "x$PROJECT_NAME" = "x" ] ; then
|
||||
echo "No PROJECT_NAME specified"
|
||||
exit -1
|
||||
fi
|
||||
echo "Project name: ${PROJECT_NAME}"
|
||||
if [ "x$REPO_NAME" = "x" ] ; then
|
||||
echo "No REPO_NAME specified"
|
||||
exit -3
|
||||
fi
|
||||
echo "Repository name: ${REPO_NAME}"
|
||||
fi
|
||||
|
||||
if [ "x$OPENJDK_URL" = "x" ] ; then
|
||||
OPENJDK_URL=${OPENJDK_URL_DEFAULT}
|
||||
echo "No OpenJDK URL specified; defaulting to ${OPENJDK_URL}"
|
||||
else
|
||||
echo "OpenJDK URL: ${OPENJDK_URL}"
|
||||
fi
|
||||
|
||||
if [ "x$COMPRESSION" = "x" ] ; then
|
||||
# rhel 5 needs tar.gz
|
||||
COMPRESSION=${COMPRESSION_DEFAULT}
|
||||
fi
|
||||
echo "Creating a tar.${COMPRESSION} archive"
|
||||
|
||||
if [ "x$FILE_NAME_ROOT" = "x" ] ; then
|
||||
FILE_NAME_ROOT=${PROJECT_NAME}-${REPO_NAME}-${VERSION}
|
||||
echo "No file name root specified; default to ${FILE_NAME_ROOT}"
|
||||
fi
|
||||
if [ "x$REPO_ROOT" = "x" ] ; then
|
||||
REPO_ROOT="${OPENJDK_URL}/${PROJECT_NAME}/${REPO_NAME}"
|
||||
echo "No repository root specified; default to ${REPO_ROOT}"
|
||||
fi;
|
||||
|
||||
mkdir "${FILE_NAME_ROOT}"
|
||||
pushd "${FILE_NAME_ROOT}"
|
||||
|
||||
echo "Cloning ${VERSION} root repository from ${REPO_ROOT}"
|
||||
hg clone ${REPO_ROOT} openjdk -r ${VERSION}
|
||||
pushd openjdk
|
||||
|
||||
|
||||
if [ "x$REPOS" = "x" ] ; then
|
||||
repos=${REPOS_DEFAULT}
|
||||
echo "No repositories specified; defaulting to ${repos}"
|
||||
else
|
||||
repos=$REPOS
|
||||
echo "Repositories: ${repos}"
|
||||
fi;
|
||||
|
||||
for subrepo in $repos
|
||||
do
|
||||
echo "Cloning ${VERSION} ${subrepo} repository from ${REPO_ROOT}"
|
||||
hg clone ${REPO_ROOT}/${subrepo} -r ${VERSION}
|
||||
done
|
||||
|
||||
if [ -d jdk ]; then
|
||||
echo "Removing EC source code we don't build"
|
||||
rm -vf jdk/src/share/native/sun/security/ec/impl/ec2.h
|
||||
rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_163.c
|
||||
rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_193.c
|
||||
rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_233.c
|
||||
rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_aff.c
|
||||
rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_mont.c
|
||||
rm -vf jdk/src/share/native/sun/security/ec/impl/ecp_192.c
|
||||
rm -vf jdk/src/share/native/sun/security/ec/impl/ecp_224.c
|
||||
|
||||
echo "Syncing EC list with NSS"
|
||||
|
||||
if [ "x$PR3756" = "x" ] ; then
|
||||
# get pr3756.patch (from http://icedtea.classpath.org/hg/icedtea8) from most correct tag
|
||||
# Do not push it or publish it (see http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=3756)
|
||||
wget http://icedtea.classpath.org/hg/icedtea8/raw-file/tip/patches/pr3756.patch
|
||||
patch -Np1 < pr3756.patch
|
||||
rm pr3756.patch
|
||||
else
|
||||
echo "Applying ${PR3756}"
|
||||
patch -Np1 < $PR3756
|
||||
fi;
|
||||
fi
|
||||
find . -name '*.orig' -exec rm -vf '{}' ';'
|
||||
|
||||
popd
|
||||
echo "Compressing remaining forest"
|
||||
if [ "X$COMPRESSION" = "Xxz" ] ; then
|
||||
SWITCH=cJf
|
||||
else
|
||||
SWITCH=czf
|
||||
fi
|
||||
TARBALL_NAME=${FILE_NAME_ROOT}.tar.${COMPRESSION}
|
||||
tar --exclude-vcs -$SWITCH ${TARBALL_NAME} openjdk
|
||||
mv ${TARBALL_NAME} ..
|
||||
|
||||
popd
|
||||
echo "Done. You may want to remove the uncompressed version."
|
||||
|
||||
|
||||
@ -21,9 +21,6 @@
|
||||
# Enable release builds by default on relevant arches.
|
||||
%bcond_without release
|
||||
|
||||
# Do not check unpackaged files
|
||||
%define _unpackaged_files_terminate_build 0
|
||||
|
||||
# The -g flag says to use strip -g instead of full strip on DSOs or EXEs.
|
||||
# This fixes detailed NMT and other tools which need minimal debug info.
|
||||
%global _find_debuginfo_opts -g
|
||||
@ -32,7 +29,6 @@
|
||||
# also necessary when passing it as parameter to other macros. If not macro, then it is considered a switch
|
||||
# see the difference between global and define:
|
||||
# See https://github.com/rpm-software-management/rpm/issues/127 to comments at "pmatilai commented on Aug 18, 2017"
|
||||
# (initiated in https://bugzilla.redhat.com/show_bug.cgi?id=1482192)
|
||||
%global debug_suffix_unquoted -slowdebug
|
||||
# quoted one for shell operations
|
||||
%global debug_suffix "%{debug_suffix_unquoted}"
|
||||
@ -56,11 +52,12 @@
|
||||
%endif
|
||||
|
||||
%global aarch64 aarch64
|
||||
%global jit_arches x86_64 %{aarch64}
|
||||
%global sa_arches x86_64 %{aarch64}
|
||||
%global jfr_arches x86_64 %{aarch64}
|
||||
|
||||
# By default, we build a debug build during main build on JIT architectures
|
||||
%if %{with slowdebug}
|
||||
%global include_debug_build 1
|
||||
%endif
|
||||
|
||||
%if %{include_debug_build}
|
||||
%global build_loop2 %{debug_suffix}
|
||||
@ -74,7 +71,11 @@
|
||||
# is expected in one single case at the end of the build
|
||||
%global rev_build_loop %{build_loop2} %{build_loop1}
|
||||
|
||||
%ifarch %{jit_arches}
|
||||
%global bootstrap_build 1
|
||||
%else
|
||||
%global bootstrap_build 0
|
||||
%endif
|
||||
|
||||
%global release_targets images zip-docs
|
||||
# No docs nor bootcycle for debug builds
|
||||
@ -96,24 +97,12 @@
|
||||
%global NSS_LIBDIR %(pkg-config --variable=libdir nss)
|
||||
%global NSS_LIBS %(pkg-config --libs nss)
|
||||
%global NSS_CFLAGS %(pkg-config --cflags nss-softokn)
|
||||
# see https://bugzilla.redhat.com/show_bug.cgi?id=1332456
|
||||
%global NSSSOFTOKN_BUILDTIME_NUMBER %(pkg-config --modversion nss-softokn || : )
|
||||
%global NSS_BUILDTIME_NUMBER %(pkg-config --modversion nss || : )
|
||||
# this is workaround for processing of requires during srpm creation
|
||||
%global NSSSOFTOKN_BUILDTIME_VERSION %(if [ "x%{NSSSOFTOKN_BUILDTIME_NUMBER}" == "x" ] ; then echo "" ;else echo ">= %{NSSSOFTOKN_BUILDTIME_NUMBER}" ;fi)
|
||||
%global NSS_BUILDTIME_VERSION %(if [ "x%{NSS_BUILDTIME_NUMBER}" == "x" ] ; then echo "" ;else echo ">= %{NSS_BUILDTIME_NUMBER}" ;fi)
|
||||
|
||||
|
||||
# Fix for https://bugzilla.redhat.com/show_bug.cgi?id=1111349.
|
||||
# See also https://bugzilla.redhat.com/show_bug.cgi?id=1590796
|
||||
# as to why some libraries *cannot* be excluded. In particular,
|
||||
# these are:
|
||||
# libjsig.so, libjava.so, libjawt.so, libjvm.so and libverify.so
|
||||
%global _privatelibs libatk-wrapper[.]so.*|libattach[.]so.*|libawt_headless[.]so.*|libawt[.]so.*|libawt_xawt[.]so.*|libdt_socket[.]so.*|libfontmanager[.]so.*|libhprof[.]so.*|libinstrument[.]so.*|libj2gss[.]so.*|libj2pcsc[.]so.*|libj2pkcs11[.]so.*|libjaas_unix[.]so.*|libjava_crw_demo[.]so.*|libjavajpeg[.]so.*|libjdwp[.]so.*|libjli[.]so.*|libjsdt[.]so.*|libjsoundalsa[.]so.*|libjsound[.]so.*|liblcms[.]so.*|libmanagement[.]so.*|libmlib_image[.]so.*|libnet[.]so.*|libnio[.]so.*|libnpt[.]so.*|libsaproc[.]so.*|libsctp[.]so.*|libsplashscreen[.]so.*|libsunec[.]so.*|libunpack[.]so.*|libzip[.]so.*|lib[.]so\\(SUNWprivate_.*
|
||||
|
||||
%global __provides_exclude ^(%{_privatelibs})$
|
||||
%global __requires_exclude ^(%{_privatelibs})$
|
||||
|
||||
# In some cases, the arch used by the JDK does
|
||||
# not match _arch.
|
||||
# Also, in some cases, the machine name used by SystemTap
|
||||
@ -127,7 +116,11 @@
|
||||
%global stapinstall arm64
|
||||
%endif
|
||||
|
||||
%ifarch %{jit_arches}
|
||||
%global with_systemtap 1
|
||||
%else
|
||||
%global with_systemtap 0
|
||||
%endif
|
||||
|
||||
# New Version-String scheme-style defines
|
||||
%global majorver 8
|
||||
@ -152,14 +145,11 @@
|
||||
%global origin openjdk
|
||||
%global origin_nice OpenJDK
|
||||
%global top_level_dir_name %{origin}
|
||||
# note, following three variables are sedded from update_sources if used correctly. Hardcode them rather there.
|
||||
%global shenandoah_project aarch64-port
|
||||
%global shenandoah_repo jdk8u-shenandoah
|
||||
%global shenandoah_revision aarch64-shenandoah-jdk8u262-b05
|
||||
# Define old aarch64/jdk8u tree variables for compatibility
|
||||
%global project %{shenandoah_project}
|
||||
%global repo %{shenandoah_repo}
|
||||
%global revision %{shenandoah_revision}
|
||||
%global project aarch64-port
|
||||
%global repo jdk8u-shenandoah
|
||||
%global revision aarch64-shenandoah-jdk8u262-b10
|
||||
%global full_revision %{project}-%{repo}-%{revision}
|
||||
# Define IcedTea version used for SystemTap tapsets and desktop files
|
||||
%global icedteaver 3.15.0
|
||||
|
||||
@ -170,7 +160,7 @@
|
||||
# eg jdk8u60-b27 -> b27
|
||||
%global buildver %(VERSION=%{revision}; echo ${VERSION##*-})
|
||||
# priority must be 7 digits in total. The expression is workarounding tip
|
||||
%global priority %(TIP=1800%{updatever}; echo ${TIP/tip/999})
|
||||
%global priority 1800%{updatever}
|
||||
|
||||
%global javaver 1.%{majorver}.0
|
||||
|
||||
@ -185,6 +175,16 @@
|
||||
%define uniquejavadocdir() %{expand:%{fullversion}%{?1}}
|
||||
# main id and dir of this jdk
|
||||
%define uniquesuffix() %{expand:%{fullversion}.%{_arch}%{?1}}
|
||||
|
||||
%global _privatelibs libatk-wrapper[.]so.*|libattach[.]so.*|libawt_headless[.]so.*|libawt[.]so.*|libawt_xawt[.]so.*|libdt_socket[.]so.*|libfontmanager[.]so.*|libhprof[.]so.*|libinstrument[.]so.*|libj2gss[.]so.*|libj2pcsc[.]so.*|libj2pkcs11[.]so.*|libjaas_unix[.]so.*|libjava_crw_demo[.]so.*|libjavajpeg[.]so.*|libjdwp[.]so.*|libjli[.]so.*|libjsdt[.]so.*|libjsoundalsa[.]so.*|libjsound[.]so.*|liblcms[.]so.*|libmanagement[.]so.*|libmlib_image[.]so.*|libnet[.]so.*|libnio[.]so.*|libnpt[.]so.*|libsaproc[.]so.*|libsctp[.]so.*|libsplashscreen[.]so.*|libsunec[.]so.*|libunpack[.]so.*|libzip[.]so.*|lib[.]so\\(SUNWprivate_.*
|
||||
%global _publiclibs libjawt[.]so.*|libjava[.]so.*|libjvm[.]so.*|libverify[.]so.*|libjsig[.]so.*
|
||||
|
||||
%global __provides_exclude ^(%{_privatelibs})$
|
||||
%global __requires_exclude ^(%{_privatelibs})$
|
||||
# Never generate lib-style provides/requires for slowdebug packages
|
||||
%global __provides_exclude_from ^.*/%{uniquesuffix -- %{debug_suffix_unquoted}}/.*$
|
||||
%global __requires_exclude_from ^.*/%{uniquesuffix -- %{debug_suffix_unquoted}}/.*$
|
||||
|
||||
%global etcjavasubdir %{_sysconfdir}/java/java-%{javaver}-%{origin}
|
||||
%define etcjavadir() %{expand:%{etcjavasubdir}/%{uniquesuffix -- %{?1}}}
|
||||
|
||||
@ -329,6 +329,9 @@ alternatives \\
|
||||
--slave %{_bindir}/jconsole jconsole %{sdkbindir -- %{?1}}/jconsole \\
|
||||
--slave %{_bindir}/jdb jdb %{sdkbindir -- %{?1}}/jdb \\
|
||||
--slave %{_bindir}/jdeps jdeps %{sdkbindir -- %{?1}}/jdeps \\
|
||||
%ifarch %{jfr_arches}
|
||||
--slave %{_bindir}/jfr jfr %{sdkbindir -- %{?1}}/jfr \\
|
||||
%endif
|
||||
--slave %{_bindir}/jhat jhat %{sdkbindir -- %{?1}}/jhat \\
|
||||
--slave %{_bindir}/jinfo jinfo %{sdkbindir -- %{?1}}/jinfo \\
|
||||
--slave %{_bindir}/jmap jmap %{sdkbindir -- %{?1}}/jmap \\
|
||||
@ -542,8 +545,10 @@ exit 0
|
||||
%{_mandir}/man1/policytool-%{uniquesuffix -- %{?1}}.1*
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/security/nss.cfg
|
||||
%config(noreplace) %{etcjavadir -- %{?1}}/lib/security/nss.cfg
|
||||
%ifarch %{jit_arches}
|
||||
%attr(444, root, root) %ghost %{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/server/classes.jsa
|
||||
%attr(444, root, root) %ghost %{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/client/classes.jsa
|
||||
%endif
|
||||
%dir %{etcjavasubdir}
|
||||
%dir %{etcjavadir -- %{?1}}
|
||||
%dir %{etcjavadir -- %{?1}}/lib
|
||||
@ -582,7 +587,9 @@ exit 0
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libnet.so
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libnio.so
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libnpt.so
|
||||
%ifarch %{sa_arches}
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libsaproc.so
|
||||
%endif
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libsctp.so
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libsunec.so
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libunpack.so
|
||||
@ -621,12 +628,20 @@ exit 0
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/sunjce_provider.jar
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/sunpkcs11.jar
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/zipfs.jar
|
||||
%ifarch %{jfr_arches}
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/jfr.jar
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/jfr/default.jfc
|
||||
%{_jvmdir}/%{jredir -- %{?1}}/lib/jfr/profile.jfc
|
||||
%endif
|
||||
|
||||
%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/images
|
||||
%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/images/cursors
|
||||
%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/management
|
||||
%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/cmm
|
||||
%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/ext
|
||||
%ifarch %{jfr_arches}
|
||||
%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/jfr
|
||||
%endif
|
||||
}
|
||||
|
||||
%define files_devel() %{expand:
|
||||
@ -654,6 +669,9 @@ exit 0
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jconsole
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jdb
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jdeps
|
||||
%ifarch %{jfr_arches}
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jfr
|
||||
%endif
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jhat
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jinfo
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jjs
|
||||
@ -689,7 +707,9 @@ exit 0
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/ir.idl
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/jconsole.jar
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/orb.idl
|
||||
%ifarch %{sa_arches}
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/sa-jdi.jar
|
||||
%endif
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/dt.jar
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/jexec
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/tools.jar
|
||||
@ -790,7 +810,7 @@ Requires: ca-certificates
|
||||
# Require javapackages-filesystem for ownership of /usr/lib/jvm/
|
||||
Requires: javapackages-filesystem
|
||||
# Require zone-info data provided by tzdata-java sub-package
|
||||
Requires: tzdata-java >= 2015d
|
||||
Requires: tzdata-java >= 2020a
|
||||
# libsctp.so.1 is being `dlopen`ed on demand
|
||||
Requires: lksctp-tools%{?_isa}
|
||||
# there is a need to depend on the exact version of NSS
|
||||
@ -823,10 +843,6 @@ Provides: java-%{javaver}-%{origin}-headless%{?1} = %{epoch}:%{version}-%{releas
|
||||
Provides: java-%{javaver}-headless%{?1} = %{epoch}:%{version}-%{release}
|
||||
Provides: java-%{origin}-headless%{?1} = %{epoch}:%{version}-%{release}
|
||||
Provides: java-headless%{?1} = %{epoch}:%{version}-%{release}
|
||||
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1312019
|
||||
Provides: /usr/bin/jjs
|
||||
|
||||
}
|
||||
|
||||
%define java_devel_rpo() %{expand:
|
||||
@ -899,7 +915,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r
|
||||
|
||||
Name: java-%{javaver}-%{origin}
|
||||
Version: %{javaver}.%{updatever}.%{buildver}
|
||||
Release: 9
|
||||
Release: 0
|
||||
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
|
||||
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
|
||||
# also included the epoch in their virtual provides. This created a
|
||||
@ -925,17 +941,9 @@ Group: Development/Languages
|
||||
# The PCSClite headers are under a BSD with advertising license
|
||||
# The elliptic curve cryptography (ECC) source code is licensed under the LGPLv2.1 or any later version
|
||||
License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib
|
||||
URL: http://openjdk.java.net
|
||||
URL: http://openjdk.java.net/
|
||||
|
||||
# Shenandoah HotSpot
|
||||
# aarch64-port/jdk8u-shenandoah contains an integration forest of
|
||||
# OpenJDK 8u, the aarch64 port and Shenandoah
|
||||
# To regenerate, use:
|
||||
# VERSION=%%{shenandoah_revision}
|
||||
# FILE_NAME_ROOT=%%{shenandoah_project}-%%{shenandoah_repo}-${VERSION}
|
||||
# REPO_ROOT=<path to checked-out repository> generate_source_tarball.sh
|
||||
# where the source is obtained from http://hg.openjdk.java.net/%%{project}/%%{repo}
|
||||
Source0: %{shenandoah_revision}.tar.xz
|
||||
Source0: %{full_revision}.tar.xz
|
||||
|
||||
# Custom README for -src subpackage
|
||||
Source2: README.md
|
||||
@ -1010,7 +1018,6 @@ Patch75: Add-ability-to-configure-third-port-for-remote-JMX.patch
|
||||
Patch76: 8203196-C1-emits-incorrect-code-due-to-integer-overf.patch
|
||||
Patch77: 8190332-PngReader-throws-NegativeArraySizeException-.patch
|
||||
Patch78: 8171410-aarch64-long-multiplyExact-shifts-by-31-inst.patch
|
||||
Patch81: fix-incorrect-offset-for-oop-field-with-weak-memory-.patch
|
||||
Patch83: 8204947-Port-ShenandoahTaskTerminator-to-mainline-an.patch
|
||||
Patch85: 8139041-Redundant-DMB-instructions.patch
|
||||
|
||||
@ -1019,6 +1026,14 @@ Patch86: 6858051-Create-GC-worker-threads-dynamically.patch
|
||||
Patch87: 6858051-Add-a-switch-for-the-dynamic-thread-related-.patch
|
||||
Patch88: dismiss-warnings-in-GCC-8.X.patch
|
||||
|
||||
# 8u262
|
||||
Patch89: 8144993-Elide-redundant-memory-barrier-after-AllocationNode.patch
|
||||
Patch90: 8223504-improve-performance-of-forall-loops-by-better.patch
|
||||
Patch91: add-vm-option-BoxTypeCachedMax-for-Integer-and-Long-cache.patch
|
||||
Patch92: 8080289-8040213-8189067-move-the-store-out-of-the-loop.patch
|
||||
Patch93: fast-serializer-jdk8.patch
|
||||
Patch94: 8182397-race-in-field-updates.patch
|
||||
|
||||
#############################################
|
||||
#
|
||||
# Upstreamable patches
|
||||
@ -1342,7 +1357,6 @@ if [ %{include_debug_build} -eq 0 -a %{include_normal_build} -eq 0 ] ; then
|
||||
exit 13
|
||||
fi
|
||||
%setup -q -c -n %{uniquesuffix ""} -T -a 0
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1189084
|
||||
prioritylength=`expr length %{priority}`
|
||||
if [ $prioritylength -ne 7 ] ; then
|
||||
echo "priority must be 7 digits in total, violated"
|
||||
@ -1401,12 +1415,17 @@ pushd %{top_level_dir_name}
|
||||
%patch76 -p1
|
||||
%patch77 -p1
|
||||
%patch78 -p1
|
||||
%patch81 -p1
|
||||
%patch83 -p1
|
||||
%patch85 -p1
|
||||
%patch86 -p1
|
||||
%patch87 -p1
|
||||
%patch88 -p1
|
||||
%patch89 -p1
|
||||
%patch90 -p1
|
||||
%patch91 -p1
|
||||
%patch92 -p1
|
||||
%patch93 -p1
|
||||
%patch94 -p1
|
||||
|
||||
popd
|
||||
|
||||
@ -1505,10 +1524,18 @@ mkdir -p %{buildoutputdir -- $suffix}
|
||||
pushd %{buildoutputdir -- $suffix}
|
||||
|
||||
bash ${top_srcdir_abs_path}/configure \
|
||||
%ifarch %{jfr_arches}
|
||||
--enable-jfr \
|
||||
%endif
|
||||
--with-native-debug-symbols=internal \
|
||||
--with-milestone="fcs" \
|
||||
--with-update-version=%{updatever} \
|
||||
--with-build-number=%{buildver} \
|
||||
--with-company-name="Boole" \
|
||||
--with-vendor-name="Boole" \
|
||||
--with-vendor-url="https://openeuler.org/" \
|
||||
--with-vendor-bug-url="https://gitee.com/src-openeuler/openjdk-1.8.0/issues/" \
|
||||
--with-vendor-vm-bug-url="https://gitee.com/src-openeuler/openjdk-1.8.0/issues/" \
|
||||
--with-debug-level=$debugbuild \
|
||||
--enable-unlimited-crypto \
|
||||
--with-zlib=system \
|
||||
@ -1538,7 +1565,6 @@ make \
|
||||
|
||||
# the build (erroneously) removes read permissions from some jars
|
||||
# this is a regression in OpenJDK 7 (our compiler):
|
||||
# http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1437
|
||||
find images/%{jdkimage} -iname '*.jar' -exec chmod ugo+r {} \;
|
||||
chmod ugo+r images/%{jdkimage}/lib/ct.sym
|
||||
|
||||
@ -1629,9 +1655,7 @@ done
|
||||
# Make sure gdb can do a backtrace based on line numbers on libjvm.so
|
||||
# javaCalls.cpp:58 should map to:
|
||||
# http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/ff3b27e6bcc2/src/share/vm/runtime/javaCalls.cpp#l58
|
||||
# Using line number 1 might cause build problems. See:
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1539664
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1538767
|
||||
# Using line number 1 might cause build problems.
|
||||
gdb -q "$JAVA_HOME/bin/java" <<EOF | tee gdb.out
|
||||
handle SIGSEGV pass nostop noprint
|
||||
handle SIGILL pass nostop noprint
|
||||
@ -1753,7 +1777,6 @@ for e in jconsole$suffix policytool$suffix ; do
|
||||
done
|
||||
|
||||
# Install /etc/.java/.systemPrefs/ directory
|
||||
# See https://bugzilla.redhat.com/show_bug.cgi?id=741821
|
||||
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/.java/.systemPrefs
|
||||
|
||||
# Find non-documentation demo files.
|
||||
@ -1826,7 +1849,6 @@ find $RPM_BUILD_ROOT%{_jvmdir}/%{sdkdir -- $suffix}/demo \
|
||||
%endif
|
||||
|
||||
bash %{SOURCE20} $RPM_BUILD_ROOT/%{_jvmdir}/%{jredir -- $suffix} %{javaver}
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1183793
|
||||
touch -t 201401010000 $RPM_BUILD_ROOT/%{_jvmdir}/%{jredir -- $suffix}/lib/security/java.security
|
||||
|
||||
# moving config files to /etc
|
||||
@ -1850,8 +1872,6 @@ done
|
||||
%if %{include_normal_build}
|
||||
# intentionally only for non-debug
|
||||
%pretrans headless -p <lua>
|
||||
-- see https://bugzilla.redhat.com/show_bug.cgi?id=1038092 for whole issue
|
||||
-- see https://bugzilla.redhat.com/show_bug.cgi?id=1290388 for pretrans over pre
|
||||
-- if copy-jdk-configs is in transaction, it installs in pretrans to temp
|
||||
-- if copy_jdk_configs is in temp, then it means that copy-jdk-configs is in transaction and so is
|
||||
-- preferred over one in %%{_libexecdir}. If it is not in transaction, then depends
|
||||
@ -2025,6 +2045,17 @@ require "copy_jdk_configs.lua"
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Jul 18 2020 jdkboy <guoge1@huawei.com> - 1:1.8.0.262-b10.0
|
||||
- Update to aarch64-shenandoah-jdk8u-8u262-b10
|
||||
- add 8144993-Elide-redundant-memory-barrier-after-AllocationNode.patch
|
||||
- add 8223504-improve-performance-of-forall-loops-by-better.patch
|
||||
- add add-vm-option-BoxTypeCachedMax-for-Integer-and-Long-cache.patch
|
||||
- add 8080289-8040213-8189067-move-the-store-out-of-the-loop.patch
|
||||
- add fast-serializer-jdk8.patch
|
||||
- add 8182397-race-in-field-updates.patch
|
||||
- add --with-company-name="Boole"
|
||||
- remove fix-incorrect-offset-for-oop-field-with-weak-memory-.patch
|
||||
|
||||
* Thu Jun 11 2020 jdkboy <guoge1@huawei.com> - 1:1.8.0.262-b05.9
|
||||
- Update to aarch64-shenandoah-jdk8u-8u262-b05
|
||||
|
||||
|
||||
2
sources
Normal file
2
sources
Normal file
@ -0,0 +1,2 @@
|
||||
SHA512 (tapsets-icedtea-3.15.0.tar.xz) = c752a197cb3d812d50c35e11e4722772be40096c81d2a57933e0d9b8a3c708b9c157b8108a4e33a06ca7bb81648170994408c75d6f69d5ff12785d0c31009671
|
||||
SHA512 (aarch64-port-jdk8u-shenandoah-aarch64-shenandoah-jdk8u262-b10.tar.xz) = ed4e67d3b6254113cbe93f47feae2dbbc205995b7a0ec613c87d1c9fc037c9275f332bcdb9c4b7a158e27dfbecb4772671b64084e47f5d1b25ba4677b27c7096
|
||||
95
update_main_sources.sh
Executable file
95
update_main_sources.sh
Executable file
@ -0,0 +1,95 @@
|
||||
#!/bin/bash -x
|
||||
# Generates the 'source tarball' for JDK 8 projects and update spec infrastructure
|
||||
# By default, this script regenerate source as they are currently used.
|
||||
# so if the version of sources change, this file changes and is pushed
|
||||
#
|
||||
# In any case you have to set PROJECT_NAME REPO_NAME and VERSION. eg:
|
||||
# PROJECT_NAME=jdk8u OR aarch64-port
|
||||
# REPO_NAME=jdk8u60 OR jdk8u60
|
||||
# VERSION=jdk8u60-b27 OR aarch64-jdk8u65-b17 OR for head, keyword 'tip' should do the job there
|
||||
#
|
||||
# If you don't, default are used and so already uploaded tarball regenerated
|
||||
# They are used to create correct name and are used in construction of sources url (unless REPO_ROOT is set)
|
||||
#
|
||||
# For other useful variables see generate_source_tarball.sh
|
||||
#
|
||||
# the used values are then substituted to spec and sources
|
||||
|
||||
if [ ! "x$PR2126" = "x" ] ; then
|
||||
if [ ! -f "$PR2126" ] ; then
|
||||
echo "You have specified PR2126 as $PR2126 but it does not exists. exiting"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
if [ "x$PROJECT_NAME" = "x" ] ; then
|
||||
PROJECT_NAME="aarch64-port"
|
||||
fi
|
||||
if [ "x$REPO_NAME" = "x" ] ; then
|
||||
REPO_NAME="jdk8u-shenandoah"
|
||||
fi
|
||||
if [ "x$VERSION" = "x" ] ; then
|
||||
VERSION="aarch64-shenandoah-jdk8u262-b10"
|
||||
fi
|
||||
|
||||
if [ "x$COMPRESSION" = "x" ] ; then
|
||||
# rhel 5 needs tar.gz
|
||||
COMPRESSION=xz
|
||||
fi
|
||||
if [ "x$FILE_NAME_ROOT" = "x" ] ; then
|
||||
FILE_NAME_ROOT=${PROJECT_NAME}-${REPO_NAME}-${VERSION}
|
||||
fi
|
||||
if [ "x$PKG" = "x" ] ; then
|
||||
URL=`cat .git/config | grep url`
|
||||
PKG=${URL##*/}
|
||||
fi
|
||||
if [ "x$SPEC" = "x" ] ; then
|
||||
SPEC=${PKG}.spec
|
||||
fi
|
||||
if [ "x$RELEASE" = "x" ] ; then
|
||||
RELEASE=1
|
||||
fi
|
||||
|
||||
FILENAME=${FILE_NAME_ROOT}.tar.${COMPRESSION}
|
||||
|
||||
if [ ! -f ${FILENAME} ] ; then
|
||||
echo "Generating ${FILENAME}"
|
||||
. ./generate_source_tarball.sh
|
||||
else
|
||||
echo "${FILENAME} already exists, using"
|
||||
fi
|
||||
|
||||
|
||||
echo "Touching spec: $SPEC"
|
||||
echo sed -i "s/^%global\s\+project.*/%global project ${PROJECT_NAME}/" $SPEC
|
||||
echo sed -i "s/^%global\s\+repo.*/%global repo ${REPO_NAME}/" $SPEC
|
||||
echo sed -i "s/^%global\s\+revision.*/%global revision ${VERSION}/" $SPEC
|
||||
# updated sources, resetting release
|
||||
echo sed -i "s/^Release:.*/Release: $RELEASE.%{buildver}%{?dist}/" $SPEC
|
||||
|
||||
echo "New sources"
|
||||
cat sources
|
||||
a_sources=`cat sources | sed "s/.*(//g" | sed "s/).*//g" | sed "s/.*\s\+//g"`
|
||||
echo " you can get inspired by following %changelog template:"
|
||||
user_name=`whoami`
|
||||
user_record=$(getent passwd $user_name)
|
||||
user_gecos_field=$(echo "$user_record" | cut -d ':' -f 5)
|
||||
user_full_name=$(echo "$user_gecos_field" | cut -d ',' -f 1)
|
||||
spec_date=`date +"%a %b %d %Y"`
|
||||
# See spec:
|
||||
revision_helper=`echo ${MAIN_VERSION%-*}`
|
||||
updatever=`echo ${revision_helper##*u}`
|
||||
buildver=`echo ${MAIN_VERSION##*-}`
|
||||
echo "* $spec_date $user_full_name <$user_name@redhat.com> - 1:1.8.0.$updatever-$RELEASE.$buildver"
|
||||
echo "- updated to $MAIN_VERSION (from $PROJECT_NAME/$MAIN_REPO_NAME)"
|
||||
echo "- updated to $VERSION (from $PROJECT_NAME/$REPO_NAME) of hotspot"
|
||||
echo "- used $FILENAME as new sources"
|
||||
echo "- used $FILENAME_SH as new sources for hotspot"
|
||||
|
||||
echo " execute:"
|
||||
echo "fedpkg/rhpkg new-sources "$a_sources
|
||||
echo " to upload sources"
|
||||
echo "you can verify by fedpkg/rhpkg prep --arch XXXX on all architectures: x86_64 i386 i586 i686 ppc ppc64 ppc64le s390 s390x aarch64 armv7hl"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user