From 5547d3204d167af149b797abd7563ac8a536a237 Mon Sep 17 00:00:00 2001 From: Patric Hedlin Date: Wed, 17 Jun 2020 11:08:44 +0200 Subject: [PATCH 01/14] 8247200: assert((unsigned)fpargs < 32) Reviewed-by: aph, neliasso --- .../cpu/aarch64/sharedRuntime_aarch64.cpp | 36 +++---------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index b25a579d9a9..03d601431f0 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1129,13 +1129,11 @@ class ComputeMoveOrder: public StackObj { }; -static void rt_call(MacroAssembler* masm, address dest, int gpargs, int fpargs, int type) { +static void rt_call(MacroAssembler* masm, address dest) { CodeBlob *cb = CodeCache::find_blob(dest); if (cb) { __ far_call(RuntimeAddress(dest)); } else { - assert((unsigned)gpargs < 256, "eek!"); - assert((unsigned)fpargs < 32, "eek!"); __ lea(rscratch1, RuntimeAddress(dest)); __ blr(rscratch1); __ maybe_isb(); @@ -1803,33 +1801,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset())); __ stlrw(rscratch1, rscratch2); - { - int return_type = 0; - switch (ret_type) { - case T_VOID: break; - return_type = 0; break; - case T_CHAR: - case T_BYTE: - case T_SHORT: - case T_INT: - case T_BOOLEAN: - case T_LONG: - return_type = 1; break; - case T_ARRAY: - case T_OBJECT: - return_type = 1; break; - case T_FLOAT: - return_type = 2; break; - case T_DOUBLE: - return_type = 3; break; - default: - ShouldNotReachHere(); - } - rt_call(masm, native_func, - int_args + 2, // AArch64 passes up to 8 args in int registers - float_args, // and up to 8 float args - return_type); - } + rt_call(masm, native_func); __ bind(native_return); @@ -2039,7 +2011,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, __ ldr(r19, Address(rthread, in_bytes(Thread::pending_exception_offset()))); __ str(zr, Address(rthread, in_bytes(Thread::pending_exception_offset()))); - rt_call(masm, CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), 3, 0, 1); + rt_call(masm, CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C)); #ifdef ASSERT { @@ -2066,7 +2038,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, __ bind(reguard); save_native_result(masm, ret_type, stack_slots); - rt_call(masm, CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages), 0, 0, 0); + rt_call(masm, CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)); restore_native_result(masm, ret_type, stack_slots); // and continue __ b(reguard_done); From f740cda5261f4b90218d11022d626c8dfbe8ddb9 Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Wed, 17 Jun 2020 07:40:09 -0700 Subject: [PATCH 02/14] 8247716: JVM_RegisterWhiteBoxMethods checks wrong classloader Reviewed-by: dcubed --- src/hotspot/share/prims/whitebox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index 11baef13089..54d01414538 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -2555,7 +2555,7 @@ JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass)) { if (WhiteBoxAPI) { // Make sure that wbclass is loaded by the null classloader - InstanceKlass* ik = InstanceKlass::cast(JNIHandles::resolve(wbclass)->klass()); + InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(wbclass))); Handle loader(THREAD, ik->class_loader()); if (loader.is_null()) { WhiteBox::register_methods(env, wbclass, thread, methods, sizeof(methods) / sizeof(methods[0])); From 338dd21cfe4973f164b992330a748c1cf203a9eb Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Wed, 17 Jun 2020 07:40:11 -0700 Subject: [PATCH 03/14] 8247725: move two tests for whitebox from test/hotspot/jtreg/sanity to test/lib-test Reviewed-by: dcubed --- .../sun/hotspot/whitebox}/MismatchedWhiteBox/WhiteBox.java | 0 .../jtreg/sanity => lib-test/sun/hotspot/whitebox}/WBApi.java | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test/{hotspot/jtreg/sanity => lib-test/sun/hotspot/whitebox}/MismatchedWhiteBox/WhiteBox.java (100%) rename test/{hotspot/jtreg/sanity => lib-test/sun/hotspot/whitebox}/WBApi.java (100%) diff --git a/test/hotspot/jtreg/sanity/MismatchedWhiteBox/WhiteBox.java b/test/lib-test/sun/hotspot/whitebox/MismatchedWhiteBox/WhiteBox.java similarity index 100% rename from test/hotspot/jtreg/sanity/MismatchedWhiteBox/WhiteBox.java rename to test/lib-test/sun/hotspot/whitebox/MismatchedWhiteBox/WhiteBox.java diff --git a/test/hotspot/jtreg/sanity/WBApi.java b/test/lib-test/sun/hotspot/whitebox/WBApi.java similarity index 100% rename from test/hotspot/jtreg/sanity/WBApi.java rename to test/lib-test/sun/hotspot/whitebox/WBApi.java From ed4b80177186c56e50c63c1f8f61e7887f2a7861 Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Wed, 17 Jun 2020 13:18:19 +0200 Subject: [PATCH 04/14] 8238735: NPE compiling lambda expression within conditional expression The fix saves result type from the first pass through the Attr.visitLambda and returns it after recovery pass to avoid NPE caused by exposure of Type.recoveryType Reviewed-by: mcimadamore --- .../classes/com/sun/tools/javac/comp/Attr.java | 9 ++++++++- test/langtools/tools/javac/8238735/T8238735.java | 13 +++++++++++++ test/langtools/tools/javac/8238735/T8238735.out | 2 ++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/langtools/tools/javac/8238735/T8238735.java create mode 100644 test/langtools/tools/javac/8238735/T8238735.out diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 10864db30ce..b6f0dd41551 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -3040,7 +3040,14 @@ public class Attr extends JCTree.Visitor { } finally { localEnv.info.scope.leave(); if (needsRecovery) { - attribTree(that, env, recoveryInfo); + Type prevResult = result; + try { + attribTree(that, env, recoveryInfo); + } finally { + if (result == Type.recoveryType) { + result = prevResult; + } + } } } } diff --git a/test/langtools/tools/javac/8238735/T8238735.java b/test/langtools/tools/javac/8238735/T8238735.java new file mode 100644 index 00000000000..eb71c9a9fe6 --- /dev/null +++ b/test/langtools/tools/javac/8238735/T8238735.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8238735 + * @summary javac should fail without throwing NPE + * @compile/fail/ref=T8238735.out -XDrawDiagnostics T8238735.java + */ + +class T8238735 { + public static void main(String[] args) { + boolean first = true; + first = first ? false : (boolean)(() -> false) ; + } +} diff --git a/test/langtools/tools/javac/8238735/T8238735.out b/test/langtools/tools/javac/8238735/T8238735.out new file mode 100644 index 00000000000..db37e00b246 --- /dev/null +++ b/test/langtools/tools/javac/8238735/T8238735.out @@ -0,0 +1,2 @@ +T8238735.java:11:43: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: boolean) +1 error From 2a794b696ce6257e8a17784feb15c838a88d7f0f Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 17 Jun 2020 09:20:24 -0700 Subject: [PATCH 05/14] 8245696: javadoc crashes when a doc-files directory contains a '#' file Reviewed-by: hannesw --- .../formats/html/DocFilesHandlerImpl.java | 21 +++++++++ .../toolkit/resources/doclets.properties | 1 + .../doclet/testDocFiles/TestDocFiles.java | 43 ++++++++++++++++++- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java index 01f0f536dfb..08ec9782a74 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java @@ -49,6 +49,8 @@ import javax.lang.model.element.PackageElement; import javax.tools.FileObject; import javax.tools.JavaFileManager.Location; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -145,6 +147,15 @@ public class DocFilesHandlerImpl implements DocFilesHandler { return; } for (DocFile srcfile: srcdir.list()) { + // ensure that the name is a valid component in an eventual full path + // and so avoid an equivalent check lower down in the file manager + // that throws IllegalArgumentException + if (!isValidFilename(srcfile)) { + configuration.messages.warning("doclet.Copy_Ignored_warning", + srcfile.getPath()); + continue; + } + DocFile destfile = dstdir.resolve(srcfile.getName()); if (srcfile.isFile()) { if (destfile.exists() && !first) { @@ -169,6 +180,16 @@ public class DocFilesHandlerImpl implements DocFilesHandler { } } + private boolean isValidFilename(DocFile f) { + try { + String n = f.getName(); + URI u = new URI(n); + return u.getPath().equals(n); + } catch (URISyntaxException e) { + return false; + } + } + private void handleHtmlFile(DocFile srcfile, DocPath dstPath) throws DocFileIOException { Utils utils = configuration.utils; FileObject fileObject = srcfile.getFileObject(); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties index 9309c756442..62246eba3ed 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties @@ -55,6 +55,7 @@ Please file a bug against the javadoc tool via the Java bug reporting page\n\ for duplicates. Include error messages and the following diagnostic in your report. Thank you. doclet.File_not_found=File not found: {0} doclet.Copy_Overwrite_warning=File {0} not copied to {1} due to existing file with same name... +doclet.Copy_Ignored_warning=File {0} not copied: invalid name doclet.Copying_File_0_To_Dir_1=Copying file {0} to directory {1}... doclet.Copying_File_0_To_File_1=Copying file {0} to file {1}... doclet.No_Public_Classes_To_Document=No public or protected classes found to document. diff --git a/test/langtools/jdk/javadoc/doclet/testDocFiles/TestDocFiles.java b/test/langtools/jdk/javadoc/doclet/testDocFiles/TestDocFiles.java index c9e6ea0ddc5..a0d6e8c3fd5 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocFiles/TestDocFiles.java +++ b/test/langtools/jdk/javadoc/doclet/testDocFiles/TestDocFiles.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8008949 8234051 + * @bug 8008949 8234051 8245696 * @summary doclet crashes if HTML files in module doc-files directories * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -33,6 +33,8 @@ import java.io.IOException; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import toolbox.ToolBox; import javadoc.tester.JavadocTester; @@ -134,4 +136,43 @@ public class TestDocFiles extends JavadocTester { checkOutput("m/p/doc-files/pkg-file.html", true, "Package HTML file"); } + + @Test + public void testBadFiles(Path base) throws IOException { + Path src = base.resolve("src"); + + tb.writeJavaFiles(src, + "package p; public class C { }"); + Path df = src.resolve("p").resolve("doc-files"); + + // note that '?' may be an illegal filename character on some systems (e.g. Windows) + List cases = List.of("valid", "#bad#", "#bad", "bad#bad", "bad?bad"); + List files = new ArrayList<>(); + for (String s : cases) { + try { + Path f = df.resolve(s); + tb.writeFile(f, "dummy contents"); + files.add(f); + } catch (Throwable t) { + out.println("Cannot write doc-file " + s); + } + } + + javadoc("-d", base.resolve("out").toString(), + "--source-path", src.toString(), + "p"); + checkExit(Exit.OK); + + // only check for those files + for (Path f : files) { + if (f.getFileName().toString().contains("valid")) { + checkOutput("p/doc-files/" + f.getFileName(), true, + "dummy contents"); + } else { + // be careful handing file separator characters in the message + checkOutput(Output.OUT, true, + "warning - File " + f + " not copied: invalid name"); + } + } + } } From ce4978ffe69c20f9e6adb13944ea4c30c912f6a4 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Wed, 17 Jun 2020 13:19:51 -0400 Subject: [PATCH 06/14] 8246257: Annotated record's vararg type component started to be uncompilable with JDK15b24 Reviewed-by: jjg, jlaskey --- .../sun/tools/javac/code/TypeAnnotations.java | 3 +++ .../javac/records/RecordCompilationTests.java | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index dd7662fdb9a..173aa65b611 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -548,6 +548,9 @@ public class TypeAnnotations { */ private Type rewriteArrayType(ArrayType type, List annotations, TypeAnnotationPosition pos) { ArrayType tomodify = new ArrayType(type); + if (type.isVarargs()) { + tomodify = tomodify.makeVarargs(); + } ArrayType res = tomodify; List loc = List.nil(); diff --git a/test/langtools/tools/javac/records/RecordCompilationTests.java b/test/langtools/tools/javac/records/RecordCompilationTests.java index d721ff8d147..c88307af46a 100644 --- a/test/langtools/tools/javac/records/RecordCompilationTests.java +++ b/test/langtools/tools/javac/records/RecordCompilationTests.java @@ -1130,6 +1130,26 @@ public class RecordCompilationTests extends CompilationTestCase { this.args = args; } } + """, + """ + record R(@A int... ints) {} + + @java.lang.annotation.Target({ + java.lang.annotation.ElementType.TYPE_USE, + java.lang.annotation.ElementType.RECORD_COMPONENT}) + @interface A {} + """, + """ + record R(@A int... ints) { + R(@A int... ints) { + this.ints = ints; + } + } + + @java.lang.annotation.Target({ + java.lang.annotation.ElementType.TYPE_USE, + java.lang.annotation.ElementType.RECORD_COMPONENT}) + @interface A {} """ )) { assertOK(source); From ecb4cbfd4a97d83eb63053ebace0047ed4015ffa Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Wed, 17 Jun 2020 14:39:44 -0400 Subject: [PATCH 07/14] 8245842: provide tests for binary compatibility assertions for sealed classes Reviewed-by: jjg --- .../sealed/BinaryCompatibilityTests.java | 487 ++++++++++++++++++ 1 file changed, 487 insertions(+) create mode 100644 test/langtools/tools/javac/sealed/BinaryCompatibilityTests.java diff --git a/test/langtools/tools/javac/sealed/BinaryCompatibilityTests.java b/test/langtools/tools/javac/sealed/BinaryCompatibilityTests.java new file mode 100644 index 00000000000..3759aee6027 --- /dev/null +++ b/test/langtools/tools/javac/sealed/BinaryCompatibilityTests.java @@ -0,0 +1,487 @@ +/* + * 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 + * @summary test binary compatibility rules for sealed classes + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util + * jdk.compiler/com.sun.tools.javac.code + * jdk.jdeps/com.sun.tools.classfile + * @build toolbox.ToolBox toolbox.JavacTask + * @run main BinaryCompatibilityTests + */ + +import java.util.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.IntStream; + +import com.sun.tools.classfile.*; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.util.Assert; +import toolbox.TestRunner; +import toolbox.ToolBox; +import toolbox.JavaTask; +import toolbox.JavacTask; +import toolbox.Task; +import toolbox.Task.OutputKind; + +import static com.sun.tools.classfile.ConstantPool.*; + +public class BinaryCompatibilityTests extends TestRunner { + ToolBox tb; + + BinaryCompatibilityTests() { + super(System.err); + tb = new ToolBox(); + } + + protected void runTests() throws Exception { + runTests(m -> new Object[]{Paths.get(m.getName())}); + } + + public static void main(String... args) throws Exception { + BinaryCompatibilityTests t = new BinaryCompatibilityTests(); + t.runTests(); + } + + Path[] findJavaFiles(Path... paths) throws IOException { + return tb.findJavaFiles(paths); + } + + @Test + public void testCompatibilityAfterMakingSuperclassSealed(Path base) throws Exception { + // sealing a super class which was not sealed, should fail with IncompatibleClassChangeError + testCompatibilityAfterModifyingSupertype( + base, + """ + package pkg; + public class Super { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + """, + """ + package pkg; + public sealed class Super permits Sub1 { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + + final class Sub1 extends Super {} + """, + """ + package pkg; + class Sub extends Super {} + """, + true + ); + } + + @Test + public void testCompatibilityAfterMakingSuperInterfaceSealed(Path base) throws Exception { + // sealing a super interface which was not sealed, should fail with IncompatibleClassChangeError + testCompatibilityAfterModifyingSupertype( + base, + """ + package pkg; + public interface Super { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + """, + """ + package pkg; + public sealed interface Super permits Sub1 { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + + final class Sub1 implements Super {} + """, + """ + package pkg; + class Sub implements Super {} + """, + true + ); + } + + /* 1- compiles the first version of the superclass source code along with the subclass source code + * 2- executes the super class just to make sure that it works + * 3- compiles the second version of the super class along with the class file of the subclass + * 4- executes the super class and makes sure that the VM throws IncompatibleClassChangeError or not + * depending on the shouldFail argument + */ + private void testCompatibilityAfterModifyingSupertype( + Path base, + String superClassCode1, + String superClassCode2, + String subClassCode, + boolean shouldFail) throws Exception { + Path src = base.resolve("src"); + Path pkg = src.resolve("pkg"); + Path superClass = pkg.resolve("Super"); + Path sub = pkg.resolve("Sub"); + + // super class initially not sealed + tb.writeJavaFiles(superClass, superClassCode1); + tb.writeJavaFiles(sub, subClassCode); + + Path out = base.resolve("out"); + Files.createDirectories(out); + + new JavacTask(tb) + .options("--enable-preview", + "-source", Integer.toString(Runtime.version().feature())) + .outdir(out) + .files(findJavaFiles(pkg)) + .run(); + + // let's execute to check that it's working + String output = new JavaTask(tb) + .vmOptions("--enable-preview") + .classpath(out.toString()) + .classArgs("pkg.Super") + .run() + .writeAll() + .getOutput(Task.OutputKind.STDOUT); + + // let's first check that it runs wo issues + if (!output.contains("done")) { + throw new AssertionError("execution of Super didn't finish"); + } + + // now lets change the super class + tb.writeJavaFiles(superClass, superClassCode2); + + new JavacTask(tb) + .options("--enable-preview", + "-source", Integer.toString(Runtime.version().feature())) + .classpath(out) + .outdir(out) + .files(findJavaFiles(superClass)) + .run(); + + if (shouldFail) { + // let's now check that there is an IncompatibleClassChangeError + output = new JavaTask(tb) + .vmOptions("--enable-preview") + .classpath(out.toString()) + .classArgs("pkg.Super") + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.STDERR); + if (!output.startsWith("Exception in thread \"main\" java.lang.IncompatibleClassChangeError")) { + throw new AssertionError("java.lang.IncompatibleClassChangeError expected"); + } + } else { + new JavaTask(tb) + .vmOptions("--enable-preview") + .classpath(out.toString()) + .classArgs("pkg.Super") + .run(Task.Expect.SUCCESS); + } + } + + @Test + public void testRemoveSealedModifierToClass(Path base) throws Exception { + // should execute without error + testCompatibilityAfterModifyingSupertype( + base, + """ + package pkg; + public sealed class Super permits pkg.Sub { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + """, + """ + package pkg; + public class Super { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + """, + """ + package pkg; + final class Sub extends Super {} + """, + false + ); + } + + @Test + public void testRemoveSealedModifierToInterface(Path base) throws Exception { + // should execute without error + testCompatibilityAfterModifyingSupertype( + base, + """ + package pkg; + public sealed interface Super permits pkg.Sub { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + """, + """ + package pkg; + public interface Super { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + """, + """ + package pkg; + final class Sub implements Super {} + """, + false + ); + } + + @Test + public void testAddNonSealedModifierToClass(Path base) throws Exception { + // should execute without error + testCompatibilityOKAfterSubclassChange( + base, + """ + package pkg; + public sealed class Super permits pkg.Sub { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + """, + """ + package pkg; + final class Sub extends Super {} + """, + """ + package pkg; + non-sealed class Sub extends Super {} + """ + ); + } + + @Test + public void testAddNonSealedModifierToInterface(Path base) throws Exception { + // should execute without error + testCompatibilityOKAfterSubclassChange( + base, + """ + package pkg; + public sealed interface Super permits pkg.Sub { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + """, + """ + package pkg; + final class Sub implements Super {} + """, + """ + package pkg; + non-sealed class Sub implements Super {} + """ + ); + } + + @Test + public void testRemoveNonSealedModifier(Path base) throws Exception { + // should execute without error + testCompatibilityOKAfterSubclassChange( + base, + """ + package pkg; + public sealed class Super permits pkg.Sub { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + """, + """ + package pkg; + non-sealed class Sub extends Super {} + """, + """ + package pkg; + final class Sub extends Super {} + """ + ); + } + + @Test + public void testRemoveNonSealedModifierFromInterface(Path base) throws Exception { + // should execute without error + testCompatibilityOKAfterSubclassChange( + base, + """ + package pkg; + public sealed interface Super permits pkg.Sub { + public static void main(String... args) { + pkg.Sub sub = new pkg.Sub(); + System.out.println("done"); + } + } + """, + """ + package pkg; + non-sealed class Sub implements Super {} + """, + """ + package pkg; + final class Sub implements Super {} + """ + ); + } + + /* 1- compiles the the superclass source code along with the first version of the subclass source code + * 2- executes the super class just to make sure that it works + * 3- compiles the second version of the subclass along with the class file of the superclass + * 4- executes the super class and makes sure that it executes successfully + */ + private void testCompatibilityOKAfterSubclassChange( + Path base, + String superClassCode, + String subClassCode1, + String subClassCode2) throws Exception { + Path src = base.resolve("src"); + Path pkg = src.resolve("pkg"); + Path superClass = pkg.resolve("Super"); + Path sub = pkg.resolve("Sub"); + + // super class initially sealed + tb.writeJavaFiles(superClass, superClassCode); + + tb.writeJavaFiles(sub, subClassCode1); + + Path out = base.resolve("out"); + + Files.createDirectories(out); + + new JavacTask(tb) + .outdir(out) + .options("--enable-preview", + "-source", Integer.toString(Runtime.version().feature())) + .files(findJavaFiles(pkg)) + .run(); + + // let's execute to check that it's working + String output = new JavaTask(tb) + .classpath(out.toString()) + .vmOptions("--enable-preview") + .classArgs("pkg.Super") + .run() + .writeAll() + .getOutput(Task.OutputKind.STDOUT); + + // let's first check that it runs wo issues + if (!output.contains("done")) { + throw new AssertionError("execution of Super didn't finish"); + } + + // now lets remove the non-sealed modifier from class Sub + tb.writeJavaFiles(sub, subClassCode2); + + new JavacTask(tb) + .options("--enable-preview", + "-source", Integer.toString(Runtime.version().feature())) + .classpath(out) + .outdir(out) + .files(findJavaFiles(sub)) + .run(); + + // should execute without issues + output = new JavaTask(tb) + .vmOptions("--enable-preview") + .classpath(out.toString()) + .classArgs("pkg.Super") + .run() + .writeAll() + .getOutput(Task.OutputKind.STDOUT); + // let's first check that it runs wo issues + if (!output.contains("done")) { + throw new AssertionError("execution of Super didn't finish"); + } + } + + @Test + public void testAfterChangingPermitsClause(Path base) throws Exception { + // the VM will throw IncompatibleClassChangeError + testCompatibilityAfterModifyingSupertype( + base, + """ + package pkg; + public sealed class Super permits pkg.Sub1, Sub2 { + public static void main(String... args) { + pkg.Sub1 sub = new pkg.Sub1(); + System.out.println("done"); + } + } + + final class Sub2 extends Super {} + """, + """ + package pkg; + public sealed class Super permits Sub2 { + public static void main(String... args) { + pkg.Sub1 sub = new pkg.Sub1(); + System.out.println("done"); + } + } + + final class Sub2 extends Super {} + """, + """ + package pkg; + final class Sub1 extends Super {} + """, + true + ); + } +} From 59a4517d0760f5e1e08ba750efa23a993fca2050 Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Thu, 18 Jun 2020 03:05:41 +0200 Subject: [PATCH 08/14] Added tag jdk-15+28 for changeset 06c9f89459da --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index c4a25b4c745..316766216af 100644 --- a/.hgtags +++ b/.hgtags @@ -642,3 +642,4 @@ f143729ca00ec14a98ea5c7f73acba88da97746e jdk-15+23 506abc554caeb275928c02bf3a16e95d1978749f jdk-15+27 506abc554caeb275928c02bf3a16e95d1978749f jdk-15+27 93813843680bbe1b7efbca56c03fd137f20a2c31 jdk-15+27 +06c9f89459daba98395fad726100feb44f89ba71 jdk-15+28 From 2cbdd21ed7a89e658a925a7d616f767a3fef3328 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Thu, 18 Jun 2020 10:39:36 +0200 Subject: [PATCH 09/14] 8241802: [Graal] compiler/loopopts/TestLogSum.java timed out Reviewed-by: kvn --- .../compiler/core/test/DeepUnrollingTest.java | 86 +++++++++++++++++++ .../loop/phases/LoopFullUnrollPhase.java | 28 +++++- .../org/graalvm/compiler/loop/LoopsData.java | 8 +- 3 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DeepUnrollingTest.java diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DeepUnrollingTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DeepUnrollingTest.java new file mode 100644 index 00000000000..cff1c29bfbd --- /dev/null +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DeepUnrollingTest.java @@ -0,0 +1,86 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.graalvm.compiler.core.test; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import org.graalvm.compiler.core.common.GraalOptions; +import org.graalvm.compiler.options.OptionValues; +import org.junit.Test; + +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public class DeepUnrollingTest extends SubprocessTest { + + public static void loops() { + for (int i = 0; i < 6; i++) { + for (int n = 2; n < 30; n++) { + for (int j = 1; j <= n; j++) { + for (int k = 1; k <= j; k++) { + // nop + } + } + } + } + } + + public static int reference(int a, int n) { + int v = a; + for (int i = 0; i < n; i++) { + if (v % 2 == 0) { + v = v / 2; + } else { + v = 3 * v + 1; + } + } + return v; + } + + public void loopTest() { + // warmup + time("reference"); + time("loops"); + long reference = time("reference"); + long loops = time("loops"); + // observed ratio is ~20-30x. Pathological case before fix was ~300x + assertTrue("Compilation of the loop nest is too slow", loops < reference * 45); + } + + public long time(String methodName) { + ResolvedJavaMethod method = getResolvedJavaMethod(methodName); + OptionValues options = new OptionValues(getInitialOptions(), + GraalOptions.FullUnroll, true); + long start = System.nanoTime(); + getCode(method, null, true, false, options); + long end = System.nanoTime(); + return TimeUnit.NANOSECONDS.toMillis(end - start); + } + + @Test + public void test() throws IOException, InterruptedException { + launchSubprocess(this::loopTest); + } +} diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopFullUnrollPhase.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopFullUnrollPhase.java index 4746dfaeed3..d6ac31b0c9c 100644 --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopFullUnrollPhase.java +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopFullUnrollPhase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -24,6 +24,11 @@ package org.graalvm.compiler.loop.phases; +import java.util.Comparator; +import java.util.List; +import java.util.function.ToDoubleFunction; +import java.util.function.ToIntFunction; + import org.graalvm.compiler.core.common.GraalOptions; import org.graalvm.compiler.debug.CounterKey; import org.graalvm.compiler.debug.DebugContext; @@ -32,11 +37,24 @@ import org.graalvm.compiler.loop.LoopPolicies; import org.graalvm.compiler.loop.LoopsData; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.spi.CoreProviders; +import org.graalvm.compiler.options.Option; +import org.graalvm.compiler.options.OptionKey; +import org.graalvm.compiler.options.OptionType; import org.graalvm.compiler.phases.common.CanonicalizerPhase; public class LoopFullUnrollPhase extends LoopPhase { + public static class Options { + @Option(help = "", type = OptionType.Expert) public static final OptionKey FullUnrollMaxApplication = new OptionKey<>(60); + } private static final CounterKey FULLY_UNROLLED_LOOPS = DebugContext.counter("FullUnrolls"); + public static final Comparator LOOP_COMPARATOR; + static { + ToDoubleFunction loopFreq = e -> e.loop().getHeader().getFirstPredecessor().getRelativeFrequency(); + ToIntFunction loopDepth = e -> e.loop().getDepth(); + LOOP_COMPARATOR = Comparator.comparingDouble(loopFreq).thenComparingInt(loopDepth).reversed(); + } + private final CanonicalizerPhase canonicalizer; public LoopFullUnrollPhase(CanonicalizerPhase canonicalizer, LoopPolicies policies) { @@ -50,11 +68,14 @@ public class LoopFullUnrollPhase extends LoopPhase { DebugContext debug = graph.getDebug(); if (graph.hasLoops()) { boolean peeled; + int applications = 0; do { peeled = false; final LoopsData dataCounted = new LoopsData(graph); dataCounted.detectedCountedLoops(); - for (LoopEx loop : dataCounted.countedLoops()) { + List countedLoops = dataCounted.countedLoops(); + countedLoops.sort(LOOP_COMPARATOR); + for (LoopEx loop : countedLoops) { if (getPolicies().shouldFullUnroll(loop)) { debug.log("FullUnroll %s", loop); LoopTransformations.fullUnroll(loop, context, canonicalizer); @@ -65,7 +86,8 @@ public class LoopFullUnrollPhase extends LoopPhase { } } dataCounted.deleteUnusedNodes(); - } while (peeled); + applications++; + } while (peeled && applications < Options.FullUnrollMaxApplication.getValue(graph.getOptions())); } } } diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopsData.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopsData.java index ec5813f1bb4..3d53a703c28 100644 --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopsData.java +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopsData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,8 +25,6 @@ package org.graalvm.compiler.loop; import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; import java.util.List; import jdk.internal.vm.compiler.collections.EconomicMap; @@ -92,8 +90,8 @@ public class LoopsData { return loops; } - public Collection countedLoops() { - List counted = new LinkedList<>(); + public List countedLoops() { + List counted = new ArrayList<>(); for (LoopEx loop : loops()) { if (loop.isCounted()) { counted.add(loop); From cfab7f4c68dfdec6aa2ab59f822716b7eb525c01 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 18 Jun 2020 11:23:19 +0200 Subject: [PATCH 10/14] 8247778: ZGC: More parallel gc/z/TestUncommit.java test configuration Reviewed-by: iignatyev, stefank --- test/hotspot/jtreg/gc/z/TestUncommit.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/hotspot/jtreg/gc/z/TestUncommit.java b/test/hotspot/jtreg/gc/z/TestUncommit.java index 08fccb61ab8..993b46be879 100644 --- a/test/hotspot/jtreg/gc/z/TestUncommit.java +++ b/test/hotspot/jtreg/gc/z/TestUncommit.java @@ -28,7 +28,19 @@ package gc.z; * @requires vm.gc.Z & !vm.graal.enabled * @summary Test ZGC uncommit unused memory * @run main/othervm -XX:+UseZGC -Xlog:gc*,gc+heap=debug,gc+stats=off -Xms128M -Xmx512M -XX:ZUncommitDelay=10 gc.z.TestUncommit true 2 + */ + +/* + * @test TestUncommit + * @requires vm.gc.Z & !vm.graal.enabled + * @summary Test ZGC uncommit unused memory * @run main/othervm -XX:+UseZGC -Xlog:gc*,gc+heap=debug,gc+stats=off -Xms512M -Xmx512M -XX:ZUncommitDelay=10 gc.z.TestUncommit false 1 + */ + +/* + * @test TestUncommit + * @requires vm.gc.Z & !vm.graal.enabled + * @summary Test ZGC uncommit unused memory * @run main/othervm -XX:+UseZGC -Xlog:gc*,gc+heap=debug,gc+stats=off -Xms128M -Xmx512M -XX:ZUncommitDelay=10 -XX:-ZUncommit gc.z.TestUncommit false 1 */ From 11ac92c8fbf7a1e9ad1af3ba631df17c2284ca48 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Tue, 16 Jun 2020 16:23:32 -0400 Subject: [PATCH 11/14] 8246244: BasicShortcutHintTest shortcut can not be found Reviewed-by: herrick, almatvee --- .../jpackage/internal/DesktopIntegration.java | 12 +++- .../jdk/jpackage/test/LinuxHelper.java | 68 +++++++++++++++++++ .../jpackage/linux/ShortcutHintTest.java | 2 + 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/DesktopIntegration.java b/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/DesktopIntegration.java index 168b6df4ef4..ecb236467c8 100644 --- a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/DesktopIntegration.java +++ b/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/DesktopIntegration.java @@ -40,6 +40,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.imageio.ImageIO; @@ -250,9 +251,14 @@ final class DesktopIntegration { data.put("APPLICATION_ICON", iconFile != null ? iconFile.installPath().toString() : null); data.put("DEPLOY_BUNDLE_CATEGORY", MENU_GROUP.fetchFrom(params)); - data.put("APPLICATION_LAUNCHER", - thePackage.installedApplicationLayout().launchersDirectory().resolve( - LinuxAppImageBuilder.getLauncherName(params)).toString()); + + String appLauncher = thePackage.installedApplicationLayout().launchersDirectory().resolve( + LinuxAppImageBuilder.getLauncherName(params)).toString(); + if (Pattern.compile("\\s").matcher(appLauncher).find()) { + // Path contains whitespace(s). Enclose in double quotes. + appLauncher = "\"" + appLauncher + "\""; + } + data.put("APPLICATION_LAUNCHER", appLauncher); return data; } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java index d741c56356f..f7906406f2f 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java @@ -28,6 +28,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -332,6 +333,73 @@ public class LinuxHelper { } }); }); + + test.addInstallVerifier(cmd -> { + // Verify .desktop files. + try (var files = Files.walk(cmd.appLayout().destktopIntegrationDirectory(), 1)) { + List desktopFiles = files + .filter(path -> path.getFileName().toString().endsWith(".desktop")) + .collect(Collectors.toList()); + if (!integrated) { + TKit.assertStringListEquals(List.of(), + desktopFiles.stream().map(Path::toString).collect( + Collectors.toList()), + "Check there are no .desktop files in the package"); + } + for (var desktopFile : desktopFiles) { + verifyDesktopFile(cmd, desktopFile); + } + } + }); + } + + private static void verifyDesktopFile(JPackageCommand cmd, Path desktopFile) + throws IOException { + TKit.trace(String.format("Check [%s] file BEGIN", desktopFile)); + List lines = Files.readAllLines(desktopFile); + TKit.assertEquals("[Desktop Entry]", lines.get(0), "Check file header"); + + Map data = lines.stream() + .skip(1) + .peek(str -> TKit.assertTextStream("=").predicate(String::contains).apply(Stream.of(str))) + .map(str -> { + String components[] = str.split("=(?=.+)"); + if (components.length == 1) { + return Map.entry(str.substring(0, str.length() - 1), ""); + } + return Map.entry(components[0], components[1]); + }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> { + TKit.assertUnexpected("Multiple values of the same key"); + return null; + })); + + final Set mandatoryKeys = new HashSet(Set.of("Name", "Comment", + "Exec", "Icon", "Terminal", "Type", "Categories")); + mandatoryKeys.removeAll(data.keySet()); + TKit.assertTrue(mandatoryKeys.isEmpty(), String.format( + "Check for missing %s keys in the file", mandatoryKeys)); + + for (var e : Map.of("Type", "Application", "Terminal", "false").entrySet()) { + String key = e.getKey(); + TKit.assertEquals(e.getValue(), data.get(key), String.format( + "Check value of [%s] key", key)); + } + + // Verify value of `Exec` property in .desktop files are escaped if required + String launcherPath = data.get("Exec"); + if (Pattern.compile("\\s").matcher(launcherPath).find()) { + TKit.assertTrue(launcherPath.startsWith("\"") + && launcherPath.endsWith("\""), + "Check path to the launcher is enclosed in double quotes"); + launcherPath = launcherPath.substring(1, launcherPath.length() - 1); + } + + Stream.of(launcherPath, data.get("Icon")) + .map(Path::of) + .map(cmd::pathToUnpackedPackageFile) + .forEach(TKit::assertFileExists); + + TKit.trace(String.format("Check [%s] file END", desktopFile)); } static void initFileAssociationsTestFile(Path testFile) { diff --git a/test/jdk/tools/jpackage/linux/ShortcutHintTest.java b/test/jdk/tools/jpackage/linux/ShortcutHintTest.java index 75bf18c15df..b7b125262f8 100644 --- a/test/jdk/tools/jpackage/linux/ShortcutHintTest.java +++ b/test/jdk/tools/jpackage/linux/ShortcutHintTest.java @@ -166,6 +166,8 @@ public class ShortcutHintTest { "Exec=APPLICATION_LAUNCHER", "Terminal=false", "Type=Application", + "Comment=", + "Icon=APPLICATION_ICON", "Categories=DEPLOY_BUNDLE_CATEGORY", expectedVersionString )); From 56048d0480a8342eb0bfe0523749e2b8f764192b Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Thu, 18 Jun 2020 17:46:15 +0100 Subject: [PATCH 12/14] 8247789: Remove use of reflection from test/jdk/java/io/Serializable/records/StreamRefTest.java Reviewed-by: rriggs, mchung --- .../Serializable/records/StreamRefTest.java | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/test/jdk/java/io/Serializable/records/StreamRefTest.java b/test/jdk/java/io/Serializable/records/StreamRefTest.java index 86bea4008b8..cb5d5f31557 100644 --- a/test/jdk/java/io/Serializable/records/StreamRefTest.java +++ b/test/jdk/java/io/Serializable/records/StreamRefTest.java @@ -30,12 +30,12 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import java.lang.reflect.Field; import org.testng.annotations.Test; import static java.lang.System.out; import static org.testng.Assert.assertEquals; @@ -116,13 +116,12 @@ public class StreamRefTest { public void basicRefWithInvalidA() throws Exception { out.println("\n---"); var a = new A(3); - Field f = A.class.getDeclaredField("x"); - f.setAccessible(true); - f.set(a, -3); // a "bad" value var b = new B(a); - assert a.x() == -3; - var byteStream = serialize(a, b); + var bytes = serializeToBytes(a, b); + // injects a bad (negative) value for field x (of record A), in the stream + updateIntValue(3, -3, bytes, 40); + var byteStream = new ObjectInputStream(new ByteArrayInputStream(bytes)); InvalidObjectException ioe = expectThrows(IOE, () -> deserializeOne(byteStream)); out.println("caught expected IOE: " + ioe); @@ -138,13 +137,12 @@ public class StreamRefTest { public void reverseBasicRefWithInvalidA() throws Exception { out.println("\n---"); var a = new A(3); - Field f = A.class.getDeclaredField("x"); - f.setAccessible(true); - f.set(a, -3); // a "bad" value var b = new B(a); - assert a.x() == -3; - var byteStream = serialize(b, a); + var bytes = serializeToBytes(b, a); + // injects a bad (negative) value for field x (of record A), in the stream + updateIntValue(3, -3, bytes, 96); + var byteStream = new ObjectInputStream(new ByteArrayInputStream(bytes)); InvalidObjectException ioe = expectThrows(IOE, () -> deserializeOne(byteStream)); out.println("caught expected IOE: " + ioe); @@ -209,14 +207,35 @@ public class StreamRefTest { // --- + static void assertExpectedIntValue(int expectedValue, byte[] bytes, int offset) + throws IOException { + ByteArrayInputStream bais = new ByteArrayInputStream(bytes, offset, 4); + DataInputStream dis = new DataInputStream(bais); + assertEquals(dis.readInt(), expectedValue); + } + + static void updateIntValue(int expectedValue, int newValue, byte[] bytes, int offset) + throws IOException + { + assertExpectedIntValue(expectedValue, bytes, offset); + bytes[offset + 0] = (byte)((newValue >>> 24) & 0xFF); + bytes[offset + 1] = (byte)((newValue >>> 16) & 0xFF); + bytes[offset + 2] = (byte)((newValue >>> 8) & 0xFF); + bytes[offset + 3] = (byte)((newValue >>> 0) & 0xFF); + assertExpectedIntValue(newValue, bytes, offset); + } + static ObjectInputStream serialize(Object... objs) throws IOException { + return new ObjectInputStream(new ByteArrayInputStream(serializeToBytes(objs))); + } + + static byte[] serializeToBytes(Object... objs) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); for (Object obj : objs) oos.writeObject(obj); oos.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - return new ObjectInputStream(bais); + return baos.toByteArray(); } @SuppressWarnings("unchecked") From a750ac5feb26ff000a933f2ae99454c7b109846c Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 11 Jun 2020 18:16:26 +0200 Subject: [PATCH 13/14] 8247358: Shenandoah: reconsider free budget slice for marking Reviewed-by: zgu --- src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp index b94b8fb687d..9315ce61609 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp @@ -50,12 +50,8 @@ * notion of progress is clear: we get reported the "used" size from the processed regions * and use the global heap-used as the baseline. * - * The allocatable space when GC is running is "free" at the start of cycle, but the + * The allocatable space when GC is running is "free" at the start of phase, but the * accounted budget is based on "used". So, we need to adjust the tax knowing that. - * Also, since we effectively count the used space three times (mark, evac, update-refs), - * we need to multiply the tax by 3. Example: for 10 MB free and 90 MB used, GC would - * come back with 3*90 MB budget, and thus for each 1 MB of allocation, we have to pay - * 3*90 / 10 MBs. In the end, we would pay back the entire budget. */ void ShenandoahPacer::setup_for_mark() { @@ -68,7 +64,7 @@ void ShenandoahPacer::setup_for_mark() { size_t taxable = free - non_taxable; double tax = 1.0 * live / taxable; // base tax for available free space - tax *= 3; // mark is phase 1 of 3, claim 1/3 of free for it + tax *= 1; // mark can succeed with immediate garbage, claim all available space tax *= ShenandoahPacingSurcharge; // additional surcharge to help unclutter heap restart_with(non_taxable, tax); @@ -91,7 +87,7 @@ void ShenandoahPacer::setup_for_evac() { size_t taxable = free - non_taxable; double tax = 1.0 * used / taxable; // base tax for available free space - tax *= 2; // evac is phase 2 of 3, claim 1/2 of remaining free + tax *= 2; // evac is followed by update-refs, claim 1/2 of remaining free tax = MAX2(1, tax); // never allocate more than GC processes during the phase tax *= ShenandoahPacingSurcharge; // additional surcharge to help unclutter heap @@ -115,7 +111,7 @@ void ShenandoahPacer::setup_for_updaterefs() { size_t taxable = free - non_taxable; double tax = 1.0 * used / taxable; // base tax for available free space - tax *= 1; // update-refs is phase 3 of 3, claim the remaining free + tax *= 1; // update-refs is the last phase, claim the remaining free tax = MAX2(1, tax); // never allocate more than GC processes during the phase tax *= ShenandoahPacingSurcharge; // additional surcharge to help unclutter heap From de3923edf93dda35ee9b9c94edce3920f3cd056b Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 18 Jun 2020 14:07:49 -0700 Subject: [PATCH 14/14] 8247788: DocCommentParser should not reject standalone '>' Reviewed-by: prappo --- .../tools/javac/parser/DocCommentParser.java | 11 ------- .../tools/javac/resources/compiler.properties | 3 -- .../javadoc/doclet/testJavaFX/TestJavaFX.java | 4 ++- .../jdk/javadoc/doclet/testJavaFX/pkg4/C.java | 2 +- .../testPackageHtml/TestPackageHtml.java | 2 +- .../doclet/testPackageHtml/pkg1/package.html | 3 +- .../tools/doclint/tidy/InvalidTag.out | 6 ++-- .../javac/diags/examples/BadGreaterThan.java | 32 ------------------- .../tools/javac/doctree/ElementTest.java | 29 ++++------------- 9 files changed, 15 insertions(+), 77 deletions(-) delete mode 100644 test/langtools/tools/javac/diags/examples/BadGreaterThan.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java index e7adca2e21e..23aa5204871 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java @@ -221,17 +221,6 @@ public class DocCommentParser { } break; - case '>': - newline = false; - addPendingText(trees, bp - 1); - trees.add(m.at(bp).newErroneousTree(newString(bp, bp + 1), diagSource, "dc.bad.gt")); - nextChar(); - if (textStart == -1) { - textStart = bp; - lastNonWhite = -1; - } - break; - case '{': inlineTag(trees); break; 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 d31b2a33b65..5268627b16f 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 @@ -3140,9 +3140,6 @@ compiler.misc.where.description.intersection.1=\ compiler.err.dc.bad.entity=\ bad HTML entity -compiler.err.dc.bad.gt=\ - bad use of ''>'' - compiler.err.dc.bad.inline.tag=\ incorrect use of inline tag diff --git a/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java b/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java index 971b31ca6c9..8f441f15ff8 100644 --- a/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java +++ b/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java @@ -39,6 +39,8 @@ public class TestJavaFX extends JavadocTester { public static void main(String... args) throws Exception { TestJavaFX tester = new TestJavaFX(); + tester.setAutomaticCheckAccessibility(false); + tester.setAutomaticCheckLinks(false); tester.runTests(); } @@ -353,6 +355,6 @@ public class TestJavaFX extends JavadocTester { checkExit(Exit.OK); // make sure the doclet indeed emits the warning - checkOutput(Output.OUT, true, "C.java:0: warning - invalid usage of tag >"); + checkOutput(Output.OUT, true, "C.java:0: warning - invalid usage of tag <"); } } diff --git a/test/langtools/jdk/javadoc/doclet/testJavaFX/pkg4/C.java b/test/langtools/jdk/javadoc/doclet/testJavaFX/pkg4/C.java index 43f4a961876..fffdc83a23b 100644 --- a/test/langtools/jdk/javadoc/doclet/testJavaFX/pkg4/C.java +++ b/test/langtools/jdk/javadoc/doclet/testJavaFX/pkg4/C.java @@ -28,7 +28,7 @@ public class C { /** * Defines the number of cycles in this animation. The {@code cycleCount} * may be {@code INDEFINITE} for animations that repeat indefinitely. - * Now we add a > to deliberately cause an Html error. + * Now we add <> to deliberately cause an Html error. * @defaultValue 11 * @since JavaFX 8.0 */ diff --git a/test/langtools/jdk/javadoc/doclet/testPackageHtml/TestPackageHtml.java b/test/langtools/jdk/javadoc/doclet/testPackageHtml/TestPackageHtml.java index 59232809554..15e72c4c664 100644 --- a/test/langtools/jdk/javadoc/doclet/testPackageHtml/TestPackageHtml.java +++ b/test/langtools/jdk/javadoc/doclet/testPackageHtml/TestPackageHtml.java @@ -46,7 +46,7 @@ public class TestPackageHtml extends JavadocTester { "-sourcepath", testSrc, "pkg1"); checkExit(Exit.ERROR); - checkOutput(Output.OUT, true, "package.html:5: error: bad use of '>'"); + checkOutput(Output.OUT, true, "package.html:4: error: malformed HTML"); } // Doclet must handle empty body in package.html, must diff --git a/test/langtools/jdk/javadoc/doclet/testPackageHtml/pkg1/package.html b/test/langtools/jdk/javadoc/doclet/testPackageHtml/pkg1/package.html index a05dc5ea338..e20b2358c14 100644 --- a/test/langtools/jdk/javadoc/doclet/testPackageHtml/pkg1/package.html +++ b/test/langtools/jdk/javadoc/doclet/testPackageHtml/pkg1/package.html @@ -1,8 +1,7 @@ -
-            <opaque value="TRUE"/>
+            <123 value="TRUE"/>
         
diff --git a/test/langtools/tools/doclint/tidy/InvalidTag.out b/test/langtools/tools/doclint/tidy/InvalidTag.out index fb67dc90618..392ae865f63 100644 --- a/test/langtools/tools/doclint/tidy/InvalidTag.out +++ b/test/langtools/tools/doclint/tidy/InvalidTag.out @@ -1,10 +1,8 @@ + InvalidTag.java:14: error: unknown tag: String * List list = new ArrayList<>(); ^ InvalidTag.java:14: error: malformed HTML * List list = new ArrayList<>(); ^ -InvalidTag.java:14: error: bad use of '>' - * List list = new ArrayList<>(); - ^ -3 errors +2 errors diff --git a/test/langtools/tools/javac/diags/examples/BadGreaterThan.java b/test/langtools/tools/javac/diags/examples/BadGreaterThan.java deleted file mode 100644 index f9be624369c..00000000000 --- a/test/langtools/tools/javac/diags/examples/BadGreaterThan.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2012, 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.err.dc.bad.gt -// key: compiler.note.note -// key: compiler.note.proc.messager -// run: backdoor -// options: -processor DocCommentProcessor -proc:only - -/** > */ -class BadGreaterThan { } - diff --git a/test/langtools/tools/javac/doctree/ElementTest.java b/test/langtools/tools/javac/doctree/ElementTest.java index 7951b2b3245..c2346b20a7d 100644 --- a/test/langtools/tools/javac/doctree/ElementTest.java +++ b/test/langtools/tools/javac/doctree/ElementTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 7021614 8078320 + * @bug 7021614 8078320 8247788 * @summary extend com.sun.source API to support parsing javadoc comments * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.file @@ -93,13 +93,8 @@ DocComment[DOC_COMMENT, pos:1 void bad_gt() { } /* DocComment[DOC_COMMENT, pos:1 - firstSentence: 3 - Text[TEXT, pos:1, abc_] - Erroneous[ERRONEOUS, pos:5 - code: compiler.err.dc.bad.gt - body: > - ] - Text[TEXT, pos:6, _def] + firstSentence: 1 + Text[TEXT, pos:1, abc_>_def] body: empty block tags: empty ] @@ -111,18 +106,13 @@ DocComment[DOC_COMMENT, pos:1 void bad_chars_start(); /* DocComment[DOC_COMMENT, pos:1 - firstSentence: 5 + firstSentence: 3 Text[TEXT, pos:1, abc_] Erroneous[ERRONEOUS, pos:5 code: compiler.err.dc.malformed.html body: < ] - Text[TEXT, pos:6, p_123] - Erroneous[ERRONEOUS, pos:11 - code: compiler.err.dc.bad.gt - body: > - ] - Text[TEXT, pos:12, _def] + Text[TEXT, pos:6, p_123>_def] body: empty block tags: empty ] @@ -134,18 +124,13 @@ DocComment[DOC_COMMENT, pos:1 void bad_chars_end(); /* DocComment[DOC_COMMENT, pos:1 - firstSentence: 5 + firstSentence: 3 Text[TEXT, pos:1, abc_] Erroneous[ERRONEOUS, pos:5 code: compiler.err.dc.malformed.html body: < ] - Text[TEXT, pos:6, /p_123] - Erroneous[ERRONEOUS, pos:12 - code: compiler.err.dc.bad.gt - body: > - ] - Text[TEXT, pos:13, _def] + Text[TEXT, pos:6, /p_123>_def] body: empty block tags: empty ]