# HG changeset patch # User andrew # Date 1597606769 -3600 # Sun Aug 16 20:39:29 2020 +0100 # Node ID f83192268a5a92e43e4f06bc616f56b503d4b12f # Parent cdd717f721013ae4ab2f23b01bff9e2f10505dc7 # Parent 0943ff57e15472fd5bb9d97c511525e6b1541ce6 Merge jdk8u272-b03 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -1497,3 +1497,4 @@ 014319f04f71d5e84bc453e2b6fe6b877ab41f3c aarch64-shenandoah-jdk8u272-b01 414c1dcfc3f3620b73cc7faf23f9a3ffde83b240 jdk8u272-b02 21931e4cd1dc539580d0c76627b9d9137dda60d2 aarch64-shenandoah-jdk8u272-b02 +e649f213636810823e761473ac871ce55a5235f7 jdk8u272-b03 diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -994,6 +994,10 @@ return res; } } else { + // The barrier is required to prevent reordering of the free chunk check + // and the klass read. + OrderAccess::loadload(); + // must read from what 'p' points to in each loop. Klass* k = ((volatile oopDesc*)p)->klass_or_null(); if (k != NULL) { @@ -1049,6 +1053,10 @@ return res; } } else { + // The barrier is required to prevent reordering of the free chunk check + // and the klass read. + OrderAccess::loadload(); + // must read from what 'p' points to in each loop. Klass* k = ((volatile oopDesc*)p)->klass_or_null(); // We trust the size of any object that has a non-NULL @@ -1111,6 +1119,11 @@ // assert(CollectedHeap::use_parallel_gc_threads() || _bt.block_start(p) == p, // "Should be a block boundary"); if (FreeChunk::indicatesFreeChunk(p)) return false; + + // The barrier is required to prevent reordering of the free chunk check + // and the klass read. + OrderAccess::loadload(); + Klass* k = oop(p)->klass_or_null(); if (k != NULL) { // Ignore mark word because it may have been used to diff --git a/src/share/vm/jfr/periodic/sampling/jfrThreadSampler.cpp b/src/share/vm/jfr/periodic/sampling/jfrThreadSampler.cpp --- a/src/share/vm/jfr/periodic/sampling/jfrThreadSampler.cpp +++ b/src/share/vm/jfr/periodic/sampling/jfrThreadSampler.cpp @@ -494,8 +494,8 @@ last_native_ms = last_java_ms; } _sample.signal(); - jlong java_interval = _interval_java == 0 ? max_jlong : MAX2(_interval_java, 10); - jlong native_interval = _interval_native == 0 ? max_jlong : MAX2(_interval_native, 10); + jlong java_interval = _interval_java == 0 ? max_jlong : MAX2(_interval_java, 1); + jlong native_interval = _interval_native == 0 ? max_jlong : MAX2(_interval_native, 1); jlong now_ms = get_monotonic_ms(); diff --git a/src/share/vm/opto/loopTransform.cpp b/src/share/vm/opto/loopTransform.cpp --- a/src/share/vm/opto/loopTransform.cpp +++ b/src/share/vm/opto/loopTransform.cpp @@ -1223,20 +1223,14 @@ Node *opaq = NULL; if (adjust_min_trip) { // If not maximally unrolling, need adjustment // Search for zero-trip guard. - assert( loop_head->is_main_loop(), "" ); - assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" ); - Node *iff = ctrl->in(0); - assert( iff->Opcode() == Op_If, "" ); - Node *bol = iff->in(1); - assert( bol->Opcode() == Op_Bool, "" ); - Node *cmp = bol->in(1); - assert( cmp->Opcode() == Op_CmpI, "" ); - opaq = cmp->in(2); - // Occasionally it's possible for a zero-trip guard Opaque1 node to be - // optimized away and then another round of loop opts attempted. - // We can not optimize this particular loop in that case. - if (opaq->Opcode() != Op_Opaque1) - return; // Cannot find zero-trip guard! Bail out! + + // Check the shape of the graph at the loop entry. If an inappropriate + // graph shape is encountered, the compiler bails out loop unrolling; + // compilation of the method will still succeed. + if (!is_canonical_main_loop_entry(loop_head)) { + return; + } + opaq = ctrl->in(0)->in(1)->in(1)->in(2); // Zero-trip test uses an 'opaque' node which is not shared. assert(opaq->outcnt() == 1 && opaq->in(1) == limit, ""); } @@ -1806,7 +1800,6 @@ #endif assert(RangeCheckElimination, ""); CountedLoopNode *cl = loop->_head->as_CountedLoop(); - assert(cl->is_main_loop(), ""); // protect against stride not being a constant if (!cl->stride_is_con()) @@ -1818,20 +1811,17 @@ // to not ever trip end tests Node *main_limit = cl->limit(); + // Check graph shape. Cannot optimize a loop if zero-trip + // Opaque1 node is optimized away and then another round + // of loop opts attempted. + if (!is_canonical_main_loop_entry(cl)) { + return; + } + // Need to find the main-loop zero-trip guard Node *ctrl = cl->in(LoopNode::EntryControl); - assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, ""); Node *iffm = ctrl->in(0); - assert(iffm->Opcode() == Op_If, ""); - Node *bolzm = iffm->in(1); - assert(bolzm->Opcode() == Op_Bool, ""); - Node *cmpzm = bolzm->in(1); - assert(cmpzm->is_Cmp(), ""); - Node *opqzm = cmpzm->in(2); - // Can not optimize a loop if zero-trip Opaque1 node is optimized - // away and then another round of loop opts attempted. - if (opqzm->Opcode() != Op_Opaque1) - return; + Node *opqzm = iffm->in(1)->in(1)->in(2); assert(opqzm->in(1) == main_limit, "do not understand situation"); // Find the pre-loop limit; we will expand it's iterations to diff --git a/src/share/vm/opto/loopnode.cpp b/src/share/vm/opto/loopnode.cpp --- a/src/share/vm/opto/loopnode.cpp +++ b/src/share/vm/opto/loopnode.cpp @@ -3292,6 +3292,41 @@ return LCA; } +// Check the shape of the graph at the loop entry. In some cases, +// the shape of the graph does not match the shape outlined below. +// That is caused by the Opaque1 node "protecting" the shape of +// the graph being removed by, for example, the IGVN performed +// in PhaseIdealLoop::build_and_optimize(). +// +// After the Opaque1 node has been removed, optimizations (e.g., split-if, +// loop unswitching, and IGVN, or a combination of them) can freely change +// the graph's shape. As a result, the graph shape outlined below cannot +// be guaranteed anymore. +bool PhaseIdealLoop::is_canonical_main_loop_entry(CountedLoopNode* cl) { + assert(cl->is_main_loop(), "check should be applied to main loops"); + Node* ctrl = cl->in(LoopNode::EntryControl); + if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) { + return false; + } + Node* iffm = ctrl->in(0); + if (iffm == NULL || !iffm->is_If()) { + return false; + } + Node* bolzm = iffm->in(1); + if (bolzm == NULL || !bolzm->is_Bool()) { + return false; + } + Node* cmpzm = bolzm->in(1); + if (cmpzm == NULL || !cmpzm->is_Cmp()) { + return false; + } + Node* opqzm = cmpzm->in(2); + if (opqzm == NULL || opqzm->Opcode() != Op_Opaque1) { + return false; + } + return true; +} + //------------------------------get_late_ctrl---------------------------------- // Compute latest legal control. Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) { diff --git a/src/share/vm/opto/loopnode.hpp b/src/share/vm/opto/loopnode.hpp --- a/src/share/vm/opto/loopnode.hpp +++ b/src/share/vm/opto/loopnode.hpp @@ -621,6 +621,9 @@ bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop); public: + + static bool is_canonical_main_loop_entry(CountedLoopNode* cl); + bool has_node( Node* n ) const { guarantee(n != NULL, "No Node."); return _nodes[n->_idx] != NULL; diff --git a/src/share/vm/opto/superword.cpp b/src/share/vm/opto/superword.cpp --- a/src/share/vm/opto/superword.cpp +++ b/src/share/vm/opto/superword.cpp @@ -2209,21 +2209,13 @@ //----------------------------get_pre_loop_end--------------------------- // Find pre loop end from main loop. Returns null if none. CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) { - Node* ctrl = cl->in(LoopNode::EntryControl); - if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; - Node* iffm = ctrl->in(0); - if (!iffm->is_If()) return NULL; - Node* bolzm = iffm->in(1); - if (!bolzm->is_Bool()) return NULL; - Node* cmpzm = bolzm->in(1); - if (!cmpzm->is_Cmp()) return NULL; - Node* opqzm = cmpzm->in(2); - // Can not optimize a loop if zero-trip Opaque1 node is optimized - // away and then another round of loop opts attempted. - if (opqzm->Opcode() != Op_Opaque1) { + // The loop cannot be optimized if the graph shape at + // the loop entry is inappropriate. + if (!PhaseIdealLoop::is_canonical_main_loop_entry(cl)) { return NULL; } - Node* p_f = iffm->in(0); + + Node* p_f = cl->in(LoopNode::EntryControl)->in(0)->in(0); if (!p_f->is_IfFalse()) return NULL; if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd(); diff --git a/src/share/vm/runtime/java.hpp b/src/share/vm/runtime/java.hpp --- a/src/share/vm/runtime/java.hpp +++ b/src/share/vm/runtime/java.hpp @@ -138,7 +138,7 @@ return JDK_Version(m); } - static JDK_Version jdk_update(uint8_t major, uint8_t update_number) { + static JDK_Version jdk_update(uint8_t major, uint16_t update_number) { return JDK_Version(major, 0, 0, update_number); }