From 0f32982872eb1454e55390760b65beb5838afc55 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Tue, 13 Jul 2021 05:55:04 +0000 Subject: [PATCH 1/8] 8270203: Missing build dependency between jdk.jfr-gendata and buildtools-hotspot Reviewed-by: tbell --- make/Main.gmk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/make/Main.gmk b/make/Main.gmk index e34766f0611..cad3ecb3203 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -857,6 +857,9 @@ else # virtual target. jdk.jdwp.agent-libs: jdk.jdwp.agent-gensrc + # jdk.jfr-gendata uses TOOL_JFR_GEN from buildtools-hotspot + jdk.jfr-gendata: buildtools-hotspot + # The swing beans need to have java base properly generated to avoid errors # in javadoc. The X11 wrappers need the java.base include files to have been # copied and processed. From 040c02b942a2829626b5bc4a63c3335cd3fe53f4 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 13 Jul 2021 08:50:09 +0000 Subject: [PATCH 2/8] 8269795: C2: Out of bounds array load floats above its range check in loop peeling resulting in SEGV Reviewed-by: thartmann, roland, kvn --- src/hotspot/share/opto/loopTransform.cpp | 30 +++++---- .../TestPeelingRemoveDominatedTest.java | 67 +++++++++++++++++++ 2 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/loopopts/TestPeelingRemoveDominatedTest.java diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp index 4cebd27c0c9..9a6223de052 100644 --- a/src/hotspot/share/opto/loopTransform.cpp +++ b/src/hotspot/share/opto/loopTransform.cpp @@ -507,24 +507,29 @@ uint IdealLoopTree::estimate_peeling(PhaseIdealLoop *phase) { // If we got the effect of peeling, either by actually peeling or by making // a pre-loop which must execute at least once, we can remove all // loop-invariant dominated tests in the main body. -void PhaseIdealLoop::peeled_dom_test_elim(IdealLoopTree *loop, Node_List &old_new) { +void PhaseIdealLoop::peeled_dom_test_elim(IdealLoopTree* loop, Node_List& old_new) { bool progress = true; while (progress) { - progress = false; // Reset for next iteration - Node *prev = loop->_head->in(LoopNode::LoopBackControl);//loop->tail(); - Node *test = prev->in(0); + progress = false; // Reset for next iteration + Node* prev = loop->_head->in(LoopNode::LoopBackControl); // loop->tail(); + Node* test = prev->in(0); while (test != loop->_head) { // Scan till run off top of loop - int p_op = prev->Opcode(); - if ((p_op == Op_IfFalse || p_op == Op_IfTrue) && - test->is_If() && // Test? - !test->in(1)->is_Con() && // And not already obvious? - // Condition is not a member of this loop? - !loop->is_member(get_loop(get_ctrl(test->in(1))))){ + assert(test != NULL, "test cannot be NULL"); + Node* test_cond = NULL; + if ((p_op == Op_IfFalse || p_op == Op_IfTrue) && test->is_If()) { + test_cond = test->in(1); + } + if (test_cond != NULL && // Test? + !test_cond->is_Con() && // And not already obvious? + // And condition is not a member of this loop? + !loop->is_member(get_loop(get_ctrl(test_cond)))) { // Walk loop body looking for instances of this test for (uint i = 0; i < loop->_body.size(); i++) { - Node *n = loop->_body.at(i); - if (n->is_If() && n->in(1) == test->in(1) /*&& n != loop->tail()->in(0)*/) { + Node* n = loop->_body.at(i); + // Check against cached test condition because dominated_by() + // replaces the test condition with a constant. + if (n->is_If() && n->in(1) == test_cond) { // IfNode was dominated by version in peeled loop body progress = true; dominated_by(old_new[prev->_idx], n); @@ -534,7 +539,6 @@ void PhaseIdealLoop::peeled_dom_test_elim(IdealLoopTree *loop, Node_List &old_ne prev = test; test = idom(test); } // End of scan tests in loop - } // End of while (progress) } diff --git a/test/hotspot/jtreg/compiler/loopopts/TestPeelingRemoveDominatedTest.java b/test/hotspot/jtreg/compiler/loopopts/TestPeelingRemoveDominatedTest.java new file mode 100644 index 00000000000..800adb39caa --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestPeelingRemoveDominatedTest.java @@ -0,0 +1,67 @@ +/* + * 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 + * @key stress randomness + * @requires vm.compiler2.enabled + * @bug 8269795 + * @summary PhaseIdealLoop::peeled_dom_test_elim wrongly moves a non-dominated test out of a loop together with control dependent data nodes. + * This results in a crash due to an out of bounds read of an array. + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xcomp -XX:-TieredCompilation -XX:+StressGCM + * -XX:CompileCommand=compileonly,compiler.loopopts.TestPeelingRemoveDominatedTest compiler.loopopts.TestPeelingRemoveDominatedTest + */ + +package compiler.loopopts; + +public class TestPeelingRemoveDominatedTest { + public static int N = 400; + static boolean bFld = true; + static int iArrFld[] = new int[N]; + + public static void main(String[] strArr) { + TestPeelingRemoveDominatedTest _instance = new TestPeelingRemoveDominatedTest(); + for (int i = 0; i < 10; i++) { + _instance.mainTest(); + } + } + + public void mainTest() { + vMeth(); + } + + + static void vMeth() { + iArrFld[1] = 2; + int i6 = 2; + while (--i6 > 0) { + try { + int i3 = (iArrFld[i6 - 1] / 56); + iArrFld[1] = (-139 % i3); + } catch (ArithmeticException a_e) { + } + if (bFld) { + } + } + } +} From e631addd70437c776eeeb481e0b44f1d0fd22fe8 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Tue, 13 Jul 2021 09:27:27 +0000 Subject: [PATCH 3/8] 8259848: Interim javadoc build does not support platform links Reviewed-by: hannesw, jjg, ihse --- make/modules/jdk.javadoc/Gendata.gmk | 68 ++++++++++++++++++---------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/make/modules/jdk.javadoc/Gendata.gmk b/make/modules/jdk.javadoc/Gendata.gmk index 78432cd6a68..c648df6e032 100644 --- a/make/modules/jdk.javadoc/Gendata.gmk +++ b/make/modules/jdk.javadoc/Gendata.gmk @@ -61,36 +61,54 @@ $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \ $(COMPILECREATESYMBOLS_ADD_EXPORTS), \ )) -$(SUPPORT_OUTPUTDIR)/javadoc-symbols/symbols: \ +GENERATE_SYMBOLS_FROM_JDK_VERSION := 11 +JDK_JAVADOC_DIR := $(JDK_OUTPUTDIR)/modules/jdk.javadoc +ELEMENT_LISTS_PKG := jdk/javadoc/internal/doclets/toolkit/resources/releases +ELEMENT_LISTS_DIR := $(JDK_JAVADOC_DIR)/$(ELEMENT_LISTS_PKG) + +$(JDK_JAVADOC_DIR)/_element_lists.marker: \ $(COMPILE_CREATE_SYMBOLS) \ $(wildcard $(TOPDIR)/make/data/symbols/*) \ $(MODULE_INFOS) - $(RM) -r $(@D) - $(MKDIR) -p $(@D) - $(ECHO) Creating javadoc element list - $(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \ - $(COMPILECREATESYMBOLS_ADD_EXPORTS) \ - -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc \ - build.tools.symbolgenerator.CreateSymbols \ - build-javadoc-data \ - $(CT_DATA_DESCRIPTION) \ - $(JDK_OUTPUTDIR)/modules/jdk.javadoc/jdk/javadoc/internal/doclets/toolkit/resources/releases \ - 11 - $(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \ - $(COMPILECREATESYMBOLS_ADD_EXPORTS) \ - -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc \ - build.tools.symbolgenerator.JavadocElementList \ - $(JDK_OUTPUTDIR)/modules/jdk.javadoc/jdk/javadoc/internal/doclets/toolkit/resources/releases/element-list-$(JDK_SOURCE_TARGET_VERSION).txt \ - $(JAVADOC_MODULESOURCEPATH) \ - $(JAVADOC_MODULES) + $(call MakeTargetDir) + $(call LogInfo, Creating javadoc element lists) + $(RM) -r $(ELEMENT_LISTS_DIR) + # Generate element-list files for JDK 11 to current-1 + $(call ExecuteWithLog, $@_historic, \ + $(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \ + $(COMPILECREATESYMBOLS_ADD_EXPORTS) \ + -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc \ + build.tools.symbolgenerator.CreateSymbols \ + build-javadoc-data \ + $(CT_DATA_DESCRIPTION) \ + $(ELEMENT_LISTS_DIR) \ + $(GENERATE_SYMBOLS_FROM_JDK_VERSION) \ + ) + # Generate element-list file for the current JDK version + $(call ExecuteWithLog, $@_current, \ + $(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \ + $(COMPILECREATESYMBOLS_ADD_EXPORTS) \ + -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc \ + build.tools.symbolgenerator.JavadocElementList \ + $(ELEMENT_LISTS_DIR)/element-list-$(JDK_SOURCE_TARGET_VERSION).txt \ + $(JAVADOC_MODULESOURCEPATH) \ + $(JAVADOC_MODULES) \ + ) $(TOUCH) $@ -# Copy ct.sym to the modules libs dir -$(eval $(call SetupCopyFiles, COPY_TO_LIBS, \ - FILES := $(SUPPORT_OUTPUTDIR)/javadoc-symbols/*.txt, \ - DEST := $(JDK_OUTPUTDIR)/modules/jdk.javadoc/jdk/javadoc/internal/doclets/toolkit/resources/releases, \ -)) +################################################################################ +# Copy element-lists to interim langtools -TARGETS += $(SUPPORT_OUTPUTDIR)/javadoc-symbols/symbols +INTERIM_JDK_JAVADOC_DIR := $(BUILDTOOLS_OUTPUTDIR)/interim_langtools_modules/jdk.javadoc.interim +INTERIM_ELEMENT_LISTS_DIR := $(INTERIM_JDK_JAVADOC_DIR)/$(ELEMENT_LISTS_PKG) + +$(INTERIM_JDK_JAVADOC_DIR)/_element_lists.marker: $(JDK_JAVADOC_DIR)/_element_lists.marker + $(call MakeDir, $(INTERIM_ELEMENT_LISTS_DIR)) + $(RM) -r $(INTERIM_ELEMENT_LISTS_DIR)/* + $(CP) -R $(ELEMENT_LISTS_DIR)/* $(INTERIM_ELEMENT_LISTS_DIR)/ + $(TOUCH) $@ ################################################################################ + +TARGETS += $(JDK_JAVADOC_DIR)/_element_lists.marker \ + $(INTERIM_JDK_JAVADOC_DIR)/_element_lists.marker From 00ef65f34d35bf1a3fa6835cc16f19af40c3c325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Tue, 13 Jul 2021 09:41:56 +0000 Subject: [PATCH 4/8] 8269525: Deadlock during Volano with JFR Reviewed-by: egahlin --- .../periodic/sampling/jfrThreadSampler.cpp | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp index e28bec34177..cad081af59b 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp @@ -351,11 +351,12 @@ class JfrThreadSampler : public NonJavaThread { }; static void clear_transition_block(JavaThread* jt) { + assert(Threads_lock->owned_by_self(), "Holding the thread table lock."); jt->clear_trace_flag(); JfrThreadLocal* const tl = jt->jfr_thread_local(); + MutexLocker ml(JfrThreadSampler::transition_block(), Mutex::_no_safepoint_check_flag); if (tl->is_trace_block()) { - MutexLocker ml(JfrThreadSampler::transition_block(), Mutex::_no_safepoint_check_flag); - JfrThreadSampler::transition_block()->notify_all(); + JfrThreadSampler::transition_block()->notify(); } } @@ -403,16 +404,21 @@ JfrThreadSampler::~JfrThreadSampler() { JfrCHeapObj::free(_frames, sizeof(JfrStackFrame) * _max_frames); } +static inline bool is_released(JavaThread* jt) { + return !jt->is_trace_suspend(); +} + void JfrThreadSampler::on_javathread_suspend(JavaThread* thread) { - JfrThreadLocal* const tl = thread->jfr_thread_local(); - tl->set_trace_block(); - { - MonitorLocker ml(transition_block(), Mutex::_no_safepoint_check_flag); - while (thread->is_trace_suspend()) { - ml.wait(); - } - tl->clear_trace_block(); + if (is_released(thread)) { + return; } + JfrThreadLocal* const tl = thread->jfr_thread_local(); + MonitorLocker ml(transition_block(), Mutex::_no_safepoint_check_flag); + tl->set_trace_block(); + while (!is_released(thread)) { + ml.wait(); + } + tl->clear_trace_block(); } JavaThread* JfrThreadSampler::next_thread(ThreadsList* t_list, JavaThread* first_sampled, JavaThread* current) { From bd95c0c9e02946ae6a0d525b1425485b1de4add8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Tue, 13 Jul 2021 09:43:49 +0000 Subject: [PATCH 5/8] 8269635: Stress test SEGV while emitting OldObjectSample Reviewed-by: jbachorik --- .../checkpoint/objectSampleCheckpoint.cpp | 22 +++++++++++++------ .../checkpoint/objectSampleCheckpoint.hpp | 2 ++ .../leakprofiler/sampling/objectSampler.cpp | 2 ++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp index 087c0850d73..8e2a1060528 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp @@ -69,12 +69,11 @@ Semaphore ThreadIdExclusiveAccess::_mutex_semaphore(1); static bool has_thread_exited(traceid tid) { assert(tid != 0, "invariant"); - return unloaded_thread_id_set != NULL && JfrPredicate::test(unloaded_thread_id_set, tid); -} - -static bool add(GrowableArray* set, traceid id) { - assert(set != NULL, "invariant"); - return JfrMutablePredicate::test(set, id); + if (unloaded_thread_id_set == NULL) { + return false; + } + ThreadIdExclusiveAccess lock; + return JfrPredicate::test(unloaded_thread_id_set, tid); } static void add_to_unloaded_thread_set(traceid tid) { @@ -82,7 +81,7 @@ static void add_to_unloaded_thread_set(traceid tid) { if (unloaded_thread_id_set == NULL) { unloaded_thread_id_set = c_heap_allocate_array(); } - add(unloaded_thread_id_set, tid); + JfrMutablePredicate::test(unloaded_thread_id_set, tid); } void ObjectSampleCheckpoint::on_thread_exit(JavaThread* jt) { @@ -92,6 +91,15 @@ void ObjectSampleCheckpoint::on_thread_exit(JavaThread* jt) { } } +void ObjectSampleCheckpoint::clear() { + assert(SafepointSynchronize::is_at_safepoint(), "invariant"); + if (unloaded_thread_id_set != NULL) { + delete unloaded_thread_id_set; + unloaded_thread_id_set = NULL; + } + assert(unloaded_thread_id_set == NULL, "invariant"); +} + template static void do_samples(ObjectSample* sample, const ObjectSample* end, Processor& processor) { assert(sample != NULL, "invariant"); diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp index 3dc5b000cb0..0ed82fd55c8 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp @@ -41,6 +41,7 @@ class Thread; class ObjectSampleCheckpoint : AllStatic { friend class EventEmitter; + friend class ObjectSampler; friend class PathToGcRootsOperation; friend class StackTraceBlobInstaller; private: @@ -48,6 +49,7 @@ class ObjectSampleCheckpoint : AllStatic { static int save_mark_words(const ObjectSampler* sampler, ObjectSampleMarker& marker, bool emit_all); static void write_stacktrace(const JfrStackTrace* trace, JfrCheckpointWriter& writer); static void write(const ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread); + static void clear(); public: static void on_type_set(JfrCheckpointWriter& writer); static void on_type_set_unload(JfrCheckpointWriter& writer); diff --git a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp index 727a9bbc955..5466d0162ad 100644 --- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp +++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp @@ -27,6 +27,7 @@ #include "gc/shared/oopStorage.hpp" #include "gc/shared/oopStorageSet.hpp" #include "jfr/jfrEvents.hpp" +#include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" #include "jfr/leakprofiler/sampling/objectSample.hpp" #include "jfr/leakprofiler/sampling/objectSampler.hpp" #include "jfr/leakprofiler/sampling/sampleList.hpp" @@ -107,6 +108,7 @@ ObjectSampler::~ObjectSampler() { bool ObjectSampler::create(size_t size) { assert(SafepointSynchronize::is_at_safepoint(), "invariant"); assert(_oop_storage != NULL, "should be already created"); + ObjectSampleCheckpoint::clear(); assert(_instance == NULL, "invariant"); _instance = new ObjectSampler(size); return _instance != NULL; From b2416b60fbe1117cc502d5ecdd8356d42d27fddb Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 13 Jul 2021 10:53:49 +0000 Subject: [PATCH 6/8] 8269281: java/foreign/Test{Down,Up}call.java time out Reviewed-by: jvernee --- test/jdk/java/foreign/CallGeneratorHelper.java | 10 ++++++++-- test/jdk/java/foreign/TestDowncall.java | 5 +---- test/jdk/java/foreign/TestUpcall.java | 6 +----- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/test/jdk/java/foreign/CallGeneratorHelper.java b/test/jdk/java/foreign/CallGeneratorHelper.java index cc90a01dd9b..9a795525e1f 100644 --- a/test/jdk/java/foreign/CallGeneratorHelper.java +++ b/test/jdk/java/foreign/CallGeneratorHelper.java @@ -47,6 +47,8 @@ public class CallGeneratorHelper extends NativeTestHelper { static SegmentAllocator IMPLICIT_ALLOCATOR = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope()); + static final int SAMPLE_FACTOR = Integer.parseInt((String)System.getProperties().getOrDefault("generator.sample.factor", "-1")); + static final int MAX_FIELDS = 3; static final int MAX_PARAMS = 3; static final int CHUNK_SIZE = 600; @@ -199,7 +201,9 @@ public class CallGeneratorHelper extends NativeTestHelper { int count = functions; int fCode = functions++ / CHUNK_SIZE; String fName = String.format("f%d_%s_%s_%s", fCode, retCode, sigCode, structCode); - downcalls.add(new Object[] { count, fName, r, ptypes, fields }); + if (SAMPLE_FACTOR == -1 || (count % SAMPLE_FACTOR) == 0) { + downcalls.add(new Object[]{count, fName, r, ptypes, fields}); + } } } } else { @@ -207,7 +211,9 @@ public class CallGeneratorHelper extends NativeTestHelper { int count = functions; int fCode = functions++ / CHUNK_SIZE; String fName = String.format("f%d_%s_%s_%s", fCode, retCode, sigCode, structCode); - downcalls.add(new Object[] { count, fName, r, ptypes, List.of() }); + if (SAMPLE_FACTOR == -1 || (count % SAMPLE_FACTOR) == 0) { + downcalls.add(new Object[]{count, fName, r, ptypes, List.of()}); + } } } } diff --git a/test/jdk/java/foreign/TestDowncall.java b/test/jdk/java/foreign/TestDowncall.java index 251ce4d179b..8a78a20e1fb 100644 --- a/test/jdk/java/foreign/TestDowncall.java +++ b/test/jdk/java/foreign/TestDowncall.java @@ -29,7 +29,7 @@ * @build NativeTestHelper CallGeneratorHelper TestDowncall * * @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies - * --enable-native-access=ALL-UNNAMED + * --enable-native-access=ALL-UNNAMED -Dgenerator.sample.factor=17 * TestDowncall */ @@ -94,9 +94,6 @@ public class TestDowncall extends CallGeneratorHelper { FunctionDescriptor descriptor = function(ret, paramTypes, fields); Object[] args = makeArgs(paramTypes, fields, checks); boolean needsScope = mt.returnType().equals(MemorySegment.class); - if (count % 100 == 0) { - System.gc(); - } Object res = doCall(addr, IMPLICIT_ALLOCATOR, mt, descriptor, args); if (ret == Ret.NON_VOID) { checks.forEach(c -> c.accept(res)); diff --git a/test/jdk/java/foreign/TestUpcall.java b/test/jdk/java/foreign/TestUpcall.java index e08f6fca84f..2b679e85396 100644 --- a/test/jdk/java/foreign/TestUpcall.java +++ b/test/jdk/java/foreign/TestUpcall.java @@ -29,7 +29,7 @@ * @build NativeTestHelper CallGeneratorHelper TestUpcall * * @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies - * --enable-native-access=ALL-UNNAMED + * --enable-native-access=ALL-UNNAMED -Dgenerator.sample.factor=17 * TestUpcall */ @@ -41,7 +41,6 @@ import jdk.incubator.foreign.MemoryLayout; import jdk.incubator.foreign.MemorySegment; import jdk.incubator.foreign.ResourceScope; -import jdk.incubator.foreign.SegmentAllocator; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -115,9 +114,6 @@ public class TestUpcall extends CallGeneratorHelper { MethodHandle mh = abi.downcallHandle(addr, IMPLICIT_ALLOCATOR, mtype, function(ret, paramTypes, fields)); Object[] args = makeArgs(ResourceScope.newImplicitScope(), ret, paramTypes, fields, returnChecks, argChecks); Object[] callArgs = args; - if (count % 100 == 0) { - System.gc(); - } Object res = mh.invokeWithArguments(callArgs); argChecks.forEach(c -> c.accept(args)); if (ret == Ret.NON_VOID) { From d32e42cdd461ee5793331ad237b072c16b096ef4 Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Tue, 13 Jul 2021 14:34:35 +0000 Subject: [PATCH 7/8] 8270184: [TESTBUG] Add coverage for jvmci ResolvedJavaType.toJavaName() for lambdas Backport-of: 6a9bc108736522897f03a75c83e90e2c2a183d27 --- .../vm/ci/runtime/test/TestResolvedJavaType.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java index a8e293a623b..ec7a7b3bd70 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java @@ -162,6 +162,19 @@ public class TestResolvedJavaType extends TypeUniverse { } } + @Test + public void internalNameTest() { + // Verify that the last slash in lambda types are not replaced with a '.' as they + // are part of the type name. + Supplier lambda = () -> () -> System.out.println("run"); + ResolvedJavaType lambdaType = metaAccess.lookupJavaType(lambda.getClass()); + String typeName = lambdaType.getName(); + int typeNameLen = TestResolvedJavaType.class.getSimpleName().length(); + int index = typeName.indexOf(TestResolvedJavaType.class.getSimpleName()); + String suffix = typeName.substring(index + typeNameLen, typeName.length() - 1); + assertEquals(TestResolvedJavaType.class.getName() + suffix, lambdaType.toJavaName()); + } + @Test public void getModifiersTest() { for (Class c : classes) { From 8583aab374c3c2ad94c88e7f649d81ce5f319a5f Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Tue, 13 Jul 2021 17:48:21 +0000 Subject: [PATCH 8/8] 8270025: DynamicCallSiteDesc::withArgs doesn't throw NPE Reviewed-by: jvernee, mchung --- .../lang/constant/DynamicCallSiteDesc.java | 7 +- .../constant/DynamicCallSiteDescTest.java | 192 ++++++++++++++++++ 2 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 test/jdk/java/lang/constant/DynamicCallSiteDescTest.java diff --git a/src/java.base/share/classes/java/lang/constant/DynamicCallSiteDesc.java b/src/java.base/share/classes/java/lang/constant/DynamicCallSiteDesc.java index 90887c8136e..cf6d09c14b3 100644 --- a/src/java.base/share/classes/java/lang/constant/DynamicCallSiteDesc.java +++ b/src/java.base/share/classes/java/lang/constant/DynamicCallSiteDesc.java @@ -66,7 +66,7 @@ public class DynamicCallSiteDesc { * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments * to the bootstrap, that would appear in the * {@code BootstrapMethods} attribute - * @throws NullPointerException if any parameter is null + * @throws NullPointerException if any parameter or its contents are {@code null} * @throws IllegalArgumentException if the invocation name has the incorrect * format * @jvms 4.2.2 Unqualified Names @@ -79,6 +79,9 @@ public class DynamicCallSiteDesc { this.invocationType = requireNonNull(invocationType); this.bootstrapMethod = requireNonNull(bootstrapMethod); this.bootstrapArgs = requireNonNull(bootstrapArgs.clone()); + for (int i = 0; i < this.bootstrapArgs.length; i++) { + requireNonNull(this.bootstrapArgs[i]); + } if (invocationName.length() == 0) throw new IllegalArgumentException("Illegal invocation name: " + invocationName); } @@ -97,7 +100,7 @@ public class DynamicCallSiteDesc { * to the bootstrap, that would appear in the * {@code BootstrapMethods} attribute * @return the nominal descriptor - * @throws NullPointerException if any parameter is null + * @throws NullPointerException if any parameter or its contents are {@code null} * @throws IllegalArgumentException if the invocation name has the incorrect * format * @jvms 4.2.2 Unqualified Names diff --git a/test/jdk/java/lang/constant/DynamicCallSiteDescTest.java b/test/jdk/java/lang/constant/DynamicCallSiteDescTest.java new file mode 100644 index 00000000000..6f5e04efeb0 --- /dev/null +++ b/test/jdk/java/lang/constant/DynamicCallSiteDescTest.java @@ -0,0 +1,192 @@ +/* + * 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. + */ + +import java.lang.invoke.MethodType; +import java.lang.constant.*; +import java.util.Arrays; +import java.util.List; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import org.testng.annotations.Test; + +import static java.lang.constant.ConstantDescs.CD_int; +import static java.lang.constant.ConstantDescs.CD_void; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; + +/** + * @test + * @compile DynamicCallSiteDescTest.java + * @run testng DynamicCallSiteDescTest + * @summary unit tests for java.lang.constant.DynamicCallSiteDesc + */ + +@Test +public class DynamicCallSiteDescTest extends SymbolicDescTest { + /* note there is no unit test for method resolveCallSiteDesc as it is being tested in another test in this + * suite, IndyDescTest + */ + + public void testOf() throws ReflectiveOperationException { + DirectMethodHandleDesc dmh = ConstantDescs.ofCallsiteBootstrap( + ClassDesc.of("BootstrapAndTarget"), + "bootstrap", + ClassDesc.of("java.lang.invoke.CallSite") + ); + try { + DynamicCallSiteDesc.of( + dmh, + "", + MethodTypeDesc.ofDescriptor("()I") + ); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException iae) { + // good + } + + try { + DynamicCallSiteDesc.of( + null, + "getTarget", + MethodTypeDesc.ofDescriptor("()I") + ); + fail("NullPointerException expected"); + } catch (NullPointerException npe) { + // good + } + + try { + DynamicCallSiteDesc.of( + dmh, + null, + MethodTypeDesc.ofDescriptor("()I") + ); + fail("NullPointerException expected"); + } catch (NullPointerException npe) { + // good + } + + try { + DynamicCallSiteDesc.of( + dmh, + "getTarget", + null + ); + fail("NullPointerException expected"); + } catch (NullPointerException npe) { + // good + } + + try { + DynamicCallSiteDesc.of( + dmh, + "getTarget", + MethodTypeDesc.ofDescriptor("()I"), + null + ); + fail("NullPointerException expected"); + } catch (NullPointerException npe) { + // good + } + try { + DynamicCallSiteDesc.of( + dmh, + "getTarget", + MethodTypeDesc.ofDescriptor("()I"), + new ConstantDesc[]{ null } + ); + fail("NullPointerException expected"); + } catch (NullPointerException npe) { + // good + } + } + + public void testWithArgs() throws ReflectiveOperationException { + DynamicCallSiteDesc desc = DynamicCallSiteDesc.of(ConstantDescs.ofCallsiteBootstrap( + ClassDesc.of("BootstrapAndTarget"), + "bootstrap", + ClassDesc.of("java.lang.invoke.CallSite") + ), + "getTarget", + MethodTypeDesc.ofDescriptor("()I") + ); + + try { + desc.withArgs(null); + fail("NullPointerException expected"); + } catch (NullPointerException npe) { + // good + } + + try { + desc.withArgs(new ConstantDesc[]{ null }); + fail("NullPointerException expected"); + } catch (NullPointerException npe) { + // good + } + } + + public void testWithNameAndType() throws ReflectiveOperationException { + DynamicCallSiteDesc desc = DynamicCallSiteDesc.of(ConstantDescs.ofCallsiteBootstrap( + ClassDesc.of("BootstrapAndTarget"), + "bootstrap", + ClassDesc.of("java.lang.invoke.CallSite") + ), + "getTarget", + MethodTypeDesc.ofDescriptor("()I") + ); + + try { + desc.withNameAndType(null, MethodTypeDesc.ofDescriptor("()I")); + fail("NullPointerException expected"); + } catch (NullPointerException npe) { + // good + } + + try { + desc.withNameAndType("bootstrap", null); + fail("NullPointerException expected"); + } catch (NullPointerException npe) { + // good + } + } + + public void testAccessorsAndFactories() throws ReflectiveOperationException { + DynamicCallSiteDesc desc = DynamicCallSiteDesc.of(ConstantDescs.ofCallsiteBootstrap( + ClassDesc.of("BootstrapAndTarget"), + "bootstrap", + ClassDesc.of("java.lang.invoke.CallSite") + ), + "_", + MethodTypeDesc.ofDescriptor("()I") + ); + assertEquals(desc, DynamicCallSiteDesc.of((DirectMethodHandleDesc)desc.bootstrapMethod(), desc.invocationType())); + assertEquals(desc, DynamicCallSiteDesc.of((DirectMethodHandleDesc)desc.bootstrapMethod(), + desc.invocationName(), desc.invocationType())); + assertEquals(desc, DynamicCallSiteDesc.of((DirectMethodHandleDesc)desc.bootstrapMethod(), + desc.invocationName(), desc.invocationType(), desc.bootstrapArgs())); + } +}