diff --git a/src/hotspot/share/gc/z/zDirector.cpp b/src/hotspot/share/gc/z/zDirector.cpp index 47e24063ead..162e05f2c07 100644 --- a/src/hotspot/share/gc/z/zDirector.cpp +++ b/src/hotspot/share/gc/z/zDirector.cpp @@ -524,6 +524,10 @@ static bool rule_major_allocation_rate(const ZDirectorStats& stats) { } static double calculate_young_to_old_worker_ratio(const ZDirectorStats& stats) { + if (!stats._old_stats._cycle._is_time_trustable) { + return 1.0; + } + const double young_gc_time = gc_time(stats._young_stats); const double old_gc_time = gc_time(stats._old_stats); const size_t reclaimed_per_young_gc = stats._young_stats._stat_heap._reclaimed_avg; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp index c7615336218..9f126bded94 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp @@ -522,6 +522,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) AwtComponent *awtParent = (parent != NULL) ? (AwtComponent *)JNI_GET_PDATA(parent) : NULL; HWND hwndOwner = awtParent ? awtParent->GetHWnd() : NULL; + jboolean doIt = JNI_FALSE; PAGESETUPDLG setup; memset(&setup, 0, sizeof(setup)); @@ -577,7 +578,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) */ if ((setup.hDevMode == NULL) && (setup.hDevNames == NULL)) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } } else { int measure = PSD_INTHOUSANDTHSOFINCHES; @@ -605,7 +606,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) pageFormatToSetup(env, self, page, &setup, AwtPrintControl::getPrintDC(env, self)); if (env->ExceptionCheck()) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } setup.lpfnPageSetupHook = reinterpret_cast(pageDlgHook); @@ -619,7 +620,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) jobject paper = getPaper(env, page); if (paper == NULL) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } int units = setup.Flags & PSD_INTHOUSANDTHSOFINCHES ? MM_HIENGLISH : @@ -661,7 +662,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) setPaperValues(env, paper, &paperSize, &margins, units); if (env->ExceptionCheck()) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } /* * Put the updated Paper instance and the orientation into @@ -670,7 +671,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) setPaper(env, page, paper); if (env->ExceptionCheck()) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } setPageFormatOrientation(env, page, orientation); if (env->ExceptionCheck()) { @@ -684,12 +685,13 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) jboolean err = setPrintPaperSize(env, self, devmode->dmPaperSize); if (err) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } } } ::GlobalUnlock(setup.hDevMode); } + doIt = JNI_TRUE; } AwtDialog::CheckUninstallModalHook(); @@ -708,7 +710,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) CLEANUP_SHOW; - return JNI_TRUE; + return doIt; CATCH_BAD_ALLOC_RET(0); } 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 08c37fc5aa4..533541bd108 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 @@ -950,6 +950,7 @@ public void visitClassDef(JCClassDecl tree) { Optional.ofNullable(env.info.attributionMode.isSpeculative ? argumentAttr.withLocalCacheContext() : null); boolean ctorProloguePrev = env.info.ctorPrologue; + env.info.ctorPrologue = false; try { // Local and anonymous classes have not been entered yet, so we need to // do it now. @@ -994,7 +995,7 @@ public void visitMethodDef(JCMethodDecl tree) { Lint lint = env.info.lint.augment(m); Lint prevLint = chk.setLint(lint); boolean ctorProloguePrev = env.info.ctorPrologue; - Assert.check(!env.info.ctorPrologue); + env.info.ctorPrologue = false; MethodSymbol prevMethod = chk.setMethod(m); try { deferredLintHandler.flush(tree.pos(), lint); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java index 926be3b6e26..7478ef1c907 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java @@ -209,7 +209,6 @@ public Env classEnv(JCClassDecl tree, Env env) { localEnv.info.lint = null; // leave this to be filled in by Attr, // when annotations have been processed localEnv.info.isAnonymousDiamond = TreeInfo.isDiamond(env.tree); - localEnv.info.ctorPrologue = false; return localEnv; } diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java index 839ac2fd041..3b9336c499d 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, 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 @@ -208,7 +208,7 @@ public void write(Attribute a, CodeAttribute lr) { indent(+1); first = false; } - for (var flag : info.flags()) { + for (var flag : maskToAccessFlagsReportUnknown(access_flags, AccessFlag.Location.INNER_CLASS)) { if (flag.sourceModifier() && (flag != AccessFlag.ABSTRACT || !info.has(AccessFlag.INTERFACE))) { print(Modifier.toString(flag.mask()) + " "); diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/BasicWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/BasicWriter.java index 8629957f907..64eecf92082 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/BasicWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/BasicWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, 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 @@ -26,6 +26,12 @@ package com.sun.tools.javap; import java.io.PrintWriter; +import java.lang.classfile.AccessFlags; +import java.lang.reflect.AccessFlag; +import java.lang.reflect.Modifier; +import java.util.EnumMap; +import java.util.Map; +import java.util.Set; import java.util.function.Supplier; /* @@ -38,6 +44,26 @@ * deletion without notice. */ public class BasicWriter { + private static final Map LOCATION_MASKS; + + static { + var map = new EnumMap(AccessFlag.Location.class); + for (var loc : AccessFlag.Location.values()) { + map.put(loc, 0); + } + + for (var flag : AccessFlag.values()) { + for (var loc : flag.locations()) { + map.compute(loc, (_, v) -> v | flag.mask()); + } + } + + // Peculiarities from AccessFlag.maskToAccessFlag + map.compute(AccessFlag.Location.METHOD, (_, v) -> v | Modifier.STRICT); + + LOCATION_MASKS = map; + } + protected BasicWriter(Context context) { lineWriter = LineWriter.instance(context); out = context.get(PrintWriter.class); @@ -46,6 +72,20 @@ protected BasicWriter(Context context) { throw new AssertionError(); } + protected Set flagsReportUnknown(AccessFlags flags) { + return maskToAccessFlagsReportUnknown(flags.flagsMask(), flags.location()); + } + + protected Set maskToAccessFlagsReportUnknown(int mask, AccessFlag.Location location) { + try { + return AccessFlag.maskToAccessFlags(mask, location); + } catch (IllegalArgumentException ex) { + mask &= LOCATION_MASKS.get(location); + report("Access Flags: " + ex.getMessage()); + return AccessFlag.maskToAccessFlags(mask, location); + } + } + protected void print(String s) { lineWriter.print(s); } diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java index edf3d803af3..2483e99e49a 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java @@ -417,7 +417,7 @@ protected void writeField(FieldModel f) { return; var flags = AccessFlags.ofField(f.flags().flagsMask()); - writeModifiers(flags.flags().stream().filter(fl -> fl.sourceModifier()) + writeModifiers(flagsReportUnknown(flags).stream().filter(fl -> fl.sourceModifier()) .map(fl -> Modifier.toString(fl.mask())).toList()); print(() -> sigPrinter.print( f.findAttribute(Attributes.signature()) @@ -446,7 +446,7 @@ protected void writeField(FieldModel f) { if (options.verbose) writeList(String.format("flags: (0x%04x) ", flags.flagsMask()), - flags.flags().stream().map(fl -> "ACC_" + fl.name()).toList(), + flagsReportUnknown(flags).stream().map(fl -> "ACC_" + fl.name()).toList(), "\n"); if (options.showAllAttrs) { @@ -478,7 +478,7 @@ protected void writeMethod(MethodModel m) { int flags = m.flags().flagsMask(); var modifiers = new ArrayList(); - for (var f : AccessFlags.ofMethod(flags).flags()) + for (var f : flagsReportUnknown(m.flags())) if (f.sourceModifier()) modifiers.add(Modifier.toString(f.mask())); String name = "???"; @@ -561,7 +561,7 @@ protected void writeMethod(MethodModel m) { StringBuilder sb = new StringBuilder(); String sep = ""; sb.append(String.format("flags: (0x%04x) ", flags)); - for (var f : AccessFlags.ofMethod(flags).flags()) { + for (var f : flagsReportUnknown(m.flags())) { sb.append(sep).append("ACC_").append(f.name()); sep = ", "; } @@ -794,17 +794,9 @@ else switch (c) { } } - private static Set getClassModifiers(int mask) { - return getModifiers(AccessFlags.ofClass((mask & ACC_INTERFACE) != 0 - ? mask & ~ACC_ABSTRACT : mask).flags()); - } - - private static Set getMethodModifiers(int mask) { - return getModifiers(AccessFlags.ofMethod(mask).flags()); - } - - private static Set getFieldModifiers(int mask) { - return getModifiers(AccessFlags.ofField(mask).flags()); + private Set getClassModifiers(int mask) { + return getModifiers(flagsReportUnknown(AccessFlags.ofClass((mask & ACC_INTERFACE) != 0 + ? mask & ~ACC_ABSTRACT : mask))); } private static Set getModifiers(Set flags) { @@ -814,16 +806,16 @@ private static Set getModifiers(Set flags) return s; } - private static Set getClassFlags(int mask) { - return getFlags(mask, AccessFlags.ofClass(mask).flags()); + private Set getClassFlags(int mask) { + return getFlags(mask, flagsReportUnknown(AccessFlags.ofClass(mask))); } - private static Set getMethodFlags(int mask) { - return getFlags(mask, AccessFlags.ofMethod(mask).flags()); + private Set getMethodFlags(int mask) { + return getFlags(mask, flagsReportUnknown(AccessFlags.ofMethod(mask))); } - private static Set getFieldFlags(int mask) { - return getFlags(mask, AccessFlags.ofField(mask).flags()); + private Set getFieldFlags(int mask) { + return getFlags(mask, flagsReportUnknown(AccessFlags.ofField(mask))); } private static Set getFlags(int mask, Set flags) { @@ -840,42 +832,6 @@ private static Set getFlags(int mask, Set return s; } - public static enum AccessFlag { - ACC_PUBLIC (ClassFile.ACC_PUBLIC, "public", true, true, true, true ), - ACC_PRIVATE (ClassFile.ACC_PRIVATE, "private", false, true, true, true ), - ACC_PROTECTED (ClassFile.ACC_PROTECTED, "protected", false, true, true, true ), - ACC_STATIC (ClassFile.ACC_STATIC, "static", false, true, true, true ), - ACC_FINAL (ClassFile.ACC_FINAL, "final", true, true, true, true ), - ACC_SUPER (ClassFile.ACC_SUPER, null, true, false, false, false), - ACC_SYNCHRONIZED(ClassFile.ACC_SYNCHRONIZED, "synchronized", false, false, false, true ), - ACC_VOLATILE (ClassFile.ACC_VOLATILE, "volatile", false, false, true, false), - ACC_BRIDGE (ClassFile.ACC_BRIDGE, null, false, false, false, true ), - ACC_TRANSIENT (ClassFile.ACC_TRANSIENT, "transient", false, false, true, false), - ACC_VARARGS (ClassFile.ACC_VARARGS, null, false, false, false, true ), - ACC_NATIVE (ClassFile.ACC_NATIVE, "native", false, false, false, true ), - ACC_INTERFACE (ClassFile.ACC_INTERFACE, null, true, true, false, false), - ACC_ABSTRACT (ClassFile.ACC_ABSTRACT, "abstract", true, true, false, true ), - ACC_STRICT (ClassFile.ACC_STRICT, "strictfp", false, false, false, true ), - ACC_SYNTHETIC (ClassFile.ACC_SYNTHETIC, null, true, true, true, true ), - ACC_ANNOTATION (ClassFile.ACC_ANNOTATION, null, true, true, false, false), - ACC_ENUM (ClassFile.ACC_ENUM, null, true, true, true, false), - ACC_MODULE (ClassFile.ACC_MODULE, null, true, false, false, false); - - public final int flag; - public final String modifier; - public final boolean isClass, isInnerClass, isField, isMethod; - - AccessFlag(int flag, String modifier, boolean isClass, - boolean isInnerClass, boolean isField, boolean isMethod) { - this.flag = flag; - this.modifier = modifier; - this.isClass = isClass; - this.isInnerClass = isInnerClass; - this.isField = isField; - this.isMethod = isMethod; - } - } - private final Options options; private final AttributeWriter attrWriter; private final CodeWriter codeWriter; diff --git a/test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java b/test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java new file mode 100644 index 00000000000..f9ce1b7c196 --- /dev/null +++ b/test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024, 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 8334366 + * @key headful printer + * @summary Verifies original pageobject is returned unmodified + * on cancelling pagedialog + * @requires (os.family == "windows") + * @run main PageDialogCancelTest + */ + +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.print.PageFormat; +import java.awt.print.PrinterJob; + +public class PageDialogCancelTest { + + public static void main(String[] args) throws Exception { + PrinterJob pj = PrinterJob.getPrinterJob(); + PageFormat oldFormat = new PageFormat(); + Robot robot = new Robot(); + Thread t1 = new Thread(() -> { + robot.delay(2000); + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.waitForIdle(); + }); + t1.start(); + PageFormat newFormat = pj.pageDialog(oldFormat); + if (!newFormat.equals(oldFormat)) { + throw new RuntimeException("Original PageFormat not returned on cancelling PageDialog"); + } + } +} + diff --git a/test/jdk/java/io/IO/IO.java b/test/jdk/java/io/IO/IO.java index 1a9a25c90c7..328c189fb2f 100644 --- a/test/jdk/java/io/IO/IO.java +++ b/test/jdk/java/io/IO/IO.java @@ -21,6 +21,7 @@ * questions. */ +import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -34,6 +35,10 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.condition.EnabledOnOs; import org.junit.jupiter.api.condition.OS; +import org.junit.jupiter.api.extension.AfterTestExecutionCallback; +import org.junit.jupiter.api.extension.BeforeTestExecutionCallback; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -48,6 +53,7 @@ * @library /test/lib * @run junit IO */ +@ExtendWith(IO.TimingExtension.class) public class IO { @Nested @@ -62,6 +68,11 @@ public static void prepareTTY() { if (!Files.exists(expect) || !Files.isExecutable(expect)) { Assumptions.abort("'" + expect + "' not found"); } + try { + var outputAnalyzer = ProcessTools.executeProcess( + expect.toAbsolutePath().toString(), "-version"); + outputAnalyzer.reportDiagnosticSummary(); + } catch (Exception _) { } } /* @@ -174,4 +185,41 @@ public void nullConsole(String method) throws Exception { assertEquals(1, output.getExitValue()); output.shouldContain("Exception in thread \"main\" java.io.IOError"); } + + + // adapted from https://junit.org/junit5/docs/current/user-guide/#extensions-lifecycle-callbacks-timing-extension + // remove after CODETOOLS-7903752 propagates to jtreg that this test is routinely run by + + public static class TimingExtension implements BeforeTestExecutionCallback, + AfterTestExecutionCallback { + + private static final System.Logger logger = System.getLogger( + TimingExtension.class.getName()); + + private static final String START_TIME = "start time"; + + @Override + public void beforeTestExecution(ExtensionContext context) { + getStore(context).put(START_TIME, time()); + } + + @Override + public void afterTestExecution(ExtensionContext context) { + Method testMethod = context.getRequiredTestMethod(); + long startTime = getStore(context).remove(START_TIME, long.class); + long duration = time() - startTime; + + logger.log(System.Logger.Level.INFO, () -> + String.format("Method [%s] took %s ms.", testMethod.getName(), duration)); + } + + private ExtensionContext.Store getStore(ExtensionContext context) { + return context.getStore(ExtensionContext.Namespace.create(getClass(), + context.getRequiredTestMethod())); + } + + private long time() { + return System.nanoTime() / 1_000_000; + } + } } diff --git a/test/jdk/java/io/IO/input.exp b/test/jdk/java/io/IO/input.exp index ba86b57b131..6f17a1379ec 100644 --- a/test/jdk/java/io/IO/input.exp +++ b/test/jdk/java/io/IO/input.exp @@ -23,6 +23,7 @@ set prompt [lindex $argv $argc-1] set stty_init "rows 24 cols 80" +set timeout -1 spawn {*}$argv expect { @@ -30,7 +31,8 @@ expect { send "hello\r" } timeout { - puts "timeout"; exit 1 + puts "timeout" + exit 1 } } expect eof diff --git a/test/jdk/java/io/IO/output.exp b/test/jdk/java/io/IO/output.exp index 9044912cfaf..a792b8791a4 100644 --- a/test/jdk/java/io/IO/output.exp +++ b/test/jdk/java/io/IO/output.exp @@ -21,12 +21,23 @@ # questions. # -################################################################################ -# This script does not expect/verify anything and is only used to simulate tty # -################################################################################ +# This script doesn't verify any output strings, it's only used to simulate tty -# Use `noecho` below, otherwise, expect will output the expanded "spawn ..." +set stty_init "rows 24 cols 80" +set timeout -1 + +# Use `-noecho` below, otherwise, expect will output the expanded "spawn ..." # command, which will interfere with asserting output from the java test +# counterpart spawn -noecho {*}$argv -expect eof + +expect { + eof { + exit 0 + } + timeout { + puts "timeout" + exit 1 + } +} diff --git a/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java b/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java index 48cbd1b0ffe..196a27b52ba 100644 --- a/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java +++ b/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, 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 @@ -28,6 +28,7 @@ */ import java.io.*; +import java.util.concurrent.CountDownLatch; class Good implements Serializable { private static final long serialVersionUID = 6319710844400051132L; @@ -51,19 +52,20 @@ class Bad implements Serializable { class SuccessfulLookup extends Thread { Class cl; long suid; - Object barrier; + final CountDownLatch lookupLatch; boolean ok; - SuccessfulLookup(Class cl, long suid, Object barrier) { + SuccessfulLookup(Class cl, long suid, CountDownLatch lookupLatch) { this.cl = cl; this.suid = suid; - this.barrier = barrier; + this.lookupLatch = lookupLatch; } public void run() { - synchronized (barrier) { - try { barrier.wait(); } catch (InterruptedException ex) {} - } + lookupLatch.countDown(); // let others know we are ready + try { + lookupLatch.await(); // await for others + } catch (InterruptedException ex) {} for (int i = 0; i < 100; i++) { if (ObjectStreamClass.lookup(cl).getSerialVersionUID() != suid) { return; @@ -75,18 +77,19 @@ public void run() { class FailingLookup extends Thread { Class cl; - final Object barrier; + final CountDownLatch lookupLatch; boolean ok; - FailingLookup(Class cl, Object barrier) { + FailingLookup(Class cl, CountDownLatch lookupLatch) { this.cl = cl; - this.barrier = barrier; + this.lookupLatch = lookupLatch; } public void run() { - synchronized (barrier) { - try { barrier.wait(); } catch (InterruptedException ex) {} - } + lookupLatch.countDown(); // let others know we are ready + try { + lookupLatch.await(); // await for others + } catch (InterruptedException ex) {} for (int i = 0; i < 100; i++) { try { ObjectStreamClass.lookup(cl); @@ -102,39 +105,36 @@ public class ConcurrentClassDescLookup { public static void main(String[] args) throws Exception { ClassLoader loader = ConcurrentClassDescLookup.class.getClassLoader(); Class cl = Class.forName("Good", false, loader); - Object barrier = new Object(); - SuccessfulLookup[] slookups = new SuccessfulLookup[50]; + int numSuccessfulLookups = 50; + CountDownLatch sLookupLatch = new CountDownLatch(numSuccessfulLookups); + SuccessfulLookup[] slookups = new SuccessfulLookup[numSuccessfulLookups]; for (int i = 0; i < slookups.length; i++) { - slookups[i] = - new SuccessfulLookup(cl, 6319710844400051132L, barrier); + slookups[i] = new SuccessfulLookup(cl, 6319710844400051132L, sLookupLatch); slookups[i].start(); } - Thread.sleep(1000); - synchronized (barrier) { - barrier.notifyAll(); - } + System.out.println("awaiting completion of " + slookups.length + " SuccessfulLookup"); for (int i = 0; i < slookups.length; i++) { slookups[i].join(); if (!slookups[i].ok) { throw new Error(); } } - + System.out.println("all " + slookups.length + " SuccessfulLookup completed"); cl = Class.forName("Bad", false, loader); - FailingLookup[] flookups = new FailingLookup[50]; + int numFailingLookups = 50; + CountDownLatch fLookupLatch = new CountDownLatch(numFailingLookups); + FailingLookup[] flookups = new FailingLookup[numFailingLookups]; for (int i = 0; i < flookups.length; i++) { - flookups[i] = new FailingLookup(cl, barrier); + flookups[i] = new FailingLookup(cl, fLookupLatch); flookups[i].start(); } - Thread.sleep(1000); - synchronized (barrier) { - barrier.notifyAll(); - } - for (int i = 0; i < slookups.length; i++) { + System.out.println("awaiting completion of " + flookups.length + " FailingLookup"); + for (int i = 0; i < flookups.length; i++) { flookups[i].join(); if (!flookups[i].ok) { throw new Error(); } } + System.out.println("all " + flookups.length + " FailingLookup completed"); } } diff --git a/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java b/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java index 8edb74b847a..58f23350dd0 100644 --- a/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java +++ b/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java @@ -29,6 +29,7 @@ import java.util.List; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import jdk.jfr.Event; @@ -143,28 +144,43 @@ private static void printTimestamp(Instant timestamp) { } private static Path makeUnorderedRecording() throws Exception { - CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); - - try (Recording r = new Recording()) { - r.start(); - List emitters = new ArrayList<>(); - for (int i = 0; i < THREAD_COUNT; i++) { - Emitter e = new Emitter(barrier); - e.start(); - emitters.add(e); - } - // Thread buffers should now have one event each - barrier.await(); - // Add another event to each thread buffer, so - // events are bound to come out of order when they - // are flushed - for (Emitter e : emitters) { - e.join(); + while (true) { + CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); + try (Recording r = new Recording()) { + r.start(); + List emitters = new ArrayList<>(); + for (int i = 0; i < THREAD_COUNT; i++) { + Emitter e = new Emitter(barrier); + e.start(); + emitters.add(e); + } + // Thread buffers should now have one event each + barrier.await(); + // Add another event to each thread buffer, so + // events are bound to come out of order when they + // are flushed + for (Emitter e : emitters) { + e.join(); + } + r.stop(); + Path p = Utils.createTempFile("recording", ".jfr"); + r.dump(p); + // Order is only guaranteed within a segment. + int segments = countSegments(p); + if (segments < 2) { + return p; + } + System.out.println("File contains more than one segment (" + segments + "). Retrying."); } - r.stop(); - Path p = Utils.createTempFile("recording", ".jfr"); - r.dump(p); - return p; + } + } + + private static int countSegments(Path file) throws Exception { + AtomicInteger segments = new AtomicInteger(); + try (EventStream es = EventStream.openFile(file)) { + es.onFlush(segments::incrementAndGet); + es.start(); + return segments.get(); } } } diff --git a/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out b/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out index c04b45bce1e..140521689a0 100644 --- a/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out +++ b/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out @@ -1,2 +1,2 @@ -AnonymousInSuperCallNegTest.java:23:49: compiler.err.cant.ref.before.ctor.called: x +AnonymousInSuperCallNegTest.java:23:49: compiler.err.no.encl.instance.of.type.in.scope: AnonymousInSuperCallNegTest.JavacBug 1 error diff --git a/test/langtools/tools/javac/LocalClassCtorPrologue.out b/test/langtools/tools/javac/LocalClassCtorPrologue.out index 65f3418825d..f1a999af491 100644 --- a/test/langtools/tools/javac/LocalClassCtorPrologue.out +++ b/test/langtools/tools/javac/LocalClassCtorPrologue.out @@ -1,4 +1,4 @@ -LocalClassCtorPrologue.java:16:17: compiler.err.cant.ref.before.ctor.called: x +LocalClassCtorPrologue.java:16:17: compiler.err.no.encl.instance.of.type.in.scope: LocalClassCtorPrologue - compiler.note.preview.filename: LocalClassCtorPrologue.java, DEFAULT - compiler.note.preview.recompile 1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java b/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java deleted file mode 100644 index a8ee3a2aea5..00000000000 --- a/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * @test /nodynamiccopyright/ - * @bug 8334488 - * @summary Verify the error message generated for early access from inner class - * @compile/fail/ref=EarlyInnerAccessErrorMessageTest.out -XDrawDiagnostics EarlyInnerAccessErrorMessageTest.java - * @enablePreview - */ -public class EarlyInnerAccessErrorMessageTest { - int x; - EarlyInnerAccessErrorMessageTest() { - class Inner { - { System.out.println(x); } - } - super(); - } -} diff --git a/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out b/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out deleted file mode 100644 index a8d690a4c23..00000000000 --- a/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out +++ /dev/null @@ -1,4 +0,0 @@ -EarlyInnerAccessErrorMessageTest.java:12:34: compiler.err.cant.ref.before.ctor.called: x -- compiler.note.preview.filename: EarlyInnerAccessErrorMessageTest.java, DEFAULT -- compiler.note.preview.recompile -1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out b/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out index ee01f9c403d..390b68ea2c9 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out @@ -1,4 +1,4 @@ -EarlyLocalClass.java:12:32: compiler.err.cant.ref.before.ctor.called: this +EarlyLocalClass.java:12:32: compiler.err.no.encl.instance.of.type.in.scope: EarlyLocalClass - compiler.note.preview.filename: EarlyLocalClass.java, DEFAULT - compiler.note.preview.recompile 1 error diff --git a/test/langtools/tools/javap/UndefinedAccessFlagTest.java b/test/langtools/tools/javap/UndefinedAccessFlagTest.java new file mode 100644 index 00000000000..bb531fa369c --- /dev/null +++ b/test/langtools/tools/javap/UndefinedAccessFlagTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2024, 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 8333748 + * @summary javap should not fail if reserved access flag bits are set to 1 + * @library /tools/lib + * @modules jdk.jdeps/com.sun.tools.javap + * @enablePreview + * @run junit UndefinedAccessFlagTest + */ + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import toolbox.JavapTask; +import toolbox.Task; +import toolbox.ToolBox; + +import java.lang.classfile.AccessFlags; +import java.lang.classfile.ClassModel; +import java.lang.classfile.FieldModel; +import java.lang.classfile.MethodModel; +import java.lang.classfile.attribute.InnerClassInfo; +import java.lang.classfile.attribute.InnerClassesAttribute; +import java.nio.file.Files; +import java.nio.file.Path; + +import static java.lang.classfile.ClassFile.*; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class UndefinedAccessFlagTest { + + final ToolBox toolBox = new ToolBox(); + + enum TestLocation { + NONE(false), CLASS, FIELD, METHOD, INNER_CLASS(false); + + final boolean fails; + TestLocation() { this(true); } + TestLocation(boolean fails) { this.fails = fails; } + } + + @ParameterizedTest + @EnumSource(TestLocation.class) + void test(TestLocation location) throws Throwable { + var cf = of(); + ClassModel cm; + try (var is = UndefinedAccessFlagTest.class.getResourceAsStream( + "/UndefinedAccessFlagTest$SampleInnerClass.class" + )) { + cm = cf.parse(is.readAllBytes()); + } + var bytes = cf.transform(cm, (cb, ce) -> { + switch (ce) { + case AccessFlags flags when location == TestLocation.CLASS -> cb + .withFlags(flags.flagsMask() | ACC_PRIVATE); + case FieldModel f when location == TestLocation.FIELD -> cb + .transformField(f, (fb, fe) -> { + if (fe instanceof AccessFlags flags) { + fb.withFlags(flags.flagsMask() | ACC_SYNCHRONIZED); + } else { + fb.with(fe); + } + }); + case MethodModel m when location == TestLocation.METHOD -> cb + .transformMethod(m, (mb, me) -> { + if (me instanceof AccessFlags flags) { + mb.withFlags(flags.flagsMask() | ACC_INTERFACE); + } else { + mb.with(me); + } + }); + case InnerClassesAttribute attr when location == TestLocation.INNER_CLASS -> cb + .with(InnerClassesAttribute.of(attr.classes().stream() + .map(ic -> InnerClassInfo.of(ic.innerClass(), ic.outerClass(), ic.innerName(), ic.flagsMask() | 0x0020)) + .toList())); + default -> cb.with(ce); + } + }); + + Files.write(Path.of("transformed.class"), bytes); + + var lines = new JavapTask(toolBox) + .classes("transformed.class") + .options("-c", "-p", "-v") + .run(location.fails ? Task.Expect.FAIL : Task.Expect.SUCCESS) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + // No termination when access flag error happens + assertTrue(lines.stream().anyMatch(l -> l.contains("java.lang.String field;"))); + assertTrue(lines.stream().anyMatch(l -> l.contains("UndefinedAccessFlagTest$SampleInnerClass();"))); + assertTrue(lines.stream().anyMatch(l -> l.contains("void method();"))); + assertTrue(lines.stream().anyMatch(l -> l.contains("SampleInnerClass=class UndefinedAccessFlagTest$SampleInnerClass of class UndefinedAccessFlagTest"))); + + // Remove non-error lines + assertTrue(lines.removeIf(st -> !st.startsWith("Error:"))); + // Desired locations has errors + assertTrue(location == TestLocation.NONE || !lines.isEmpty()); + // Access Flag errors only + assertTrue(lines.stream().allMatch(l -> l.contains("Access Flags:")), () -> String.join("\n", lines)); + } + + static class SampleInnerClass { + String field; + void method() {} + } +}