From a7e5da22c4e801b47e86957de8eaec3b057425f2 Mon Sep 17 00:00:00 2001 From: Ningsheng Jian Date: Tue, 12 Jan 2021 01:31:58 +0000 Subject: [PATCH 01/20] 8258384: AArch64: SVE verify_ptrue fails on some tests Reviewed-by: adinn, ngasson --- src/hotspot/cpu/aarch64/aarch64.ad | 20 ++++++++---------- .../gc/z/zBarrierSetAssembler_aarch64.cpp | 11 +++++----- .../cpu/aarch64/macroAssembler_aarch64.cpp | 15 ++++++++++--- .../cpu/aarch64/macroAssembler_aarch64.hpp | 8 ++++--- .../cpu/aarch64/sharedRuntime_aarch64.cpp | 13 +++++------- .../cpu/aarch64/stubGenerator_aarch64.cpp | 21 ++++++++----------- 6 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 2d5ddfe86f15f..d51783fbdb81c 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -1,6 +1,6 @@ // -// Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2014, 2020, Red Hat, Inc. All rights reserved. +// Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2014, 2021, Red Hat, Inc. 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 @@ -1911,7 +1911,7 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { __ bind(L_skip_barrier); } - if (UseSVE > 0 && C->max_vector_size() >= 16) { + if (C->max_vector_size() >= 16) { __ reinitialize_ptrue(); } @@ -3793,11 +3793,9 @@ encode %{ } } - if (UseSVE > 0 && Compile::current()->max_vector_size() >= 16) { - // Only non uncommon_trap calls need to reinitialize ptrue. - if (uncommon_trap_request() == 0) { - __ reinitialize_ptrue(); - } + // Only non uncommon_trap calls need to reinitialize ptrue. + if (Compile::current()->max_vector_size() >= 16 && uncommon_trap_request() == 0) { + __ reinitialize_ptrue(); } %} @@ -3808,7 +3806,7 @@ encode %{ if (call == NULL) { ciEnv::current()->record_failure("CodeCache is full"); return; - } else if (UseSVE > 0 && Compile::current()->max_vector_size() >= 16) { + } else if (Compile::current()->max_vector_size() >= 16) { __ reinitialize_ptrue(); } %} @@ -3846,7 +3844,7 @@ encode %{ __ bind(retaddr); __ add(sp, sp, 2 * wordSize); } - if (UseSVE > 0 && Compile::current()->max_vector_size() >= 16) { + if (Compile::current()->max_vector_size() >= 16) { __ reinitialize_ptrue(); } %} @@ -3859,7 +3857,7 @@ encode %{ enc_class aarch64_enc_ret() %{ C2_MacroAssembler _masm(&cbuf); #ifdef ASSERT - if (UseSVE > 0 && Compile::current()->max_vector_size() >= 16) { + if (Compile::current()->max_vector_size() >= 16) { __ verify_ptrue(); } #endif diff --git a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp index 7ba655077ed43..2c28159290f5a 100644 --- a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -354,6 +354,10 @@ class ZSaveLiveRegisters { ~ZSaveLiveRegisters() { // Restore registers __ pop_fp(_fp_regs, sp); + + // External runtime call may clobber ptrue reg + __ reinitialize_ptrue(); + __ pop(_gp_regs, sp); } }; @@ -428,11 +432,6 @@ void ZBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, Z ZSetupArguments setup_arguments(masm, stub); __ mov(rscratch1, stub->slow_path()); __ blr(rscratch1); - if (UseSVE > 0) { - // Reinitialize the ptrue predicate register, in case the external runtime - // call clobbers ptrue reg, as we may return to SVE compiled code. - __ reinitialize_ptrue(); - } } // Stub exit __ b(*stub->continuation()); diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 0e18c8cc382db..05e00afb95a11 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Red Hat Inc. 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 @@ -2659,6 +2659,8 @@ void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) { as_FloatRegister(i+3), T1D, Address(post(sp, 4 * wordSize))); } + reinitialize_ptrue(); + pop(call_clobbered_registers() - exclude, sp); } @@ -2695,6 +2697,11 @@ void MacroAssembler::pop_CPU_state(bool restore_vectors, bool use_sve, ld1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2), as_FloatRegister(i+3), restore_vectors ? T2D : T1D, Address(post(sp, step))); } + + if (restore_vectors) { + reinitialize_ptrue(); + } + pop(0x3fffffff, sp); // integer registers except lr & sp } @@ -5304,7 +5311,9 @@ void MacroAssembler::verify_sve_vector_length() { void MacroAssembler::verify_ptrue() { Label verify_ok; - assert(UseSVE > 0, "should only be used for SVE"); + if (!UseSVE) { + return; + } sve_cntp(rscratch1, B, ptrue, ptrue); // get true elements count. sve_dec(rscratch1, B); cbz(rscratch1, verify_ok); diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index c1fad8b10b8cd..f191039820018 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Red Hat Inc. 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 @@ -967,7 +967,9 @@ class MacroAssembler: public Assembler { void verify_sve_vector_length(); void reinitialize_ptrue() { - sve_ptrue(ptrue, B); + if (UseSVE > 0) { + sve_ptrue(ptrue, B); + } } void verify_ptrue(); diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 5caca699ccd0d..5acbd5dad1fb4 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Red Hat Inc. 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 @@ -2791,12 +2791,6 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t __ membar(Assembler::LoadLoad | Assembler::LoadStore); - if (UseSVE > 0 && save_vectors) { - // Reinitialize the ptrue predicate register, in case the external runtime - // call clobbers ptrue reg, as we may return to SVE compiled code. - __ reinitialize_ptrue(); - } - __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset())); __ cbz(rscratch1, noException); @@ -3019,6 +3013,9 @@ void OptoRuntime::generate_exception_blob() { // handle_exception_C is a special VM call which does not require an explicit // instruction sync afterwards. + // May jump to SVE compiled code + __ reinitialize_ptrue(); + // Set an oopmap for the call site. This oopmap will only be used if we // are unwinding the stack. Hence, all locations will be dead. // Callee-saved registers will be the same as the frame above (i.e., diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index 3022aacd40db5..1378a8f233bc2 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Red Hat Inc. 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 @@ -488,11 +488,10 @@ class StubGenerator: public StubCodeGenerator { __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rthread, c_rarg1); - if (UseSVE > 0 ) { - // Reinitialize the ptrue predicate register, in case the external runtime - // call clobbers ptrue reg, as we may return to SVE compiled code. - __ reinitialize_ptrue(); - } + // Reinitialize the ptrue predicate register, in case the external runtime + // call clobbers ptrue reg, as we may return to SVE compiled code. + __ reinitialize_ptrue(); + // we should not really care that lr is no longer the callee // address. we saved the value the handler needs in r19 so we can // just copy it to r3. however, the C2 handler will push its own @@ -5653,11 +5652,9 @@ class StubGenerator: public StubCodeGenerator { __ reset_last_Java_frame(true); - if (UseSVE > 0) { - // Reinitialize the ptrue predicate register, in case the external runtime - // call clobbers ptrue reg, as we may return to SVE compiled code. - __ reinitialize_ptrue(); - } + // Reinitialize the ptrue predicate register, in case the external runtime + // call clobbers ptrue reg, as we may return to SVE compiled code. + __ reinitialize_ptrue(); __ leave(); From 28ff2de1860bf70b1174fd434346be750d9dbf01 Mon Sep 17 00:00:00 2001 From: Pankaj Bansal Date: Tue, 12 Jan 2021 09:46:06 +0000 Subject: [PATCH 02/20] 8259237: Demo selection changes with left/right arrow key. No need to press space for selection. Reviewed-by: psadhukhan, kizune, serb --- .../javax/swing/plaf/basic/BasicButtonUI.java | 17 ++-- .../TestButtonGroupFocusTraversal.java | 88 ++++++++++++++++++- 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java index 4d73309869f10..bc0409c5ba89c 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java @@ -762,8 +762,11 @@ else if (!srcFound) { } /** - * Find the new toggle button that focus needs to be + * Find the new toggle/radio button that focus needs to be * moved to in the group, select the button + * In case of radio button, setPressed and setArmed is called + * on the button model, so that Action set on button is performed + * on selecting the button * * @param next, indicate if it's arrow up/left or down/right */ @@ -785,12 +788,16 @@ void selectNewButton(boolean next) { if (newSelectedBtn != null && (newSelectedBtn != activeBtn)) { ButtonModel btnModel = newSelectedBtn.getModel(); - btnModel.setPressed(true); - btnModel.setArmed(true); + if (newSelectedBtn instanceof JRadioButton) { + btnModel.setPressed(true); + btnModel.setArmed(true); + } newSelectedBtn.requestFocusInWindow(); newSelectedBtn.setSelected(true); - btnModel.setPressed(false); - btnModel.setArmed(false); + if (newSelectedBtn instanceof JRadioButton) { + btnModel.setPressed(false); + btnModel.setArmed(false); + } } } } diff --git a/test/jdk/javax/swing/ButtonGroup/TestButtonGroupFocusTraversal.java b/test/jdk/javax/swing/ButtonGroup/TestButtonGroupFocusTraversal.java index 4e677c7ab0fe9..c115d44edbf79 100644 --- a/test/jdk/javax/swing/ButtonGroup/TestButtonGroupFocusTraversal.java +++ b/test/jdk/javax/swing/ButtonGroup/TestButtonGroupFocusTraversal.java @@ -24,13 +24,15 @@ /* * @test * @key headful - * @bug 8249548 + * @bug 8249548 8259237 * @summary Test focus traversal in button group containing JToggleButton * and JRadioButton * @run main TestButtonGroupFocusTraversal */ +import javax.swing.AbstractAction; import javax.swing.ButtonGroup; +import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JRadioButton; import javax.swing.JTextField; @@ -43,12 +45,16 @@ import java.awt.KeyboardFocusManager; import java.awt.Point; import java.awt.Robot; +import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; public class TestButtonGroupFocusTraversal { private static JFrame frame; private static JTextField textFieldFirst, textFieldLast; private static JToggleButton toggleButton1, toggleButton2; + private static JCheckBox checkBox1, checkBox2; + private static boolean toggleButtonActionPerformed; + private static boolean checkboxActionPerformed; private static JRadioButton radioButton1, radioButton2; private static Robot robot; @@ -75,6 +81,36 @@ public void run() { toggleButton2 = new JToggleButton("2"); radioButton1 = new JRadioButton("1"); radioButton2 = new JRadioButton("2"); + checkBox1 = new JCheckBox("1"); + checkBox2 = new JCheckBox("2"); + + toggleButton1.setAction(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + toggleButtonActionPerformed = true; + } + }); + + toggleButton2.setAction(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + toggleButtonActionPerformed = true; + } + }); + + checkBox1.setAction(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + checkboxActionPerformed = true; + } + }); + + checkBox2.setAction(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + checkboxActionPerformed = true; + } + }); ButtonGroup toggleGroup = new ButtonGroup(); toggleGroup.add(toggleButton1); @@ -84,8 +120,13 @@ public void run() { radioGroup.add(radioButton1); radioGroup.add(radioButton2); + ButtonGroup checkboxButtonGroup = new ButtonGroup(); + checkboxButtonGroup.add(checkBox1); + checkboxButtonGroup.add(checkBox2); + toggleButton2.setSelected(true); radioButton2.setSelected(true); + checkBox2.setSelected(true); frame = new JFrame("Test"); frame.setLayout(new FlowLayout()); @@ -96,6 +137,8 @@ public void run() { pane.add(toggleButton2); pane.add(radioButton1); pane.add(radioButton2); + pane.add(checkBox1); + pane.add(checkBox2); pane.add(textFieldLast); frame.pack(); @@ -127,6 +170,20 @@ private static void checkFocusedComponent (Component component) { } } + private static void checkToggleButtonActionPerformed() { + if (toggleButtonActionPerformed) { + throw new RuntimeException("Toggle Button Action should not be" + + "performed"); + } + } + + private static void checkCheckboxActionPerformed() { + if (toggleButtonActionPerformed) { + throw new RuntimeException("Checkbox Action should not be" + + "performed"); + } + } + public static void main(String[] args) throws Exception { robot = new Robot(); robot.setAutoDelay(100); @@ -164,9 +221,15 @@ public static void main(String[] args) throws Exception { pressKey(KeyEvent.VK_TAB); checkFocusedComponent(radioButton2); + pressKey(KeyEvent.VK_TAB); + checkFocusedComponent(checkBox2); + pressKey(KeyEvent.VK_TAB); checkFocusedComponent(textFieldLast); + pressKey(KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); + checkFocusedComponent(checkBox2); + pressKey(KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); checkFocusedComponent(radioButton2); @@ -181,15 +244,19 @@ public static void main(String[] args) throws Exception { pressKey(KeyEvent.VK_LEFT); checkFocusedComponent(toggleButton1); + checkToggleButtonActionPerformed(); pressKey(KeyEvent.VK_RIGHT); checkFocusedComponent(toggleButton2); + checkToggleButtonActionPerformed(); pressKey(KeyEvent.VK_UP); checkFocusedComponent(toggleButton1); + checkToggleButtonActionPerformed(); pressKey(KeyEvent.VK_DOWN); checkFocusedComponent(toggleButton2); + checkToggleButtonActionPerformed(); pressKey(KeyEvent.VK_TAB); checkFocusedComponent(radioButton2); @@ -206,6 +273,24 @@ public static void main(String[] args) throws Exception { pressKey(KeyEvent.VK_DOWN); checkFocusedComponent(radioButton2); + pressKey(KeyEvent.VK_TAB); + checkFocusedComponent(checkBox2); + + pressKey(KeyEvent.VK_LEFT); + checkCheckboxActionPerformed(); + checkFocusedComponent(checkBox1); + + pressKey(KeyEvent.VK_RIGHT); + checkCheckboxActionPerformed(); + checkFocusedComponent(checkBox2); + + pressKey(KeyEvent.VK_UP); + checkCheckboxActionPerformed(); + checkFocusedComponent(checkBox1); + + pressKey(KeyEvent.VK_DOWN); + checkCheckboxActionPerformed(); + checkFocusedComponent(checkBox2); } finally { if (frame != null) { SwingUtilities.invokeAndWait(frame::dispose); @@ -214,4 +299,3 @@ public static void main(String[] args) throws Exception { } } } - From 67e1b639bafb2efb821de4dc92f9e9c17637fe1f Mon Sep 17 00:00:00 2001 From: Patrick Zhang Date: Tue, 12 Jan 2021 10:10:48 +0000 Subject: [PATCH 03/20] 8259380: Correct pretouch chunk size to cap with actual page size Reviewed-by: tschatzl, sjohanss --- src/hotspot/share/gc/shared/pretouchTask.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/gc/shared/pretouchTask.cpp b/src/hotspot/share/gc/shared/pretouchTask.cpp index 4398d3924cc11..b790cc12a1b01 100644 --- a/src/hotspot/share/gc/shared/pretouchTask.cpp +++ b/src/hotspot/share/gc/shared/pretouchTask.cpp @@ -64,13 +64,14 @@ void PretouchTask::work(uint worker_id) { void PretouchTask::pretouch(const char* task_name, char* start_address, char* end_address, size_t page_size, WorkGang* pretouch_gang) { - + // Chunk size should be at least (unmodified) page size as using multiple threads + // pretouch on a single page can decrease performance. + size_t chunk_size = MAX2(PretouchTask::chunk_size(), page_size); #ifdef LINUX // When using THP we need to always pre-touch using small pages as the OS will // initially always use small pages. page_size = UseTransparentHugePages ? (size_t)os::vm_page_size() : page_size; #endif - size_t chunk_size = MAX2(PretouchTask::chunk_size(), page_size); PretouchTask task(task_name, start_address, end_address, page_size, chunk_size); size_t total_bytes = pointer_delta(end_address, start_address, sizeof(char)); From 8a81cf154fb72ab6b51855abc387c2ebfbcf9ebc Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Tue, 12 Jan 2021 17:04:34 +0000 Subject: [PATCH 04/20] 8259298: broken link in Stream::toList spec Reviewed-by: bchristi, iris, lancea, naoto --- src/java.base/share/classes/java/util/stream/Stream.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/util/stream/Stream.java b/src/java.base/share/classes/java/util/stream/Stream.java index feed9303cd633..21c626dcf7521 100644 --- a/src/java.base/share/classes/java/util/stream/Stream.java +++ b/src/java.base/share/classes/java/util/stream/Stream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1169,7 +1169,7 @@ R collect(Supplier supplier, * {@code UnsupportedOperationException} to be thrown. There are no * guarantees on the implementation type or serializability of the returned List. * - *

