From bf78f716bd3e58df24ff1e6f4a0104025379f821 Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Tue, 13 Dec 2022 19:07:44 +0000 Subject: [PATCH 01/10] 8295857: Clarify that cleanup code can be skipped when the JVM terminates (e.g. when calling halt()) Reviewed-by: iris Backport-of: c7aca73177339f931f7dfb6627365548a32874f7 --- .../share/classes/java/lang/Runtime.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Runtime.java b/src/java.base/share/classes/java/lang/Runtime.java index fd35265c0cc..ffef8160c25 100644 --- a/src/java.base/share/classes/java/lang/Runtime.java +++ b/src/java.base/share/classes/java/lang/Runtime.java @@ -89,10 +89,14 @@ import jdk.internal.reflect.Reflection; * shutdown sequence. * *

When the JVM terminates, all threads are immediately prevented from executing any further - * Java code. This includes shutdown hooks as well as daemon and non-daemon threads. The - * threads' current methods do not complete normally or abruptly; no {@code finally} clause - * of any method is executed, nor is any {@linkplain Thread.UncaughtExceptionHandler - * uncaught exception handler}. + * Java code. This includes shutdown hooks as well as daemon and non-daemon threads. + * This means, for example, that: + *

* * @implNote * Native code typically uses the @@ -278,7 +282,8 @@ public class Runtime { * @apiNote * This method should be used with extreme caution. Using it may circumvent or disrupt * any cleanup actions intended to be performed by shutdown hooks, possibly leading to - * data corruption. + * data corruption. See the termination section above + * for other possible consequences of halting the Java Virtual Machine. * * @param status * Termination status. By convention, a nonzero status code From c6f22b416072a9be5436f45e2f595ceea228f3bd Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 13 Dec 2022 20:48:13 +0000 Subject: [PATCH 02/10] 8297305: Clarify that javax.lang.model.util.Elements.overrides is irreflexive Reviewed-by: jjg --- .../share/classes/javax/lang/model/util/Elements.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java index f567c7f3b1b..c8849d6f612 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java @@ -622,6 +622,8 @@ public interface Elements { * overrides another method. * When a non-abstract method overrides an abstract one, the * former is also said to implement the latter. + * As implied by JLS {@jls 8.4.8.1}, a method does not + * override itself. The overrides relation is irreflexive. * *

In the simplest and most typical usage, the value of the * {@code type} parameter will simply be the class or interface From 61ab16f79a735a98b3c095daf1b541f4fc5413c0 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 13 Dec 2022 23:20:43 +0000 Subject: [PATCH 03/10] 8298700: Typo in DocTree comment Reviewed-by: darcy --- .../share/classes/com/sun/source/doctree/DocTree.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java index 9d457a739da..7f81af9a507 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java @@ -227,7 +227,7 @@ public interface DocTree { SPEC("spec"), /** - * Used for instances of {@link EndElementTree} + * Used for instances of {@link StartElementTree} * representing the start of an HTML element. */ START_ELEMENT, From 51f0a1ce4b0d72cf7e82e01f7014274d8b7d1575 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Wed, 14 Dec 2022 07:32:28 +0000 Subject: [PATCH 04/10] 8298527: Cygwin's uname -m returns different string than before Reviewed-by: erikj --- make/autoconf/build-aux/config.guess | 74 +++++++++++++--------------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/make/autoconf/build-aux/config.guess b/make/autoconf/build-aux/config.guess index b08072b556c..daf45ae414d 100644 --- a/make/autoconf/build-aux/config.guess +++ b/make/autoconf/build-aux/config.guess @@ -29,7 +29,40 @@ # and fix the broken property, if needed. DIR=`dirname $0` -OUT=`. $DIR/autoconf-config.guess` +OUT=`. $DIR/autoconf-config.guess 2> /dev/null` + +# Handle some cases that autoconf-config.guess is not capable of +if [ "x$OUT" = x ]; then + if [ `uname -s` = Linux ]; then + # Test and fix little endian MIPS. + if [ `uname -m` = mipsel ]; then + OUT=mipsel-unknown-linux-gnu + elif [ `uname -m` = mips64el ]; then + OUT=mips64el-unknown-linux-gnu + # Test and fix little endian PowerPC64. + elif [ `uname -m` = ppc64le ]; then + OUT=powerpc64le-unknown-linux-gnu + # Test and fix LoongArch64. + elif [ `uname -m` = loongarch64 ]; then + OUT=loongarch64-unknown-linux-gnu + # Test and fix RISC-V. + elif [ `uname -m` = riscv64 ]; then + OUT=riscv64-unknown-linux-gnu + fi + # Test and fix cygwin machine arch .x86_64 + elif [[ `uname -s` = CYGWIN* ]]; then + if [ `uname -m` = ".x86_64" ]; then + OUT=x86_64-unknown-cygwin + fi + fi + + if [ "x$OUT" = x ]; then + # Run autoconf-config.guess again to get the error message. + . $DIR/autoconf-config.guess > /dev/null + else + printf "guessed by custom config.guess... " >&2 + fi +fi # Detect C library. # Use '-gnu' suffix on systems that use glibc. @@ -81,45 +114,6 @@ if test $? = 0; then OUT=powerpc$KERNEL_BITMODE`echo $OUT | sed -e 's/[^-]*//'` fi -# Test and fix little endian PowerPC64. -# TODO: should be handled by autoconf-config.guess. -if [ "x$OUT" = x ]; then - if [ `uname -m` = ppc64le ]; then - if [ `uname -s` = Linux ]; then - OUT=powerpc64le-unknown-linux-gnu - fi - fi -fi - -# Test and fix little endian MIPS. -if [ "x$OUT" = x ]; then - if [ `uname -s` = Linux ]; then - if [ `uname -m` = mipsel ]; then - OUT=mipsel-unknown-linux-gnu - elif [ `uname -m` = mips64el ]; then - OUT=mips64el-unknown-linux-gnu - fi - fi -fi - -# Test and fix LoongArch64. -if [ "x$OUT" = x ]; then - if [ `uname -s` = Linux ]; then - if [ `uname -m` = loongarch64 ]; then - OUT=loongarch64-unknown-linux-gnu - fi - fi -fi - -# Test and fix RISC-V. -if [ "x$OUT" = x ]; then - if [ `uname -s` = Linux ]; then - if [ `uname -m` = riscv64 ]; then - OUT=riscv64-unknown-linux-gnu - fi - fi -fi - # Test and fix cpu on macos-aarch64, uname -p reports arm, buildsys expects aarch64 echo $OUT | grep arm-apple-darwin > /dev/null 2> /dev/null if test $? != 0; then From 27d4971182ab1cbe7e6bc40cd22c1c70661a3ab2 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Wed, 14 Dec 2022 10:03:36 +0000 Subject: [PATCH 05/10] 8298520: C2: assert(found_opaque == res) failed: wrong pattern Reviewed-by: thartmann, chagedorn --- src/hotspot/share/opto/loopnode.cpp | 21 +++++++++++++++++++-- src/hotspot/share/opto/loopnode.hpp | 2 ++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp index f8250bf59b4..4f7f2c44f1b 100644 --- a/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp @@ -2547,7 +2547,8 @@ SafePointNode* CountedLoopNode::outer_safepoint() const { Node* CountedLoopNode::skip_predicates_from_entry(Node* ctrl) { while (ctrl != NULL && ctrl->is_Proj() && ctrl->in(0) != NULL && ctrl->in(0)->is_If() && - (ctrl->in(0)->as_If()->proj_out_or_null(1-ctrl->as_Proj()->_con) == NULL || + !is_zero_trip_guard_if(ctrl->in(0)->as_If()) && + (ctrl->in(0)->as_If()->proj_out_or_null(1-ctrl->as_Proj()->_con) == NULL || (ctrl->in(0)->as_If()->proj_out(1-ctrl->as_Proj()->_con)->outcnt() == 1 && ctrl->in(0)->as_If()->proj_out(1-ctrl->as_Proj()->_con)->unique_out()->Opcode() == Op_Halt))) { ctrl = ctrl->in(0)->in(0); @@ -2556,6 +2557,22 @@ Node* CountedLoopNode::skip_predicates_from_entry(Node* ctrl) { return ctrl; } +bool CountedLoopNode::is_zero_trip_guard_if(const IfNode* iff) { + if (iff->in(1) == NULL || !iff->in(1)->is_Bool()) { + return false; + } + if (iff->in(1)->in(1) == NULL || iff->in(1)->in(1)->Opcode() != Op_CmpI) { + return false; + } + if (iff->in(1)->in(1)->in(1) != NULL && iff->in(1)->in(1)->in(1)->Opcode() == Op_OpaqueZeroTripGuard) { + return true; + } + if (iff->in(1)->in(1)->in(2) != NULL && iff->in(1)->in(1)->in(2)->Opcode() == Op_OpaqueZeroTripGuard) { + return true; + } + return false; +} + Node* CountedLoopNode::skip_predicates() { Node* ctrl = in(LoopNode::EntryControl); if (is_main_loop()) { @@ -5459,7 +5476,7 @@ Node* CountedLoopNode::is_canonical_loop_entry() { return NULL; } Node* iffm = ctrl->in(0); - if (iffm == NULL || !iffm->is_If()) { + if (iffm == NULL || iffm->Opcode() != Op_If) { return NULL; } Node* bolzm = iffm->in(1); diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index defb1ad6cbb..aadcf42a592 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -355,6 +355,8 @@ public: #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; #endif + + static bool is_zero_trip_guard_if(const IfNode* iff); }; class LongCountedLoopNode : public BaseCountedLoopNode { From 9bcdfc428597e1465c8a014d816ef671420d22df Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Wed, 14 Dec 2022 11:36:04 +0000 Subject: [PATCH 06/10] 8298425: System.console().readLine() hangs in jshell Reviewed-by: naoto, alanb --- .../execution/JdiDefaultExecutionControl.java | 8 +++- test/langtools/jdk/jshell/ConsoleTest.java | 42 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test/langtools/jdk/jshell/ConsoleTest.java diff --git a/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java b/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java index c9590380064..0044c1b4be4 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java @@ -48,6 +48,7 @@ import com.sun.jdi.StackFrame; import com.sun.jdi.ThreadReference; import com.sun.jdi.VMDisconnectedException; import com.sun.jdi.VirtualMachine; +import java.util.stream.Stream; import jdk.jshell.spi.ExecutionControl; import jdk.jshell.spi.ExecutionEnv; import static jdk.jshell.execution.Util.remoteInputOutput; @@ -96,10 +97,15 @@ public class JdiDefaultExecutionControl extends JdiExecutionControl { // timeout on I/O-socket listener.setSoTimeout(timeout); int port = listener.getLocalPort(); + List augmentedremoteVMOptions = + Stream.concat(env.extraRemoteVMOptions().stream(), + //disable System.console(): + List.of("-Djdk.console=java.base").stream()) + .toList(); // Set-up the JDI connection JdiInitiator jdii = new JdiInitiator(port, - env.extraRemoteVMOptions(), remoteAgent, isLaunch, host, + augmentedremoteVMOptions, remoteAgent, isLaunch, host, timeout, Collections.emptyMap()); VirtualMachine vm = jdii.vm(); Process process = jdii.process(); diff --git a/test/langtools/jdk/jshell/ConsoleTest.java b/test/langtools/jdk/jshell/ConsoleTest.java new file mode 100644 index 00000000000..5d2d8602df7 --- /dev/null +++ b/test/langtools/jdk/jshell/ConsoleTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8298425 + * @summary Verify behavior of System.console() + * @build KullaTesting TestingInputStream + * @run testng ConsoleTest + */ + + +import org.testng.annotations.Test; + +public class ConsoleTest extends KullaTesting { + + @Test + public void testConsole1() { + assertEval("System.console()", "null"); + } + +} From 0bbc4181cdbccfc3a542f306ce1902cc2e9f36cb Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Wed, 14 Dec 2022 13:32:21 +0000 Subject: [PATCH 07/10] 8294902: Undefined Behavior in C2 regalloc with null references Reviewed-by: kvn, vlivanov --- src/hotspot/share/memory/arena.cpp | 1 + src/hotspot/share/opto/bytecodeInfo.cpp | 6 +-- src/hotspot/share/opto/chaitin.hpp | 4 +- src/hotspot/share/opto/postaloc.cpp | 49 ++++++++++--------- src/hotspot/share/runtime/vmStructs.hpp | 15 ++++-- .../share/utilities/globalDefinitions.hpp | 5 ++ .../share/utilities/globalDefinitions_gcc.hpp | 19 +++++-- 7 files changed, 63 insertions(+), 36 deletions(-) diff --git a/src/hotspot/share/memory/arena.cpp b/src/hotspot/share/memory/arena.cpp index 050d129351f..8ae29c1d627 100644 --- a/src/hotspot/share/memory/arena.cpp +++ b/src/hotspot/share/memory/arena.cpp @@ -369,6 +369,7 @@ void *Arena::Arealloc(void* old_ptr, size_t old_size, size_t new_size, AllocFail // Determine if pointer belongs to this Arena or not. bool Arena::contains( const void *ptr ) const { + if (_chunk == NULL) return false; if( (void*)_chunk->bottom() <= ptr && ptr < (void*)_hwm ) return true; // Check for in this chunk for (Chunk *c = _first; c; c = c->next()) { diff --git a/src/hotspot/share/opto/bytecodeInfo.cpp b/src/hotspot/share/opto/bytecodeInfo.cpp index 9c1de4ea3c4..1191913bfb9 100644 --- a/src/hotspot/share/opto/bytecodeInfo.cpp +++ b/src/hotspot/share/opto/bytecodeInfo.cpp @@ -44,7 +44,7 @@ InlineTree::InlineTree(Compile* c, JVMState* caller_jvms, int caller_bci, int max_inline_level) : C(c), - _caller_jvms(caller_jvms), + _caller_jvms(NULL), _method(callee), _late_inline(false), _caller_tree((InlineTree*) caller_tree), @@ -57,13 +57,13 @@ InlineTree::InlineTree(Compile* c, _count_inlines = 0; _forced_inline = false; #endif - if (_caller_jvms != NULL) { + if (caller_jvms != NULL) { // Keep a private copy of the caller_jvms: _caller_jvms = new (C) JVMState(caller_jvms->method(), caller_tree->caller_jvms()); _caller_jvms->set_bci(caller_jvms->bci()); assert(!caller_jvms->should_reexecute(), "there should be no reexecute bytecode with inlining"); + assert(_caller_jvms->same_calls_as(caller_jvms), "consistent JVMS"); } - assert(_caller_jvms->same_calls_as(caller_jvms), "consistent JVMS"); assert((caller_tree == NULL ? 0 : caller_tree->stack_depth() + 1) == stack_depth(), "correct (redundant) depth parameter"); assert(caller_bci == this->caller_bci(), "correct (redundant) bci parameter"); // Update hierarchical counts, count_inline_bcs() and count_inlines() diff --git a/src/hotspot/share/opto/chaitin.hpp b/src/hotspot/share/opto/chaitin.hpp index 3134dbdb9c7..240b638bde3 100644 --- a/src/hotspot/share/opto/chaitin.hpp +++ b/src/hotspot/share/opto/chaitin.hpp @@ -731,8 +731,8 @@ private: int yank_if_dead_recurse(Node *old, Node *orig_old, Block *current_block, Node_List *value, Node_List *regnd); int yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ); - int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List ®nd, bool can_change_regs ); - int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List ®nd ); + int elide_copy( Node *n, int k, Block *current_block, Node_List *value, Node_List *regnd, bool can_change_regs ); + int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List *value, Node_List *regnd ); bool may_be_copy_of_callee( Node *def ) const; // If nreg already contains the same constant as val then eliminate it diff --git a/src/hotspot/share/opto/postaloc.cpp b/src/hotspot/share/opto/postaloc.cpp index 96c30a122bb..579d4cdec4d 100644 --- a/src/hotspot/share/opto/postaloc.cpp +++ b/src/hotspot/share/opto/postaloc.cpp @@ -30,7 +30,7 @@ // See if this register (or pairs, or vector) already contains the value. static bool register_contains_value(Node* val, OptoReg::Name reg, int n_regs, - Node_List& value) { + const Node_List &value) { for (int i = 0; i < n_regs; i++) { OptoReg::Name nreg = OptoReg::add(reg,-i); if (value[nreg] != val) @@ -77,7 +77,7 @@ bool PhaseChaitin::may_be_copy_of_callee( Node *def ) const { //------------------------------yank----------------------------------- // Helper function for yank_if_dead -int PhaseChaitin::yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) { +int PhaseChaitin::yank(Node *old, Block *current_block, Node_List *value, Node_List *regnd) { int blk_adjust=0; Block *oldb = _cfg.get_block_for_node(old); oldb->find_remove(old); @@ -87,9 +87,10 @@ int PhaseChaitin::yank( Node *old, Block *current_block, Node_List *value, Node_ } _cfg.unmap_node_from_block(old); OptoReg::Name old_reg = lrgs(_lrg_map.live_range_id(old)).reg(); - if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available? - value->map(old_reg,NULL); // Yank from value/regnd maps - regnd->map(old_reg,NULL); // This register's value is now unknown + assert(value != NULL || regnd == NULL, "sanity"); + if (value != NULL && regnd != NULL && regnd->at(old_reg) == old) { // Instruction is currently available? + value->map(old_reg, NULL); // Yank from value/regnd maps + regnd->map(old_reg, NULL); // This register's value is now unknown } return blk_adjust; } @@ -161,7 +162,7 @@ int PhaseChaitin::yank_if_dead_recurse(Node *old, Node *orig_old, Block *current // Use the prior value instead of the current value, in an effort to make // the current value go dead. Return block iterator adjustment, in case // we yank some instructions from this block. -int PhaseChaitin::use_prior_register( Node *n, uint idx, Node *def, Block *current_block, Node_List &value, Node_List ®nd ) { +int PhaseChaitin::use_prior_register( Node *n, uint idx, Node *def, Block *current_block, Node_List *value, Node_List *regnd ) { // No effect? if( def == n->in(idx) ) return 0; // Def is currently dead and can be removed? Do not resurrect @@ -207,7 +208,7 @@ int PhaseChaitin::use_prior_register( Node *n, uint idx, Node *def, Block *curre _post_alloc++; // Is old def now dead? We successfully yanked a copy? - return yank_if_dead(old,current_block,&value,®nd); + return yank_if_dead(old,current_block,value,regnd); } @@ -229,7 +230,7 @@ Node *PhaseChaitin::skip_copies( Node *c ) { //------------------------------elide_copy------------------------------------- // Remove (bypass) copies along Node n, edge k. -int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List ®nd, bool can_change_regs ) { +int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List *value, Node_List *regnd, bool can_change_regs ) { int blk_adjust = 0; uint nk_idx = _lrg_map.live_range_id(n->in(k)); @@ -253,11 +254,14 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v // Phis and 2-address instructions cannot change registers so easily - their // outputs must match their input. - if( !can_change_regs ) + if (!can_change_regs) { return blk_adjust; // Only check stupid copies! - + } // Loop backedges won't have a value-mapping yet - if( &value == NULL ) return blk_adjust; + assert(regnd != NULL || value == NULL, "sanity"); + if (value == NULL || regnd == NULL) { + return blk_adjust; + } // Skip through all copies to the _value_ being used. Do not change from // int to pointer. This attempts to jump through a chain of copies, where @@ -273,10 +277,11 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v // See if it happens to already be in the correct register! // (either Phi's direct register, or the common case of the name // never-clobbered original-def register) - if (register_contains_value(val, val_reg, n_regs, value)) { - blk_adjust += use_prior_register(n,k,regnd[val_reg],current_block,value,regnd); - if( n->in(k) == regnd[val_reg] ) // Success! Quit trying - return blk_adjust; + if (register_contains_value(val, val_reg, n_regs, *value)) { + blk_adjust += use_prior_register(n,k,regnd->at(val_reg),current_block,value,regnd); + if (n->in(k) == regnd->at(val_reg)) { + return blk_adjust; // Success! Quit trying + } } // See if we can skip the copy by changing registers. Don't change from @@ -304,7 +309,7 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v if (ignore_self) continue; } - Node *vv = value[reg]; + Node *vv = value->at(reg); // For scalable register, number of registers may be inconsistent between // "val_reg" and "reg". For example, when "val" resides in register // but "reg" is located in stack. @@ -325,7 +330,7 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v last = (n_regs-1); // Looking for the last part of a set } if ((reg&last) != last) continue; // Wrong part of a set - if (!register_contains_value(vv, reg, n_regs, value)) continue; // Different value + if (!register_contains_value(vv, reg, n_regs, *value)) continue; // Different value } if( vv == val || // Got a direct hit? (t && vv && vv->bottom_type() == t && vv->is_Mach() && @@ -333,9 +338,9 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v assert( !n->is_Phi(), "cannot change registers at a Phi so easily" ); if( OptoReg::is_stack(nk_reg) || // CISC-loading from stack OR OptoReg::is_reg(reg) || // turning into a register use OR - regnd[reg]->outcnt()==1 ) { // last use of a spill-load turns into a CISC use - blk_adjust += use_prior_register(n,k,regnd[reg],current_block,value,regnd); - if( n->in(k) == regnd[reg] ) // Success! Quit trying + regnd->at(reg)->outcnt()==1 ) { // last use of a spill-load turns into a CISC use + blk_adjust += use_prior_register(n,k,regnd->at(reg),current_block,value,regnd); + if( n->in(k) == regnd->at(reg) ) // Success! Quit trying return blk_adjust; } // End of if not degrading to a stack } // End of if found value in another register @@ -535,7 +540,7 @@ void PhaseChaitin::post_allocate_copy_removal() { Block* pb = _cfg.get_block_for_node(block->pred(j)); // Remove copies along phi edges for (uint k = 1; k < phi_dex; k++) { - elide_copy(block->get_node(k), j, block, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false); + elide_copy(block->get_node(k), j, block, blk2value[pb->_pre_order], blk2regnd[pb->_pre_order], false); } if (blk2value[pb->_pre_order]) { // Have a mapping on this edge? // See if this predecessor's mappings have been used by everybody @@ -691,7 +696,7 @@ void PhaseChaitin::post_allocate_copy_removal() { // Remove copies along input edges for (k = 1; k < n->req(); k++) { - j -= elide_copy(n, k, block, value, regnd, two_adr != k); + j -= elide_copy(n, k, block, &value, ®nd, two_adr != k); } // Unallocated Nodes define no registers diff --git a/src/hotspot/share/runtime/vmStructs.hpp b/src/hotspot/share/runtime/vmStructs.hpp index 5e9db68bd70..7b0425b17c9 100644 --- a/src/hotspot/share/runtime/vmStructs.hpp +++ b/src/hotspot/share/runtime/vmStructs.hpp @@ -188,13 +188,18 @@ private: #ifdef ASSERT // This macro checks the type of a VMStructEntry by comparing pointer types -#define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \ - {typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; \ - assert(offset_of(typeName, fieldName) < sizeof(typeName), "Illegal nonstatic struct entry, field offset too large"); } +#define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) { \ + static_assert( \ + std::is_convertible< \ + std::add_pointer_t().fieldName)>, \ + std::add_pointer_t>::value, \ + "type mismatch for " XSTR(fieldName) " member of " XSTR(typeName)); \ + assert(offset_of(typeName, fieldName) < sizeof(typeName), "..."); \ +} // This macro checks the type of a volatile VMStructEntry by comparing pointer types -#define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \ - {typedef type dummyvtype; typeName *dummyObj = NULL; volatile dummyvtype* dummy = &dummyObj->fieldName; } +#define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \ + CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, std::add_volatile_t) // This macro checks the type of a static VMStructEntry by comparing pointer types #define CHECK_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \ diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index 3771ac0f277..5c6281eed42 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -35,6 +35,7 @@ #include COMPILER_HEADER(utilities/globalDefinitions) #include +#include class oopDesc; @@ -1287,4 +1288,8 @@ template bool primitive_equals(const K& k0, const K& k1) { // Allow use of C++ thread_local when approved - see JDK-8282469. #define APPROVED_CPP_THREAD_LOCAL thread_local +// Converts any type T to a reference type. +template +std::add_rvalue_reference_t declval() noexcept; + #endif // SHARE_UTILITIES_GLOBALDEFINITIONS_HPP diff --git a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp index 4aed8605182..9ccf8fa2008 100644 --- a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp @@ -139,10 +139,21 @@ inline int g_isfinite(jdouble f) { return isfinite(f); } #endif // _LP64 // gcc warns about applying offsetof() to non-POD object or calculating -// offset directly when base address is NULL. Use 16 to get around the -// warning. The -Wno-invalid-offsetof option could be used to suppress -// this warning, but we instead just avoid the use of offsetof(). -#define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16) +// offset directly when base address is NULL. The -Wno-invalid-offsetof +// option could be used to suppress this warning, but we instead just +// avoid the use of offsetof(). +// +// FIXME: This macro is complex and rather arcane. Perhaps we should +// use offsetof() instead, with the invalid-offsetof warning +// temporarily disabled. +#define offset_of(klass,field) \ +[]() { \ + char space[sizeof (klass)] ATTRIBUTE_ALIGNED(16); \ + klass* dummyObj = (klass*)space; \ + char* c = (char*)(void*)&dummyObj->field; \ + return (size_t)(c - space); \ +}() + #if defined(_LP64) && defined(__APPLE__) #define JLONG_FORMAT "%ld" From 279170147a10ec2da2242b4dcb3279c41c471000 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Wed, 14 Dec 2022 13:36:36 +0000 Subject: [PATCH 08/10] 8298296: gc/TestFullGCCount.java fails with "System.gc collections miscounted." Reviewed-by: tschatzl, ayang --- test/hotspot/jtreg/ProblemList.txt | 1 - test/hotspot/jtreg/gc/TestFullGCCount.java | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 1cd805f7450..66121e1dcb1 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -80,7 +80,6 @@ gc/stress/gclocker/TestGCLockerWithG1.java 8180622 generic-all gc/stress/TestJNIBlockFullGC/TestJNIBlockFullGC.java 8192647 generic-all gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8241293,8298073 macosx-x64,macosx-aarch64 gc/stress/TestStressG1Humongous.java 8286554 windows-x64 -gc/TestFullGCCount.java 8298296 linux-x64 ############################################################################# diff --git a/test/hotspot/jtreg/gc/TestFullGCCount.java b/test/hotspot/jtreg/gc/TestFullGCCount.java index 4557fb95c7b..08f8125de83 100644 --- a/test/hotspot/jtreg/gc/TestFullGCCount.java +++ b/test/hotspot/jtreg/gc/TestFullGCCount.java @@ -29,6 +29,8 @@ package gc; * @summary JMM GC counters overcount in some cases * @comment Shenandoah has "ExplicitGCInvokesConcurrent" on by default * @requires !(vm.gc == "Shenandoah" & vm.opt.ExplicitGCInvokesConcurrent != false) + * @comment G1 has separate counters for STW Full GC and concurrent GC. + * @requires !(vm.gc == "G1" & vm.opt.ExplicitGCInvokesConcurrent) * @requires vm.gc != "Z" * @modules java.management * @run main/othervm -Xlog:gc gc.TestFullGCCount From 0eeaf6b219758563712d951b3c6ff160ebeff52d Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 14 Dec 2022 13:40:15 +0000 Subject: [PATCH 09/10] 8298649: JFR: RemoteRecordingStream support for checkpoint event sizes beyond u4 Reviewed-by: mgronlun --- .../share/classes/jdk/management/jfr/DiskRepository.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/jdk.management.jfr/share/classes/jdk/management/jfr/DiskRepository.java b/src/jdk.management.jfr/share/classes/jdk/management/jfr/DiskRepository.java index 10822fa5403..4b3fda3defd 100644 --- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/DiskRepository.java +++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/DiskRepository.java @@ -139,7 +139,7 @@ final class DiskRepository implements Closeable { private long typeId; private int typeIdshift; private int sizeShift; - private int payLoadSize; + private long payLoadSize; private int longValueshift; private int eventFieldSize; private int lastFlush; @@ -225,7 +225,7 @@ final class DiskRepository implements Closeable { private void processEvent() { int left = currentByteArray.length - index; if (left >= payLoadSize) { - index += payLoadSize; + index = index + (int)payLoadSize; payLoadSize = 0; state = State.EVENT_SIZE; } else { @@ -261,7 +261,7 @@ final class DiskRepository implements Closeable { eventFieldSize++; byte b = nextByte(false); - int v = (b & 0x7F); + long v = (b & 0x7F); payLoadSize += (v << sizeShift); if (b >= 0) { if (payLoadSize == 0) { From 581f9f2306835680cd6d5dbbe37f610fb4de4677 Mon Sep 17 00:00:00 2001 From: Axel Boldt-Christmas Date: Wed, 14 Dec 2022 14:10:24 +0000 Subject: [PATCH 10/10] 8297235: ZGC: assert(regs[i] != regs[j]) failed: Multiple uses of register: rax Reviewed-by: thartmann, rcastanedalo Backport-of: 042b7062f19b313f31b228bd96d2a74cc1165ab9 --- src/hotspot/cpu/x86/gc/z/z_x86_64.ad | 63 +++++++++++++------------- test/jdk/ProblemList-zgc.txt | 68 ---------------------------- 2 files changed, 31 insertions(+), 100 deletions(-) diff --git a/src/hotspot/cpu/x86/gc/z/z_x86_64.ad b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad index f3e19b41733..44f3f221fae 100644 --- a/src/hotspot/cpu/x86/gc/z/z_x86_64.ad +++ b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad @@ -35,7 +35,7 @@ source %{ static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, uint8_t barrier_data) { if (barrier_data == ZLoadBarrierElided) { - return; // Elided. + return; } ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, barrier_data); { @@ -60,6 +60,27 @@ static void z_load_barrier_cmpxchg(MacroAssembler& _masm, const MachNode* node, __ bind(*stub->continuation()); } +static void z_cmpxchg_common(MacroAssembler& _masm, const MachNode* node, Register mem_reg, Register newval, Register tmp) { + // Compare value (oldval) is in rax + const Address mem = Address(mem_reg, 0); + + if (node->barrier_data() != ZLoadBarrierElided) { + __ movptr(tmp, rax); + } + + __ lock(); + __ cmpxchgptr(newval, mem); + + if (node->barrier_data() != ZLoadBarrierElided) { + Label good; + z_load_barrier_cmpxchg(_masm, node, mem, rax, tmp, good); + __ movptr(rax, tmp); + __ lock(); + __ cmpxchgptr(newval, mem); + __ bind(good); + } +} + %} // Load Pointer @@ -81,7 +102,7 @@ instruct zLoadP(rRegP dst, memory mem, rFlagsReg cr) ins_pipe(ialu_reg_mem); %} -instruct zCompareAndExchangeP(memory mem, rax_RegP oldval, rRegP newval, rRegP tmp, rFlagsReg cr) %{ +instruct zCompareAndExchangeP(indirect mem, rax_RegP oldval, rRegP newval, rRegP tmp, rFlagsReg cr) %{ match(Set oldval (CompareAndExchangeP mem (Binary oldval newval))); predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong); effect(KILL cr, TEMP tmp); @@ -90,26 +111,14 @@ instruct zCompareAndExchangeP(memory mem, rax_RegP oldval, rRegP newval, rRegP t "cmpxchgq $newval, $mem" %} ins_encode %{ - if (barrier_data() != ZLoadBarrierElided) { // barrier could be elided by ZBarrierSetC2::analyze_dominating_barriers() - __ movptr($tmp$$Register, $oldval$$Register); - } - __ lock(); - __ cmpxchgptr($newval$$Register, $mem$$Address); - - if (barrier_data() != ZLoadBarrierElided) { - Label good; - z_load_barrier_cmpxchg(_masm, this, $mem$$Address, $oldval$$Register, $tmp$$Register, good); - __ movptr($oldval$$Register, $tmp$$Register); - __ lock(); - __ cmpxchgptr($newval$$Register, $mem$$Address); - __ bind(good); - } + precond($oldval$$Register == rax); + z_cmpxchg_common(_masm, this, $mem$$Register, $newval$$Register, $tmp$$Register); %} ins_pipe(pipe_cmpxchg); %} -instruct zCompareAndSwapP(rRegI res, memory mem, rRegP newval, rRegP tmp, rFlagsReg cr, rax_RegP oldval) %{ +instruct zCompareAndSwapP(rRegI res, indirect mem, rRegP newval, rRegP tmp, rFlagsReg cr, rax_RegP oldval) %{ match(Set res (CompareAndSwapP mem (Binary oldval newval))); match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong); @@ -121,20 +130,10 @@ instruct zCompareAndSwapP(rRegI res, memory mem, rRegP newval, rRegP tmp, rFlags "movzbl $res, $res" %} ins_encode %{ - if (barrier_data() != ZLoadBarrierElided) { // barrier could be elided by ZBarrierSetC2::analyze_dominating_barriers() - __ movptr($tmp$$Register, $oldval$$Register); - } - __ lock(); - __ cmpxchgptr($newval$$Register, $mem$$Address); - + precond($oldval$$Register == rax); + z_cmpxchg_common(_masm, this, $mem$$Register, $newval$$Register, $tmp$$Register); if (barrier_data() != ZLoadBarrierElided) { - Label good; - z_load_barrier_cmpxchg(_masm, this, $mem$$Address, $oldval$$Register, $tmp$$Register, good); - __ movptr($oldval$$Register, $tmp$$Register); - __ lock(); - __ cmpxchgptr($newval$$Register, $mem$$Address); - __ bind(good); - __ cmpptr($tmp$$Register, $oldval$$Register); + __ cmpptr($tmp$$Register, rax); } __ setb(Assembler::equal, $res$$Register); __ movzbl($res$$Register, $res$$Register); @@ -143,7 +142,7 @@ instruct zCompareAndSwapP(rRegI res, memory mem, rRegP newval, rRegP tmp, rFlags ins_pipe(pipe_cmpxchg); %} -instruct zXChgP(memory mem, rRegP newval, rFlagsReg cr) %{ +instruct zXChgP(indirect mem, rRegP newval, rFlagsReg cr) %{ match(Set newval (GetAndSetP mem newval)); predicate(UseZGC && n->as_LoadStore()->barrier_data() != 0); effect(KILL cr); @@ -151,7 +150,7 @@ instruct zXChgP(memory mem, rRegP newval, rFlagsReg cr) %{ format %{ "xchgq $newval, $mem" %} ins_encode %{ - __ xchgptr($newval$$Register, $mem$$Address); + __ xchgptr($newval$$Register, Address($mem$$Register, 0)); z_load_barrier(_masm, this, Address(noreg, 0), $newval$$Register, noreg /* tmp */, barrier_data()); %} diff --git a/test/jdk/ProblemList-zgc.txt b/test/jdk/ProblemList-zgc.txt index f4b2f9ae4e8..c3d4ecd4b9f 100644 --- a/test/jdk/ProblemList-zgc.txt +++ b/test/jdk/ProblemList-zgc.txt @@ -26,71 +26,3 @@ # List of quarantined tests for testing with ZGC. # ############################################################################# - -java/lang/StackWalker/AcrossThreads.java 8297235 generic-x64 -java/math/BigInteger/BigIntegerParallelMultiplyTest.java 8297235 generic-x64 -java/util/Arrays/SetAllTest.java 8297235 generic-x64 -java/util/Arrays/Sorting.java 8297235 generic-x64 -java/util/Arrays/largeMemory/ParallelPrefix.java 8297235 generic-x64 -java/util/BitSet/stream/BitSetStreamTest.java 8297235 generic-x64 -java/util/Collection/IteratorMicroBenchmark.java 8297235 generic-x64 -java/util/Collections/UnmodifiableMapEntrySet.java 8297235 generic-x64 -java/util/DoubleStreamSums/CompensatedSums.java 8297235 generic-x64 -java/util/Random/RandomTest.java 8297235 generic-x64 -java/util/Scanner/ScannerStreamTest.java 8297235 generic-x64 -java/util/concurrent/forkjoin/AsyncShutdownNow.java 8297235 generic-x64 -java/util/concurrent/forkjoin/AsyncShutdownNowInvokeAny.java 8297235 generic-x64 -java/util/concurrent/forkjoin/AsyncShutdownNowInvokeAnyRace.java 8297235 generic-x64 -java/util/concurrent/forkjoin/Integrate.java 8297235 generic-x64 -java/util/concurrent/forkjoin/NQueensCS.java 8297235 generic-x64 -java/util/concurrent/tck/JSR166TestCase.java 8297235 generic-x64 -java/util/regex/PatternStreamTest.java 8297235 generic-x64 -java/util/stream/CustomFJPoolTest.java 8297235 generic-x64 -java/util/stream/boottest/java.base/java/util/stream/DoubleNodeTest.java 8297235 generic-x64 -java/util/stream/boottest/java.base/java/util/stream/FlagOpTest.java 8297235 generic-x64 -java/util/stream/boottest/java.base/java/util/stream/IntNodeTest.java 8297235 generic-x64 -java/util/stream/boottest/java.base/java/util/stream/LongNodeTest.java 8297235 generic-x64 -java/util/stream/boottest/java.base/java/util/stream/NodeTest.java 8297235 generic-x64 -java/util/stream/boottest/java.base/java/util/stream/StreamReuseTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/SplittableRandomTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/CollectorsTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/ConcatOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/CountTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/DistinctOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/DoublePrimitiveOpsTests.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/FilterOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/FindAnyOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/FindFirstOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/GroupByOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/InfiniteStreamWithLimitOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/IntReduceTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/IntSliceOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/IntUniqOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/IterateTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/LongPrimitiveOpsTests.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/MapOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/MatchOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/MinMaxTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/PrimitiveAverageOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/PrimitiveSumTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/RangeTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceByOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/SequentialOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/StreamLinkTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/TeeOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/ToListOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/WhileOpStatefulTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/WhileOpTest.java 8297235 generic-x64 -java/util/stream/test/org/openjdk/tests/java/util/stream/mapMultiOpTest.java 8297235 generic-x64 - -jdk/internal/vm/Continuation/Fuzz.java#default 8298058 generic-x64