The returned instance may be value-based. + *

The returned instance may be value-based. * Callers should make no assumptions about the identity of the returned instances. * Identity-sensitive operations on these instances (reference equality ({@code ==}), * identity hash code, and synchronization) are unreliable and should be avoided. From b03880e33b0d9442a608c9ec911afbe863221bf2 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 12 Jan 2021 17:09:05 +0000 Subject: [PATCH 05/20] 8259634: MemorySegment::asByteBuffer does not respect spatial bounds Reviewed-by: alanb, chegar --- .../share/classes/java/nio/Buffer.java | 2 +- test/jdk/java/foreign/TestByteBuffer.java | 30 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/nio/Buffer.java b/src/java.base/share/classes/java/nio/Buffer.java index 8e286584b1fd6..0506078eed800 100644 --- a/src/java.base/share/classes/java/nio/Buffer.java +++ b/src/java.base/share/classes/java/nio/Buffer.java @@ -793,7 +793,7 @@ public ByteBuffer newMappedByteBuffer(UnmapperProxy unmapperProxy, long address, @Override public ByteBuffer newHeapByteBuffer(byte[] hb, int offset, int capacity, MemorySegmentProxy segment) { - return new HeapByteBuffer(hb, offset, capacity, segment); + return new HeapByteBuffer(hb, -1, 0, capacity, capacity, offset, segment); } @Override diff --git a/test/jdk/java/foreign/TestByteBuffer.java b/test/jdk/java/foreign/TestByteBuffer.java index a396ec48ec5c1..27d7a8a3e0055 100644 --- a/test/jdk/java/foreign/TestByteBuffer.java +++ b/test/jdk/java/foreign/TestByteBuffer.java @@ -64,6 +64,7 @@ import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; @@ -71,6 +72,7 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Stream; import jdk.internal.foreign.HeapMemorySegmentImpl; @@ -635,7 +637,8 @@ public void testIOOnClosedConfinedSegmentBuffer() throws IOException { } } - public void testIOOnClosedConfinedSegment() throws IOException { + @Test + public void testIOOnConfinedSegment() throws IOException { File tmp = File.createTempFile("tmp", "txt"); tmp.deleteOnExit(); try (FileChannel channel = FileChannel.open(tmp.toPath(), StandardOpenOption.WRITE)) { @@ -648,6 +651,31 @@ public void testIOOnClosedConfinedSegment() throws IOException { } } + @Test(dataProvider="segments") + public void buffersAndArraysFromSlices(Supplier segmentSupplier) { + try (MemorySegment segment = segmentSupplier.get()) { + int newSize = 8; + var slice = segment.asSlice(4, newSize); + + var bytes = slice.toByteArray(); + assertEquals(newSize, bytes.length); + + var buffer = slice.asByteBuffer(); + // Fails for heap segments, but passes for native segments: + assertEquals(0, buffer.position()); + assertEquals(newSize, buffer.limit()); + assertEquals(newSize, buffer.capacity()); + } + } + + @DataProvider(name = "segments") + public static Object[][] segments() throws Throwable { + return new Object[][] { + { (Supplier) () -> MemorySegment.allocateNative(16) }, + { (Supplier) () -> MemorySegment.ofArray(new byte[16]) } + }; + } + @DataProvider(name = "bufferOps") public static Object[][] bufferOps() throws Throwable { List args = new ArrayList<>(); From 5f9cd72c5460012d88a91f394f99a89e1ed9331c Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 12 Jan 2021 19:57:08 +0000 Subject: [PATCH 06/20] 8259645: Revert JDK-8245956 JavaCompiler still uses File API instead of Path API in a specific case Reviewed-by: chegar --- .../tools/javac/file/JavacFileManager.java | 8 +-- .../tools/javac/T8245956/T8245956.java | 67 ------------------- 2 files changed, 4 insertions(+), 71 deletions(-) delete mode 100644 test/langtools/tools/javac/T8245956/T8245956.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java index c5301ba2c064e..c7b95b80437fd 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -741,13 +741,13 @@ public void close() throws IOException { @Override @DefinedBy(Api.COMPILER) public ClassLoader getClassLoader(Location location) { checkNotModuleOrientedLocation(location); - Collection searchPath = getLocationAsPaths(location); - if (searchPath == null) + Iterable path = getLocation(location); + if (path == null) return null; ListBuffer lb = new ListBuffer<>(); - for (Path p : searchPath) { + for (File f: path) { try { - lb.append(p.toUri().toURL()); + lb.append(f.toURI().toURL()); } catch (MalformedURLException e) { throw new AssertionError(e); } diff --git a/test/langtools/tools/javac/T8245956/T8245956.java b/test/langtools/tools/javac/T8245956/T8245956.java deleted file mode 100644 index 5da20eafc97e5..0000000000000 --- a/test/langtools/tools/javac/T8245956/T8245956.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 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 - * 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 8245956 - * @summary JavaCompiler still uses File API instead of Path API in a specific case - * @run main T8245956 - */ - -import java.net.URI; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import javax.tools.DiagnosticCollector; -import javax.tools.JavaCompiler; -import javax.tools.JavaFileObject; -import javax.tools.StandardJavaFileManager; -import javax.tools.StandardLocation; -import javax.tools.ToolProvider; - -public class T8245956 { - public static void main(String[] args) throws Exception { - Path zipFilePath = Path.of("T8245956.zip"); - URI zipFileUri = zipFilePath.toUri(); - URI jarZipFileUri = URI.create("jar:" + zipFileUri.toString()); - Map env = new LinkedHashMap<>(); - env.put("create", "true"); - try (FileSystem fs = FileSystems.newFileSystem(jarZipFileUri, env)) { - Path fsPath = fs.getPath(""); - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - DiagnosticCollector diagnosticCollector = new DiagnosticCollector<>(); - try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnosticCollector, null, null)) { - List classPath = new ArrayList<>(); - classPath.add(fsPath); - fileManager.setLocationFromPaths(StandardLocation.CLASS_PATH, classPath); - fileManager.getClassLoader(StandardLocation.CLASS_PATH); // Should not generate any exceptions. - System.out.println("The method getClassLoader terminated normally.\n"); - } - } - } -} From 17b4db31cbc5c2b4829c2d38b832832b874ae28e Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 12 Jan 2021 21:06:03 +0000 Subject: [PATCH 07/20] 8259636: Check for buffer backed by shared segment kicks in in unexpected places Reviewed-by: sundar, alanb, chegar --- .../classes/java/nio/Direct-X-Buffer.java.template | 2 +- test/jdk/java/foreign/TestByteBuffer.java | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template index f3e1c8b224889..5257c1e2e59d8 100644 --- a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template +++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template @@ -203,7 +203,7 @@ class Direct$Type$Buffer$RW$$BO$ { #if[rw] super(mark, pos, lim, cap, segment); - address = db.address() + off; + address = ((Buffer)db).address + off; #if[byte] cleaner = null; #end[byte] diff --git a/test/jdk/java/foreign/TestByteBuffer.java b/test/jdk/java/foreign/TestByteBuffer.java index 27d7a8a3e0055..d5b9b5a040f83 100644 --- a/test/jdk/java/foreign/TestByteBuffer.java +++ b/test/jdk/java/foreign/TestByteBuffer.java @@ -64,7 +64,6 @@ import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; @@ -668,6 +667,15 @@ public void buffersAndArraysFromSlices(Supplier segmentSupplier) } } + @Test(dataProvider="segments") + public void viewsFromSharedSegment(Supplier segmentSupplier) { + try (MemorySegment segment = segmentSupplier.get().share()) { + var byteBuffer = segment.asByteBuffer(); + byteBuffer.asReadOnlyBuffer(); + byteBuffer.slice(0, 8); + } + } + @DataProvider(name = "segments") public static Object[][] segments() throws Throwable { return new Object[][] { From 1cf2378bda6a4a098b2503f9b23911a01b6ea600 Mon Sep 17 00:00:00 2001 From: Xiaohong Gong Date: Wed, 13 Jan 2021 05:48:08 +0000 Subject: [PATCH 08/20] 8259353: VectorReinterpretNode is incorrectly optimized out Reviewed-by: vlivanov, njian --- src/hotspot/share/opto/vectornode.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index cca896859126c..0979adce7a0e4 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1198,7 +1198,11 @@ void VectorMaskCmpNode::dump_spec(outputStream *st) const { Node* VectorReinterpretNode::Identity(PhaseGVN *phase) { Node* n = in(1); if (n->Opcode() == Op_VectorReinterpret) { - if (Type::cmp(bottom_type(), n->in(1)->bottom_type()) == 0) { + // "VectorReinterpret (VectorReinterpret node) ==> node" if: + // 1) Types of 'node' and 'this' are identical + // 2) Truncations are not introduced by the first VectorReinterpret + if (Type::cmp(bottom_type(), n->in(1)->bottom_type()) == 0 && + length_in_bytes() <= n->bottom_type()->is_vect()->length_in_bytes()) { return n->in(1); } } From 15dd8f3aa4fa72eeb30b1d74298b35ba9246b190 Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Wed, 13 Jan 2021 05:51:52 +0000 Subject: [PATCH 09/20] 8259275: JRuby crashes while resolving invokedynamic instruction Reviewed-by: iklam, minqi, lfoltan --- .../share/classfile/classListParser.cpp | 48 +++++------ .../share/classfile/classListParser.hpp | 3 +- src/hotspot/share/oops/constantPool.cpp | 19 +++-- test/hotspot/jtreg/TEST.groups | 3 +- .../jtreg/runtime/cds/appcds/BadBSM.java | 6 +- .../cds/appcds/LambdaWithOldClass.java | 80 +++++++++++++++++++ .../test-classes/LambdaWithOldClassApp.java | 38 +++++++++ .../cds/appcds/test-classes/OldClass.jasm | 37 +++++++++ 8 files changed, 196 insertions(+), 38 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/test-classes/LambdaWithOldClassApp.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/test-classes/OldClass.jasm diff --git a/src/hotspot/share/classfile/classListParser.cpp b/src/hotspot/share/classfile/classListParser.cpp index 5a7766f0ce6b4..2236c077fac6c 100644 --- a/src/hotspot/share/classfile/classListParser.cpp +++ b/src/hotspot/share/classfile/classListParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -460,19 +460,34 @@ bool ClassListParser::is_matching_cp_entry(constantPoolHandle &pool, int cp_inde } return true; } - void ClassListParser::resolve_indy(Symbol* class_name_symbol, TRAPS) { + ClassListParser::resolve_indy_impl(class_name_symbol, THREAD); + if (HAS_PENDING_EXCEPTION) { + ResourceMark rm(THREAD); + char* ex_msg = (char*)""; + oop message = java_lang_Throwable::message(PENDING_EXCEPTION); + if (message != NULL) { + ex_msg = java_lang_String::as_utf8_string(message); + } + log_warning(cds)("resolve_indy for class %s has encountered exception: %s %s", + class_name_symbol->as_C_string(), + PENDING_EXCEPTION->klass()->external_name(), + ex_msg); + CLEAR_PENDING_EXCEPTION; + } +} + +void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) { Handle class_loader(THREAD, SystemDictionary::java_system_loader()); Handle protection_domain; - Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, THREAD); // FIXME should really be just a lookup + Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, CHECK); // FIXME should really be just a lookup if (klass != NULL && klass->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(klass); if (SystemDictionaryShared::has_class_failed_verification(ik)) { // don't attempt to resolve indy on classes that has previously failed verification return; } - MetaspaceShared::try_link_class(ik, THREAD); - assert(!HAS_PENDING_EXCEPTION, "unexpected exception"); + MetaspaceShared::try_link_class(ik, CHECK); ConstantPool* cp = ik->constants(); ConstantPoolCache* cpcache = cp->cache(); @@ -484,36 +499,23 @@ void ClassListParser::resolve_indy(Symbol* class_name_symbol, TRAPS) { constantPoolHandle pool(THREAD, cp); if (pool->tag_at(pool_index).is_invoke_dynamic()) { BootstrapInfo bootstrap_specifier(pool, pool_index, indy_index); - Handle bsm = bootstrap_specifier.resolve_bsm(THREAD); + Handle bsm = bootstrap_specifier.resolve_bsm(CHECK); if (!SystemDictionaryShared::is_supported_invokedynamic(&bootstrap_specifier)) { log_debug(cds, lambda)("is_supported_invokedynamic check failed for cp_index %d", pool_index); continue; } - if (is_matching_cp_entry(pool, pool_index, THREAD)) { + bool matched = is_matching_cp_entry(pool, pool_index, CHECK); + if (matched) { found = true; CallInfo info; - bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(info, THREAD); + bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(info, CHECK); if (!is_done) { // resolve it Handle recv; - LinkResolver::resolve_invoke(info, recv, pool, indy_index, Bytecodes::_invokedynamic, THREAD); + LinkResolver::resolve_invoke(info, recv, pool, indy_index, Bytecodes::_invokedynamic, CHECK); break; } cpce->set_dynamic_call(pool, info); - if (HAS_PENDING_EXCEPTION) { - ResourceMark rm(THREAD); - tty->print("resolve_indy for class %s has", class_name_symbol->as_C_string()); - oop message = java_lang_Throwable::message(PENDING_EXCEPTION); - if (message != NULL) { - char* ex_msg = java_lang_String::as_utf8_string(message); - tty->print_cr(" exception pending '%s %s'", - PENDING_EXCEPTION->klass()->external_name(), ex_msg); - } else { - tty->print_cr(" exception pending %s ", - PENDING_EXCEPTION->klass()->external_name()); - } - exit(1); - } } } } diff --git a/src/hotspot/share/classfile/classListParser.hpp b/src/hotspot/share/classfile/classListParser.hpp index dd5cf0b62ffca..f8598a500219b 100644 --- a/src/hotspot/share/classfile/classListParser.hpp +++ b/src/hotspot/share/classfile/classListParser.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,6 +114,7 @@ class ClassListParser : public StackObj { bool is_matching_cp_entry(constantPoolHandle &pool, int cp_index, TRAPS); void resolve_indy(Symbol* class_name_symbol, TRAPS); + void resolve_indy_impl(Symbol* class_name_symbol, TRAPS); public: ClassListParser(const char* file); ~ClassListParser(); diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index 8ae78664ab372..a33e8e37228ab 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -406,15 +406,14 @@ void ConstantPool::remove_unshareable_info() { _flags |= (_on_stack | _is_shared); int num_klasses = 0; for (int index = 1; index < length(); index++) { // Index 0 is unused - if (!DynamicDumpSharedSpaces) { - assert(!tag_at(index).is_unresolved_klass_in_error(), "This must not happen during static dump time"); - } else { - if (tag_at(index).is_unresolved_klass_in_error() || - tag_at(index).is_method_handle_in_error() || - tag_at(index).is_method_type_in_error() || - tag_at(index).is_dynamic_constant_in_error()) { - tag_at_put(index, JVM_CONSTANT_UnresolvedClass); - } + if (tag_at(index).is_unresolved_klass_in_error()) { + tag_at_put(index, JVM_CONSTANT_UnresolvedClass); + } else if (tag_at(index).is_method_handle_in_error()) { + tag_at_put(index, JVM_CONSTANT_MethodHandle); + } else if (tag_at(index).is_method_type_in_error()) { + tag_at_put(index, JVM_CONSTANT_MethodType); + } else if (tag_at(index).is_dynamic_constant_in_error()) { + tag_at_put(index, JVM_CONSTANT_Dynamic); } if (tag_at(index).is_klass()) { // This class was resolved as a side effect of executing Java code diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index 1cd45d79eeb66..652f8675c2273 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -336,6 +336,7 @@ hotspot_appcds_dynamic = \ -runtime/cds/appcds/LambdaEagerInit.java \ -runtime/cds/appcds/LambdaProxyClasslist.java \ -runtime/cds/appcds/LambdaVerificationFailedDuringDump.java \ + -runtime/cds/appcds/LambdaWithOldClass.java \ -runtime/cds/appcds/LongClassListPath.java \ -runtime/cds/appcds/LotsOfClasses.java \ -runtime/cds/appcds/NonExistClasspath.java \ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/BadBSM.java b/test/hotspot/jtreg/runtime/cds/appcds/BadBSM.java index f7671662f1261..04ebce69a04f2 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/BadBSM.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/BadBSM.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ public static void main(String[] args) throws Exception { TestCommon.list("WrongBSM", "@lambda-proxy WrongBSM 7"), "-Xlog:cds+lambda=debug"); - out.shouldHaveExitValue(0); - out.shouldContain( "is_supported_invokedynamic check failed for cp_index 7"); + out.shouldHaveExitValue(0) + .shouldContain("resolve_indy for class WrongBSM has encountered exception: java.lang.NoSuchMethodError"); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java new file mode 100644 index 0000000000000..5410348dc2ba3 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8259275 + * @summary VM should not crash during CDS dump and run time when a lambda + * expression references an old version of class. + * @requires vm.cds + * @library /test/lib + * @compile test-classes/OldClass.jasm + * @compile test-classes/LambdaWithOldClassApp.java + * @run driver LambdaWithOldClass + */ + +import jdk.test.lib.cds.CDSOptions; +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class LambdaWithOldClass { + + public static void main(String[] args) throws Exception { + String mainClass = "LambdaWithOldClassApp"; + String namePrefix = "lambdawitholdclass"; + JarBuilder.build(namePrefix, mainClass, "OldClass", "TestInterface"); + + String appJar = TestCommon.getTestJar(namePrefix + ".jar"); + String classList = namePrefix + ".list"; + String archiveName = namePrefix + ".jsa"; + + // dump class list + ProcessBuilder pb = ProcessTools.createTestJvm( + "-XX:DumpLoadedClassList=" + classList, + "-cp", appJar, + mainClass); + OutputAnalyzer output = TestCommon.executeAndLog(pb, namePrefix); + output.shouldHaveExitValue(0); + + // create archive with the class list + CDSOptions opts = (new CDSOptions()) + .addPrefix("-XX:ExtraSharedClassListFile=" + classList, + "-cp", appJar, + "-Xlog:class+load,cds") + .setArchiveName(archiveName); + CDSTestUtils.createArchiveAndCheck(opts); + + // run with archive + CDSOptions runOpts = (new CDSOptions()) + .addPrefix("-cp", appJar, "-Xlog:class+load,cds=debug") + .setArchiveName(archiveName) + .setUseVersion(false) + .addSuffix(mainClass); + output = CDSTestUtils.runWithArchive(runOpts); + output.shouldContain("[class,load] LambdaWithOldClassApp source: shared objects file") + .shouldMatch(".class.load. LambdaWithOldClassApp[$][$]Lambda[$].*/0x.*source:.*LambdaWithOldClassApp") + .shouldHaveExitValue(0); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/LambdaWithOldClassApp.java b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/LambdaWithOldClassApp.java new file mode 100644 index 0000000000000..a1c5adcbc4616 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/LambdaWithOldClassApp.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + * + */ +interface TestInterface { + public void apply(OldClass c); +} + +public class LambdaWithOldClassApp { + public static void main(String args[]) { + doit((c) -> { + System.out.println("c = " + c); + }); + } + static void doit(TestInterface i) { + OldClass c = new OldClass(); + i.apply(c); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/OldClass.jasm b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/OldClass.jasm new file mode 100644 index 0000000000000..35ce9f8e113e3 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/OldClass.jasm @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + * + */ +super class OldClass + version 49:0 +{ + + +Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + +} // end Class OldClass From 793017d2ed59136b99d9bbfad0f531aa7ee234e8 Mon Sep 17 00:00:00 2001 From: Xiaohong Gong Date: Wed, 13 Jan 2021 05:52:45 +0000 Subject: [PATCH 10/20] 8259601: AArch64: Fix reinterpretX2D match rule issue Reviewed-by: adinn, njian --- src/hotspot/cpu/aarch64/aarch64_neon.ad | 23 ++++++------ src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 | 41 +++++++++++++++------- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64_neon.ad b/src/hotspot/cpu/aarch64/aarch64_neon.ad index 309ec4860679c..386c6e30aa2a1 100644 --- a/src/hotspot/cpu/aarch64/aarch64_neon.ad +++ b/src/hotspot/cpu/aarch64/aarch64_neon.ad @@ -1,5 +1,5 @@ -// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2020, Arm Limited. All rights reserved. +// Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2021, Arm Limited. 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 @@ -84,9 +84,11 @@ instruct reinterpretD2X(vecX dst, vecD src) n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 8); match(Set dst (VectorReinterpret src)); ins_cost(INSN_COST); - format %{ " # reinterpret $dst,$src" %} + format %{ " # reinterpret $dst,$src\t# D2X" %} ins_encode %{ - // If register is the same, then move is not needed. + // If registers are the same, no register move is required - the + // upper 64 bits of 'src' are expected to have been initialized + // to zero. if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), @@ -102,14 +104,13 @@ instruct reinterpretX2D(vecD dst, vecX src) n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 16); match(Set dst (VectorReinterpret src)); ins_cost(INSN_COST); - format %{ " # reinterpret $dst,$src" %} + format %{ " # reinterpret $dst,$src\t# X2D" %} ins_encode %{ - // If register is the same, then move is not needed. - if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { - __ orr(as_FloatRegister($dst$$reg), __ T8B, - as_FloatRegister($src$$reg), - as_FloatRegister($src$$reg)); - } + // Resize the vector from 128-bits to 64-bits. The higher 64-bits of + // the "dst" register must be cleared to zero. + __ orr(as_FloatRegister($dst$$reg), __ T8B, + as_FloatRegister($src$$reg), + as_FloatRegister($src$$reg)); %} ins_pipe(vlogical64); %} diff --git a/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 b/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 index 9ac9bad3dc87a..04c4338c6d450 100644 --- a/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 +++ b/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 @@ -1,5 +1,5 @@ -// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2020, Arm Limited. All rights reserved. +// Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2021, Arm Limited. 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 @@ -97,16 +97,18 @@ dnl $1 $2 REINTERPRET(D, 8) REINTERPRET(X, 16) dnl -define(`REINTERPRET_X', ` -instruct reinterpret$1`'2$2`'(vec$2 dst, vec$1 src) + +instruct reinterpretD2X(vecX dst, vecD src) %{ - predicate(n->bottom_type()->is_vect()->length_in_bytes() == $3 && - n->in(1)->bottom_type()->is_vect()->length_in_bytes() == $4); + predicate(n->bottom_type()->is_vect()->length_in_bytes() == 16 && + n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 8); match(Set dst (VectorReinterpret src)); ins_cost(INSN_COST); - format %{ " # reinterpret $dst,$src" %} + format %{ " # reinterpret $dst,$src\t# D2X" %} ins_encode %{ - // If register is the same, then move is not needed. + // If registers are the same, no register move is required - the + // upper 64 bits of 'src' are expected to have been initialized + // to zero. if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), @@ -114,11 +116,24 @@ instruct reinterpret$1`'2$2`'(vec$2 dst, vec$1 src) } %} ins_pipe(vlogical64); -%}')dnl -dnl $1 $2 $3 $4 -REINTERPRET_X(D, X, 16, 8) -REINTERPRET_X(X, D, 8, 16) -dnl +%} + +instruct reinterpretX2D(vecD dst, vecX src) +%{ + predicate(n->bottom_type()->is_vect()->length_in_bytes() == 8 && + n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 16); + match(Set dst (VectorReinterpret src)); + ins_cost(INSN_COST); + format %{ " # reinterpret $dst,$src\t# X2D" %} + ins_encode %{ + // Resize the vector from 128-bits to 64-bits. The higher 64-bits of + // the "dst" register must be cleared to zero. + __ orr(as_FloatRegister($dst$$reg), __ T8B, + as_FloatRegister($src$$reg), + as_FloatRegister($src$$reg)); + %} + ins_pipe(vlogical64); +%} // ------------------------------ Vector cast ------------------------------- dnl From 417e1d1a4e05d9311aeca2904807e5f18eba8f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Wed, 13 Jan 2021 07:22:30 +0000 Subject: [PATCH 11/20] 8259061: C2: assert(found) failed: memory-writing node is not placed in its original loop or an ancestor of it Remove assertion that is too general, that is, it can fail on compilations where C2 generates correct code otherwise. Reviewed-by: chagedorn, thartmann, kvn --- src/hotspot/share/opto/block.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/hotspot/share/opto/block.cpp b/src/hotspot/share/opto/block.cpp index 943a2fb30ca06..22e6d927c3479 100644 --- a/src/hotspot/share/opto/block.cpp +++ b/src/hotspot/share/opto/block.cpp @@ -1221,26 +1221,6 @@ void PhaseCFG::verify() const { if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) { assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block"); } - // Verify that memory-writing nodes (such as stores and calls) are placed - // in their original loop L (given by the control input) or in an ancestor - // of L. This is guaranteed by the freq. estimation model for reducible - // CFGs, and by special handling in PhaseCFG::schedule_late() otherwise. - if (n->is_Mach() && n->bottom_type()->has_memory() && n->in(0) != NULL) { - Block* original_block = find_block_for_node(n->in(0)); - assert(original_block != NULL, "missing block for memory-writing node"); - CFGLoop* original_or_ancestor = original_block->_loop; - assert(block->_loop != NULL && original_or_ancestor != NULL, "no loop"); - bool found = false; - do { - if (block->_loop == original_or_ancestor) { - found = true; - break; - } - original_or_ancestor = original_or_ancestor->parent(); - } while (original_or_ancestor != NULL); - assert(found, "memory-writing node is not placed in its original loop " - "or an ancestor of it"); - } if (n->needs_anti_dependence_check()) { verify_anti_dependences(block, n); } From efc36be5be7f5963761fcb70982b6b52e4b44b98 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Wed, 13 Jan 2021 08:22:40 +0000 Subject: [PATCH 12/20] 8258985: Parallel WeakProcessor may use too few threads Use total workers rather than active. Reviewed-by: tschatzl, ayang, sjohanss --- src/hotspot/share/gc/shared/weakProcessor.hpp | 13 +++++++++---- .../share/gc/shared/weakProcessor.inline.hpp | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/gc/shared/weakProcessor.hpp b/src/hotspot/share/gc/shared/weakProcessor.hpp index c66e00291a977..f581e6419075c 100644 --- a/src/hotspot/share/gc/shared/weakProcessor.hpp +++ b/src/hotspot/share/gc/shared/weakProcessor.hpp @@ -47,8 +47,9 @@ class WeakProcessor : AllStatic { // Visit all oop*s and apply the given closure. static void oops_do(OopClosure* closure); - // Parallel version. Uses ergo_workers(), active workers, and - // phase_time's max_threads to determine the number of threads to use. + // Parallel version. Uses ergo_workers() to determine the number of + // threads to use, limited by the total workers and phase_times' + // max_threads. // IsAlive must be derived from BoolObjectClosure. // KeepAlive must be derived from OopClosure. template @@ -57,8 +58,9 @@ class WeakProcessor : AllStatic { KeepAlive* keep_alive, WeakProcessorPhaseTimes* phase_times); - // Convenience parallel version. Uses ergo_workers() and active workers - // to determine the number of threads to run. Implicitly logs phase times. + // Convenience parallel version. Uses ergo_workers() to determine the + // number of threads to use, limited by the total workers. Implicitly + // logs phase times. // IsAlive must be derived from BoolObjectClosure. // KeepAlive must be derived from OopClosure. template @@ -67,7 +69,10 @@ class WeakProcessor : AllStatic { KeepAlive* keep_alive, uint indent_log); + // Uses the total number of weak references and ReferencesPerThread to + // determine the number of threads to use, limited by max_workers. static uint ergo_workers(uint max_workers); + class Task; private: diff --git a/src/hotspot/share/gc/shared/weakProcessor.inline.hpp b/src/hotspot/share/gc/shared/weakProcessor.inline.hpp index 1050758a072ae..a7d1a4be7c61b 100644 --- a/src/hotspot/share/gc/shared/weakProcessor.inline.hpp +++ b/src/hotspot/share/gc/shared/weakProcessor.inline.hpp @@ -134,7 +134,7 @@ void WeakProcessor::weak_oops_do(WorkGang* workers, WeakProcessorPhaseTimes* phase_times) { WeakProcessorTimeTracker tt(phase_times); - uint nworkers = ergo_workers(MIN2(workers->active_workers(), + uint nworkers = ergo_workers(MIN2(workers->total_workers(), phase_times->max_threads())); GangTask task("Weak Processor", is_alive, keep_alive, phase_times, nworkers); @@ -147,7 +147,7 @@ void WeakProcessor::weak_oops_do(WorkGang* workers, IsAlive* is_alive, KeepAlive* keep_alive, uint indent_log) { - uint nworkers = ergo_workers(workers->active_workers()); + uint nworkers = ergo_workers(workers->total_workers()); WeakProcessorPhaseTimes pt(nworkers); weak_oops_do(workers, is_alive, keep_alive, &pt); pt.log_print_phases(indent_log); From a99df45b7c63de36bdae0a3add76de10d61e3da0 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 13 Jan 2021 08:49:12 +0000 Subject: [PATCH 13/20] 8259560: Zero m68k: "static assertion failed: align" after JDK-8252049 Reviewed-by: dholmes --- src/hotspot/share/ci/ciMethodData.cpp | 5 +++++ src/hotspot/share/oops/methodData.hpp | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/hotspot/share/ci/ciMethodData.cpp b/src/hotspot/share/ci/ciMethodData.cpp index fef6e6f166d6f..3a36f677d2d4a 100644 --- a/src/hotspot/share/ci/ciMethodData.cpp +++ b/src/hotspot/share/ci/ciMethodData.cpp @@ -202,7 +202,12 @@ void ciMethodData::load_data() { // _extra_data_size = extra_data_limit - extra_data_base // total_size = _data_size + _extra_data_size // args_data_limit = data_base + total_size - parameter_data_size + +#ifndef ZERO + // Some Zero platforms do not have expected alignment, and do not use + // this code. static_assert would still fire and fail for them. static_assert(sizeof(_orig) % HeapWordSize == 0, "align"); +#endif Copy::disjoint_words_atomic((HeapWord*) &mdo->_compiler_counters, (HeapWord*) &_orig, sizeof(_orig) / HeapWordSize); diff --git a/src/hotspot/share/oops/methodData.hpp b/src/hotspot/share/oops/methodData.hpp index 464e783b2a49e..a02362b01f861 100644 --- a/src/hotspot/share/oops/methodData.hpp +++ b/src/hotspot/share/oops/methodData.hpp @@ -1984,7 +1984,11 @@ class MethodData : public Metadata { public: CompilerCounters() : _nof_decompiles(0), _nof_overflow_recompiles(0), _nof_overflow_traps(0) { +#ifndef ZERO + // Some Zero platforms do not have expected alignment, and do not use + // this code. static_assert would still fire and fail for them. static_assert(sizeof(_trap_hist) % HeapWordSize == 0, "align"); +#endif uint size_in_words = sizeof(_trap_hist) / HeapWordSize; Copy::zero_to_words((HeapWord*) &_trap_hist, size_in_words); } From 55675309163fe7e824f57d86d1bb572a2e6370e7 Mon Sep 17 00:00:00 2001 From: Nils Eliasson Date: Wed, 13 Jan 2021 09:16:08 +0000 Subject: [PATCH 14/20] 8258272: LoadVectorMaskedNode can't be replaced by zero con Reviewed-by: chagedorn, vlivanov --- src/hotspot/share/opto/memnode.cpp | 6 +- .../TestArrayCopyMaskedWithZeroSrc.java | 59 +++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyMaskedWithZeroSrc.java diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index 90d221964cd34..63a0ded74a3fc 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -2044,10 +2044,12 @@ const Type* LoadNode::Value(PhaseGVN* phase) const { } } - if (is_instance) { + bool is_vect = (_type->isa_vect() != NULL); + if (is_instance && !is_vect) { // If we have an instance type and our memory input is the // programs's initial memory state, there is no matching store, - // so just return a zero of the appropriate type + // so just return a zero of the appropriate type - + // except if it is vectorized - then we have no zero constant. Node *mem = in(MemNode::Memory); if (mem->is_Parm() && mem->in(0)->is_Start()) { assert(mem->as_Parm()->_con == TypeFunc::Memory, "must be memory Parm"); diff --git a/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyMaskedWithZeroSrc.java b/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyMaskedWithZeroSrc.java new file mode 100644 index 0000000000000..85637a83c65e6 --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyMaskedWithZeroSrc.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8258272 + * @summary Test that LoadVectorMaskedNodes works when the source array is known to only contain zeros + * + * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,*::testArrayCopy* + * compiler.arraycopy.TestArrayCopyMaskedWithZeroSrc + */ + +package compiler.arraycopy; + +import java.util.*; + +public class TestArrayCopyMaskedWithZeroSrc { + + public static void main(String[] args) { + TestArrayCopyMaskedWithZeroSrc t = new TestArrayCopyMaskedWithZeroSrc(); + t.test(); + } + + void test() { + for (int i = 0; i < 20000; i++) { + testArrayCopy1(3); + } + } + + // src is allocated locally - it is known it only contains zeros. + // The copy of will exapnd into LoadVectorMasked on AVX512 machines + // LoadNode::value will try to replace the load from src with a zero constant. + + byte [] testArrayCopy1(int partial_len) { + byte [] src = new byte[5]; + byte [] dest = Arrays.copyOf(src, partial_len); + return dest; + } +} From 6bb6093fcaacca83a8c523b1e6a0e1156e037803 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 13 Jan 2021 12:40:25 +0000 Subject: [PATCH 15/20] 8259657: typo in generated HELP page prevents localization Reviewed-by: vromero --- .../internal/doclets/formats/html/resources/standard.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties index 3a8844685f5f6..83cd87941c373 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties @@ -214,7 +214,7 @@ doclet.help.serial_form.body=\ doclet.help.constants.body=\ The {0} page lists the static final fields and their values. doclet.help.systemProperties.body=\ - The {0) page lists references to system properties. + The {0} page lists references to system properties. doclet.help.footnote=\ This help file applies to API documentation generated by the standard doclet. doclet.help.enum.intro=\ From 42d2d6dcc12d6777f9c1b4d1004312ce3c933d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96sterlund?= Date: Wed, 13 Jan 2021 16:48:17 +0000 Subject: [PATCH 16/20] 8259063: Possible deadlock with vtable/itable creation vs concurrent class unloading Reviewed-by: pliden, neliasso --- src/hotspot/share/code/codeBlob.cpp | 27 +++++++++++++++++++++++++-- src/hotspot/share/code/codeBlob.hpp | 2 ++ src/hotspot/share/code/codeCache.cpp | 10 ++++++---- src/hotspot/share/code/codeCache.hpp | 2 +- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index b4f95bf96da06..68cfbf9c56d52 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -304,12 +304,22 @@ AdapterBlob* AdapterBlob::create(CodeBuffer* cb) { return blob; } +void* VtableBlob::operator new(size_t s, unsigned size) throw() { + // Handling of allocation failure stops compilation and prints a bunch of + // stuff, which requires unlocking the CodeCache_lock, so that the Compile_lock + // can be locked, and then re-locking the CodeCache_lock. That is not safe in + // this context as we hold the CompiledICLocker. So we just don't handle code + // cache exhaustion here; we leave that for a later allocation that does not + // hold the CompiledICLocker. + return CodeCache::allocate(size, CodeBlobType::NonNMethod, false /* handle_alloc_failure */); +} + VtableBlob::VtableBlob(const char* name, int size) : BufferBlob(name, size) { } VtableBlob* VtableBlob::create(const char* name, int buffer_size) { - ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock + assert(JavaThread::current()->thread_state() == _thread_in_vm, "called with the wrong state"); VtableBlob* blob = NULL; unsigned int size = sizeof(VtableBlob); @@ -318,8 +328,21 @@ VtableBlob* VtableBlob::create(const char* name, int buffer_size) { size += align_up(buffer_size, oopSize); assert(name != NULL, "must provide a name"); { - MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + if (!CodeCache_lock->try_lock()) { + // If we can't take the CodeCache_lock, then this is a bad time to perform the ongoing + // IC transition to megamorphic, for which this stub will be needed. It is better to + // bail out the transition, and wait for a more opportune moment. Not only is it not + // worth waiting for the lock blockingly for the megamorphic transition, it might + // also result in a deadlock to blockingly wait, when concurrent class unloading is + // performed. At this point in time, the CompiledICLocker is taken, so we are not + // allowed to blockingly wait for the CodeCache_lock, as these two locks are otherwise + // consistently taken in the opposite order. Bailing out results in an IC transition to + // the clean state instead, which will cause subsequent calls to retry the transitioning + // eventually. + return NULL; + } blob = new (size) VtableBlob(name, size); + CodeCache_lock->unlock(); } // Track memory usage statistic after releasing CodeCache_lock MemoryService::track_code_cache_memory_usage(); diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index d9bd003a52dcf..17d466b4bb0fc 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -441,6 +441,8 @@ class VtableBlob: public BufferBlob { private: VtableBlob(const char*, int); + void* operator new(size_t s, unsigned size) throw(); + public: // Creation static VtableBlob* create(const char* name, int buffer_size); diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index a0c42c6dd8395..634e58b298c54 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -483,7 +483,7 @@ CodeBlob* CodeCache::next_blob(CodeHeap* heap, CodeBlob* cb) { * run the constructor for the CodeBlob subclass he is busy * instantiating. */ -CodeBlob* CodeCache::allocate(int size, int code_blob_type, int orig_code_blob_type) { +CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool handle_alloc_failure, int orig_code_blob_type) { // Possibly wakes up the sweeper thread. NMethodSweeper::report_allocation(code_blob_type); assert_locked_or_safepoint(CodeCache_lock); @@ -531,11 +531,13 @@ CodeBlob* CodeCache::allocate(int size, int code_blob_type, int orig_code_blob_t tty->print_cr("Extension of %s failed. Trying to allocate in %s.", heap->name(), get_code_heap(type)->name()); } - return allocate(size, type, orig_code_blob_type); + return allocate(size, type, handle_alloc_failure, orig_code_blob_type); } } - MutexUnlocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - CompileBroker::handle_full_code_cache(orig_code_blob_type); + if (handle_alloc_failure) { + MutexUnlocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + CompileBroker::handle_full_code_cache(orig_code_blob_type); + } return NULL; } if (PrintCodeCacheExtension) { diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp index 959396f8699ef..b0c2f0926aca4 100644 --- a/src/hotspot/share/code/codeCache.hpp +++ b/src/hotspot/share/code/codeCache.hpp @@ -136,7 +136,7 @@ class CodeCache : AllStatic { static const GrowableArray* nmethod_heaps() { return _nmethod_heaps; } // Allocation/administration - static CodeBlob* allocate(int size, int code_blob_type, int orig_code_blob_type = CodeBlobType::All); // allocates a new CodeBlob + static CodeBlob* allocate(int size, int code_blob_type, bool handle_alloc_failure = true, int orig_code_blob_type = CodeBlobType::All); // allocates a new CodeBlob static void commit(CodeBlob* cb); // called when the allocated CodeBlob has been filled static int alignment_unit(); // guaranteed alignment of all CodeBlobs static int alignment_offset(); // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header) From ac4cd2e3c977d5919b490e9e5ec08692ee3e7a2a Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Wed, 13 Jan 2021 17:27:32 +0000 Subject: [PATCH 17/20] 8231461: static/instance overload leads to 'unexpected static method found in unbound lookup' when resolving method reference Reviewed-by: mcimadamore --- .../com/sun/tools/javac/comp/Resolve.java | 50 ++++++- .../tools/javac/resources/compiler.properties | 31 ++++ .../javac/combo/CompilationTestCase.java | 4 + .../combo/tools/javac/combo/Diagnostics.java | 4 + .../javac/combo/JavacTemplateTestBase.java | 7 + .../examples/BoundUnboundMethRefSearch.java | 41 ++++++ .../examples/BoundUnboundMethRefSearch2.java | 47 ++++++ .../BoundUnboundSearchTest.java | 136 ++++++++++++++++++ 8 files changed, 317 insertions(+), 3 deletions(-) create mode 100644 test/langtools/tools/javac/diags/examples/BoundUnboundMethRefSearch.java create mode 100644 test/langtools/tools/javac/diags/examples/BoundUnboundMethRefSearch2.java create mode 100644 test/langtools/tools/javac/lambda/methodReference/BoundUnboundSearchTest.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index 5d9a6bb23e35a..e18409a234844 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -112,6 +112,7 @@ public class Resolve { private final boolean allowLocalVariableTypeInference; private final boolean allowYieldStatement; final EnumSet verboseResolutionMode; + final boolean dumpMethodReferenceSearchResults; WriteableScope polymorphicSignatureScope; @@ -151,6 +152,7 @@ protected Resolve(Context context) { polymorphicSignatureScope = WriteableScope.create(syms.noSymbol); allowModules = Feature.MODULES.allowedInSource(source); allowRecords = Feature.RECORDS.allowedInSource(source); + dumpMethodReferenceSearchResults = options.isSet("debug.dumpMethodReferenceSearchResults"); } /** error symbols, which are returned when resolution fails @@ -2777,7 +2779,7 @@ Symbol findPolymorphicSignatureInstance(final Symbol spMethod, // Check that there is already a method symbol for the method // type and owner if (types.isSameType(mtype, sym.type) && - spMethod.owner == sym.owner) { + spMethod.owner == sym.owner) { return sym; } } @@ -3090,6 +3092,9 @@ Pair resolveMemberReference(Env env, Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundSearchResolveContext, boundLookupHelper); ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext); + if (dumpMethodReferenceSearchResults) { + dumpMethodReferenceSearchResults(referenceTree, boundSearchResolveContext, boundSym, true); + } //step 2 - unbound lookup Symbol unboundSym = methodNotFound; @@ -3103,6 +3108,9 @@ Pair resolveMemberReference(Env env, unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, unboundSearchResolveContext, unboundLookupHelper); unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext); + if (dumpMethodReferenceSearchResults) { + dumpMethodReferenceSearchResults(referenceTree, unboundSearchResolveContext, unboundSym, false); + } } //merge results @@ -3126,6 +3134,42 @@ Pair resolveMemberReference(Env env, return res; } + private void dumpMethodReferenceSearchResults(JCMemberReference referenceTree, + MethodResolutionContext resolutionContext, + Symbol bestSoFar, + boolean bound) { + ListBuffer subDiags = new ListBuffer<>(); + int pos = 0; + int mostSpecificPos = -1; + for (Candidate c : resolutionContext.candidates) { + if (resolutionContext.step != c.step || !c.isApplicable()) { + continue; + } else { + JCDiagnostic subDiag = null; + if (c.sym.type.hasTag(FORALL)) { + subDiag = diags.fragment(Fragments.PartialInstSig(c.mtype)); + } + + String key = subDiag == null ? + "applicable.method.found.2" : + "applicable.method.found.3"; + subDiags.append(diags.fragment(key, pos, + c.sym.isStatic() ? Fragments.Static : Fragments.NonStatic, c.sym, subDiag)); + if (c.sym == bestSoFar) + mostSpecificPos = pos; + pos++; + } + } + JCDiagnostic main = diags.note( + log.currentSource(), + referenceTree, + "method.ref.search.results.multi", + bound ? Fragments.Bound : Fragments.Unbound, + referenceTree.toString(), mostSpecificPos); + JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList()); + log.report(d); + } + /** * This class is used to represent a method reference lookup result. It keeps track of two * things: (i) the symbol found during a method reference lookup and (ii) the static kind @@ -3280,12 +3324,12 @@ ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) { @Override ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) { - if (boundRes.hasKind(StaticKind.STATIC) && + if (boundRes.isSuccess() && boundRes.sym.isStatic() && (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) { //the first search produces a static method and no non-static method is applicable //during the second search return boundRes; - } else if (unboundRes.hasKind(StaticKind.NON_STATIC) && + } else if (unboundRes.isSuccess() && !unboundRes.sym.isStatic() && (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) { //the second search produces a non-static method and no static method is applicable //during the first search diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 6b9362f8b9fcd..7cc4505778ff5 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -3066,6 +3066,37 @@ compiler.note.deferred.method.inst=\ compiler.note.verbose.l2m.deduplicate=\ deduplicating lambda implementation method {0} +######################################## +# Diagnostics for method reference search +# results used by Resolve (debug only) +######################################## + +# 0: fragment, 1: string, 2: number +compiler.note.method.ref.search.results.multi=\ + {0} search results for {1}, with most specific {2}\n\ + applicable candidates: + +# 0: number, 1: fragment, 2: symbol +compiler.misc.applicable.method.found.2=\ + #{0} applicable method found: {1} {2} + +# 0: number, 1: fragment, 2: symbol, 3: message segment +compiler.misc.applicable.method.found.3=\ + #{0} applicable method found: {1} {2}\n\ + ({3}) + +compiler.misc.static=\ + static + +compiler.misc.non.static=\ + non-static + +compiler.misc.bound=\ + bound + +compiler.misc.unbound=\ + unbound + ######################################## # Diagnostics for where clause implementation # used by the RichDiagnosticFormatter. diff --git a/test/langtools/lib/combo/tools/javac/combo/CompilationTestCase.java b/test/langtools/lib/combo/tools/javac/combo/CompilationTestCase.java index 9fd36c78f9bc5..27a2940a2c846 100644 --- a/test/langtools/lib/combo/tools/javac/combo/CompilationTestCase.java +++ b/test/langtools/lib/combo/tools/javac/combo/CompilationTestCase.java @@ -121,6 +121,10 @@ protected File assertOK(boolean generate, String... constructs) { return assertCompile(expandMarkers(constructs), this::assertCompileSucceeded, generate); } + protected File assertOK(Consumer> diagConsumer, String... constructs) { + return assertCompile(expandMarkers(constructs), () -> assertCompileSucceeded(diagConsumer), false); + } + protected void assertOKWithWarning(String warning, String... constructs) { assertCompile(expandMarkers(constructs), () -> assertCompileSucceededWithWarning(warning), false); } diff --git a/test/langtools/lib/combo/tools/javac/combo/Diagnostics.java b/test/langtools/lib/combo/tools/javac/combo/Diagnostics.java index b65fd5fb2ee97..47f496b589172 100644 --- a/test/langtools/lib/combo/tools/javac/combo/Diagnostics.java +++ b/test/langtools/lib/combo/tools/javac/combo/Diagnostics.java @@ -66,6 +66,10 @@ public Diagnostic getDiagWithKey(String key) { return null; } + public List> getAllDiags() { + return diags.stream().map(d -> (Diagnostic)d).collect(toList()); + } + /** Do the diagnostics contain the specified error key? */ public boolean containsErrorKey(String key) { return diags.stream() diff --git a/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java b/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java index cd1be44745f02..be94ec7a3fad5 100644 --- a/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java +++ b/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java @@ -177,6 +177,13 @@ protected void assertCompileSucceeded() { fail("Expected successful compilation"); } + /** Assert that all previous calls to compile() succeeded, also accepts a diagnostics consumer */ + protected void assertCompileSucceeded(Consumer> diagConsumer) { + if (diags.errorsFound()) + fail("Expected successful compilation"); + diags.getAllDiags().stream().forEach(diagConsumer); + } + /** Assert that all previous calls to compile() succeeded */ protected void assertCompileSucceededWithWarning(String warning) { if (diags.errorsFound()) diff --git a/test/langtools/tools/javac/diags/examples/BoundUnboundMethRefSearch.java b/test/langtools/tools/javac/diags/examples/BoundUnboundMethRefSearch.java new file mode 100644 index 0000000000000..0bc33b87abfae --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/BoundUnboundMethRefSearch.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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 + * 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. + */ + +// key: compiler.note.method.ref.search.results.multi +// key: compiler.misc.bound +// key: compiler.misc.applicable.method.found.2 +// key: compiler.misc.static +// key: compiler.misc.non.static +// key: compiler.misc.unbound +// options: --debug=dumpMethodReferenceSearchResults + +import java.util.function.*; + +class BoundUnboundMethRefSearch { + public String foo(Object o) { return "foo"; } + public static String foo(String o) { return "bar"; } + + void m() { + Function f = BoundUnboundMethRefSearch::foo; + } +} diff --git a/test/langtools/tools/javac/diags/examples/BoundUnboundMethRefSearch2.java b/test/langtools/tools/javac/diags/examples/BoundUnboundMethRefSearch2.java new file mode 100644 index 0000000000000..78e661d776735 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/BoundUnboundMethRefSearch2.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 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 + * 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. + */ + +// key: compiler.note.method.ref.search.results.multi +// key: compiler.misc.bound +// key: compiler.misc.applicable.method.found.3 +// key: compiler.misc.static +// key: compiler.misc.partial.inst.sig +// key: compiler.misc.unbound +// options: --debug=dumpMethodReferenceSearchResults + +import java.util.function.*; + +class BoundUnboundMethRefSearch2 { + interface SAM { + boolean test(T n, T m); + } + + static boolean foo(T x, T y) { + return false; + } + + void bar() { + SAM mRef = BoundUnboundMethRefSearch2::foo; + } + +} diff --git a/test/langtools/tools/javac/lambda/methodReference/BoundUnboundSearchTest.java b/test/langtools/tools/javac/lambda/methodReference/BoundUnboundSearchTest.java new file mode 100644 index 0000000000000..e5119f2c0b887 --- /dev/null +++ b/test/langtools/tools/javac/lambda/methodReference/BoundUnboundSearchTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 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 + * 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 8231461 + * @summary static/instance overload leads to 'unexpected static method found in unbound lookup' when resolving method reference + * @library /lib/combo /tools/lib /tools/javac/lib + * @modules + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.util + * @run testng BoundUnboundSearchTest + */ + +import java.util.function.*; + +import javax.tools.Diagnostic; + +import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper; +import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.JCDiagnostic; + +import org.testng.annotations.Test; +import tools.javac.combo.CompilationTestCase; + +import static org.testng.Assert.assertEquals; + +@Test +public class BoundUnboundSearchTest extends CompilationTestCase { + static final String TEMPLATE = + """ + import java.util.function.*; + class Test { + #CANDIDATES + void m() { + Function f = Test::foo; + } + } + """; + + public BoundUnboundSearchTest() { + setDefaultFilename("Test.java"); + setCompileOptions(new String[]{"--debug=dumpMethodReferenceSearchResults"}); + } + + private Consumer> getDiagConsumer(final int boundCandidate, final int unboundCandidate) { + return diagWrapper -> { + JCDiagnostic diagnostic = ((DiagnosticSourceUnwrapper)diagWrapper).d; + Object[] args = diagnostic.getArgs(); + if (args[0].toString().equals("bound")) { + Assert.check(args[2].equals(boundCandidate)); + } else if (args[0].toString().equals("unbound")) { + Assert.check(args[2].equals(unboundCandidate)); + } + }; + } + + public void test() { + assertOK( + getDiagConsumer(0, -1), + TEMPLATE.replaceFirst("#CANDIDATES", + """ + public String foo(Object o) { return "foo"; } // candidate 0 + public static String foo(String o) { return "bar"; } // candidate 1 + """ + ) + ); + + assertOK( + getDiagConsumer(0, -1), + TEMPLATE.replaceFirst("#CANDIDATES", + """ + public static String foo(Object o) { return "foo"; } // candidate 0 + public static String foo(String o) { return "bar"; } // candidate 0 + """ + ) + ); + + assertFail("compiler.err.prob.found.req", + getDiagConsumer(0, -1), + TEMPLATE.replaceFirst("#CANDIDATES", + """ + public static String foo(Object o) { return "foo"; } // candidate 0 + public String foo(String o) { return "bar"; } // candidate 1 + """ + ) + ); + + assertFail("compiler.err.prob.found.req", + getDiagConsumer(0, -1), + TEMPLATE.replaceFirst("#CANDIDATES", + """ + public String foo(Object o) { return "foo"; } // candidate 0 + public String foo(String o) { return "bar"; } // candidate 1 + """ + ) + ); + + assertFail("compiler.err.invalid.mref", + getDiagConsumer(-1, -1), + """ + import java.util.function.*; + + public class Test { + public String foo(Object o) { return "foo"; } + public static String foo(String o) { return "bar"; } + + public void test() { + // method bar doesn't exist + Function f = Test::bar; + } + } + """ + ); + } +} From fb8ac24720a4fbcdd40fb1e9130c32f638e628bc Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 13 Jan 2021 18:23:12 +0000 Subject: [PATCH 18/20] 8259722: ProblemList two jdk/jfr/startupargs tests on Windows Reviewed-by: mgronlun --- test/jdk/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index ed22bf1235126..3f9b2dc478f11 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -850,6 +850,8 @@ jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java 8228990,8229370 jdk/jfr/event/compiler/TestCodeSweeper.java 8225209 generic-all jdk/jfr/event/os/TestThreadContextSwitches.java 8247776 windows-all jdk/jfr/jmx/streaming/TestRotate.java 8257215 generic-all +jdk/jfr/startupargs/TestStartName.java 8214685 windows-x64 +jdk/jfr/startupargs/TestStartDuration.java 8214685 windows-x64 ############################################################################ From 8abefdeca47fc1fc437dd2afaf483b96e7bdaad1 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 13 Jan 2021 18:23:41 +0000 Subject: [PATCH 19/20] 8259720: ProblemList java/awt/Focus/AppletInitialFocusTest/AppletInitialFocusTest1.java on Windows Reviewed-by: kizune, pbansal --- test/jdk/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 3f9b2dc478f11..d78668256a58a 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -895,6 +895,7 @@ java/awt/FileDialog/RegexpFilterTest/RegexpFilterTest.html 7187728 macosx-all,li java/awt/print/PageFormat/Orient.java 8016055 macosx-all java/awt/TextArea/TextAreaCursorTest/HoveringAndDraggingTest.java 8024986 macosx-all,linux-all java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter.java 8254841 macosx-all +java/awt/Focus/AppletInitialFocusTest/AppletInitialFocusTest1.java 8256289 windows-x64 ############################################################################ From 5926d75fa1a96e001c4167a4352e55024644adad Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 13 Jan 2021 19:52:04 +0000 Subject: [PATCH 20/20] 8259719: ProblemList runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP_JFR.java on Windows Reviewed-by: pliden --- test/hotspot/jtreg/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 4ae9f9c164975..45fbf33335edd 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -84,6 +84,7 @@ gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8241293 macosx-x64 # :hotspot_runtime +runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP_JFR.java 8253437 windows-x64 runtime/cds/DeterministicDump.java 8253495 generic-all runtime/jni/terminatedThread/TestTerminatedThread.java 8219652 aix-ppc64 runtime/ReservedStack/ReservedStackTest.java 8231031 generic-all