From ca5390c4d9a8744fbbfb0f378f7e31ac9486d0d6 Mon Sep 17 00:00:00 2001 From: Gui Cao Date: Mon, 6 Jan 2025 03:35:46 +0000 Subject: [PATCH 001/286] 8346924: TestVectorizationNegativeScale.java fails without the rvv extension on RISCV fastdebug VM Reviewed-by: fyang, kvn --- .../compiler/vectorization/TestVectorizationNegativeScale.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/vectorization/TestVectorizationNegativeScale.java b/test/hotspot/jtreg/compiler/vectorization/TestVectorizationNegativeScale.java index 58464880070ca..4fc9f7d1ed11e 100644 --- a/test/hotspot/jtreg/compiler/vectorization/TestVectorizationNegativeScale.java +++ b/test/hotspot/jtreg/compiler/vectorization/TestVectorizationNegativeScale.java @@ -25,7 +25,7 @@ * @test * @bug 8332827 * @summary [REDO] C2: crash in compiled code because of dependency on removed range check CastIIs - * + * @requires os.arch != "riscv64" | vm.cpu.features ~= ".*rvv.*" * @library /test/lib / * @run driver TestVectorizationNegativeScale * From e98f41266346aa676a3e764528806f2b82ec7e46 Mon Sep 17 00:00:00 2001 From: Gui Cao Date: Mon, 6 Jan 2025 03:36:00 +0000 Subject: [PATCH 002/286] 8346922: TestVectorReinterpret.java fails without the rvv extension on RISCV fastdebug VM Reviewed-by: fyang, kvn --- .../jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java index 5891033fbd9d0..7f00fece7e610 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java @@ -39,6 +39,7 @@ * @modules jdk.incubator.vector * @modules java.base/jdk.internal.misc * @summary Test that vector reinterpret intrinsics work as intended. + * @requires os.arch != "riscv64" | vm.cpu.features ~= ".*rvv.*" * @library /test/lib / * @run main compiler.vectorapi.reshape.TestVectorReinterpret */ From 9393897817a3280e08a8278b86df71f59608be9c Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Mon, 6 Jan 2025 06:01:24 +0000 Subject: [PATCH 003/286] 8346260: Test "javax/swing/JOptionPane/bug4174551.java" failed because the font size of message "Hi 24" is not set to 24 in Nimbus LookAndFeel Reviewed-by: aivanov, dnguyen --- .../javax/swing/plaf/synth/SynthDefaultLookup.java | 10 +++++++++- test/jdk/javax/swing/JOptionPane/bug4174551.java | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java index ba1927bb948e4..ad6b226dd705f 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,9 @@ package javax.swing.plaf.synth; import sun.swing.DefaultLookup; + import javax.swing.JComponent; +import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; /** @@ -35,6 +37,12 @@ */ class SynthDefaultLookup extends DefaultLookup { public Object getDefault(JComponent c, ComponentUI ui, String key) { + if (ui instanceof SynthOptionPaneUI) { + Object value = super.getDefault(c, ui, key); + if (value != null) { + return value; + } + } if (!(ui instanceof SynthUI)) { Object value = super.getDefault(c, ui, key); return value; diff --git a/test/jdk/javax/swing/JOptionPane/bug4174551.java b/test/jdk/javax/swing/JOptionPane/bug4174551.java index f65f95192b7e2..dbe6cdffe1a7d 100644 --- a/test/jdk/javax/swing/JOptionPane/bug4174551.java +++ b/test/jdk/javax/swing/JOptionPane/bug4174551.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4174551 + * @bug 4174551 8346260 * @summary JOptionPane should allow custom buttons * @library /java/awt/regtesthelpers * @build PassFailJFrame From f1d85ab3e61f923b4e120cf30e16109e04505b53 Mon Sep 17 00:00:00 2001 From: Qizheng Xing Date: Mon, 6 Jan 2025 06:23:53 +0000 Subject: [PATCH 004/286] 8346773: Fix unmatched brackets in some misc files Reviewed-by: kbarrett, alanb, rriggs, dholmes, erikj, liach --- doc/hotspot-unit-tests.html | 2 +- doc/hotspot-unit-tests.md | 2 +- src/hotspot/share/jfr/metadata/metadata.xml | 4 ++-- src/hotspot/share/prims/jvmti.xml | 2 +- src/java.base/share/man/java.md | 2 +- src/java.base/share/man/keytool.md | 6 +++--- src/jdk.compiler/share/man/javac.md | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/hotspot-unit-tests.html b/doc/hotspot-unit-tests.html index 556cfecc42d7f..fcd4a93f8e485 100644 --- a/doc/hotspot-unit-tests.html +++ b/doc/hotspot-unit-tests.html @@ -245,7 +245,7 @@

Error messages

All GoogleTest asserts print compared expressions and their values, so there is no need to have them in error messages. Asserts print only compared values, they do not print any of interim variables, e.g. -ASSERT_TRUE((val1 == val2 && isFail(foo(8)) || i == 18) +ASSERT_TRUE((val1 == val2 && isFail(foo(8))) || i == 18) prints only one value. If you use some complex predicates, please consider EXPECT_PRED* or EXPECT_FORMAT_PRED assertions family, they check that a predicate returns true/success and diff --git a/doc/hotspot-unit-tests.md b/doc/hotspot-unit-tests.md index 62ace4ef6ee8b..e1222baa2e3a4 100644 --- a/doc/hotspot-unit-tests.md +++ b/doc/hotspot-unit-tests.md @@ -172,7 +172,7 @@ Provide informative, but not too verbose error messages. All GoogleTest asserts print compared expressions and their values, so there is no need to have them in error messages. Asserts print only compared values, they do not print any of interim variables, e.g. -`ASSERT_TRUE((val1 == val2 && isFail(foo(8)) || i == 18)` prints only +`ASSERT_TRUE((val1 == val2 && isFail(foo(8))) || i == 18)` prints only one value. If you use some complex predicates, please consider `EXPECT_PRED*` or `EXPECT_FORMAT_PRED` assertions family, they check that a predicate returns true/success and print out all parameters values. diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 3b5e24ca9a256..1b85cb1350cbd 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -46,10 +46,10 @@ $ jfr print dump.jfr Programmatic access: - try (var rf = new RecordingFile(Path.of("dump.jfr)) { + try (var rf = new RecordingFile(Path.of("dump.jfr"))) { while (rf.hasMoreEvents()) { RecordedEvent e = rf.readEvent(); - System.out.println(e.getName() + " " + e.getDuration())); + System.out.println(e.getName() + " " + e.getDuration()); } }; !--> diff --git a/src/hotspot/share/prims/jvmti.xml b/src/hotspot/share/prims/jvmti.xml index 0afbf56b3fc97..e8e127486ca63 100644 --- a/src/hotspot/share/prims/jvmti.xml +++ b/src/hotspot/share/prims/jvmti.xml @@ -1218,7 +1218,7 @@ jvmtiEnv *jvmti;

  • Timed wait?
    • Indefinite (JVMTI_THREAD_STATE_WAITING_INDEFINITELY
    • + id="JVMTI_THREAD_STATE_WAITING_INDEFINITELY">JVMTI_THREAD_STATE_WAITING_INDEFINITELY)
    • Timed (JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT)
    diff --git a/src/java.base/share/man/java.md b/src/java.base/share/man/java.md index 01f7b3f7e7768..a048d2a6dcfa0 100644 --- a/src/java.base/share/man/java.md +++ b/src/java.base/share/man/java.md @@ -1311,7 +1311,7 @@ These `java` options control the runtime behavior of the Java HotSpot VM. `-XX:+PreserveFramePointer` : Selects between using the RBP register as a general purpose register (`-XX:-PreserveFramePointer`) and using the RBP register to hold the frame - pointer of the currently executing method (`-XX:+PreserveFramePointer` . If + pointer of the currently executing method (`-XX:+PreserveFramePointer`). If the frame pointer is available, then external profiling tools (for example, Linux perf) can construct more accurate stack traces. diff --git a/src/java.base/share/man/keytool.md b/src/java.base/share/man/keytool.md index 22b2877a3e73a..8484ec6b5b312 100644 --- a/src/java.base/share/man/keytool.md +++ b/src/java.base/share/man/keytool.md @@ -662,7 +662,7 @@ perform. - {`-noprompt`}: Do not prompt - - {`-addprovider` *name* \[`-providerarg` *arg*\]: Add security provider + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider by name (such as SunPKCS11) with an optional configure argument. - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security @@ -1617,7 +1617,7 @@ name information, the keystore password, and the private key password. The rest of the examples assume that you responded to the prompts with values equal to those specified in the first `-genkeypair` command. For example, a distinguished name of -`cn=`*myname*`, ou=`*mygroup*`, o=`*mycompany*`, c=`*mycountry*). +`cn=`*myname*`, ou=`*mygroup*`, o=`*mycompany*`, c=`*mycountry*. ## Requesting a Signed Certificate from a CA @@ -1914,7 +1914,7 @@ Keystore implementation The `keytool` command works on any file-based keystore implementation. It treats the keystore location that is passed to it at the command line as a file name and converts it to a `FileInputStream`, from which it loads the - keystore information.)The `jarsigner` commands can read a keystore from any + keystore information. The `jarsigner` commands can read a keystore from any location that can be specified with a URL. For `keytool` and `jarsigner`, you can specify a keystore type at the diff --git a/src/jdk.compiler/share/man/javac.md b/src/jdk.compiler/share/man/javac.md index 7761cde2b5802..3edbeda6ecaf9 100644 --- a/src/jdk.compiler/share/man/javac.md +++ b/src/jdk.compiler/share/man/javac.md @@ -1667,7 +1667,7 @@ internal and subject to change at any time. public static int m() { try { throw new NullPointerException(); - } catch (NullPointerException(); { + } catch (NullPointerException e) { System.err.println("Caught NullPointerException."); return 1; } finally { From dfaa89162a35acd20b1ed35e147f9626a181510a Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Mon, 6 Jan 2025 13:44:35 +0000 Subject: [PATCH 005/286] 8346569: Shenandoah: Worker initializes ShenandoahThreadLocalData twice results in memory leak Reviewed-by: wkemper, shade --- src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp index 4a49d28ea861b..c9dbe5f402421 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, 2021, Red Hat, Inc. All rights reserved. + * Copyright (c) 2014, 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 @@ -73,7 +74,6 @@ ShenandoahPushWorkerScope::~ShenandoahPushWorkerScope() { } void ShenandoahWorkerThreads::on_create_worker(WorkerThread* worker) { - ShenandoahThreadLocalData::create(worker); if (_initialize_gclab) { ShenandoahThreadLocalData::initialize_gclab(worker); } From e0695e0ef0dd1bfacbaac32edda055ba852a2421 Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Mon, 6 Jan 2025 14:08:32 +0000 Subject: [PATCH 006/286] 8346981: Remove obsolete java.base exports of jdk.internal.objectweb.asm packages Reviewed-by: liach, alanb --- src/java.base/share/classes/module-info.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 2904f66573211..66e6267367c26 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, 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 @@ -197,14 +197,6 @@ jdk.jlink; exports jdk.internal.logger to java.logging; - exports jdk.internal.org.objectweb.asm to - jdk.jfr; - exports jdk.internal.org.objectweb.asm.tree to - jdk.jfr; - exports jdk.internal.org.objectweb.asm.util to - jdk.jfr; - exports jdk.internal.org.objectweb.asm.commons to - jdk.jfr; exports jdk.internal.org.xml.sax to jdk.jfr; exports jdk.internal.org.xml.sax.helpers to From c027f2ed1d77f34bbd1db8418156322d3a13ab81 Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Mon, 6 Jan 2025 14:08:45 +0000 Subject: [PATCH 007/286] 8346983: Remove ASM-based transforms from Class-File API tests Reviewed-by: liach --- test/jdk/jdk/classfile/TEST.properties | 4 +- .../jdk/jdk/classfile/helpers/Transforms.java | 351 +----------------- 2 files changed, 3 insertions(+), 352 deletions(-) diff --git a/test/jdk/jdk/classfile/TEST.properties b/test/jdk/jdk/classfile/TEST.properties index 62414b36eae48..2d8d20cf1f4c0 100644 --- a/test/jdk/jdk/classfile/TEST.properties +++ b/test/jdk/jdk/classfile/TEST.properties @@ -2,6 +2,4 @@ maxOutputSize = 2500000 modules = \ java.base/jdk.internal.classfile.components \ java.base/jdk.internal.classfile.impl \ - java.base/jdk.internal.classfile.impl.verifier \ - java.base/jdk.internal.org.objectweb.asm \ - java.base/jdk.internal.org.objectweb.asm.tree \ No newline at end of file + java.base/jdk.internal.classfile.impl.verifier \ No newline at end of file diff --git a/test/jdk/jdk/classfile/helpers/Transforms.java b/test/jdk/jdk/classfile/helpers/Transforms.java index b0e88bd8212b5..dba3f21cbd83d 100644 --- a/test/jdk/jdk/classfile/helpers/Transforms.java +++ b/test/jdk/jdk/classfile/helpers/Transforms.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -43,27 +43,12 @@ import java.lang.classfile.MethodModel; import java.lang.classfile.MethodTransform; import jdk.internal.classfile.components.ClassRemapper; -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.Attribute; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import jdk.internal.org.objectweb.asm.Handle; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.ModuleVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.RecordComponentVisitor; -import jdk.internal.org.objectweb.asm.TypePath; -import jdk.internal.org.objectweb.asm.tree.ClassNode; /** * Transforms */ public class Transforms { - static int ASM9 = 9 << 16 | 0 << 8; - public static final ClassTransform threeLevelNoop = (cb, ce) -> { if (ce instanceof MethodModel mm) { cb.transformMethod(mm, (mb, me) -> { @@ -128,42 +113,10 @@ public enum NoOpTransform { UNSHARED_3(false, threeLevelNoop), SHARED_3_NO_STACKMAP(true, threeLevelNoop, ClassFile.StackMapsOption.DROP_STACK_MAPS), SHARED_3_NO_DEBUG(true, threeLevelNoop, ClassFile.DebugElementsOption.DROP_DEBUG, ClassFile.LineNumbersOption.DROP_LINE_NUMBERS), - ASM_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_TREE(bytes -> { - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - node.accept(cw); - return cw.toByteArray(); - }), CLASS_REMAPPER(bytes -> ClassRemapper.of(Map.of()).remapClass(ClassFile.of(), ClassFile.of().parse(bytes))); - // Need ASM, LOW_UNSHARED + // Need LOW_UNSHARED public final UnaryOperator transform; public final boolean shared; @@ -202,12 +155,6 @@ public Optional classRecord(byte[] bytes) throws IOException { } public enum InjectNopTransform { - ASM_NOP_SHARED(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new NopClassVisitor(cw), 0); - return cw.toByteArray(); - }), NOP_SHARED(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -242,13 +189,6 @@ public void accept(CodeElement e) { } public enum SimpleTransform { - ASM_ADD_FIELD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - cw.visitField(0, "argleBargleWoogaWooga", "I", null, null); - return cw.toByteArray(); - }), HIGH_SHARED_ADD_FIELD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -273,20 +213,6 @@ public void atEnd(ClassBuilder builder) { cb.withField("argleBargleWoogaWooga", ConstantDescs.CD_int, b -> { }); }); }), - ASM_DEL_METHOD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - ClassVisitor v = new ClassVisitor(ASM9, cw) { - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return (name.equals("hashCode") && descriptor.equals("()Z")) - ? null - : super.visitMethod(access, name, descriptor, signature, exceptions); - } - }; - cr.accept(cw, 0); - return cw.toByteArray(); - }), HIGH_SHARED_DEL_METHOD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -319,277 +245,4 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str } } - static class CustomClassVisitor extends ClassVisitor { - - public CustomClassVisitor(ClassVisitor writer) { - super(ASM9, writer); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitSource(String source, String debug) { - super.visitSource(source, debug); - } - - @Override - public ModuleVisitor visitModule(String name, int access, String version) { - return super.visitModule(name, access, version); - } - - @Override - public void visitNestHost(String nestHost) { - super.visitNestHost(nestHost); - } - - @Override - public void visitOuterClass(String owner, String name, String descriptor) { - super.visitOuterClass(owner, name, descriptor); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitNestMember(String nestMember) { - super.visitNestMember(nestMember); - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - super.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public RecordComponentVisitor visitRecordComponent(String name, String descriptor, String signature) { - return super.visitRecordComponent(name, descriptor, signature); - } - - @Override - public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - return super.visitField(access, name, descriptor, signature, value); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new CustomMethodVisitor(mv); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - - static class CustomMethodVisitor extends MethodVisitor { - - public CustomMethodVisitor(MethodVisitor methodVisitor) { - super(ASM9, methodVisitor); - } - - @Override - public void visitParameter(String name, int access) { - super.visitParameter(name, access); - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - return super.visitAnnotationDefault(); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAnnotableParameterCount(int parameterCount, boolean visible) { - super.visitAnnotableParameterCount(parameterCount, visible); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String descriptor, boolean visible) { - return super.visitParameterAnnotation(parameter, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitCode() { - super.visitCode(); - } - - @Override - public void visitFrame(int type, int numLocal, Object[] local, int numStack, Object[] stack) { - super.visitFrame(type, numLocal, local, numStack, stack); - } - - @Override - public void visitInsn(int opcode) { - super.visitInsn(opcode); - } - - @Override - public void visitIntInsn(int opcode, int operand) { - super.visitIntInsn(opcode, operand); - } - - @Override - public void visitVarInsn(int opcode, int var) { - super.visitVarInsn(opcode, var); - } - - @Override - public void visitTypeInsn(int opcode, String type) { - super.visitTypeInsn(opcode, type); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String descriptor) { - super.visitFieldInsn(opcode, owner, name, descriptor); - } - - @Override - @SuppressWarnings("deprecation") - public void visitMethodInsn(int opcode, String owner, String name, String descriptor) { - super.visitMethodInsn(opcode, owner, name, descriptor); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { - super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - } - - @Override - public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) { - super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); - } - - @Override - public void visitJumpInsn(int opcode, Label label) { - super.visitJumpInsn(opcode, label); - } - - @Override - public void visitLabel(Label label) { - super.visitLabel(label); - } - - @Override - public void visitLdcInsn(Object value) { - super.visitLdcInsn(value); - } - - @Override - public void visitIincInsn(int var, int increment) { - super.visitIincInsn(var, increment); - } - - @Override - public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { - super.visitTableSwitchInsn(min, max, dflt, labels); - } - - @Override - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - super.visitLookupSwitchInsn(dflt, keys, labels); - } - - @Override - public void visitMultiANewArrayInsn(String descriptor, int numDimensions) { - super.visitMultiANewArrayInsn(descriptor, numDimensions); - } - - @Override - public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - super.visitTryCatchBlock(start, end, handler, type); - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) { - super.visitLocalVariable(name, descriptor, signature, start, end, index); - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String descriptor, boolean visible) { - return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible); - } - - @Override - public void visitLineNumber(int line, Label start) { - super.visitLineNumber(line, start); - } - - @Override - public void visitMaxs(int maxStack, int maxLocals) { - super.visitMaxs(maxStack, maxLocals); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - static class NopClassVisitor extends CustomClassVisitor { - - public NopClassVisitor(ClassVisitor writer) { - super(writer); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new NopMethodVisitor(mv); - } - } - - static class NopMethodVisitor extends CustomMethodVisitor { - - public NopMethodVisitor(MethodVisitor methodVisitor) { - super(methodVisitor); - } - - @Override - public void visitCode() { - super.visitCode(); - visitInsn(Opcodes.NOP); - } - } - } From 594e5196481fd3f9ba21f56120d4377a901f52ec Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Mon, 6 Jan 2025 14:10:19 +0000 Subject: [PATCH 008/286] 8346984: Remove ASM-based benchmarks from Class-File API benchmarks Reviewed-by: liach, redestad, erikj --- make/test/BuildMicrobenchmark.gmk | 4 +- .../classfile/AbstractCorpusBenchmark.java | 4 +- .../bench/jdk/classfile/AdaptNull.java | 6 +- .../openjdk/bench/jdk/classfile/ReadDeep.java | 57 +-- .../bench/jdk/classfile/ReadMetadata.java | 70 +--- .../bench/jdk/classfile/Transforms.java | 349 +----------------- .../openjdk/bench/jdk/classfile/Write.java | 72 +--- 7 files changed, 7 insertions(+), 555 deletions(-) diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk index 1052e422f7b06..272cb1af0a6bb 100644 --- a/make/test/BuildMicrobenchmark.gmk +++ b/make/test/BuildMicrobenchmark.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, 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 @@ -96,8 +96,6 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \ --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \ --add-exports java.base/jdk.internal.util=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \ --add-exports java.base/jdk.internal.vm=ALL-UNNAMED \ --add-exports java.base/sun.invoke.util=ALL-UNNAMED \ --add-exports java.base/sun.security.util=ALL-UNNAMED \ diff --git a/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java b/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java index f3c934d9c658d..ea361b4975b02 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,8 +44,6 @@ @Warmup(iterations = 2) @Measurement(iterations = 4) @Fork(value = 1, jvmArgs = { - "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED"}) @State(Scope.Benchmark) diff --git a/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java b/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java index 55c33b36805a3..680d1626b2c62 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -35,10 +35,6 @@ public class AdaptNull extends AbstractCorpusBenchmark { @Param({ // "ARRAYCOPY", - "ASM_1", - "ASM_3", - "ASM_UNSHARED_3", -// "ASM_TREE", "SHARED_1", "SHARED_2", "SHARED_3", diff --git a/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java b/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java index 4165785135cea..a134e04bd5adb 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -29,12 +29,6 @@ import java.lang.classfile.CompoundElement; import java.lang.classfile.MethodModel; import java.lang.classfile.instruction.LoadInstruction; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.tree.ClassNode; -import jdk.internal.org.objectweb.asm.tree.MethodNode; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; @@ -45,55 +39,6 @@ */ public class ReadDeep extends AbstractCorpusBenchmark { - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmStreamCountLoads(Blackhole bh) { - for (byte[] bytes : classes) { - ClassReader cr = new ClassReader(bytes); - - var mv = new MethodVisitor(Opcodes.ASM9) { - int count = 0; - - @Override - public void visitVarInsn(int opcode, int var) { - ++count; - } - }; - - var visitor = new ClassVisitor(Opcodes.ASM9) { - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return mv; - } - }; - cr.accept(visitor, 0); - bh.consume(mv.count); - } - } - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmTreeCountLoads(Blackhole bh) { - for (byte[] bytes : classes) { - var mv = new MethodVisitor(Opcodes.ASM9) { - int count = 0; - - @Override - public void visitVarInsn(int opcode, int var) { - ++count; - } - }; - - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - for (MethodNode mn : node.methods) { - mn.accept(mv); - } - bh.consume(mv.count); - } - } - @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkElementsCountLoads(Blackhole bh) { diff --git a/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java b/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java index 08b1b6312b1c0..0a12c5214e7bb 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -27,42 +27,11 @@ import java.lang.classfile.ClassModel; import java.lang.classfile.ClassFile; import java.lang.classfile.FieldModel; -import jdk.internal.org.objectweb.asm.*; -import jdk.internal.org.objectweb.asm.tree.*; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; public class ReadMetadata extends AbstractCorpusBenchmark { - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmStreamReadName(Blackhole bh) { - for (byte[] bytes : classes) { - ClassReader cr = new ClassReader(bytes); - var visitor = new ClassVisitor(Opcodes.ASM9) { - String theName; - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - theName = name; - } - }; - cr.accept(visitor, 0); - bh.consume(visitor.theName); - } - } - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmTreeReadName(Blackhole bh) { - for (byte[] bytes : classes) { - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - bh.consume(node.name); - } - } - @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkReadName(Blackhole bh) { @@ -90,43 +59,6 @@ public void jdkReadMemberNames(Blackhole bh) { } } - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmStreamCountFields(Blackhole bh) { - for (byte[] bytes : classes) { - ClassReader cr = new ClassReader(bytes); - var visitor = new ClassVisitor(Opcodes.ASM9) { - int count; - - @Override - public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - if ((access & Opcodes.ACC_PUBLIC) != 1) { - ++count; - } - return null; - } - }; - cr.accept(visitor, 0); - bh.consume(visitor.count); - } - } - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmTreeCountFields(Blackhole bh) { - for (byte[] bytes : classes) { - int count = 0; - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - for (FieldNode fn : node.fields) - if ((fn.access & Opcodes.ACC_PUBLIC) != 1) { - ++count; - } - bh.consume(count); - } - } - @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkTreeCountFields(Blackhole bh) { diff --git a/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java b/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java index 8af03a8b874c4..19c8744203983 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -41,27 +41,12 @@ import java.lang.classfile.MethodModel; import java.lang.classfile.MethodTransform; import jdk.internal.classfile.components.ClassRemapper; -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.Attribute; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import jdk.internal.org.objectweb.asm.Handle; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.ModuleVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.RecordComponentVisitor; -import jdk.internal.org.objectweb.asm.TypePath; -import jdk.internal.org.objectweb.asm.tree.ClassNode; /** * Transforms */ public class Transforms { - static int ASM9 = 9 << 16 | 0 << 8; - public static final ClassTransform threeLevelNoop = (cb, ce) -> { if (ce instanceof MethodModel mm) { cb.transformMethod(mm, (mb, me) -> { @@ -123,38 +108,6 @@ public enum NoOpTransform { UNSHARED_3(false, threeLevelNoop), SHARED_3_NO_STACKMAP(true, threeLevelNoop, ClassFile.StackMapsOption.DROP_STACK_MAPS), SHARED_3_NO_DEBUG(true, threeLevelNoop, ClassFile.DebugElementsOption.DROP_DEBUG, ClassFile.LineNumbersOption.DROP_LINE_NUMBERS), - ASM_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_TREE(bytes -> { - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - node.accept(cw); - return cw.toByteArray(); - }), CLASS_REMAPPER(bytes -> ClassRemapper.of(Map.of()).remapClass(ClassFile.of(), ClassFile.of().parse(bytes))); @@ -186,12 +139,6 @@ public enum NoOpTransform { } public enum InjectNopTransform { - ASM_NOP_SHARED(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new NopClassVisitor(cw), 0); - return cw.toByteArray(); - }), NOP_SHARED(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -226,13 +173,6 @@ public void accept(CodeElement e) { } public enum SimpleTransform { - ASM_ADD_FIELD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - cw.visitField(0, "argleBargleWoogaWooga", "I", null, null); - return cw.toByteArray(); - }), HIGH_SHARED_ADD_FIELD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -257,20 +197,6 @@ public void atEnd(ClassBuilder builder) { cb.withField("argleBargleWoogaWooga", ConstantDescs.CD_int, b -> { }); }); }), - ASM_DEL_METHOD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - ClassVisitor v = new ClassVisitor(ASM9, cw) { - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return (name.equals("hashCode") && descriptor.equals("()Z")) - ? null - : super.visitMethod(access, name, descriptor, signature, exceptions); - } - }; - cr.accept(cw, 0); - return cw.toByteArray(); - }), HIGH_SHARED_DEL_METHOD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -303,277 +229,4 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str } } - static class CustomClassVisitor extends ClassVisitor { - - public CustomClassVisitor(ClassVisitor writer) { - super(ASM9, writer); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitSource(String source, String debug) { - super.visitSource(source, debug); - } - - @Override - public ModuleVisitor visitModule(String name, int access, String version) { - return super.visitModule(name, access, version); - } - - @Override - public void visitNestHost(String nestHost) { - super.visitNestHost(nestHost); - } - - @Override - public void visitOuterClass(String owner, String name, String descriptor) { - super.visitOuterClass(owner, name, descriptor); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitNestMember(String nestMember) { - super.visitNestMember(nestMember); - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - super.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public RecordComponentVisitor visitRecordComponent(String name, String descriptor, String signature) { - return super.visitRecordComponent(name, descriptor, signature); - } - - @Override - public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - return super.visitField(access, name, descriptor, signature, value); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new CustomMethodVisitor(mv); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - - static class CustomMethodVisitor extends MethodVisitor { - - public CustomMethodVisitor(MethodVisitor methodVisitor) { - super(ASM9, methodVisitor); - } - - @Override - public void visitParameter(String name, int access) { - super.visitParameter(name, access); - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - return super.visitAnnotationDefault(); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAnnotableParameterCount(int parameterCount, boolean visible) { - super.visitAnnotableParameterCount(parameterCount, visible); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String descriptor, boolean visible) { - return super.visitParameterAnnotation(parameter, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitCode() { - super.visitCode(); - } - - @Override - public void visitFrame(int type, int numLocal, Object[] local, int numStack, Object[] stack) { - super.visitFrame(type, numLocal, local, numStack, stack); - } - - @Override - public void visitInsn(int opcode) { - super.visitInsn(opcode); - } - - @Override - public void visitIntInsn(int opcode, int operand) { - super.visitIntInsn(opcode, operand); - } - - @Override - public void visitVarInsn(int opcode, int var) { - super.visitVarInsn(opcode, var); - } - - @Override - public void visitTypeInsn(int opcode, String type) { - super.visitTypeInsn(opcode, type); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String descriptor) { - super.visitFieldInsn(opcode, owner, name, descriptor); - } - - @Override - @SuppressWarnings("deprecation") - public void visitMethodInsn(int opcode, String owner, String name, String descriptor) { - super.visitMethodInsn(opcode, owner, name, descriptor); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { - super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - } - - @Override - public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) { - super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); - } - - @Override - public void visitJumpInsn(int opcode, Label label) { - super.visitJumpInsn(opcode, label); - } - - @Override - public void visitLabel(Label label) { - super.visitLabel(label); - } - - @Override - public void visitLdcInsn(Object value) { - super.visitLdcInsn(value); - } - - @Override - public void visitIincInsn(int var, int increment) { - super.visitIincInsn(var, increment); - } - - @Override - public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { - super.visitTableSwitchInsn(min, max, dflt, labels); - } - - @Override - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - super.visitLookupSwitchInsn(dflt, keys, labels); - } - - @Override - public void visitMultiANewArrayInsn(String descriptor, int numDimensions) { - super.visitMultiANewArrayInsn(descriptor, numDimensions); - } - - @Override - public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - super.visitTryCatchBlock(start, end, handler, type); - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) { - super.visitLocalVariable(name, descriptor, signature, start, end, index); - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String descriptor, boolean visible) { - return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible); - } - - @Override - public void visitLineNumber(int line, Label start) { - super.visitLineNumber(line, start); - } - - @Override - public void visitMaxs(int maxStack, int maxLocals) { - super.visitMaxs(maxStack, maxLocals); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - static class NopClassVisitor extends CustomClassVisitor { - - public NopClassVisitor(ClassVisitor writer) { - super(writer); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new NopMethodVisitor(mv); - } - } - - static class NopMethodVisitor extends CustomMethodVisitor { - - public NopMethodVisitor(MethodVisitor methodVisitor) { - super(methodVisitor); - } - - @Override - public void visitCode() { - super.visitCode(); - visitInsn(Opcodes.NOP); - } - } - } diff --git a/test/micro/org/openjdk/bench/jdk/classfile/Write.java b/test/micro/org/openjdk/bench/jdk/classfile/Write.java index ffd5b8f1c5ed5..9317ef78806eb 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/Write.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/Write.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,7 +25,6 @@ import java.lang.reflect.AccessFlag; import java.lang.classfile.ClassFile; import java.lang.classfile.attribute.SourceFileAttribute; -import jdk.internal.org.objectweb.asm.*; import org.openjdk.jmh.annotations.*; import java.io.FileOutputStream; import static java.lang.classfile.ClassFile.ACC_PUBLIC; @@ -57,8 +56,6 @@ @Warmup(iterations = 3) @Measurement(iterations = 5) @Fork(value = 1, jvmArgs = { - "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED"}) public class Write { static final int REPEATS = 40; @@ -70,76 +67,9 @@ public class Write { } METHOD_NAMES = names; } - static String checkFileAsm = "/tmp/asw/MyClass.class"; static String checkFileBc = "/tmp/byw/MyClass.class"; - static boolean writeClassAsm = Files.exists(Paths.get(checkFileAsm).getParent()); static boolean writeClassBc = Files.exists(Paths.get(checkFileBc).getParent()); - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public byte[] asmStream() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - cw.visit(Opcodes.V12, Opcodes.ACC_PUBLIC, "MyClass", null, "java/lang/Object", null); - cw.visitSource("MyClass.java", null); - - { - MethodVisitor mv = cw.visitMethod(0, INIT_NAME, "()V", null, null); - mv.visitCode(); - Label startLabel = new Label(); - Label endLabel = new Label(); - mv.visitLabel(startLabel); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", INIT_NAME, "()V", false); - mv.visitInsn(Opcodes.RETURN); - mv.visitLabel(endLabel); - mv.visitLocalVariable("this", "LMyClass;", null, startLabel, endLabel, 1); - mv.visitMaxs(-1, -1); - mv.visitEnd(); - } - - for (int xi = 0; xi < REPEATS; ++xi) { - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_STATIC, METHOD_NAMES[xi], "([Ljava/lang/String;)V", null, null); - mv.visitCode(); - Label loopTop = new Label(); - Label loopEnd = new Label(); - Label startLabel = new Label(); - Label endLabel = new Label(); - Label iStart = new Label(); - mv.visitLabel(startLabel); - mv.visitInsn(Opcodes.ICONST_1); - mv.visitVarInsn(Opcodes.ISTORE, 1); - mv.visitLabel(iStart); - mv.visitInsn(Opcodes.ICONST_1); - mv.visitVarInsn(Opcodes.ISTORE, 2); - mv.visitLabel(loopTop); - mv.visitVarInsn(Opcodes.ILOAD, 2); - mv.visitIntInsn(Opcodes.BIPUSH, 10); - mv.visitJumpInsn(Opcodes.IF_ICMPGE, loopEnd); - mv.visitVarInsn(Opcodes.ILOAD, 1); - mv.visitVarInsn(Opcodes.ILOAD, 2); - mv.visitInsn(Opcodes.IMUL); - mv.visitVarInsn(Opcodes.ISTORE, 1); - mv.visitIincInsn(2, 1); - mv.visitJumpInsn(Opcodes.GOTO, loopTop); - mv.visitLabel(loopEnd); - mv.visitFieldInsn(Opcodes.GETSTATIC,"java/lang/System", "out", "Ljava/io/PrintStream;"); - mv.visitVarInsn(Opcodes.ILOAD, 1); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V", false); - mv.visitLabel(endLabel); - mv.visitInsn(Opcodes.RETURN); - mv.visitLocalVariable("fac", "I", null, startLabel, endLabel, 1); - mv.visitLocalVariable("i", "I", null, iStart, loopEnd, 2); - mv.visitMaxs(-1, -1); - mv.visitEnd(); - } - cw.visitEnd(); - - byte[] bytes = cw.toByteArray(); - if (writeClassAsm) writeClass(bytes, checkFileAsm); - return bytes; - } - @Benchmark @BenchmarkMode(Mode.Throughput) public byte[] jdkTree() { From ccf3d57ebcae718336770a4c3fc896d85340df23 Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Mon, 6 Jan 2025 14:10:34 +0000 Subject: [PATCH 009/286] 8346985: Convert test/jdk/com/sun/jdi/ClassUnloadEventTest.java to Class-File API Reviewed-by: liach --- .../jdk/com/sun/jdi/ClassUnloadEventTest.java | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/test/jdk/com/sun/jdi/ClassUnloadEventTest.java b/test/jdk/com/sun/jdi/ClassUnloadEventTest.java index cf77ba846ae21..41b1bff5e42f2 100644 --- a/test/jdk/com/sun/jdi/ClassUnloadEventTest.java +++ b/test/jdk/com/sun/jdi/ClassUnloadEventTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,18 +24,13 @@ /* * @test * @bug 8256811 - * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/jdk.internal.misc + * @modules java.base/jdk.internal.misc * @library /test/lib * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm/native ClassUnloadEventTest run */ -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; import jdk.test.lib.classloader.ClassUnloadCommon; import com.sun.jdi.*; @@ -45,6 +40,9 @@ import java.util.*; import java.io.*; +import java.lang.classfile.ClassFile; +import java.lang.constant.ClassDesc; +import java.lang.constant.ConstantDescs; public class ClassUnloadEventTest { static final String CLASS_NAME_PREFIX = "SampleClass__"; @@ -65,18 +63,13 @@ public static void main(String[] args) throws Exception { } } - private static class TestClassLoader extends ClassLoader implements Opcodes { + private static class TestClassLoader extends ClassLoader { private static byte[] generateSampleClass(String name) { - ClassWriter cw = new ClassWriter(0); - - cw.visit(52, ACC_SUPER | ACC_PUBLIC, name, null, "java/lang/Object", null); - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "m", "()V", null, null); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - cw.visitEnd(); - return cw.toByteArray(); + return ClassFile.of().build(ClassDesc.of(name), clb -> + clb.withVersion(52, 0) + .withFlags(ClassFile.ACC_SUPER | ClassFile.ACC_PUBLIC) + .withMethodBody("m", ConstantDescs.MTD_void, ClassFile.ACC_PUBLIC | ClassFile.ACC_STATIC, cob -> + cob.return_())); } @Override From dd81f8dcf504d4329e710623c4c92e4786948ada Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Mon, 6 Jan 2025 15:28:36 +0000 Subject: [PATCH 010/286] 8344079: Minor fixes and cleanups to compiler lint-related code Reviewed-by: mcimadamore --- .../com/sun/tools/javac/code/Lint.java | 202 +++++++++--------- .../com/sun/tools/javac/comp/Check.java | 18 +- .../sun/tools/javac/file/BaseFileManager.java | 10 +- .../sun/tools/javac/parser/JavaTokenizer.java | 6 +- .../com/sun/tools/javac/util/Warner.java | 6 +- 5 files changed, 129 insertions(+), 113 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java index e28c0fe60f89c..1131800f8ed44 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -30,16 +30,17 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Stream; -import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.main.Option; +import com.sun.tools.javac.tree.JCTree.*; +import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.LintWarning; -import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Options; -import com.sun.tools.javac.util.Pair; /** * A class for handling -Xlint suboptions and @SuppressWarnings. @@ -49,8 +50,8 @@ * This code and its internal interfaces are subject to change or * deletion without notice. */ -public class Lint -{ +public class Lint { + /** The context key for the root Lint object. */ protected static final Context.Key lintKey = new Context.Key<>(); @@ -63,26 +64,35 @@ public static Lint instance(Context context) { } /** - * Returns the result of combining the values in this object with - * the given annotation. + * Obtain an instance with additional warning supression applied from any + * @SuppressWarnings and/or @Deprecated annotations on the given symbol. + * + *

    + * The returned instance will be different from this instance if and only if + * {@link #suppressionsFrom} returns a non-empty set. + * + * @param sym symbol + * @return lint instance with new warning suppressions applied, or this instance if none */ - public Lint augment(Attribute.Compound attr) { - return augmentor.augment(this, attr); + public Lint augment(Symbol sym) { + EnumSet suppressions = suppressionsFrom(sym); + if (!suppressions.isEmpty()) { + Lint lint = new Lint(this); + lint.values.removeAll(suppressions); + lint.suppressedValues.addAll(suppressions); + return lint; + } + return this; } - /** - * Returns the result of combining the values in this object with - * the metadata on the given symbol. + * Returns a new Lint that has the given LintCategorys enabled. + * @param lc one or more categories to be enabled */ - public Lint augment(Symbol sym) { - Lint l = augmentor.augment(this, sym.getDeclarationAttributes()); - if (sym.isDeprecated() && sym.isDeprecatableViaAnnotation()) { - if (l == this) - l = new Lint(this); - l.values.remove(LintCategory.DEPRECATION); - l.suppressedValues.add(LintCategory.DEPRECATION); - } + public Lint enable(LintCategory... lc) { + Lint l = new Lint(this); + l.values.addAll(Arrays.asList(lc)); + l.suppressedValues.removeAll(Arrays.asList(lc)); return l; } @@ -97,8 +107,13 @@ public Lint suppress(LintCategory... lc) { return l; } - private final AugmentVisitor augmentor; + private final Context context; + + // These are initialized lazily to avoid dependency loops + private Symtab syms; + private Names names; + // Invariant: it's never the case that a category is in both "values" and "suppressedValues" private final EnumSet values; private final EnumSet suppressedValues; @@ -114,10 +129,10 @@ protected Lint(Context context) { values = EnumSet.allOf(LintCategory.class); } else if (options.isSet(Option.XLINT_CUSTOM, "none")) { // if -Xlint:none is given, disable all categories by default - values = EnumSet.noneOf(LintCategory.class); + values = LintCategory.newEmptySet(); } else { // otherwise, enable on-by-default categories - values = EnumSet.noneOf(LintCategory.class); + values = LintCategory.newEmptySet(); Source source = Source.instance(context); if (source.compareTo(Source.JDK9) >= 0) { @@ -146,21 +161,23 @@ protected Lint(Context context) { } } - suppressedValues = EnumSet.noneOf(LintCategory.class); + suppressedValues = LintCategory.newEmptySet(); + this.context = context; context.put(lintKey, this); - augmentor = new AugmentVisitor(context); } protected Lint(Lint other) { - this.augmentor = other.augmentor; + this.context = other.context; + this.syms = other.syms; + this.names = other.names; this.values = other.values.clone(); this.suppressedValues = other.suppressedValues.clone(); } @Override public String toString() { - return "Lint:[values" + values + " suppressedValues" + suppressedValues + "]"; + return "Lint:[enable" + values + ",suppress" + suppressedValues + "]"; } /** @@ -373,6 +390,11 @@ public static Optional get(String option) { return Optional.ofNullable(map.get(option)); } + public static EnumSet newEmptySet() { + return EnumSet.noneOf(LintCategory.class); + } + + /** Get the string representing this category in @SuppressAnnotations and -Xlint options. */ public final String option; } @@ -404,82 +426,64 @@ public void logIfEnabled(Log log, DiagnosticPosition pos, LintWarning warning) { } } - protected static class AugmentVisitor implements Attribute.Visitor { - private final Context context; - private Symtab syms; - private Lint parent; - private Lint lint; - - AugmentVisitor(Context context) { - // to break an ugly sequence of initialization dependencies, - // we defer the initialization of syms until it is needed - this.context = context; - } - - Lint augment(Lint parent, Attribute.Compound attr) { - initSyms(); - this.parent = parent; - lint = null; - attr.accept(this); - return (lint == null ? parent : lint); - } - - Lint augment(Lint parent, List attrs) { - initSyms(); - this.parent = parent; - lint = null; - for (Attribute.Compound a: attrs) { - a.accept(this); - } - return (lint == null ? parent : lint); - } - - private void initSyms() { - if (syms == null) - syms = Symtab.instance(context); - } - - private void suppress(LintCategory lc) { - if (lint == null) - lint = new Lint(parent); - lint.suppressedValues.add(lc); - lint.values.remove(lc); - } - - public void visitConstant(Attribute.Constant value) { - if (value.type.tsym == syms.stringType.tsym) { - LintCategory.get((String)value.value) - .ifPresent(this::suppress); - } - } - - public void visitClass(Attribute.Class clazz) { - } - - // If we find a @SuppressWarnings annotation, then we continue - // walking the tree, in order to suppress the individual warnings - // specified in the @SuppressWarnings annotation. - public void visitCompound(Attribute.Compound compound) { - if (compound.type.tsym == syms.suppressWarningsType.tsym) { - for (List> v = compound.values; - v.nonEmpty(); v = v.tail) { - Pair value = v.head; - if (value.fst.name.toString().equals("value")) - value.snd.accept(this); - } + /** + * Obtain the set of recognized lint warning categories suppressed at the given symbol's declaration. + * + *

    + * This set can be non-empty only if the symbol is annotated with either + * @SuppressWarnings or @Deprecated. + * + * @param symbol symbol corresponding to a possibly-annotated declaration + * @return new warning suppressions applied to sym + */ + public EnumSet suppressionsFrom(Symbol symbol) { + EnumSet suppressions = suppressionsFrom(symbol.getDeclarationAttributes().stream()); + if (symbol.isDeprecated() && symbol.isDeprecatableViaAnnotation()) + suppressions.add(LintCategory.DEPRECATION); + return suppressions; + } - } - } + /** + * Retrieve the recognized lint categories suppressed by the given @SuppressWarnings annotation. + * + * @param annotation @SuppressWarnings annotation, or null + * @return set of lint categories, possibly empty but never null + */ + private EnumSet suppressionsFrom(JCAnnotation annotation) { + initializeIfNeeded(); + if (annotation == null) + return LintCategory.newEmptySet(); + Assert.check(annotation.attribute.type.tsym == syms.suppressWarningsType.tsym); + return suppressionsFrom(Stream.of(annotation).map(anno -> anno.attribute)); + } - public void visitArray(Attribute.Array array) { - for (Attribute value : array.values) - value.accept(this); - } + // Find the @SuppressWarnings annotation in the given stream and extract the recognized suppressions + private EnumSet suppressionsFrom(Stream attributes) { + initializeIfNeeded(); + EnumSet result = LintCategory.newEmptySet(); + attributes + .filter(attribute -> attribute.type.tsym == syms.suppressWarningsType.tsym) + .map(this::suppressionsFrom) + .forEach(result::addAll); + return result; + } - public void visitEnum(Attribute.Enum e) { + // Given a @SuppressWarnings annotation, extract the recognized suppressions + private EnumSet suppressionsFrom(Attribute.Compound suppressWarnings) { + EnumSet result = LintCategory.newEmptySet(); + Attribute.Array values = (Attribute.Array)suppressWarnings.member(names.value); + for (Attribute value : values.values) { + Optional.of((String)((Attribute.Constant)value).value) + .flatMap(LintCategory::get) + .ifPresent(result::add); } + return result; + } - public void visitError(Attribute.Error e) { + private void initializeIfNeeded() { + if (syms == null) { + syms = Symtab.instance(context); + names = Names.instance(context); } } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java index a5b4186659bf4..a76dab2bb31cf 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -2945,11 +2945,19 @@ boolean potentiallyAmbiguousOverload(Type site, MethodSymbol msym1, MethodSymbol return potentiallyAmbiguous; } + // Apply special flag "-XDwarnOnAccessToMembers" which turns on just this particular warning for all types of access void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) { - if (warnOnAnyAccessToMembers || - (lint.isEnabled(LintCategory.SERIAL) && - !lint.isSuppressed(LintCategory.SERIAL) && - isLambda)) { + final Lint prevLint = setLint(warnOnAnyAccessToMembers ? lint.enable(LintCategory.SERIAL) : lint); + try { + if (warnOnAnyAccessToMembers || isLambda) + checkAccessFromSerializableElementInner(tree, isLambda); + } finally { + setLint(prevLint); + } + } + + private void checkAccessFromSerializableElementInner(final JCTree tree, boolean isLambda) { + if (lint.isEnabled(LintCategory.SERIAL)) { Symbol sym = TreeInfo.symbol(tree); if (!sym.kind.matches(KindSelector.VAL_MTH)) { return; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java index 646db6a6bf333..4a5370f7a1495 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, 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 @@ -53,6 +53,7 @@ import javax.tools.JavaFileObject; import javax.tools.JavaFileObject.Kind; +import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.main.Option; import com.sun.tools.javac.main.OptionHelper; import com.sun.tools.javac.main.OptionHelper.GrumpyHelper; @@ -90,10 +91,13 @@ public void setContext(Context context) { classLoaderClass = options.get("procloader"); // Detect Lint options, but use Options.isLintSet() to avoid initializing the Lint class - boolean warn = options.isLintSet("path"); + boolean warn = options.isLintSet(LintCategory.PATH.option); + boolean fileClashOption = options.isLintSet(LintCategory.OUTPUT_FILE_CLASH.option); locations.update(log, warn, FSInfo.instance(context)); + + // Only track file clashes if enabled synchronized (this) { - outputFilesWritten = options.isLintSet("output-file-clash") ? new HashSet<>() : null; + outputFilesWritten = fileClashOption ? new HashSet<>() : null; } // Setting this option is an indication that close() should defer actually closing diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java index b25ca99eb88f7..2cec3549c7a78 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -219,12 +219,12 @@ protected void lexError(DiagnosticFlag flags, int pos, JCDiagnostic.Error key) { } /** - * Report an error at the given position using the provided arguments. + * Report a warning at the given position using the provided arguments. * * @param pos position in input buffer. * @param key error key to report. */ - protected void lexWarning(int pos, JCDiagnostic.Warning key) { + protected void lexWarning(int pos, JCDiagnostic.LintWarning key) { DiagnosticPosition dp = new SimpleDiagnosticPosition(pos) ; log.warning(dp, key); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Warner.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Warner.java index 7b993c1bf1618..3da0be49d332c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Warner.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Warner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -42,8 +42,8 @@ public class Warner { private DiagnosticPosition pos = null; protected boolean warned = false; - private EnumSet nonSilentLintSet = EnumSet.noneOf(LintCategory.class); - private EnumSet silentLintSet = EnumSet.noneOf(LintCategory.class); + private EnumSet nonSilentLintSet = LintCategory.newEmptySet(); + private EnumSet silentLintSet = LintCategory.newEmptySet(); public DiagnosticPosition pos() { return pos; From 12700cb81bdfc006bcd228e43b509b8810af6549 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 6 Jan 2025 15:36:28 +0000 Subject: [PATCH 011/286] 8346264: "Total compile time" counter should include time spent in failing/bailout compiles Reviewed-by: kvn, mli --- src/hotspot/share/compiler/compileBroker.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 30956b6c793bd..67a48cfdd152d 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -2532,6 +2532,11 @@ void CompileBroker::collect_statistics(CompilerThread* thread, elapsedTimer time // C1 and C2 counters are counting both successful and unsuccessful compiles _t_total_compilation.add(time); + // Update compilation times. Used by the implementation of JFR CompilerStatistics + // and java.lang.management.CompilationMXBean. + _perf_total_compilation->inc(time.ticks()); + _peak_compilation_time = MAX2(time.milliseconds(), _peak_compilation_time); + if (!success) { _total_bailout_count++; if (UsePerfData) { @@ -2550,12 +2555,6 @@ void CompileBroker::collect_statistics(CompilerThread* thread, elapsedTimer time _t_invalidated_compilation.add(time); } else { // Compilation succeeded - - // update compilation ticks - used by the implementation of - // java.lang.management.CompilationMXBean - _perf_total_compilation->inc(time.ticks()); - _peak_compilation_time = time.milliseconds() > _peak_compilation_time ? time.milliseconds() : _peak_compilation_time; - if (CITime) { int bytes_compiled = method->code_size() + task->num_inlined_bytecodes(); if (is_osr) { From 9a60f4457bb56d0f5039a97e6b943e62a8a2c3ee Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Mon, 6 Jan 2025 17:04:07 +0000 Subject: [PATCH 012/286] 8345668: ZoneOffset.ofTotalSeconds performance regression Reviewed-by: rriggs, aturbanov --- .../share/classes/java/time/ZoneOffset.java | 16 +++++++++++----- .../java/time/format/DateTimeTextProvider.java | 12 ++++++++++-- .../classes/java/time/format/DecimalStyle.java | 12 ++++++++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/java.base/share/classes/java/time/ZoneOffset.java b/src/java.base/share/classes/java/time/ZoneOffset.java index 14ac5fcfb6ba1..520a0e0b9a194 100644 --- a/src/java.base/share/classes/java/time/ZoneOffset.java +++ b/src/java.base/share/classes/java/time/ZoneOffset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -424,11 +424,17 @@ public static ZoneOffset ofTotalSeconds(int totalSeconds) { throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00"); } if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) { - return SECONDS_CACHE.computeIfAbsent(totalSeconds, totalSecs -> { - ZoneOffset result = new ZoneOffset(totalSecs); + Integer totalSecs = totalSeconds; + ZoneOffset result = SECONDS_CACHE.get(totalSecs); + if (result == null) { + result = new ZoneOffset(totalSeconds); + var existing = SECONDS_CACHE.putIfAbsent(totalSecs, result); + if (existing != null) { + result = existing; + } ID_CACHE.putIfAbsent(result.getId(), result); - return result; - }); + } + return result; } else { return new ZoneOffset(totalSeconds); } diff --git a/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java b/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java index 5ee4c5c23c816..5be33551c707a 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java +++ b/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -309,7 +309,15 @@ public Iterator> getTextIterator(Chronology chrono, Temporal private Object findStore(TemporalField field, Locale locale) { Entry key = createEntry(field, locale); - return CACHE.computeIfAbsent(key, e -> createStore(e.getKey(), e.getValue())); + Object store = CACHE.get(key); + if (store == null) { + store = createStore(field, locale); + var existing = CACHE.putIfAbsent(key, store); + if (existing != null) { + store = existing; + } + } + return store; } private static int toWeekDay(int calWeekDay) { diff --git a/src/java.base/share/classes/java/time/format/DecimalStyle.java b/src/java.base/share/classes/java/time/format/DecimalStyle.java index b2513888790ee..a9ad8a4e273e6 100644 --- a/src/java.base/share/classes/java/time/format/DecimalStyle.java +++ b/src/java.base/share/classes/java/time/format/DecimalStyle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -160,7 +160,15 @@ public static DecimalStyle ofDefaultLocale() { */ public static DecimalStyle of(Locale locale) { Objects.requireNonNull(locale, "locale"); - return CACHE.computeIfAbsent(locale, DecimalStyle::create); + DecimalStyle info = CACHE.get(locale); + if (info == null) { + info = create(locale); + var existing = CACHE.putIfAbsent(locale, info); + if (existing != null) { + info = existing; + } + } + return info; } private static DecimalStyle create(Locale locale) { From 9c393a243d6678b8435178a141b38b444b348580 Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Mon, 6 Jan 2025 17:24:23 +0000 Subject: [PATCH 013/286] 8346953: Remove unnecessary @SuppressWarnings annotations (client, #2) Reviewed-by: azvegint --- .../com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java | 5 +---- .../unix/classes/sun/awt/X11/XComponentPeer.java | 4 +--- .../unix/classes/sun/awt/X11/XFileDialogPeer.java | 4 +--- src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java | 3 +-- .../unix/classes/sun/awt/X11/XMouseInfoPeer.java | 3 +-- .../unix/classes/sun/awt/X11/XWindowPeer.java | 3 +-- .../sun/java/swing/plaf/windows/WindowsFileChooserUI.java | 8 +------- .../swing/plaf/windows/WindowsInternalFrameTitlePane.java | 3 +-- .../windows/classes/sun/awt/windows/WDialogPeer.java | 3 +-- 9 files changed, 9 insertions(+), 27 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java index 79c86de16c6f6..19d77115025c2 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, 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 @@ -621,7 +621,6 @@ public void installComponents(JFileChooser fc) { fc.add(interior, BorderLayout.CENTER); - @SuppressWarnings("serial") // anonymous class JPanel comboBoxPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0) { public void layoutContainer(Container target) { @@ -733,7 +732,6 @@ public void layoutContainer(Container target) { if (currentDirectory != null) { curDirName = currentDirectory.getPath(); } - @SuppressWarnings("serial") // anonymous class JLabel tmp = new JLabel(curDirName) { public Dimension getMaximumSize() { Dimension d = super.getMaximumSize(); @@ -748,7 +746,6 @@ public Dimension getMaximumSize() { interior.add(pathFieldPanel); // add the fileName field - @SuppressWarnings("serial") // anonymous class JTextField tmp2 = new JTextField() { public Dimension getMaximumSize() { Dimension d = super.getMaximumSize(); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java index 79d6965e05f62..42e684bfac781 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, 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 @@ -168,7 +168,6 @@ public boolean isReparentSupported() { return System.getProperty("sun.awt.X11.XComponentPeer.reparentNotSupported", "false").equals("false"); } - @SuppressWarnings("deprecation") public boolean isObscured() { Container container = (target instanceof Container) ? (Container)target : target.getParent(); @@ -244,7 +243,6 @@ static final AWTEvent wrapInSequenced(AWTEvent event) { } // TODO: consider moving it to KeyboardFocusManagerPeerImpl - @SuppressWarnings("deprecation") public final boolean requestFocus(Component lightweightChild, boolean temporary, boolean focusedWindowChangeAllowed, long time, FocusEvent.Cause cause) diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java index 98caf9f43cf78..5c6fde2251cdb 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -197,7 +197,6 @@ private void init(FileDialog target) { // After showing we should display 'user.dir' as current directory // if user didn't set directory programmatically pathField = new TextField(savedDir != null ? savedDir : userDir); - @SuppressWarnings("serial") // Anonymous class Choice tmp = new Choice() { public Dimension getPreferredSize() { return new Dimension(PATH_CHOICE_WIDTH, pathField.getPreferredSize().height); @@ -778,7 +777,6 @@ public void dispose() { } // 03/02/2005 b5097243 Pressing 'ESC' on a file dlg does not dispose the dlg on Xtoolkit - @SuppressWarnings("deprecation") public void setVisible(boolean b){ if (fileDialog == null) { init(target); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java index c7f3ba95bc16d..acbe8639702cc 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, 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 @@ -137,7 +137,6 @@ void setupState(boolean onInit) { setExtendedState(state); } - @SuppressWarnings("deprecation") public void setMenuBar(MenuBar mb) { // state_lock should always be the second after awt_lock XToolkit.awtLock(); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java index f4c46c2766d38..321cb4fbf1ec6 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -83,7 +83,6 @@ public int fillPointWithCoords(Point point) { return 0; } - @SuppressWarnings("deprecation") public boolean isWindowUnderMouse(Window w) { if (w == null) { return false; diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java index a37e82d227393..cda05e0a6c729 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, 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 @@ -214,7 +214,6 @@ protected String getWMName() { private static native String getLocalHostname(); private static native int getJvmPID(); - @SuppressWarnings("deprecation") void postInit(XCreateWindowParams params) { super.postInit(params); diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java index 41fa0c3f048a4..7065e3db19ba6 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -273,7 +273,6 @@ public void installComponents(JFileChooser fc) { fc.add(topPanel, BorderLayout.NORTH); // ComboBox Label - @SuppressWarnings("serial") // anonymous class JLabel tmp1 = new JLabel(lookInLabelText, JLabel.TRAILING) { public Dimension getPreferredSize() { return getMinimumSize(); @@ -295,7 +294,6 @@ public Dimension getMinimumSize() { topPanel.add(Box.createRigidArea(new Dimension(8,0))); // CurrentDir ComboBox - @SuppressWarnings("serial") // anonymous class JComboBox tmp2 = new JComboBox() { public Dimension getMinimumSize() { Dimension d = super.getMinimumSize(); @@ -477,7 +475,6 @@ public void propertyChange(PropertyChangeEvent e) { fileAndFilterPanel.add(Box.createRigidArea(vstrut8)); fileAndFilterPanel.setLayout(new BoxLayout(fileAndFilterPanel, BoxLayout.Y_AXIS)); - @SuppressWarnings("serial") // anonymous class JTextField tmp3 = new JTextField(35) { public Dimension getMaximumSize() { return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height); @@ -518,7 +515,6 @@ public void focusGained(FocusEvent e) { // buttons getButtonPanel().setLayout(new BoxLayout(getButtonPanel(), BoxLayout.Y_AXIS)); - @SuppressWarnings("serial") // anonymous class JButton tmp4 = new JButton(getApproveButtonText(fc)) { public Dimension getMaximumSize() { return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ? @@ -537,7 +533,6 @@ public Dimension getMaximumSize() { getButtonPanel().add(approveButton); getButtonPanel().add(Box.createRigidArea(vstrut4)); - @SuppressWarnings("serial") // anonymous class JButton tmp5 = new JButton(cancelButtonText) { public Dimension getMaximumSize() { return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ? @@ -974,7 +969,6 @@ protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser return new DirectoryComboBoxRenderer(); } - @SuppressWarnings("serial") // anonymous class private static JButton createToolButton(Action a, Icon defaultIcon, String toolTipText, String accessibleName) { final JButton result = new JButton(a); diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java index cd0987a907991..083563b4464df 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, 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 @@ -289,7 +289,6 @@ protected void assembleSystemMenu() { systemPopupMenu = new JPopupMenu(); addSystemMenuItems(systemPopupMenu); enableActions(); - @SuppressWarnings("serial") // anonymous class JLabel tmp = new JLabel(frame.getFrameIcon()) { protected void paintComponent(Graphics g) { int x = 0; diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java index 930064d598120..a02bceae7fbf9 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, 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 @@ -94,7 +94,6 @@ protected void realShow() { } @Override - @SuppressWarnings("deprecation") void hide() { Dialog dlg = (Dialog)target; if (dlg.getModalityType() != Dialog.ModalityType.MODELESS) { From d723597dd953c3fb7c3ae04a1c6cce7e10869406 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Mon, 6 Jan 2025 17:47:10 +0000 Subject: [PATCH 014/286] 8345432: (ch, fs) Replace anonymous Thread with InnocuousThread Reviewed-by: alanb --- .../share/classes/sun/nio/ch/ThreadPool.java | 2 +- .../share/classes/sun/nio/fs/AbstractPoller.java | 9 +++------ .../share/classes/sun/nio/fs/Cancellable.java | 11 ++++++----- .../share/classes/sun/nio/fs/PollingWatchService.java | 3 ++- .../windows/classes/sun/nio/ch/PipeImpl.java | 2 +- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/java.base/share/classes/sun/nio/ch/ThreadPool.java b/src/java.base/share/classes/sun/nio/ch/ThreadPool.java index 92aee3238235c..38a49567c1566 100644 --- a/src/java.base/share/classes/sun/nio/ch/ThreadPool.java +++ b/src/java.base/share/classes/sun/nio/ch/ThreadPool.java @@ -70,7 +70,7 @@ int poolSize() { static ThreadFactory defaultThreadFactory() { return (Runnable r) -> { - Thread t = new Thread(r); + Thread t = InnocuousThread.newThread(r); t.setDaemon(true); return t; }; diff --git a/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java b/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java index e2ac950f01dc6..29c0722398891 100644 --- a/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java +++ b/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java @@ -25,9 +25,10 @@ package sun.nio.fs; -import java.nio.file.*; import java.io.IOException; +import java.nio.file.*; import java.util.*; +import jdk.internal.misc.InnocuousThread; /** * Base implementation of background poller thread used in watch service @@ -53,11 +54,7 @@ protected AbstractPoller() { * Starts the poller thread */ public void start() { - Thread thr = new Thread(null, - this, - "FileSystemWatchService", - 0, - false); + Thread thr = InnocuousThread.newThread("FileSystemWatchService", this); thr.setDaemon(true); thr.start(); } diff --git a/src/java.base/share/classes/sun/nio/fs/Cancellable.java b/src/java.base/share/classes/sun/nio/fs/Cancellable.java index 5e3ff43a7b0aa..df3c95abcc936 100644 --- a/src/java.base/share/classes/sun/nio/fs/Cancellable.java +++ b/src/java.base/share/classes/sun/nio/fs/Cancellable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -25,14 +25,15 @@ package sun.nio.fs; -import jdk.internal.misc.Unsafe; import java.util.concurrent.ExecutionException; +import jdk.internal.misc.InnocuousThread; +import jdk.internal.misc.Unsafe; /** * Base implementation of a task (typically native) that polls a memory location * during execution so that it may be aborted/cancelled before completion. The - * task is executed by invoking the {@link runInterruptibly} method defined - * here and cancelled by invoking Thread.interrupt. + * task is executed by invoking the {@linkplain #runInterruptibly} method + * defined here and cancelled by invoking Thread.interrupt. */ abstract class Cancellable implements Runnable { @@ -117,7 +118,7 @@ public final void run() { * thread by writing into the memory location that it polls cooperatively. */ static void runInterruptibly(Cancellable task) throws ExecutionException { - Thread t = new Thread(null, task, "NIO-Task", 0, false); + Thread t = InnocuousThread.newThread("CancellableOp", task); t.start(); boolean cancelledByInterrupt = false; while (t.isAlive()) { diff --git a/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java b/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java index 0284156ca3ba1..da486231a1da8 100644 --- a/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java +++ b/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java @@ -47,6 +47,7 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import jdk.internal.misc.InnocuousThread; import static java.nio.file.LinkOption.NOFOLLOW_LINKS; /** @@ -73,7 +74,7 @@ class PollingWatchService .newSingleThreadScheduledExecutor(new ThreadFactory() { @Override public Thread newThread(Runnable r) { - Thread t = new Thread(null, r, "FileSystemWatcher", 0, false); + Thread t = InnocuousThread.newThread("FileSystemWatcher", r); t.setDaemon(true); return t; }}); diff --git a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java index 7e138a5cc1194..1e4b6a05ce153 100644 --- a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java @@ -78,7 +78,7 @@ public void init() throws IOException { connector.run(); if (ioe instanceof ClosedByInterruptException) { ioe = null; - Thread connThread = new Thread(connector) { + Thread connThread = new Thread(connector, "LoopbackConnector") { @Override public void interrupt() {} }; From 8d388ccd9eae279018bf499e49152fd276aab5bf Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Mon, 6 Jan 2025 17:59:10 +0000 Subject: [PATCH 015/286] 8346457: AOT cache creation crashes with "assert(pair_at(i).match() < pair_at(i+1).match()) failed: unsorted table entries" Reviewed-by: iklam, dholmes --- src/hotspot/share/cds/metaspaceShared.cpp | 4 +- .../cds/appcds/CreateAOTCacheVerifyError.java | 49 ++++++++ .../appcds/test-classes/BadLookupSwitch.jcod | 118 ++++++++++++++++++ 3 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/CreateAOTCacheVerifyError.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/test-classes/BadLookupSwitch.jcod diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index 753160e7ec126..bd2f05080222f 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -987,8 +987,10 @@ bool MetaspaceShared::try_link_class(JavaThread* current, InstanceKlass* ik) { ik->external_name()); CLEAR_PENDING_EXCEPTION; SystemDictionaryShared::set_class_has_failed_verification(ik); + } else { + assert(!SystemDictionaryShared::has_class_failed_verification(ik), "sanity"); + ik->compute_has_loops_flag_for_methods(); } - ik->compute_has_loops_flag_for_methods(); BytecodeVerificationLocal = saved; return true; } else { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/CreateAOTCacheVerifyError.java b/test/hotspot/jtreg/runtime/cds/appcds/CreateAOTCacheVerifyError.java new file mode 100644 index 0000000000000..c478fad7cc2e6 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/CreateAOTCacheVerifyError.java @@ -0,0 +1,49 @@ +/* + * 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 8346457 + * @summary VM should not crash during AOT cache creation when encountering a + * class with VerifyError. + * @requires vm.cds + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes + * @compile test-classes/BadLookupSwitch.jcod + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar badlookupswitch.jar BadLookupSwitch + * @run driver CreateAOTCacheVerifyError + */ + +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; + +public class CreateAOTCacheVerifyError { + + public static void main(String[] args) throws Exception { + String appJar = ClassFileInstaller.getJarPath("badlookupswitch.jar"); + String classList[] = { BadLookupSwitch.class.getName() }; + OutputAnalyzer out = TestCommon.testDump(appJar, classList); + out.shouldContain("Preload Warning: Verification failed for BadLookupSwitch"); + out.shouldHaveExitValue(0); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/BadLookupSwitch.jcod b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/BadLookupSwitch.jcod new file mode 100644 index 0000000000000..4912479a8aa8a --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/BadLookupSwitch.jcod @@ -0,0 +1,118 @@ +/* + * 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. + * + */ + +class BadLookupSwitch { + 0xCAFEBABE; + 0; + 50; + [] { // Constant Pool + ; // first element is empty + class #12; // #1 at 0x0A + class #15; // #2 at 0x0D + Method #2 #4; // #3 at 0x10 + NameAndType #6 #5; // #4 at 0x15 + Utf8 "()V"; // #5 at 0x1A + Utf8 ""; // #6 at 0x20 + Utf8 "Code"; // #7 at 0x29 + Utf8 "ConstantValue"; // #8 at 0x30 + Utf8 "Exceptions"; // #9 at 0x40 + Utf8 "LineNumberTable"; // #10 at 0x4D + Utf8 "LocalVariables"; // #11 at 0x5F + Utf8 "BadLookupSwitch"; // #12 at 0x70 + Utf8 "SourceFile"; // #13 at 0x76 + Utf8 "f.java"; // #14 at 0x83 + Utf8 "java/lang/Object"; // #15 at 0x8C + Utf8 "m"; // #16 at 0x9F + Utf8 "StackMapTable"; // #17 + } // Constant Pool + + 0x0020; // access + #1;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [2] { // methods + { // Member at 0xAF + 0x0001; // access + #16; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#7) { // Code at 0xB7 + 1; // max_stack + 1; // max_locals + Bytes[29] { + 0x04AB00000000001B; // iconst_1; +/* right: + 0x0000000200000001; // lookupswitch 27 2 1 27 2 27; + 0x0000001B00000002; + 0x0000001B; +end right */ +// wrong: + 0x0000000200000002; // lookupswitch 27 2 2 27 1 27; + 0x0000001B00000001; + 0x0000001B; +// end wrong + 0xB1; // return + }; + [0] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // StackMap + [] { // + 255b, 28, []{O,1}, []{}; + } + } // end StackMap + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0xD6 + 0x0000; // access + #6; // name_cpx + #5; // sig_cpx + [1] { // Attributes + Attr(#7) { // Code at 0xDE + 1; // max_stack + 1; // max_locals + Bytes[5] { + 0x2AB70003B1; + }; + [0] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + } // Attributes +} // end class From 27646e551686ec02740600fc73694fc2fbd00a88 Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Mon, 6 Jan 2025 18:37:19 +0000 Subject: [PATCH 016/286] 8344148: Add an explicit compiler phase for warning generation Reviewed-by: vromero --- .../sun/tools/javac/comp/CompileStates.java | 13 ++-- .../com/sun/tools/javac/comp/Flow.java | 3 +- .../tools/javac/comp/ThisEscapeAnalyzer.java | 57 ++++++++++++--- .../com/sun/tools/javac/comp/TransTypes.java | 8 +-- .../sun/tools/javac/comp/WarningAnalyzer.java | 63 ++++++++++++++++ .../sun/tools/javac/main/JavaCompiler.java | 71 +++++++++++++++++-- .../tools/javac/6734819/T6734819a.out | 3 + .../tools/javac/6734819/T6734819b.out | 2 + .../tools/javac/6734819/T6734819c.out | 2 + .../SkipAttrFlowGenForImplicits.out | 1 + .../tools/javac/policy/test1/byfile.ABD.out | 3 + .../tools/javac/policy/test1/byfile.ACD.out | 3 + .../tools/javac/policy/test1/bytodo.ABD.out | 4 ++ .../tools/javac/policy/test1/bytodo.ACD.out | 4 ++ .../tools/javac/policy/test2/byfile.AB.out | 2 + .../tools/javac/policy/test2/byfile.BA.out | 2 + .../tools/javac/policy/test2/bytodo.AB.out | 2 + .../tools/javac/policy/test2/bytodo.BA.out | 2 + .../tools/javac/recovery/AttrRecovery.java | 4 +- 19 files changed, 219 insertions(+), 30 deletions(-) create mode 100644 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/WarningAnalyzer.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java index b9cab47d8ab52..4896ecbe72806 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -58,11 +58,12 @@ public enum CompileState { PROCESS(3), ATTR(4), FLOW(5), - TRANSTYPES(6), - TRANSPATTERNS(7), - LOWER(8), - UNLAMBDA(9), - GENERATE(10); + WARN(6), + TRANSTYPES(7), + TRANSPATTERNS(8), + LOWER(9), + UNLAMBDA(10), + GENERATE(11); CompileState(int value) { this.value = value; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index 175cceeeb7faf..b0b79104def3a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -229,7 +229,6 @@ public void analyzeTree(Env env, TreeMaker make) { new AssignAnalyzer().analyzeTree(env, make); new FlowAnalyzer().analyzeTree(env, make); new CaptureAnalyzer().analyzeTree(env, make); - new ThisEscapeAnalyzer(names, syms, types, rs, log, lint).analyzeTree(env); } public void analyzeLambda(Env env, JCLambda that, TreeMaker make, boolean speculative) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index e1bf92a7f7ba7..77ddd5c65833e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -58,6 +58,7 @@ import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; @@ -140,8 +141,17 @@ *

  • We assume that native methods do not leak. *
  • We don't try to follow {@code super()} invocations; that's for the superclass analysis to handle. * + * + *

    This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ -class ThisEscapeAnalyzer extends TreeScanner { +public class ThisEscapeAnalyzer extends TreeScanner { + + protected static final Context.Key contextKey = new Context.Key<>(); + +// Other singletons we utilize private final Names names; private final Symtab syms; @@ -211,15 +221,24 @@ class ThisEscapeAnalyzer extends TreeScanner { */ private RefSet refs; -// Constructor +// Access - ThisEscapeAnalyzer(Names names, Symtab syms, Types types, Resolve rs, Log log, Lint lint) { - this.names = names; - this.syms = syms; - this.types = types; - this.rs = rs; - this.log = log; - this.lint = lint; + public static ThisEscapeAnalyzer instance(Context context) { + ThisEscapeAnalyzer instance = context.get(contextKey); + if (instance == null) + instance = new ThisEscapeAnalyzer(context); + return instance; + } + + @SuppressWarnings("this-escape") + protected ThisEscapeAnalyzer(Context context) { + context.put(contextKey, this); + names = Names.instance(context); + log = Log.instance(context); + syms = Symtab.instance(context); + types = Types.instance(context); + rs = Resolve.instance(context); + lint = Lint.instance(context); } // @@ -227,6 +246,24 @@ class ThisEscapeAnalyzer extends TreeScanner { // public void analyzeTree(Env env) { + try { + doAnalyzeTree(env); + } finally { + attrEnv = null; + methodMap.clear(); + nonPublicOuters.clear(); + targetClass = null; + warningList.clear(); + methodClass = null; + callStack.clear(); + invocations.clear(); + pendingWarning = null; + depth = -1; + refs = null; + } + } + + private void doAnalyzeTree(Env env) { // Sanity check Assert.check(checkInvariants(false, false)); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java index a0b1ef27255f2..fe4d3d62f3b39 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -1168,7 +1168,7 @@ private Type erasure(Type t) { private Env env; private static final String statePreviousToFlowAssertMsg = - "The current compile state [%s] of class %s is previous to FLOW"; + "The current compile state [%s] of class %s is previous to WARN"; void translateClass(ClassSymbol c) { Type st = types.supertype(c.type); @@ -1189,7 +1189,7 @@ void translateClass(ClassSymbol c) { * 1) has no compile state being it the most outer class. * We accept this condition for inner classes. * - * 2) has a compile state which is previous to Flow state. + * 2) has a compile state which is previous to WARN state. */ boolean envHasCompState = compileStates.get(myEnv) != null; if (!envHasCompState && c.outermostClass() == c) { @@ -1197,7 +1197,7 @@ void translateClass(ClassSymbol c) { } if (envHasCompState && - CompileState.FLOW.isAfter(compileStates.get(myEnv))) { + CompileState.WARN.isAfter(compileStates.get(myEnv))) { Assert.error(String.format(statePreviousToFlowAssertMsg, compileStates.get(myEnv), myEnv.enclClass.sym)); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/WarningAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/WarningAnalyzer.java new file mode 100644 index 0000000000000..00d1de386dbc3 --- /dev/null +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/WarningAnalyzer.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025, 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 com.sun.tools.javac.comp; + +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; + +/** This pass checks for various things to warn about. + * It runs after attribution and flow analysis. + * + *

    This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class WarningAnalyzer { + + protected static final Context.Key contextKey = new Context.Key<>(); + + private final Log log; + private final ThisEscapeAnalyzer thisEscapeAnalyzer; + + public static WarningAnalyzer instance(Context context) { + WarningAnalyzer instance = context.get(contextKey); + if (instance == null) + instance = new WarningAnalyzer(context); + return instance; + } + + @SuppressWarnings("this-escape") + protected WarningAnalyzer(Context context) { + context.put(contextKey, this); + log = Log.instance(context); + thisEscapeAnalyzer = ThisEscapeAnalyzer.instance(context); + } + + public void analyzeTree(Env env) { + thisEscapeAnalyzer.analyzeTree(env); + } +} diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 96cf4049533d4..05efcf7c04112 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -306,6 +306,10 @@ else if (option.equals("class")) */ protected Flow flow; + /** The warning analyzer. + */ + protected WarningAnalyzer warningAnalyzer; + /** The modules visitor */ protected Modules modules; @@ -419,6 +423,7 @@ public JavaCompiler(Context context) { chk = Check.instance(context); gen = Gen.instance(context); flow = Flow.instance(context); + warningAnalyzer = WarningAnalyzer.instance(context); transTypes = TransTypes.instance(context); lower = Lower.instance(context); annotate = Annotate.instance(context); @@ -962,20 +967,20 @@ public void compile(Collection sourceFileObjects, if (!CompileState.ATTR.isAfter(shouldStopPolicyIfNoError)) { switch (compilePolicy) { case SIMPLE: - generate(desugar(flow(attribute(todo)))); + generate(desugar(warn(flow(attribute(todo))))); break; case BY_FILE: { Queue>> q = todo.groupByFile(); while (!q.isEmpty() && !shouldStop(CompileState.ATTR)) { - generate(desugar(flow(attribute(q.remove())))); + generate(desugar(warn(flow(attribute(q.remove()))))); } } break; case BY_TODO: while (!todo.isEmpty()) - generate(desugar(flow(attribute(todo.remove())))); + generate(desugar(warn(flow(attribute(todo.remove()))))); break; default: @@ -1435,6 +1440,56 @@ protected void flow(Env env, Queue> results) { } } + /** + * Check for various things to warn about. + * + * @return the list of attributed parse trees + */ + public Queue> warn(Queue> envs) { + ListBuffer> results = new ListBuffer<>(); + for (Env env: envs) { + warn(env, results); + } + return stopIfError(CompileState.WARN, results); + } + + /** + * Check for various things to warn about in an attributed parse tree. + */ + public Queue> warn(Env env) { + ListBuffer> results = new ListBuffer<>(); + warn(env, results); + return stopIfError(CompileState.WARN, results); + } + + /** + * Check for various things to warn about in an attributed parse tree. + */ + protected void warn(Env env, Queue> results) { + if (compileStates.isDone(env, CompileState.WARN)) { + results.add(env); + return; + } + + if (shouldStop(CompileState.WARN)) + return; + + if (verboseCompilePolicy) + printNote("[warn " + env.enclClass.sym + "]"); + JavaFileObject prev = log.useSource( + env.enclClass.sym.sourcefile != null ? + env.enclClass.sym.sourcefile : + env.toplevel.sourcefile); + try { + warningAnalyzer.analyzeTree(env); + compileStates.put(env, CompileState.WARN); + results.add(env); + } + finally { + log.useSource(prev); + } + } + private TaskEvent newAnalyzeTaskEvent(Env env) { JCCompilationUnit toplevel = env.toplevel; ClassSymbol sym; @@ -1493,6 +1548,10 @@ protected void desugar(final Env env, Queue, return; } + // Ensure the file has reached the WARN state + if (!compileStates.isDone(env, CompileState.WARN)) + warn(env); + /** * Ensure that superclasses of C are desugared before C itself. This is * required for two reasons: (i) as erasure (TransTypes) destroys @@ -1576,8 +1635,8 @@ public void visitSwitchExpression(JCSwitchExpression tree) { ScanNested scanner = new ScanNested(); scanner.scan(env.tree); for (Env dep: scanner.dependencies) { - if (!compileStates.isDone(dep, CompileState.FLOW)) - desugaredEnvs.put(dep, desugar(flow(attribute(dep)))); + if (!compileStates.isDone(dep, CompileState.WARN)) + desugaredEnvs.put(dep, desugar(warn(flow(attribute(dep))))); } //We need to check for error another time as more classes might diff --git a/test/langtools/tools/javac/6734819/T6734819a.out b/test/langtools/tools/javac/6734819/T6734819a.out index a3ccb07e67e0a..c29dbde637b29 100644 --- a/test/langtools/tools/javac/6734819/T6734819a.out +++ b/test/langtools/tools/javac/6734819/T6734819a.out @@ -1,9 +1,12 @@ [attribute Y] [flow Y] +[warn Y] [attribute W] [flow W] +[warn W] [attribute Z] [flow Z] +[warn Z] [desugar Z] [desugar W] [desugar Y] diff --git a/test/langtools/tools/javac/6734819/T6734819b.out b/test/langtools/tools/javac/6734819/T6734819b.out index 0c9629006df19..61c1f31f179b6 100644 --- a/test/langtools/tools/javac/6734819/T6734819b.out +++ b/test/langtools/tools/javac/6734819/T6734819b.out @@ -1,7 +1,9 @@ [attribute A] [flow A] +[warn A] [attribute B] [flow B] +[warn B] [desugar B] [desugar A] [generate code A] diff --git a/test/langtools/tools/javac/6734819/T6734819c.out b/test/langtools/tools/javac/6734819/T6734819c.out index 1d4cff3212fd8..6ae56176acba4 100644 --- a/test/langtools/tools/javac/6734819/T6734819c.out +++ b/test/langtools/tools/javac/6734819/T6734819c.out @@ -1,7 +1,9 @@ [attribute Y] [flow Y] +[warn Y] [attribute W] [flow W] +[warn W] [attribute Z] [flow Z] T6734819c.java:15:11: compiler.err.unreachable.stmt diff --git a/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out b/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out index 11cc81304f034..e240208da72c1 100644 --- a/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out +++ b/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out @@ -1,4 +1,5 @@ [attribute Explicit] [flow Explicit] +[warn Explicit] [desugar Explicit] [generate code Explicit] diff --git a/test/langtools/tools/javac/policy/test1/byfile.ABD.out b/test/langtools/tools/javac/policy/test1/byfile.ABD.out index dfa86a4413294..0710de49c867d 100644 --- a/test/langtools/tools/javac/policy/test1/byfile.ABD.out +++ b/test/langtools/tools/javac/policy/test1/byfile.ABD.out @@ -4,6 +4,9 @@ [flow A] [flow A1] [flow A2] +[warn A] +[warn A1] +[warn A2] [desugar A] [desugar A1] [desugar A2] diff --git a/test/langtools/tools/javac/policy/test1/byfile.ACD.out b/test/langtools/tools/javac/policy/test1/byfile.ACD.out index 66534ce00c5f8..70cc4856557c7 100644 --- a/test/langtools/tools/javac/policy/test1/byfile.ACD.out +++ b/test/langtools/tools/javac/policy/test1/byfile.ACD.out @@ -4,6 +4,9 @@ [flow A] [flow A1] [flow A2] +[warn A] +[warn A1] +[warn A2] [desugar A] [desugar A1] [desugar A2] diff --git a/test/langtools/tools/javac/policy/test1/bytodo.ABD.out b/test/langtools/tools/javac/policy/test1/bytodo.ABD.out index 5b3b8faace742..3296547f0ffec 100644 --- a/test/langtools/tools/javac/policy/test1/bytodo.ABD.out +++ b/test/langtools/tools/javac/policy/test1/bytodo.ABD.out @@ -1,17 +1,21 @@ [attribute A] [flow A] +[warn A] [desugar A] [generate code A] [attribute A1] [flow A1] +[warn A1] [desugar A1] [generate code A1] [attribute A2] [flow A2] +[warn A2] [desugar A2] [generate code A2] [attribute B] [flow B] +[warn B] [desugar B] [generate code B] [attribute B1] diff --git a/test/langtools/tools/javac/policy/test1/bytodo.ACD.out b/test/langtools/tools/javac/policy/test1/bytodo.ACD.out index a29c0880de96c..767a9912a05e8 100644 --- a/test/langtools/tools/javac/policy/test1/bytodo.ACD.out +++ b/test/langtools/tools/javac/policy/test1/bytodo.ACD.out @@ -1,17 +1,21 @@ [attribute A] [flow A] +[warn A] [desugar A] [generate code A] [attribute A1] [flow A1] +[warn A1] [desugar A1] [generate code A1] [attribute A2] [flow A2] +[warn A2] [desugar A2] [generate code A2] [attribute C] [flow C] +[warn C] [desugar C] [generate code C] [attribute C1] diff --git a/test/langtools/tools/javac/policy/test2/byfile.AB.out b/test/langtools/tools/javac/policy/test2/byfile.AB.out index 6d152c873aabe..63a51108f3646 100644 --- a/test/langtools/tools/javac/policy/test2/byfile.AB.out +++ b/test/langtools/tools/javac/policy/test2/byfile.AB.out @@ -1,7 +1,9 @@ [attribute A] [flow A] +[warn A] [attribute B] [flow B] +[warn B] [desugar B] [desugar A] [generate code A.A1] diff --git a/test/langtools/tools/javac/policy/test2/byfile.BA.out b/test/langtools/tools/javac/policy/test2/byfile.BA.out index 565ad13861529..3c3567043a0f1 100644 --- a/test/langtools/tools/javac/policy/test2/byfile.BA.out +++ b/test/langtools/tools/javac/policy/test2/byfile.BA.out @@ -1,10 +1,12 @@ [attribute B] [flow B] +[warn B] [desugar B] [generate code B.Inner] [generate code B] [attribute A] [flow A] +[warn A] [desugar A] [generate code A.A1] [generate code A.A2] diff --git a/test/langtools/tools/javac/policy/test2/bytodo.AB.out b/test/langtools/tools/javac/policy/test2/bytodo.AB.out index 6d152c873aabe..63a51108f3646 100644 --- a/test/langtools/tools/javac/policy/test2/bytodo.AB.out +++ b/test/langtools/tools/javac/policy/test2/bytodo.AB.out @@ -1,7 +1,9 @@ [attribute A] [flow A] +[warn A] [attribute B] [flow B] +[warn B] [desugar B] [desugar A] [generate code A.A1] diff --git a/test/langtools/tools/javac/policy/test2/bytodo.BA.out b/test/langtools/tools/javac/policy/test2/bytodo.BA.out index 565ad13861529..3c3567043a0f1 100644 --- a/test/langtools/tools/javac/policy/test2/bytodo.BA.out +++ b/test/langtools/tools/javac/policy/test2/bytodo.BA.out @@ -1,10 +1,12 @@ [attribute B] [flow B] +[warn B] [desugar B] [generate code B.Inner] [generate code B] [attribute A] [flow A] +[warn A] [desugar A] [generate code A.A1] [generate code A.A2] diff --git a/test/langtools/tools/javac/recovery/AttrRecovery.java b/test/langtools/tools/javac/recovery/AttrRecovery.java index db679915e08b2..c5d393a23b323 100644 --- a/test/langtools/tools/javac/recovery/AttrRecovery.java +++ b/test/langtools/tools/javac/recovery/AttrRecovery.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -115,7 +115,7 @@ public void overridable(C c) {} Path curPath = Path.of("."); List actual = new JavacTask(tb) .options("-XDrawDiagnostics", "-XDdev", - "-XDshould-stop.at=FLOW", "-Xlint:this-escape") + "-XDshould-stop.at=WARN", "-Xlint:this-escape") .sources(code) .outdir(curPath) .run(Expect.FAIL) From de0250368edbf4e9bebf326778f8f8773b69b84c Mon Sep 17 00:00:00 2001 From: Fei Yang Date: Tue, 7 Jan 2025 03:39:50 +0000 Subject: [PATCH 017/286] 8346832: runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java fails on RISC-V Reviewed-by: stuefe, fjiang --- src/hotspot/cpu/riscv/compressedKlass_riscv.cpp | 7 +------ .../CompressedCPUSpecificClassSpaceReservation.java | 11 ++--------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp b/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp index 7e596e0a7e99a..7d5f630d0aa37 100644 --- a/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp +++ b/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp @@ -31,7 +31,7 @@ char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size char* result = nullptr; - // RiscV loads a 64-bit immediate in up to four separate steps, splitting it into four different sections + // RISC-V loads a 64-bit immediate in up to four separate steps, splitting it into four different sections // (two 32-bit sections, each split into two subsections of 20/12 bits). // // 63 ....... 44 43 ... 32 31 ....... 12 11 ... 0 @@ -51,11 +51,6 @@ char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size // with one instruction (2) result = reserve_address_space_for_unscaled_encoding(size, aslr); - // Failing that, attempt to reserve for base=zero shift>0 - if (result == nullptr && optimize_for_zero_base) { - result = reserve_address_space_for_zerobased_encoding(size, aslr); - } - // Failing that, optimize for case (3) - a base with only bits set between [32-44) if (result == nullptr) { const uintptr_t from = nth_bit(32); diff --git a/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java b/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java index 574a680acebfa..48fc6699fa2b8 100644 --- a/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java +++ b/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java @@ -85,15 +85,8 @@ private static void do_test(boolean CDS) throws IOException { output.shouldContain(tryReserveFor16bitMoveIntoQ3); } else if (Platform.isRISCV64()) { output.shouldContain(tryReserveForUnscaled); // unconditionally - if (CDS) { - output.shouldNotContain(tryReserveForZeroBased); - // bits 32..44 - output.shouldContain("reserve_between (range [0x0000000100000000-0x0000100000000000)"); - } else { - output.shouldContain(tryReserveForZeroBased); - // bits 32..44, but not lower than zero-based limit - output.shouldContain("reserve_between (range [0x0000000800000000-0x0000100000000000)"); - } + // bits 32..44 + output.shouldContain("reserve_between (range [0x0000000100000000-0x0000100000000000)"); // bits 44..64 output.shouldContain("reserve_between (range [0x0000100000000000-0xffffffffffffffff)"); } else if (Platform.isS390x()) { From 08debd335e9160d20b87e06a2e83ddedd5f473b8 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Tue, 7 Jan 2025 06:15:48 +0000 Subject: [PATCH 018/286] 8346993: C2 SuperWord: refactor to make more vector nodes available in VectorNode::make Reviewed-by: chagedorn, kvn --- src/hotspot/share/opto/vectornode.cpp | 53 +++++++++++++++------------ src/hotspot/share/opto/vectornode.hpp | 6 ++- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index 33429dfacad0c..e62524b37cd3c 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -666,7 +666,7 @@ VectorNode* VectorNode::make_mask_node(int vopc, Node* n1, Node* n2, uint vlen, } } -// Make a vector node for binary operation +// Make a vector node for unary or binary operation VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, bool is_mask, bool is_var_shift, bool is_unsigned) { // This method should not be called for unimplemented vectors. guarantee(vopc > 0, "vopc must be > 0"); @@ -747,6 +747,9 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, b case Op_URShiftVI: return new URShiftVINode(n1, n2, vt, is_var_shift); case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt, is_var_shift); + case Op_LShiftCntV: return new LShiftCntVNode(n1, vt); + case Op_RShiftCntV: return new RShiftCntVNode(n1, vt); + case Op_AndV: return new AndVNode(n1, n2, vt); case Op_OrV: return new OrVNode (n1, n2, vt); case Op_XorV: return new XorVNode(n1, n2, vt); @@ -766,6 +769,18 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, b case Op_SaturatingAddV: return new SaturatingAddVNode(n1, n2, vt, is_unsigned); case Op_SaturatingSubV: return new SaturatingSubVNode(n1, n2, vt, is_unsigned); + case Op_VectorCastB2X: return new VectorCastB2XNode(n1, vt); + case Op_VectorCastS2X: return new VectorCastS2XNode(n1, vt); + case Op_VectorCastI2X: return new VectorCastI2XNode(n1, vt); + case Op_VectorCastL2X: return new VectorCastL2XNode(n1, vt); + case Op_VectorCastF2X: return new VectorCastF2XNode(n1, vt); + case Op_VectorCastD2X: return new VectorCastD2XNode(n1, vt); + case Op_VectorUCastB2X: return new VectorUCastB2XNode(n1, vt); + case Op_VectorUCastS2X: return new VectorUCastS2XNode(n1, vt); + case Op_VectorUCastI2X: return new VectorUCastI2XNode(n1, vt); + case Op_VectorCastHF2F: return new VectorCastHF2FNode(n1, vt); + case Op_VectorCastF2HF: return new VectorCastF2HFNode(n1, vt); + default: fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); return nullptr; @@ -791,6 +806,7 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, Node* n3, const TypeV case Op_SelectFromTwoVector: return new SelectFromTwoVectorNode(n1, n2, n3, vt); case Op_SignumVD: return new SignumVDNode(n1, n2, n3, vt); case Op_SignumVF: return new SignumVFNode(n1, n2, n3, vt); + case Op_VectorBlend: return new VectorBlendNode(n1, n2, n3); default: fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); return nullptr; @@ -818,22 +834,26 @@ VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, BasicType bt, bool is_ } VectorNode* VectorNode::shift_count(int opc, Node* cnt, uint vlen, BasicType bt) { - // Match shift count type with shift vector type. + int vopc = VectorNode::shift_count_opcode(opc); const TypeVect* vt = TypeVect::make(bt, vlen); + return VectorNode::make(vopc, cnt, nullptr, vt); +} + +int VectorNode::shift_count_opcode(int opc) { switch (opc) { case Op_LShiftI: case Op_LShiftL: - return new LShiftCntVNode(cnt, vt); + return Op_LShiftCntV; case Op_RShiftI: case Op_RShiftL: case Op_URShiftB: case Op_URShiftS: case Op_URShiftI: case Op_URShiftL: - return new RShiftCntVNode(cnt, vt); + return Op_RShiftCntV; default: - fatal("Missed vector creation for '%s'", NodeClassNames[opc]); - return nullptr; + fatal("Node class '%s' is not supported for shift count", NodeClassNames[opc]); + return -1; } } @@ -1412,24 +1432,9 @@ VectorStoreMaskNode* VectorStoreMaskNode::make(PhaseGVN& gvn, Node* in, BasicTyp return new VectorStoreMaskNode(in, gvn.intcon(elem_size), vt); } -VectorCastNode* VectorCastNode::make(int vopc, Node* n1, BasicType bt, uint vlen) { +VectorNode* VectorCastNode::make(int vopc, Node* n1, BasicType bt, uint vlen) { const TypeVect* vt = TypeVect::make(bt, vlen); - switch (vopc) { - case Op_VectorCastB2X: return new VectorCastB2XNode(n1, vt); - case Op_VectorCastS2X: return new VectorCastS2XNode(n1, vt); - case Op_VectorCastI2X: return new VectorCastI2XNode(n1, vt); - case Op_VectorCastL2X: return new VectorCastL2XNode(n1, vt); - case Op_VectorCastF2X: return new VectorCastF2XNode(n1, vt); - case Op_VectorCastD2X: return new VectorCastD2XNode(n1, vt); - case Op_VectorUCastB2X: return new VectorUCastB2XNode(n1, vt); - case Op_VectorUCastS2X: return new VectorUCastS2XNode(n1, vt); - case Op_VectorUCastI2X: return new VectorUCastI2XNode(n1, vt); - case Op_VectorCastHF2F: return new VectorCastHF2FNode(n1, vt); - case Op_VectorCastF2HF: return new VectorCastF2HFNode(n1, vt); - default: - assert(false, "unknown node: %s", NodeClassNames[vopc]); - return nullptr; - } + return VectorNode::make(vopc, n1, nullptr, vt); } int VectorCastNode::opcode(int sopc, BasicType bt, bool is_signed) { diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index f5574ba79e3c5..0bd1c71d7e628 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -95,6 +95,8 @@ class VectorNode : public TypeNode { static int opcode(int sopc, BasicType bt); // scalar_opc -> vector_opc static int scalar_opcode(int vopc, BasicType bt); // vector_opc -> scalar_opc + static int shift_count_opcode(int opc); + // Limits on vector size (number of elements) for auto-vectorization. static bool vector_size_supported_auto_vectorization(const BasicType bt, int size); static bool implemented(int opc, uint vlen, BasicType bt); @@ -1764,7 +1766,7 @@ class VectorCastNode : public VectorNode { VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} virtual int Opcode() const; - static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen); + static VectorNode* make(int vopc, Node* n1, BasicType bt, uint vlen); static int opcode(int opc, BasicType bt, bool is_signed = true); static bool implemented(int opc, uint vlen, BasicType src_type, BasicType dst_type); From 0a81676fae3b25117dd2289a734193bcbee822de Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Tue, 7 Jan 2025 08:10:28 +0000 Subject: [PATCH 019/286] 8346881: [ubsan] logSelection.cpp:154:24 / logSelectionList.cpp:72:94 : runtime error: applying non-zero offset 1 to null pointer Reviewed-by: clanger, mdoerr, dholmes, syan, amitkumar --- src/hotspot/share/logging/logDecorators.cpp | 6 ++++-- src/hotspot/share/logging/logSelection.cpp | 6 ++++-- src/hotspot/share/logging/logSelectionList.cpp | 8 ++++++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/logging/logDecorators.cpp b/src/hotspot/share/logging/logDecorators.cpp index 6c06bd4571627..019c2fcb36ca5 100644 --- a/src/hotspot/share/logging/logDecorators.cpp +++ b/src/hotspot/share/logging/logDecorators.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -100,7 +100,9 @@ bool LogDecorators::parse(const char* decorator_args, outputStream* errstream) { break; } tmp_decorators |= mask(d); - token = comma_pos + 1; + if (comma_pos != nullptr) { + token = comma_pos + 1; + } } while (comma_pos != nullptr); os::free(args_copy); if (result) { diff --git a/src/hotspot/share/logging/logSelection.cpp b/src/hotspot/share/logging/logSelection.cpp index 99ecc9f87f272..f5a0ab1bf533a 100644 --- a/src/hotspot/share/logging/logSelection.cpp +++ b/src/hotspot/share/logging/logSelection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -151,7 +151,9 @@ static LogSelection parse_internal(char *str, outputStream* errstream) { return LogSelection::Invalid; } tags[ntags++] = tag; - cur_tag = plus_pos + 1; + if (plus_pos != nullptr) { + cur_tag = plus_pos + 1; + } } while (plus_pos != nullptr); for (size_t i = 0; i < ntags; i++) { diff --git a/src/hotspot/share/logging/logSelectionList.cpp b/src/hotspot/share/logging/logSelectionList.cpp index ac63f20512c2a..d7e5981aa00c8 100644 --- a/src/hotspot/share/logging/logSelectionList.cpp +++ b/src/hotspot/share/logging/logSelectionList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -69,7 +69,7 @@ bool LogSelectionList::parse(const char* str, outputStream* errstream) { } char* copy = os::strdup_check_oom(str, mtLogging); // Split string on commas - for (char *comma_pos = copy, *cur = copy; success && comma_pos != nullptr; cur = comma_pos + 1) { + for (char *comma_pos = copy, *cur = copy; success; cur = comma_pos + 1) { if (_nselections == MaxSelections) { if (errstream != nullptr) { errstream->print_cr("Can not have more than " SIZE_FORMAT " log selections in a single configuration.", @@ -90,6 +90,10 @@ bool LogSelectionList::parse(const char* str, outputStream* errstream) { break; } _selections[_nselections++] = selection; + + if (comma_pos == nullptr) { + break; + } } os::free(copy); From 0285020c7ea01f32b32efe166a0a5dae39957216 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Tue, 7 Jan 2025 08:15:12 +0000 Subject: [PATCH 020/286] 8345676: [ubsan] ProcessImpl_md.c:561:40: runtime error: applying zero offset to null pointer on macOS aarch64 Reviewed-by: rriggs --- src/java.base/unix/native/libjava/ProcessImpl_md.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/java.base/unix/native/libjava/ProcessImpl_md.c b/src/java.base/unix/native/libjava/ProcessImpl_md.c index 506b33aae9602..5a3a5cd088a6a 100644 --- a/src/java.base/unix/native/libjava/ProcessImpl_md.c +++ b/src/java.base/unix/native/libjava/ProcessImpl_md.c @@ -558,7 +558,9 @@ spawnChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) return -1; } offset = copystrings(buf, 0, &c->argv[0]); - offset = copystrings(buf, offset, &c->envv[0]); + if (c->envv != NULL) { + offset = copystrings(buf, offset, &c->envv[0]); + } if (c->pdir != NULL) { if (sp.dirlen > 0) { memcpy(buf+offset, c->pdir, sp.dirlen); From 379ac349d13e2c0c6986eb0787f33b9a7a2a3749 Mon Sep 17 00:00:00 2001 From: Fei Yang Date: Tue, 7 Jan 2025 10:32:11 +0000 Subject: [PATCH 021/286] 8346838: RISC-V: runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java crash with debug VMs Reviewed-by: fjiang, rehn --- .../riscv/templateInterpreterGenerator_riscv.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index bc67de54c4bc6..5ea9077a2b72a 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -189,7 +189,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dsin()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_cos : @@ -202,7 +202,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dcos()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_tan : @@ -215,7 +215,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dtan()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_log : @@ -228,7 +228,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dlog()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_log10 : @@ -241,7 +241,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dlog10()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_exp : @@ -254,7 +254,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dexp()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_pow : @@ -268,7 +268,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dpow()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_fmaD : From f1196638b347c9a2e7d7dc1795c6c24ea7efe711 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Tue, 7 Jan 2025 10:34:18 +0000 Subject: [PATCH 022/286] 8346573: Can't use custom default file system provider with custom system class loader Reviewed-by: mkartashev, bpb --- .../classes/java/nio/file/FileSystems.java | 27 +++++++------ .../nio/file/spi/CustomSystemClassLoader.java | 40 +++++++++++++++++++ .../java/nio/file/spi/SetDefaultProvider.java | 17 +++++++- 3 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 test/jdk/java/nio/file/spi/CustomSystemClassLoader.java diff --git a/src/java.base/share/classes/java/nio/file/FileSystems.java b/src/java.base/share/classes/java/nio/file/FileSystems.java index ab0538a1d4117..f60f798c6e276 100644 --- a/src/java.base/share/classes/java/nio/file/FileSystems.java +++ b/src/java.base/share/classes/java/nio/file/FileSystems.java @@ -34,6 +34,7 @@ import java.util.ServiceConfigurationError; import java.util.ServiceLoader; +import jdk.internal.loader.ClassLoaders; import jdk.internal.misc.VM; import sun.nio.fs.DefaultFileSystemProvider; @@ -112,11 +113,9 @@ private static FileSystemProvider getDefaultProvider() { if (propValue != null) { for (String cn: propValue.split(",")) { try { - Class c = Class - .forName(cn, true, ClassLoader.getSystemClassLoader()); - Constructor ctor = c - .getDeclaredConstructor(FileSystemProvider.class); - provider = (FileSystemProvider)ctor.newInstance(provider); + Class c = Class.forName(cn, true, ClassLoaders.appClassLoader()); + Constructor ctor = c.getDeclaredConstructor(FileSystemProvider.class); + provider = (FileSystemProvider) ctor.newInstance(provider); // must be "file" if (!provider.getScheme().equals("file")) @@ -146,13 +145,17 @@ private static FileSystemProvider getDefaultProvider() { * is invoked to create the default file system. * *

    If the system property {@code java.nio.file.spi.DefaultFileSystemProvider} - * is defined then it is taken to be a list of one or more fully-qualified - * names of concrete provider classes identified by the URI scheme - * {@code "file"}. Where the property is a list of more than one name then - * the names are separated by a comma. Each class is loaded, using the system - * class loader, and instantiated by invoking a one argument constructor - * whose formal parameter type is {@code FileSystemProvider}. The providers - * are loaded and instantiated in the order they are listed in the property. + * is defined then it is taken to be a list of one or more fully-qualified names + * of concrete provider classes identified by the URI scheme {@code "file"}. + * If the property is a list of more than one name then the names are separated + * by a comma character. Each provider class is a {@code public} class with a + * {@code public} constructor that has one formal parameter of type {@code + * FileSystemProvider}. If the provider class is in a named module then the module + * exports the package containing the provider class to at least {@code java.base}. + * Each provider class is loaded, using the + * {@linkplain ClassLoader#getSystemClassLoader() default system class loader}, + * and instantiated by invoking the constructor. The providers are loaded and + * instantiated in the order they are listed in the property. * If this process fails or a provider's scheme is not equal to {@code "file"} * then an unspecified error is thrown. URI schemes are normally compared * without regard to case but for the default provider, the scheme is diff --git a/test/jdk/java/nio/file/spi/CustomSystemClassLoader.java b/test/jdk/java/nio/file/spi/CustomSystemClassLoader.java new file mode 100644 index 0000000000000..8ad9a41c5fd32 --- /dev/null +++ b/test/jdk/java/nio/file/spi/CustomSystemClassLoader.java @@ -0,0 +1,40 @@ +/* + * 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. + */ + +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; + +/** + * Use by tests in SetDefaultProvider to test startup with a custom default file system + * provider and a custom system class loader. + */ + +public class CustomSystemClassLoader extends ClassLoader { + public CustomSystemClassLoader(ClassLoader parent) { + super(parent); + + // use default file system + FileSystem fs = FileSystems.getDefault(); + var path = fs.getPath("foo"); + } +} \ No newline at end of file diff --git a/test/jdk/java/nio/file/spi/SetDefaultProvider.java b/test/jdk/java/nio/file/spi/SetDefaultProvider.java index ea154b5952edb..f4486885b6a7e 100644 --- a/test/jdk/java/nio/file/spi/SetDefaultProvider.java +++ b/test/jdk/java/nio/file/spi/SetDefaultProvider.java @@ -23,10 +23,10 @@ /* * @test - * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 8331467 + * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 8331467 8346573 * @modules jdk.jartool jdk.jlink * @library /test/lib - * @build testfsp/* testapp/* + * @build testfsp/* testapp/* CustomSystemClassLoader * @run junit SetDefaultProvider * @summary Runs tests with -Djava.nio.file.spi.DefaultFileSystemProvider set on * the command line to override the default file system provider @@ -204,6 +204,19 @@ void testPatchedAppOnModulePath2() throws Exception { "-m", TESTAPP + "/" + TESTAPP_MAIN); } + /** + * Test file system provider on class path in conjunction with a custom system + * class loader that uses the file system API during its initialization. + */ + @Test + void testCustomSystemClassLoader() throws Exception { + String testClasses = System.getProperty("test.classes"); + exec(SET_DEFAULT_FSP, + "-Djava.system.class.loader=CustomSystemClassLoader", + "-cp", ofClasspath(testClasses, TESTFSP_CLASSES, TESTAPP_CLASSES), + TESTAPP_MAIN); + } + /** * Returns the directory containing the classes for the given module. */ From 3f7052ed7af89efd1c6977df0b4f3b95fcfec764 Mon Sep 17 00:00:00 2001 From: Fei Yang Date: Tue, 7 Jan 2025 10:54:52 +0000 Subject: [PATCH 023/286] 8346868: RISC-V: compiler/sharedstubs tests fail after JDK-8332689 Reviewed-by: rehn, mli --- src/hotspot/cpu/riscv/codeBuffer_riscv.hpp | 2 +- .../jtreg/compiler/sharedstubs/SharedTrampolineTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp index a864d7073dcfb..f541ac117eba0 100644 --- a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp +++ b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp @@ -33,6 +33,6 @@ public: void flush_bundle(bool start_new_bundle) {} - static bool supports_shared_stubs() { return false; } + static bool supports_shared_stubs() { return true; } #endif // CPU_RISCV_CODEBUFFER_RISCV_HPP diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java index f1e4d18b93a8c..0ce62954db792 100644 --- a/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java @@ -30,7 +30,7 @@ * * @requires vm.compiler2.enabled * @requires vm.opt.TieredCompilation == null - * @requires os.arch=="aarch64" | os.arch=="riscv64" + * @requires os.arch=="aarch64" * @requires vm.debug * * @run driver compiler.sharedstubs.SharedTrampolineTest -XX:-TieredCompilation From 5e6cda4799a6bf12370bc6a04b218ebed32dee53 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Tue, 7 Jan 2025 12:32:31 +0000 Subject: [PATCH 024/286] 8347000: Bug in com/sun/net/httpserver/bugs/B6361557.java test Reviewed-by: msheppar, michaelm --- test/jdk/com/sun/net/httpserver/bugs/B6361557.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/com/sun/net/httpserver/bugs/B6361557.java b/test/jdk/com/sun/net/httpserver/bugs/B6361557.java index 57e831ec693d0..66094230d6974 100644 --- a/test/jdk/com/sun/net/httpserver/bugs/B6361557.java +++ b/test/jdk/com/sun/net/httpserver/bugs/B6361557.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, 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 @@ -65,7 +65,7 @@ public void handle (HttpExchange t) } final static String request = "GET /test/foo.html HTTP/1.1\r\nContent-length: 0\r\n\r\n"; - final static ByteBuffer requestBuf = ByteBuffer.allocate(64).put(request.getBytes()); + final static ByteBuffer requestBuf = ByteBuffer.wrap(request.getBytes()); public static void main (String[] args) throws Exception { Handler handler = new Handler(); From 8b22517cb0b24c4134a2dbf22591f6f84d7d866c Mon Sep 17 00:00:00 2001 From: Joachim Kern Date: Tue, 7 Jan 2025 13:54:09 +0000 Subject: [PATCH 025/286] 8211851: (ch) java/nio/channels/AsynchronousSocketChannel/StressLoopback.java times out (aix) Reviewed-by: mdoerr, varadam --- .../aix/classes/sun/nio/ch/AixPollPort.java | 71 ++++++++++--------- test/jdk/ProblemList.txt | 2 - 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java b/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java index 4f5bda557c63c..b8610655b6c56 100644 --- a/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java +++ b/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 SAP SE. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024 SAP SE. 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,15 +26,17 @@ package sun.nio.ch; -import java.nio.channels.spi.AsynchronousChannelProvider; -import sun.nio.ch.Pollset; +import java.io.FileDescriptor; import java.io.IOException; -import java.util.HashSet; -import java.util.Iterator; +import java.nio.channels.spi.AsynchronousChannelProvider; import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.RejectedExecutionException; +import java.util.HashSet; +import java.util.Iterator; +import sun.nio.ch.IOUtil; +import sun.nio.ch.Pollset; /** * AsynchronousChannelGroup implementation based on the AIX pollset framework. @@ -141,6 +143,8 @@ static class ControlEvent { sv = new int[2]; try { Pollset.socketpair(sv); + // make the reading part of the socket nonblocking, so the drain (drain_all) method works + IOUtil.configureBlocking(IOUtil.newFD(sv[0]), false); // register one end with pollset Pollset.pollsetCtl(pollset, Pollset.PS_ADD, sv[0], Net.POLLIN); } catch (IOException x) { @@ -271,23 +275,21 @@ private void queueControlEvent(ControlEvent ev) { // Process all events currently stored in the control queue. private void processControlQueue() { - synchronized (controlQueue) { - // On Aix it is only possible to set the event - // bits on the first call of pollsetCtl. Later - // calls only add bits, but cannot remove them. - // Therefore, we always remove the file - // descriptor ignoring the error and then add it. - Iterator iter = controlQueue.iterator(); - while (iter.hasNext()) { - ControlEvent ev = iter.next(); - Pollset.pollsetCtl(pollset, Pollset.PS_DELETE, ev.fd(), 0); - if (!ev.removeOnly()) { - ev.setError(Pollset.pollsetCtl(pollset, Pollset.PS_MOD, ev.fd(), ev.events())); - } - iter.remove(); + // On Aix it is only possible to set the event + // bits on the first call of pollsetCtl. Later + // calls only add bits, but cannot remove them. + // Therefore, we always remove the file + // descriptor ignoring the error and then add it. + Iterator iter = controlQueue.iterator(); + while (iter.hasNext()) { + ControlEvent ev = iter.next(); + Pollset.pollsetCtl(pollset, Pollset.PS_DELETE, ev.fd(), 0); + if (!ev.removeOnly()) { + ev.setError(Pollset.pollsetCtl(pollset, Pollset.PS_MOD, ev.fd(), ev.events())); } - controlQueue.notifyAll(); + iter.remove(); } + controlQueue.notifyAll(); } /* @@ -306,8 +308,21 @@ private Event poll() throws IOException { int n; controlLock.lock(); try { - n = Pollset.pollsetPoll(pollset, address, + int m; + m = n = Pollset.pollsetPoll(pollset, address, MAX_EVENTS_TO_POLL, Pollset.PS_NO_TIMEOUT); + while (m-- > 0) { + long eventAddress = Pollset.getEvent(address, m); + int fd = Pollset.getDescriptor(eventAddress); + + // To emulate one shot semantic we need to remove + // the file descriptor here. + if (fd != sp[0] && fd != ctlSp[0]) { + synchronized (controlQueue) { + Pollset.pollsetCtl(pollset, Pollset.PS_DELETE, fd, 0); + } + } + } } finally { controlLock.unlock(); } @@ -323,14 +338,6 @@ private Event poll() throws IOException { long eventAddress = Pollset.getEvent(address, n); int fd = Pollset.getDescriptor(eventAddress); - // To emulate one shot semantic we need to remove - // the file descriptor here. - if (fd != sp[0] && fd != ctlSp[0]) { - synchronized (controlQueue) { - Pollset.pollsetCtl(pollset, Pollset.PS_DELETE, fd, 0); - } - } - // wakeup if (fd == sp[0]) { if (wakeupCount.decrementAndGet() == 0) { @@ -350,7 +357,7 @@ private Event poll() throws IOException { // wakeup to process control event if (fd == ctlSp[0]) { synchronized (controlQueue) { - Pollset.drain1(ctlSp[0]); + IOUtil.drain(ctlSp[0]); processControlQueue(); } if (n > 0) { diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index e9d7c76952361..6a2ab0d1e0451 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -583,8 +583,6 @@ java/net/Socket/asyncClose/Race.java 8317801 aix-ppc6 # jdk_nio -java/nio/channels/AsynchronousSocketChannel/StressLoopback.java 8211851 aix-ppc64 - java/nio/channels/Channels/SocketChannelStreams.java 8317838 aix-ppc64 java/nio/channels/DatagramChannel/AdaptorMulticasting.java 8308807,8144003 aix-ppc64,macosx-all From e5f0c19084dcb5f16a5e7665f98005a35173f61d Mon Sep 17 00:00:00 2001 From: Tobias Holenstein Date: Tue, 7 Jan 2025 14:30:05 +0000 Subject: [PATCH 026/286] 8345041: IGV: Free Placement Mode in IGV Layout Reviewed-by: chagedorn, epeter, rcastanedalo --- .../FreeInteractiveLayoutManager.java | 384 ++++++++++++++++++ .../HierarchicalLayoutManager.java | 5 + .../igv/hierarchicallayout/LayoutGraph.java | 61 ++- .../igv/hierarchicallayout/LayoutMover.java | 2 + .../igv/hierarchicallayout/LayoutNode.java | 16 +- .../sun/hotspot/igv/settings/Settings.java | 1 + .../sun/hotspot/igv/view/DiagramScene.java | 108 ++++- .../hotspot/igv/view/DiagramViewModel.java | 15 +- .../hotspot/igv/view/EditorTopComponent.java | 5 + .../view/actions/EnableFreeLayoutAction.java | 49 +++ .../hotspot/igv/view/widgets/LineWidget.java | 52 ++- .../sun/hotspot/igv/view/images/dynamic.png | Bin 0 -> 2218 bytes 12 files changed, 670 insertions(+), 28 deletions(-) create mode 100644 src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/FreeInteractiveLayoutManager.java create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/EnableFreeLayoutAction.java create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/dynamic.png diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/FreeInteractiveLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/FreeInteractiveLayoutManager.java new file mode 100644 index 0000000000000..7aec57ec2a092 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/FreeInteractiveLayoutManager.java @@ -0,0 +1,384 @@ +/* + * 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. + * + */ +package com.sun.hotspot.igv.hierarchicallayout; + +import static com.sun.hotspot.igv.hierarchicallayout.LayoutNode.LAYOUT_NODE_DEGREE_COMPARATOR; +import com.sun.hotspot.igv.layout.Link; +import com.sun.hotspot.igv.layout.Vertex; +import java.awt.Point; +import java.util.*; + +public class FreeInteractiveLayoutManager extends LayoutManager implements LayoutMover { + + private boolean cutEdges = false; + + private static final int LINE_OFFSET = 10; + + private Map layoutNodes; + + private LayoutGraph prevGraph; + + private final Random random = new Random(42); + + // Constants for offsets and displacements + private static final int MAX_OFFSET_AROUND_NEIGHBOR = 200; // Max offset for random positioning around a neighbor + private static final int MAX_OFFSET_AROUND_ORIGIN = 200; // Max offset for random positioning around origin + private static final int DISPLACEMENT_RANGE_BARYCENTER = 100; // Displacement range for barycenter calculation + private static final int DISPLACEMENT_RANGE_SINGLE = 200; + + // Create a comparator to sort nodes by the number of unassigned neighbors + private final Comparator LeastUnassignedNeighborsComparator = Comparator.comparingInt(node -> { + Vertex vertex = node.getVertex(); + int unassignedNeighbors = 0; + for (Vertex neighborVertex : prevGraph.getNeighborVertices(vertex)) { + if (!layoutNodes.containsKey(neighborVertex)) { + unassignedNeighbors++; + } + } + return unassignedNeighbors; + }); + + public FreeInteractiveLayoutManager() { + this.cutEdges = false; + this.layoutNodes = new HashMap<>(); + this.prevGraph = null; + } + + @Override + public void moveLink(Point linkPos, int shiftX) {} + + @Override + public void moveVertices(Set movedVertices) { + for (Vertex v : movedVertices) { + moveVertex(v); + } + } + + @Override + public void moveVertex(Vertex vertex) { + assert prevGraph.containsVertex(vertex); + LayoutNode layoutNode = layoutNodes.get(vertex); + layoutNode.setX(vertex.getPosition().x); + layoutNode.setY(vertex.getPosition().y); + for (Link link : prevGraph.getAllLinks(vertex)) { + setLinkControlPoints(link); + } + } + + @Override + public boolean isFreeForm() { + return true; + } + + public void setCutEdges(boolean enable) { + this.cutEdges = enable; + } + + @Override + public void doLayout(LayoutGraph graph) { + prevGraph = graph; + if (layoutNodes.isEmpty()) { + HierarchicalLayoutManager manager = new HierarchicalLayoutManager(); + manager.doLayout(graph); + for (LayoutNode node : graph.getLayoutNodes()) { + node.initSize(); + layoutNodes.put(node.getVertex(), node); + } + graph.clearLayout(); + } else { + // add new vertices to layoutNodes, x/y from barycenter + List newLayoutNodes = new ArrayList<>(); + + // Set up layout nodes for each vertex + for (Vertex vertex : prevGraph.getVertices()) { + if (!layoutNodes.containsKey(vertex)) { + LayoutNode addedNode = new LayoutNode(vertex); + addedNode.initSize(); + newLayoutNodes.add(addedNode); + } + } + + positionNewLayoutNodes(newLayoutNodes); + } + + // Write back vertices + for (Vertex vertex : prevGraph.getVertices()) { + LayoutNode layoutNode = layoutNodes.get(vertex); + layoutNode.setVertex(vertex); + vertex.setPosition(new Point(layoutNode.getLeft(), layoutNode.getTop())); + } + + // Write back links + for (Link link : prevGraph.getLinks()) { + setLinkControlPoints(link); + } + } + + public void positionNewLayoutNodes(List newLayoutNodes) { + // First pass: Initial positioning based on unassigned neighbors + newLayoutNodes.sort(LeastUnassignedNeighborsComparator); + + for (LayoutNode node : newLayoutNodes) { + Vertex vertex = node.getVertex(); + + // Gather assigned neighbors + List assignedNeighbors = new ArrayList<>(); + for (Vertex neighborVertex : prevGraph.getNeighborVertices(vertex)) { + if (layoutNodes.containsKey(neighborVertex)) { + assignedNeighbors.add(layoutNodes.get(neighborVertex)); + } + } + + if (!assignedNeighbors.isEmpty()) { + if (assignedNeighbors.size() == 1) { + // Single neighbor: position around the neighbor + setPositionAroundSingleNode(node, assignedNeighbors.get(0), DISPLACEMENT_RANGE_SINGLE); + } else { + // Multiple neighbors: Calculate barycenter with displacement + calculateBarycenterWithDisplacement(node, assignedNeighbors, DISPLACEMENT_RANGE_BARYCENTER); + } + } else { + // No neighbors: Position randomly around (0, 0) + setRandomPositionAroundOrigin(node, random); + } + + // Add the new node to the layout + layoutNodes.put(vertex, node); + } + + // Second pass: Refine positions based on neighbor degree + newLayoutNodes.sort(LAYOUT_NODE_DEGREE_COMPARATOR.reversed()); + + // Collect all nodes (existing and new) + Collection allNodes = layoutNodes.values(); + + for (LayoutNode node : newLayoutNodes) { + Vertex vertex = node.getVertex(); + + // Gather assigned neighbors + List assignedNeighbors = new ArrayList<>(); + for (Vertex neighborVertex : prevGraph.getNeighborVertices(vertex)) { + if (layoutNodes.containsKey(neighborVertex)) { + assignedNeighbors.add(layoutNodes.get(neighborVertex)); + } + } + + if (!assignedNeighbors.isEmpty()) { + // Refine position based on force-based method + applyForceBasedAdjustment(node, assignedNeighbors, allNodes); + } + + // Ensure node's position remains updated in the layout + layoutNodes.put(vertex, node); + } + } + + /** + * Applies a force-based adjustment to the position of a given layout node + * based on repulsive forces from all other nodes and attractive forces from its assigned neighbors. + *

    + * This method simulates a physical system where nodes repel each other to maintain spacing + * and are pulled towards their neighbors to maintain connectivity. The forces are calculated + * using Coulomb's law for repulsion and Hooke's law for attraction. The system iterates for + * a fixed number of iterations to stabilize the position of the node. + * + * @param node The node whose position is being adjusted. + * @param assignedNeighbors A list of neighboring nodes that attract this node. + * @param allNodes A collection of all nodes in the layout, used for repulsive forces. + */ + private void applyForceBasedAdjustment(LayoutNode node, List assignedNeighbors, Collection allNodes) { + // Constants for force-based adjustment + final int ITERATIONS = 50; // Number of simulation iterations + final double REPULSION_CONSTANT = 1000; // Magnitude of repulsive forces (Coulomb's law) + final double SPRING_CONSTANT = 0.2; // Strength of attractive forces to neighbors (Hooke's law) + final double DAMPING = 0.8; // Factor to reduce displacement and ensure stability + final double IDEAL_LENGTH = 100; // Desired distance between a node and its neighbors + final double MAX_FORCE = 1000; // Upper limit for the magnitude of applied forces + final double CONVERGENCE_THRESHOLD = 0.01; // Force threshold for stopping early + + double posX = node.getX(); + double posY = node.getY(); + double dx = 0, dy = 0; // Displacement + + for (int i = 0; i < ITERATIONS; i++) { + double netForceX = 0; + double netForceY = 0; + + // Repulsive forces from all other nodes + for (LayoutNode otherNode : allNodes) { + if (otherNode == node) continue; // Skip self + + double deltaX = posX - otherNode.getX(); + double deltaY = posY - otherNode.getY(); + double distanceSquared = deltaX * deltaX + deltaY * deltaY; + double distance = Math.sqrt(distanceSquared); + + // Avoid division by zero by introducing a minimum distance + if (distance < 1e-6) { + deltaX = random.nextDouble() * 0.1 - 0.05; + deltaY = random.nextDouble() * 0.1 - 0.05; + distanceSquared = deltaX * deltaX + deltaY * deltaY; + distance = Math.sqrt(distanceSquared); + } + + // Repulsive force (Coulomb's law) + double repulsiveForce = REPULSION_CONSTANT / distanceSquared; + + // Normalize force to prevent large displacements + if (repulsiveForce > MAX_FORCE) repulsiveForce = MAX_FORCE; + + netForceX += (deltaX / distance) * repulsiveForce; + netForceY += (deltaY / distance) * repulsiveForce; + } + + // Attractive forces to assigned neighbors + for (LayoutNode neighbor : assignedNeighbors) { + double deltaX = neighbor.getX() - posX; + double deltaY = neighbor.getY() - posY; + double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + + if (distance < 1e-6) { + deltaX = random.nextDouble() * 0.1 - 0.05; + deltaY = random.nextDouble() * 0.1 - 0.05; + distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + } + + // Attractive force (Hooke's law) + double displacement = distance - IDEAL_LENGTH; + double attractiveForce = SPRING_CONSTANT * displacement; + + if (attractiveForce > MAX_FORCE) attractiveForce = MAX_FORCE; + + netForceX += (deltaX / distance) * attractiveForce; + netForceY += (deltaY / distance) * attractiveForce; + } + + // Apply damping and update displacement + dx = (dx + netForceX) * DAMPING; + dy = (dy + netForceY) * DAMPING; + + // Scale displacement if it's too large + double displacementMagnitude = Math.sqrt(dx * dx + dy * dy); + if (displacementMagnitude > MAX_FORCE) { + dx *= MAX_FORCE / displacementMagnitude; + dy *= MAX_FORCE / displacementMagnitude; + } + + // Update position + posX += dx; + posY += dy; + + // Stop early if the net force is negligible + if (Math.abs(netForceX) < CONVERGENCE_THRESHOLD && Math.abs(netForceY) < CONVERGENCE_THRESHOLD) { + break; + } + + // Validate position to avoid invalid or extreme values + if (Double.isNaN(posX) || Double.isInfinite(posX) || Double.isNaN(posY) || Double.isInfinite(posY)) { + posX = node.getX(); // Reset to original position + posY = node.getY(); + break; + } + } + + // Set final position + node.setX((int) Math.round(posX)); + node.setY((int) Math.round(posY)); + } + + // Utility method: position around a given node + private void setPositionAroundSingleNode(LayoutNode node, LayoutNode neighbor, int displacement) { + boolean neighborIsPredecessor = prevGraph.isPredecessorVertex(node.getVertex(), neighbor.getVertex()); + boolean neighborIsSuccessor = prevGraph.isSuccessorVertex(node.getVertex(), neighbor.getVertex()); + + int shiftY = 0; + if (neighborIsPredecessor) { + shiftY = displacement; + } else if (neighborIsSuccessor) { + shiftY = -displacement; + } + assert shiftY != 0; + + int randomY = neighbor.getY() + random.nextInt(MAX_OFFSET_AROUND_NEIGHBOR + 1) + shiftY; + int randomX = neighbor.getX() + random.nextInt(MAX_OFFSET_AROUND_NEIGHBOR + 1); + node.setX(randomX); + node.setY(randomY); + } + + // Utility method: Random position around origin + private void setRandomPositionAroundOrigin(LayoutNode node, Random random) { + int randomX = random.nextInt(MAX_OFFSET_AROUND_ORIGIN + 1); + int randomY = random.nextInt(MAX_OFFSET_AROUND_ORIGIN + 1); + node.setX(randomX); + node.setY(randomY); + } + + // Utility method: Calculate barycenter with displacement + private void calculateBarycenterWithDisplacement(LayoutNode node, List neighbors, int displacementRange) { + double barycenterX = 0, barycenterY = 0; + for (LayoutNode neighbor : neighbors) { + barycenterX += neighbor.getX(); + barycenterY += neighbor.getY(); + } + barycenterX /= neighbors.size(); + barycenterY /= neighbors.size(); + + // Add random displacement for slight separation + int displacementX = random.nextInt(displacementRange + 1); + int displacementY = random.nextInt(displacementRange + 1); + node.setX((int) barycenterX + displacementX); + node.setY((int) barycenterY + displacementY); + } + + /** + * Sets control points for a given link based on its start and end layout nodes. + *

    + * Calculates the start and end points, applies offsets for curvature, and updates + * the link's control points. + * + * @param link The link to process. + */ + private void setLinkControlPoints(Link link) { + if (link.getFrom().getVertex() == link.getTo().getVertex()) return; // Skip self-links + + LayoutNode from = layoutNodes.get(link.getFrom().getVertex()); + from.setVertex(link.getFrom().getVertex()); + from.updateSize(); + + LayoutNode to = layoutNodes.get(link.getTo().getVertex()); + to.setVertex(link.getTo().getVertex()); + to.updateSize(); + + Point startPoint = new Point(from.getLeft() + link.getFrom().getRelativePosition().x, from.getBottom()); + Point endPoint = new Point(to.getLeft() + link.getTo().getRelativePosition().x, to.getTop()); + + List controlPoints = new ArrayList<>(); + controlPoints.add(startPoint); + controlPoints.add(new Point(startPoint.x, startPoint.y + LINE_OFFSET)); + controlPoints.add(new Point(endPoint.x, endPoint.y - LINE_OFFSET)); + controlPoints.add(endPoint); + + link.setControlPoints(controlPoints); + } +} diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java index e2d6bf1803981..cb9487ae828fa 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java @@ -53,6 +53,11 @@ public void setCutEdges(boolean enable) { maxLayerLength = enable ? 10 : -1; } + @Override + public boolean isFreeForm() { + return false; + } + @Override public void doLayout(LayoutGraph layoutGraph) { layoutGraph.initializeLayout(); diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java index 64d9641246764..956d72924b991 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -169,7 +169,7 @@ public Collection getLayoutNodes() { * Retrieves a combined list of all nodes in the graph, * including both layout nodes and dummy nodes. * - * @return An unmodifiable list containing all nodes in the graph. + * @return An unmodifiable list containing all nodes in the graph */ public List getAllNodes() { List allNodes = new ArrayList<>(); @@ -447,6 +447,63 @@ public List getOutputLinks(Vertex vertex) { return outputLinks; } + /** + * Checks if the given predecessorVertex is a direct predecessor of the specified vertex. + * + * @param vertex The vertex to check for predecessors. + * @param predecessorVertex The vertex to verify as a predecessor of the given vertex. + * @return true if predecessorVertex is a direct predecessor of vertex, false otherwise. + */ + public boolean isPredecessorVertex(Vertex vertex, Vertex predecessorVertex) { + for (Port inputPort : inputPorts.getOrDefault(vertex, Collections.emptySet())) { + for (Link inputLink : portLinks.getOrDefault(inputPort, Collections.emptySet())) { + Vertex fromVertex = inputLink.getFrom().getVertex(); + if (fromVertex.equals(predecessorVertex)) { + return true; + } + } + } + return false; + } + + /** + * Checks if the given successorVertex is a direct successor of the specified vertex. + * + * @param vertex The vertex to check for successors. + * @param successorVertex The vertex to verify as a successor of the given vertex. + * @return true if successorVertex is a direct successor of vertex, false otherwise. + */ + public boolean isSuccessorVertex(Vertex vertex, Vertex successorVertex) { + for (Port outputPort : outputPorts.getOrDefault(vertex, Collections.emptySet())) { + for (Link outputLink : portLinks.getOrDefault(outputPort, Collections.emptySet())) { + Vertex toVertex = outputLink.getTo().getVertex(); + if (toVertex.equals(successorVertex)) { + return true; + } + } + } + return false; + } + + public List getNeighborVertices(Vertex vertex) { + List neighborVertices = new ArrayList<>(); + for (Port inputPort : inputPorts.getOrDefault(vertex, Collections.emptySet())) { + for (Link inputLink : portLinks.getOrDefault(inputPort, Collections.emptySet())) { + Vertex fromVertex = inputLink.getFrom().getVertex(); + assert fromVertex != null; + neighborVertices.add(fromVertex); + } + } + for (Port outputPort : outputPorts.getOrDefault(vertex, Collections.emptySet())) { + for (Link outputLink : portLinks.getOrDefault(outputPort, Collections.emptySet())) { + Vertex toVertex = outputLink.getTo().getVertex(); + assert toVertex != null; + neighborVertices.add(toVertex); + } + } + return neighborVertices; + } + public List getAllLinks(Vertex vertex) { List allLinks = new ArrayList<>(); diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutMover.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutMover.java index 19f24f1f7e69c..48599d78d7580 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutMover.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutMover.java @@ -49,5 +49,7 @@ public interface LayoutMover { * @param movedVertex The vertex to be moved. */ void moveVertex(Vertex movedVertex); + + boolean isFreeForm(); } diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutNode.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutNode.java index 9ad0c70b912eb..2816115080e17 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutNode.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutNode.java @@ -107,12 +107,7 @@ public LayoutNode() { this(null); } - /** - * Initializes the size and margins of the node. - * If the node represents a real vertex, it uses the vertex's size. - * Dummy nodes use default dimensions. - */ - public void initSize() { + public void updateSize() { if (vertex == null) { height = DUMMY_HEIGHT; width = DUMMY_WIDTH; @@ -121,6 +116,15 @@ public void initSize() { height = size.height; width = size.width; } + } + + /** + * Initializes the size and margins of the node. + * If the node represents a real vertex, it uses the vertex's size. + * Dummy nodes use default dimensions. + */ + public void initSize() { + updateSize(); topMargin = 0; bottomMargin = 0; leftMargin = 0; diff --git a/src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/Settings.java b/src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/Settings.java index 41af4a1d26282..480fb43ea5b8d 100644 --- a/src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/Settings.java +++ b/src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/Settings.java @@ -37,6 +37,7 @@ public static class DefaultView { public static final int CLUSTERED_SEA_OF_NODES = 1; public static final int CONTROL_FLOW_GRAPH = 2; public static final int STABLE_SEA_OF_NODES = 3; + public static final int INTERACTIVE_FREE_NODES = 4; } public static final String NODE_TEXT = "nodeText"; diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 90d5e0ac424b4..99ae3380bb39d 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -89,6 +89,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl private final Map> outputSlotToLineWidget = new HashMap<>(); private final Map> inputSlotToLineWidget = new HashMap<>(); + private final FreeInteractiveLayoutManager freeInteractiveLayoutManager; private final HierarchicalStableLayoutManager hierarchicalStableLayoutManager; private HierarchicalLayoutManager seaLayoutManager; private LayoutMover layoutMover; @@ -511,6 +512,7 @@ public void ancestorResized(HierarchyEvent e) { } }); + freeInteractiveLayoutManager = new FreeInteractiveLayoutManager(); hierarchicalStableLayoutManager = new HierarchicalStableLayoutManager(); seaLayoutManager = new HierarchicalLayoutManager(); @@ -643,6 +645,8 @@ public void movementStarted(Widget widget) { widget.bringToFront(); startLayerY = widget.getLocation().y; hasMoved = false; // Reset the movement flag + if (layoutMover.isFreeForm()) return; + Set

    selectedFigures = model.getSelectedFigures(); if (selectedFigures.size() == 1) { Figure selectedFigure = selectedFigures.iterator().next(); @@ -702,8 +706,12 @@ public void setNewLocation(Widget widget, Point location) { hasMoved = true; // Mark that a movement occurred int shiftX = location.x - widget.getLocation().x; - int shiftY = magnetToStartLayerY(widget, location); - + int shiftY; + if (layoutMover.isFreeForm()) { + shiftY = location.y - widget.getLocation().y; + } else { + shiftY = magnetToStartLayerY(widget, location); + } List
    selectedFigures = new ArrayList<>( model.getSelectedFigures()); selectedFigures.sort(Comparator.comparingInt(f -> f.getPosition().x)); for (Figure figure : selectedFigures) { @@ -713,12 +721,15 @@ public void setNewLocation(Widget widget, Point location) { if (inputSlotToLineWidget.containsKey(inputSlot)) { for (LineWidget lw : inputSlotToLineWidget.get(inputSlot)) { assert lw != null; - Point toPt = lw.getTo(); Point fromPt = lw.getFrom(); - if (toPt != null && fromPt != null) { - int xTo = toPt.x + shiftX; - int yTo = toPt.y + shiftY; - lw.setTo(new Point(xTo, yTo)); + Point toPt = lw.getTo(); + if (toPt == null || fromPt == null) { + continue; + } + int xTo = toPt.x + shiftX; + int yTo = toPt.y + shiftY; + lw.setTo(new Point(xTo, yTo)); + if (!layoutMover.isFreeForm()) { lw.setFrom(new Point(fromPt.x + shiftX, fromPt.y)); LineWidget pred = lw.getPredecessor(); pred.setTo(new Point(pred.getTo().x + shiftX, pred.getTo().y)); @@ -735,10 +746,13 @@ public void setNewLocation(Widget widget, Point location) { assert lw != null; Point fromPt = lw.getFrom(); Point toPt = lw.getTo(); - if (toPt != null && fromPt != null) { - int xFrom = fromPt.x + shiftX; - int yFrom = fromPt.y + shiftY; - lw.setFrom(new Point(xFrom, yFrom)); + if (toPt == null || fromPt == null) { + continue; + } + int xFrom = fromPt.x + shiftX; + int yFrom = fromPt.y + shiftY; + lw.setFrom(new Point(xFrom, yFrom)); + if (!layoutMover.isFreeForm()) { lw.setTo(new Point(toPt.x + shiftX, toPt.y)); for (LineWidget succ : lw.getSuccessors()) { succ.setFrom(new Point(succ.getFrom().x + shiftX, succ.getFrom().y)); @@ -753,10 +767,12 @@ public void setNewLocation(Widget widget, Point location) { ActionFactory.createDefaultMoveProvider().setNewLocation(fw, newLocation); } - FigureWidget fw = getWidget(selectedFigures.iterator().next()); - pointerWidget.setVisible(true); - Point newLocation = new Point(fw.getLocation().x + shiftX -3, fw.getLocation().y + shiftY); - ActionFactory.createDefaultMoveProvider().setNewLocation(pointerWidget, newLocation); + if (selectedFigures.size() == 1 && !layoutMover.isFreeForm()) { + FigureWidget fw = getWidget(selectedFigures.iterator().next()); + pointerWidget.setVisible(true); + Point newLocation = new Point(fw.getLocation().x + shiftX -3, fw.getLocation().y + shiftY); + ActionFactory.createDefaultMoveProvider().setNewLocation(pointerWidget, newLocation); + } connectionLayer.revalidate(); connectionLayer.repaint(); } @@ -834,7 +850,9 @@ private void relayout() { Set
    visibleFigures = getVisibleFigures(); Set visibleConnections = getVisibleConnections(); - if (getModel().getShowStableSea()) { + if (getModel().getShowFreeInteractive()) { + doFreeInteractiveLayout(visibleFigures, visibleConnections); + } else if (getModel().getShowStableSea()) { doStableSeaLayout(visibleFigures, visibleConnections); } else if (getModel().getShowSea()) { doSeaLayout(visibleFigures, visibleConnections); @@ -904,6 +922,12 @@ private boolean isVisibleFigureConnection(FigureConnection figureConnection) { return w1.isVisible() && w2.isVisible(); } + private void doFreeInteractiveLayout(Set
    visibleFigures, Set visibleConnections) { + layoutMover = freeInteractiveLayoutManager; + freeInteractiveLayoutManager.setCutEdges(model.getCutEdges()); + freeInteractiveLayoutManager.doLayout(new LayoutGraph(visibleConnections, visibleFigures)); + } + private void doStableSeaLayout(Set
    visibleFigures, Set visibleConnections) { layoutMover = null; boolean enable = model.getCutEdges(); @@ -1108,6 +1132,52 @@ private void processOutputSlot(OutputSlot outputSlot, List con } } + private void processFreeForm(OutputSlot outputSlot, List connections) { + for (FigureConnection connection : connections) { + if (isVisibleFigureConnection(connection)) { + boolean isBold = false; + boolean isDashed = true; + boolean isVisible = true; + if (connection.getStyle() == Connection.ConnectionStyle.BOLD) { + isBold = true; + } else if (connection.getStyle() == Connection.ConnectionStyle.INVISIBLE) { + isVisible = false; + } + if (connection.getStyle() != Connection.ConnectionStyle.DASHED) { + isDashed = false; + } + + + List controlPoints = connection.getControlPoints(); + if (controlPoints.size() <= 2) continue; + Point firstPoint = controlPoints.get(0); // First point + Point lastPoint = controlPoints.get(controlPoints.size() - 1); // Last point + List connectionList = new ArrayList<>(Collections.singleton(connection)); + LineWidget line = new LineWidget(this, outputSlot, connectionList, firstPoint, lastPoint, null, isBold, isDashed); + line.setFromControlYOffset(50); + line.setToControlYOffset(-50); + line.setVisible(isVisible); + connectionLayer.addChild(line); + + addObject(new ConnectionSet(connectionList), line); + line.getActions().addAction(hoverAction); + + if (outputSlotToLineWidget.containsKey(outputSlot)) { + outputSlotToLineWidget.get(outputSlot).add(line); + } else { + outputSlotToLineWidget.put(outputSlot, new HashSet<>(Collections.singleton(line))); + } + + InputSlot inputSlot = connection.getInputSlot(); + if (inputSlotToLineWidget.containsKey(inputSlot)) { + inputSlotToLineWidget.get(inputSlot).add(line); + } else { + inputSlotToLineWidget.put(inputSlot, new HashSet<>(Collections.singleton(line))); + } + } + } + } + private void processBlockConnection(BlockConnection blockConnection) { boolean isDashed = blockConnection.getStyle() == Connection.ConnectionStyle.DASHED; boolean isBold = blockConnection.getStyle() == Connection.ConnectionStyle.BOLD; @@ -1281,7 +1351,11 @@ private void rebuildConnectionLayer() { for (Figure figure : getModel().getDiagram().getFigures()) { for (OutputSlot outputSlot : figure.getOutputSlots()) { List connectionList = new ArrayList<>(outputSlot.getConnections()); - processOutputSlot(outputSlot, connectionList, 0, null, null); + if (layoutMover != null && layoutMover.isFreeForm()) { + processFreeForm(outputSlot, connectionList); + } else { + processOutputSlot(outputSlot, connectionList, 0, null, null); + } } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index e6cdbebbe52f2..710c5c125f61a 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -63,6 +63,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene private final ChangedEvent selectedNodesChangedEvent = new ChangedEvent<>(this); private final ChangedEvent hiddenNodesChangedEvent = new ChangedEvent<>(this); private ChangedListener titleChangedListener = g -> {}; + private boolean showFreeInteractive; private boolean showStableSea; private boolean showSea; private boolean showBlocks; @@ -104,6 +105,17 @@ public void setGlobalSelection(boolean enable, boolean fire) { } } + public boolean getShowFreeInteractive() { + return showFreeInteractive; + } + + public void setShowFreeInteractive(boolean enable) { + showFreeInteractive = enable; + if (enable) { + diagramChangedEvent.fire(); + } + } + public boolean getShowStableSea() { return showStableSea; } @@ -224,6 +236,7 @@ public DiagramViewModel(InputGraph graph) { globalSelection = GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(); cutEdges = CutEdgesAction.get(CutEdgesAction.class).isSelected(); + showFreeInteractive = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.INTERACTIVE_FREE_NODES; showStableSea = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.STABLE_SEA_OF_NODES; showSea = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.SEA_OF_NODES; showBlocks = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CLUSTERED_SEA_OF_NODES; @@ -266,7 +279,7 @@ public void setSelectedNodes(Set nodes) { for (String ignored : getPositions()) { colors.add(Color.black); } - if (nodes.size() >= 1) { + if (!nodes.isEmpty()) { for (Integer id : nodes) { if (id < 0) { id = -id; diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index d067925fb87b7..ff51b8928f676 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -176,6 +176,11 @@ public void mouseMoved(MouseEvent e) {} toolBar.addSeparator(); ButtonGroup layoutButtons = new ButtonGroup(); + JToggleButton freeInteractiveLayoutButton = new JToggleButton(new EnableFreeLayoutAction(this)); + freeInteractiveLayoutButton.setSelected(diagramViewModel.getShowFreeInteractive()); + layoutButtons.add(freeInteractiveLayoutButton); + toolBar.add(freeInteractiveLayoutButton); + JToggleButton stableSeaLayoutButton = new JToggleButton(new EnableStableSeaLayoutAction(this)); stableSeaLayoutButton.setSelected(diagramViewModel.getShowStableSea()); layoutButtons.add(stableSeaLayoutButton); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/EnableFreeLayoutAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/EnableFreeLayoutAction.java new file mode 100644 index 0000000000000..201fc51e15e9e --- /dev/null +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/EnableFreeLayoutAction.java @@ -0,0 +1,49 @@ +/* + * 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. + * + */ +package com.sun.hotspot.igv.view.actions; + +import com.sun.hotspot.igv.view.EditorTopComponent; +import java.beans.PropertyChangeEvent; + +public class EnableFreeLayoutAction extends EnableLayoutAction { + + public EnableFreeLayoutAction(EditorTopComponent etc) { + super(etc); + } + + @Override + protected String iconResource() { + return "com/sun/hotspot/igv/view/images/dynamic.png"; + } + + @Override + protected String getDescription() { + return "Show dynamic free layout"; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + editor.getModel().setShowFreeInteractive(this.isSelected()); + } +} diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LineWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LineWidget.java index 93d16d359148f..01ebb8ed9e31f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LineWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LineWidget.java @@ -30,14 +30,16 @@ import com.sun.hotspot.igv.layout.Vertex; import com.sun.hotspot.igv.util.StringUtils; import com.sun.hotspot.igv.view.DiagramScene; -import com.sun.hotspot.igv.view.actions.CustomSelectAction; import java.awt.*; +import java.awt.geom.CubicCurve2D; import java.awt.geom.Line2D; import java.util.*; import java.util.List; import javax.swing.JPopupMenu; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; + +import com.sun.hotspot.igv.view.actions.CustomSelectAction; import org.netbeans.api.visual.action.ActionFactory; import org.netbeans.api.visual.action.PopupMenuProvider; import org.netbeans.api.visual.action.SelectProvider; @@ -70,6 +72,8 @@ public class LineWidget extends Widget implements PopupMenuProvider { private final boolean isBold; private final boolean isDashed; private boolean needToInitToolTipText = true; + private int fromControlYOffset; + private int toControlYOffset; public LineWidget(DiagramScene scene, OutputSlot s, List connections, Point from, Point to, LineWidget predecessor, boolean isBold, boolean isDashed) { super(scene); @@ -172,6 +176,16 @@ public void setTo(Point to) { computeClientArea(); } + public void setFromControlYOffset(int fromControlYOffset) { + this.fromControlYOffset = fromControlYOffset; + computeClientArea(); + } + + public void setToControlYOffset(int toControlYOffset) { + this.toControlYOffset = toControlYOffset; + computeClientArea(); + } + public Point getFrom() { return from; } @@ -225,7 +239,41 @@ protected void paintWidget() { g.setStroke(new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)); } - g.drawLine(from.x, from.y, to.x, to.y); + // Define S-shaped curve with control points + if (fromControlYOffset != 0 && toControlYOffset != 0) { + if (from.y < to.y) { // non-reversed edges + if (Math.abs(from.x - to.x) > 10) { + CubicCurve2D.Float sShape = new CubicCurve2D.Float(); + sShape.setCurve(from.x, from.y, + from.x, from.y + fromControlYOffset, + to.x, to.y + toControlYOffset, + to.x, to.y); + g.draw(sShape); + } else { + g.drawLine(from.x, from.y, to.x, to.y); + } + } else { // reverse edges + if (from.x - to.x > 0) { + CubicCurve2D.Float sShape = new CubicCurve2D.Float(); + sShape.setCurve(from.x, from.y, + from.x - 150, from.y + fromControlYOffset, + to.x + 150, to.y + toControlYOffset, + to.x, to.y); + g.draw(sShape); + } else { + // add x offset + CubicCurve2D.Float sShape = new CubicCurve2D.Float(); + sShape.setCurve(from.x, from.y, + from.x + 150, from.y + fromControlYOffset, + to.x - 150, to.y + toControlYOffset, + to.x, to.y); + g.draw(sShape); + } + } + } else { + // Fallback to straight line if control points are not set + g.drawLine(from.x, from.y, to.x, to.y); + } boolean sameFrom = false; boolean sameTo = successors.isEmpty(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/dynamic.png b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/dynamic.png new file mode 100644 index 0000000000000000000000000000000000000000..781b98176f8657d705976bf1ceb15e78a07f8098 GIT binary patch literal 2218 zcmZ{l4Ny}@5P&a${A2)8X;r8a!>EXmmmfh0Nh&4^!GZx|8`Nq;^1xR@UM6{w0OBu- z$oPj+9I^N}PKAzCDB@s6l&X*sDdJci1Vqpxh1LQirJ&M#Awob%a=Fd!e!I7KZ!ejW zh!7{L8x;WHBn}lt!P$iz_O|fbqirkUA0>V&3oULTR+{(%|#X@Z`wq^P+wes$<|dgyVCY?L}G@s zbJ5&#HaohYdk^hJ_wHF)=?8l<#pnBv zq~wQg?X4~CEkxYrt!x{-K6m!#1q~gC)y-XN+hd0mLG`SF-si6p?o}C^2i<#^M{74o zQ2WZ#TN6nBgm3WBcZl?ejfyzr7p#uJs|`X{lmSy8buD()JhW zZ<=@@jsid(P zEGB~$005iGW^q~Y!=yoh!{qw00I<&92kam-7mlVgR-+kQ&RCDh&<28|g<>(BKhEk9 zw(SHoIA}s+bhCycZjyuI;gi}8fX!)4DkEg!UvL$8B15jkV^M}7QA5T9JOdYsi6|kb z84^`$9oN98n>@HsCe;X?W^y4C_;eX8M2Krqnm>cdVA2It8jZ%&D&x3OqSa;`{^HZO z5QK({AW2C{j3f>N*Ty5Pz`#I+$wt_0U+CehOI8zdgRffWITGYU91*HhXfX|e;c6Ng zS00P&2|k@pCK`Q>tP?e0W0}-Cb6K!JgtQ$ zsTfVA(Q8$vjZi8ORD~v@YC;D&7BX5tERRR7oGZjtxHeiNSD*qG&s2=1YHTM)yd{_c zRmnscjHrXVCSduSnTdu;!I-H)3&TWkoetFs@kFu&!AFmwIk}~e1rIl$YeI0X6vtHp z%g*2-6Ri`#a9oMSC5vFQ3CJGuWx)?q`k{wLa0?#`nmi)T;#S*FGIr*CwvVGp-;{a5 z#}SQNA&o7ZQy@E$wR!hLuaar9lGy+Hy5p-4`Y4T^E}lOg%n7yu>l$rqBIWMqtV3BX zO<%4c08#e~b-z_>>(36`57$OhKP~Iubwzimu#oEAQ`B|wbt?T(u7>#;m%UJEa?g9%|qB#<=!(gq)#xOIk9+ Date: Tue, 7 Jan 2025 15:07:00 +0000 Subject: [PATCH 027/286] 8346965: Multiple compiler/ciReplay test fails with -XX:+SegmentedCodeCache Reviewed-by: kvn --- test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java index a974a09d61517..017242c6d9ec3 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java +++ b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -71,6 +71,7 @@ public abstract class CiReplayBase { "-XX:-BackgroundCompilation", "-XX:CompileCommand=inline,java.io.PrintStream::*", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222", // extra profile data as a stress test "-XX:+CICountNative", "-XX:CICrashAt=1", "-XX:+DumpReplayDataOnError", + "-XX:-SegmentedCodeCache", REPLAY_FILE_OPTION}; private static final String[] REPLAY_OPTIONS = new String[]{DISABLE_COREDUMP_ON_CRASH, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222", From 4d8fb80732fd17352c36254c6dfc1be5dbfbacf1 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Tue, 7 Jan 2025 15:08:24 +0000 Subject: [PATCH 028/286] 8347038: [JMH] jdk.incubator.vector.SpiltReplicate fails NoClassDefFoundError Reviewed-by: psandoz --- .../openjdk/bench/jdk/incubator/vector/SpiltReplicate.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java index 9f717908569a6..447eab012de24 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -31,7 +31,7 @@ @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Fork(1) +@Fork(value=1, jvmArgs={"--add-modules=jdk.incubator.vector"}) public class SpiltReplicate { @CompilerControl(CompilerControl.Mode.DONT_INLINE) public long broadcastInt() { From c8a9dd3a027781d006850c028714a62903c487d5 Mon Sep 17 00:00:00 2001 From: Per Minborg Date: Tue, 7 Jan 2025 15:18:02 +0000 Subject: [PATCH 029/286] 8346609: Improve MemorySegment.toString Reviewed-by: mcimadamore --- .../foreign/AbstractMemorySegmentImpl.java | 17 +++++++++++++---- test/jdk/java/foreign/TestByteBuffer.java | 3 ++- test/jdk/java/foreign/TestSegments.java | 4 +++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index a52881b047b18..e51e158c93c97 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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 @@ -486,9 +486,18 @@ public int characteristics() { @Override public String toString() { - return "MemorySegment{ " + - heapBase().map(hb -> "heapBase: " + hb + ", ").orElse("") + - "address: " + Utils.toHexString(address()) + + final String kind; + if (this instanceof HeapMemorySegmentImpl) { + kind = "heap"; + } else if (this instanceof MappedMemorySegmentImpl) { + kind = "mapped"; + } else { + kind = "native"; + } + return "MemorySegment{ kind: " + + kind + + heapBase().map(hb -> ", heapBase: " + hb).orElse("") + + ", address: " + Utils.toHexString(address()) + ", byteSize: " + length + " }"; } diff --git a/test/jdk/java/foreign/TestByteBuffer.java b/test/jdk/java/foreign/TestByteBuffer.java index a77f97018caf4..3a5d1ef7c970d 100644 --- a/test/jdk/java/foreign/TestByteBuffer.java +++ b/test/jdk/java/foreign/TestByteBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -260,6 +260,7 @@ public void testMappedSegmentOperations(MappedSegmentOp mappedBufferOp) throws T try (FileChannel fileChannel = FileChannel.open(f.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE)) { MemorySegment segment = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0L, 8L, arena); assertTrue(segment.isMapped()); + assertTrue(segment.toString().contains("mapped")); arena.close(); mappedBufferOp.apply(segment); } diff --git a/test/jdk/java/foreign/TestSegments.java b/test/jdk/java/foreign/TestSegments.java index a76bc69fbd8ae..af63959673484 100644 --- a/test/jdk/java/foreign/TestSegments.java +++ b/test/jdk/java/foreign/TestSegments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -234,8 +234,10 @@ public void testToString(Supplier segmentSupplier) { assertTrue(s.contains("byteSize: ")); if (segment.heapBase().isPresent()) { assertTrue(s.contains("heapBase: [")); + assertFalse(s.contains("native")); } else { assertFalse(s.contains("heapBase: ")); + assertTrue(s.contains("native")); } assertFalse(s.contains("Optional")); } From 030149fec4f175e5571e053fa56d2921d95c6b13 Mon Sep 17 00:00:00 2001 From: Renjith Kannath Pariyangad Date: Tue, 7 Jan 2025 16:54:04 +0000 Subject: [PATCH 030/286] 8334644: Automate javax/print/attribute/PageRangesException.java Reviewed-by: aivanov, abhiscxk, azvegint --- .../print/attribute/PageRangesException.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 test/jdk/javax/print/attribute/PageRangesException.java diff --git a/test/jdk/javax/print/attribute/PageRangesException.java b/test/jdk/javax/print/attribute/PageRangesException.java new file mode 100644 index 0000000000000..81f9eb1a59289 --- /dev/null +++ b/test/jdk/javax/print/attribute/PageRangesException.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.print.attribute.standard.PageRanges; + +/* + * @test + * @bug 4433126 4433096 + * @key printer + * @summary The line "ERROR: " should NOT appear. + * @run main PageRangesException + */ + +public class PageRangesException { + public static void main(String[] args) throws Exception { + // test 4433126 + try { + PageRanges pr = new PageRanges("0:22"); + throw new RuntimeException("ERROR: no exceptions"); + } catch (IllegalArgumentException ie) { + System.out.println("OKAY: IllegalArgumentException " + ie); + } + + // test 4433096 + try { + int[][] m = null; + PageRanges pr = new PageRanges(m); + throw new RuntimeException("ERROR: NullPointerException expected"); + } catch (IllegalArgumentException ie) { + throw new RuntimeException("ERROR: IllegalArgumentException", ie); + } catch (NullPointerException e) { + System.out.println("OKAY: NullPointerException"); + } + } +} From 9702accdd9a25e05628d470bf248edd5d80c0c4d Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Tue, 7 Jan 2025 17:40:01 +0000 Subject: [PATCH 031/286] 8175709: DateTimeFormatterBuilder.appendZoneId() has misleading JavaDoc Reviewed-by: rriggs --- .../time/format/DateTimeFormatterBuilder.java | 69 +++++++++---------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java index 33dea914b6690..7c83de46c52b8 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java @@ -1097,14 +1097,14 @@ public DateTimeFormatterBuilder appendLocalizedOffset(TextStyle style) { * During parsing, the text must match a known zone or offset. * There are two types of zone ID, offset-based, such as '+01:30' and * region-based, such as 'Europe/London'. These are parsed differently. - * If the parse starts with '+', '-', 'UT', 'UTC' or 'GMT', then the parser - * expects an offset-based zone and will not match region-based zones. - * The offset ID, such as '+02:30', may be at the start of the parse, - * or prefixed by 'UT', 'UTC' or 'GMT'. The offset ID parsing is - * equivalent to using {@link #appendOffset(String, String)} using the - * arguments 'HH:MM:ss' and the no offset string '0'. - * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser cannot - * match a following offset ID, then {@link ZoneOffset#UTC} is selected. + * If the parse starts with '+' or '-', then the parser expects an + * offset-based zone and will not match region-based zones. The offset + * ID parsing is equivalent to using {@link #appendOffset(String, String)} + * using the arguments 'HH:MM:ss' and the no offset string '0'. + * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser can + * match a following offset, then a region-based zone with the parsed + * offset will be returned, or else if the parser cannot match a following + * offset, then {@link ZoneOffset#UTC} is selected. * In all other cases, the list of known region-based zones is used to * find the longest available match. If no match is found, and the parse * starts with 'Z', then {@code ZoneOffset.UTC} is selected. @@ -1118,9 +1118,9 @@ public DateTimeFormatterBuilder appendLocalizedOffset(TextStyle style) { * "UTC" -- ZoneId.of("UTC") * "GMT" -- ZoneId.of("GMT") * "+01:30" -- ZoneOffset.of("+01:30") - * "UT+01:30" -- ZoneOffset.of("+01:30") - * "UTC+01:30" -- ZoneOffset.of("+01:30") - * "GMT+01:30" -- ZoneOffset.of("+01:30") + * "UT+01:30" -- ZoneId.of("UT+01:30") + * "UTC+01:30" -- ZoneId.of("UTC+01:30") + * "GMT+01:30" -- ZoneId.of("GMT+01:30") * * * @return this, for chaining, not null @@ -1135,8 +1135,7 @@ public DateTimeFormatterBuilder appendZoneId() { * Appends the time-zone region ID, such as 'Europe/Paris', to the formatter, * rejecting the zone ID if it is a {@code ZoneOffset}. *

    - * This appends an instruction to format/parse the zone ID to the builder - * only if it is a region-based ID. + * This appends an instruction to format only region-based zone IDs to the builder. *

    * During formatting, the zone is obtained using a mechanism equivalent * to querying the temporal with {@link TemporalQueries#zoneId()}. @@ -1148,14 +1147,14 @@ public DateTimeFormatterBuilder appendZoneId() { * During parsing, the text must match a known zone or offset. * There are two types of zone ID, offset-based, such as '+01:30' and * region-based, such as 'Europe/London'. These are parsed differently. - * If the parse starts with '+', '-', 'UT', 'UTC' or 'GMT', then the parser - * expects an offset-based zone and will not match region-based zones. - * The offset ID, such as '+02:30', may be at the start of the parse, - * or prefixed by 'UT', 'UTC' or 'GMT'. The offset ID parsing is - * equivalent to using {@link #appendOffset(String, String)} using the - * arguments 'HH:MM:ss' and the no offset string '0'. - * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser cannot - * match a following offset ID, then {@link ZoneOffset#UTC} is selected. + * If the parse starts with '+' or '-', then the parser expects an + * offset-based zone and will not match region-based zones. The offset + * ID parsing is equivalent to using {@link #appendOffset(String, String)} + * using the arguments 'HH:MM:ss' and the no offset string '0'. + * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser can + * match a following offset, then a region-based zone with the parsed + * offset will be returned, or else if the parser cannot match a following + * offset, then {@link ZoneOffset#UTC} is selected. * In all other cases, the list of known region-based zones is used to * find the longest available match. If no match is found, and the parse * starts with 'Z', then {@code ZoneOffset.UTC} is selected. @@ -1169,9 +1168,9 @@ public DateTimeFormatterBuilder appendZoneId() { * "UTC" -- ZoneId.of("UTC") * "GMT" -- ZoneId.of("GMT") * "+01:30" -- ZoneOffset.of("+01:30") - * "UT+01:30" -- ZoneOffset.of("+01:30") - * "UTC+01:30" -- ZoneOffset.of("+01:30") - * "GMT+01:30" -- ZoneOffset.of("+01:30") + * "UT+01:30" -- ZoneId.of("UT+01:30") + * "UTC+01:30" -- ZoneId.of("UTC+01:30") + * "GMT+01:30" -- ZoneId.of("GMT+01:30") * *

    * Note that this method is identical to {@code appendZoneId()} except @@ -1206,14 +1205,14 @@ public DateTimeFormatterBuilder appendZoneRegionId() { * During parsing, the text must match a known zone or offset. * There are two types of zone ID, offset-based, such as '+01:30' and * region-based, such as 'Europe/London'. These are parsed differently. - * If the parse starts with '+', '-', 'UT', 'UTC' or 'GMT', then the parser - * expects an offset-based zone and will not match region-based zones. - * The offset ID, such as '+02:30', may be at the start of the parse, - * or prefixed by 'UT', 'UTC' or 'GMT'. The offset ID parsing is - * equivalent to using {@link #appendOffset(String, String)} using the - * arguments 'HH:MM:ss' and the no offset string '0'. - * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser cannot - * match a following offset ID, then {@link ZoneOffset#UTC} is selected. + * If the parse starts with '+' or '-', then the parser expects an + * offset-based zone and will not match region-based zones. The offset + * ID parsing is equivalent to using {@link #appendOffset(String, String)} + * using the arguments 'HH:MM:ss' and the no offset string '0'. + * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser can + * match a following offset, then a region-based zone with the parsed + * offset will be returned, or else if the parser cannot match a following + * offset, then {@link ZoneOffset#UTC} is selected. * In all other cases, the list of known region-based zones is used to * find the longest available match. If no match is found, and the parse * starts with 'Z', then {@code ZoneOffset.UTC} is selected. @@ -1227,9 +1226,9 @@ public DateTimeFormatterBuilder appendZoneRegionId() { * "UTC" -- ZoneId.of("UTC") * "GMT" -- ZoneId.of("GMT") * "+01:30" -- ZoneOffset.of("+01:30") - * "UT+01:30" -- ZoneOffset.of("UT+01:30") - * "UTC+01:30" -- ZoneOffset.of("UTC+01:30") - * "GMT+01:30" -- ZoneOffset.of("GMT+01:30") + * "UT+01:30" -- ZoneId.of("UT+01:30") + * "UTC+01:30" -- ZoneId.of("UTC+01:30") + * "GMT+01:30" -- ZoneId.of("GMT+01:30") * *

    * Note that this method is identical to {@code appendZoneId()} except From e413fc643c4a58e3c46d81025c3ac9fbf89db4b9 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 7 Jan 2025 19:34:12 +0000 Subject: [PATCH 032/286] 8347127: CTW fails to build after JDK-8334733 Reviewed-by: kvn, epeter --- test/hotspot/jtreg/testlibrary/ctw/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/testlibrary/ctw/Makefile b/test/hotspot/jtreg/testlibrary/ctw/Makefile index 5c64c67d82873..ea133f9762190 100644 --- a/test/hotspot/jtreg/testlibrary/ctw/Makefile +++ b/test/hotspot/jtreg/testlibrary/ctw/Makefile @@ -53,6 +53,7 @@ WB_CLASS_FILES := $(subst $(TESTLIBRARY_DIR)/,,$(WB_SRC_FILES)) WB_CLASS_FILES := $(patsubst %.java,%.class,$(WB_CLASS_FILES)) EXPORTS=--add-exports java.base/jdk.internal.jimage=ALL-UNNAMED \ --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \ + --add-exports java.base/jdk.internal.module=ALL-UNNAMED \ --add-exports java.base/jdk.internal.reflect=ALL-UNNAMED \ --add-exports java.base/jdk.internal.access=ALL-UNNAMED From 098afc8b7d0e7caa82999fb9d4e319ea8aed09a1 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Tue, 7 Jan 2025 22:03:38 +0000 Subject: [PATCH 033/286] 8339113: AccessFlags can be u2 in metadata Co-authored-by: Amit Kumar Reviewed-by: sspitsyn, vlivanov, yzheng, dlong, dholmes --- .../cpu/aarch64/interp_masm_aarch64.cpp | 4 +- .../cpu/aarch64/sharedRuntime_aarch64.cpp | 4 +- .../templateInterpreterGenerator_aarch64.cpp | 18 +++---- src/hotspot/cpu/arm/interp_masm_arm.cpp | 4 +- .../arm/templateInterpreterGenerator_arm.cpp | 16 +++--- src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp | 6 +-- src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp | 4 +- .../ppc/templateInterpreterGenerator_ppc.cpp | 16 +++--- src/hotspot/cpu/riscv/interp_masm_riscv.cpp | 4 +- src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp | 4 +- .../templateInterpreterGenerator_riscv.cpp | 18 +++---- src/hotspot/cpu/s390/interp_masm_s390.cpp | 4 +- src/hotspot/cpu/s390/macroAssembler_s390.cpp | 14 ++++- src/hotspot/cpu/s390/macroAssembler_s390.hpp | 3 +- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 4 +- .../templateInterpreterGenerator_s390.cpp | 24 +++++---- src/hotspot/cpu/x86/interp_masm_x86.cpp | 4 +- src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp | 4 +- .../x86/templateInterpreterGenerator_x86.cpp | 18 +++---- .../templateInterpreterGenerator_x86_64.cpp | 6 +-- src/hotspot/share/c1/c1_LIRGenerator.cpp | 4 +- src/hotspot/share/ci/ciFlags.cpp | 4 +- src/hotspot/share/ci/ciFlags.hpp | 39 +++++++------- src/hotspot/share/ci/ciKlass.cpp | 4 +- .../share/classfile/classFileParser.cpp | 12 ++--- src/hotspot/share/classfile/javaClasses.cpp | 6 +-- src/hotspot/share/classfile/vmIntrinsics.cpp | 14 ++--- src/hotspot/share/classfile/vmIntrinsics.hpp | 6 +-- .../share/interpreter/linkResolver.cpp | 4 +- .../jfr/leakprofiler/chains/edgeUtils.cpp | 4 +- .../recorder/checkpoint/types/jfrTypeSet.cpp | 8 +-- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 4 +- src/hotspot/share/jvmci/jvmciEnv.cpp | 6 +-- src/hotspot/share/jvmci/vmStructs_jvmci.cpp | 5 +- src/hotspot/share/oops/fieldInfo.cpp | 6 +-- src/hotspot/share/oops/fieldInfo.inline.hpp | 4 +- src/hotspot/share/oops/instanceKlass.cpp | 8 +-- src/hotspot/share/oops/instanceKlass.hpp | 8 ++- src/hotspot/share/oops/klass.hpp | 42 +++++++-------- src/hotspot/share/oops/method.cpp | 6 +-- src/hotspot/share/oops/method.hpp | 4 +- src/hotspot/share/oops/objArrayKlass.cpp | 6 +-- src/hotspot/share/oops/objArrayKlass.hpp | 4 +- src/hotspot/share/oops/typeArrayKlass.cpp | 4 +- src/hotspot/share/oops/typeArrayKlass.hpp | 4 +- src/hotspot/share/opto/library_call.cpp | 13 +++-- src/hotspot/share/opto/memnode.cpp | 10 ++-- src/hotspot/share/prims/jvm.cpp | 14 ++--- .../prims/jvmtiClassFileReconstituter.cpp | 8 +-- src/hotspot/share/prims/jvmtiEnv.cpp | 6 +-- .../share/prims/jvmtiRedefineClasses.cpp | 16 +++--- src/hotspot/share/prims/methodHandles.cpp | 12 ++--- src/hotspot/share/runtime/reflection.cpp | 8 +-- src/hotspot/share/runtime/vmStructs.cpp | 6 +-- src/hotspot/share/utilities/accessFlags.cpp | 4 +- src/hotspot/share/utilities/accessFlags.hpp | 51 +++++++++---------- .../sun/jvm/hotspot/oops/AccessFlags.java | 7 +-- .../jvm/hotspot/runtime/ClassConstants.java | 11 +--- 58 files changed, 278 insertions(+), 283 deletions(-) diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp index 836caa86cb0af..017e86a9dc30f 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -503,7 +503,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags ldr(r1, Address(rfp, frame::interpreter_frame_method_offset * wordSize)); - ldr(r2, Address(r1, Method::access_flags_offset())); + ldrh(r2, Address(r1, Method::access_flags_offset())); tbz(r2, exact_log2(JVM_ACC_SYNCHRONIZED), unlocked); // Don't unlock anything if the _do_not_unlock_if_synchronized flag diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index fa48092fd505a..6010ddd25fe33 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -760,7 +760,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ ldrw(rscratch1, Address(rmethod, Method::access_flags_offset())); + __ ldrh(rscratch1, Address(rmethod, Method::access_flags_offset())); __ andsw(zr, rscratch1, JVM_ACC_STATIC); __ br(Assembler::EQ, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index f70450b722223..0a3240fa56efc 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -809,7 +809,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::NE, L); __ stop("method doesn't need synchronization"); @@ -820,7 +820,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ ldr(r0, Address(rlocals, Interpreter::local_offset_in_bytes(0))); @@ -1225,7 +1225,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); { Label L; __ tst(r0, JVM_ACC_NATIVE); @@ -1277,7 +1277,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::EQ, L); __ stop("method needs synchronization"); @@ -1354,7 +1354,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ ldrw(t, Address(rmethod, Method::access_flags_offset())); + __ ldrh(t, Address(rmethod, Method::access_flags_offset())); __ tbz(t, exact_log2(JVM_ACC_STATIC), L); // get mirror __ load_mirror(t, rmethod, r10, rscratch2); @@ -1564,7 +1564,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ ldrw(t, Address(rmethod, Method::access_flags_offset())); + __ ldrh(t, Address(rmethod, Method::access_flags_offset())); __ tbz(t, exact_log2(JVM_ACC_SYNCHRONIZED), L); // the code below should be shared with interpreter macro // assembler implementation @@ -1695,7 +1695,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); { Label L; __ tst(r0, JVM_ACC_NATIVE); @@ -1751,7 +1751,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::EQ, L); __ stop("method needs synchronization"); diff --git a/src/hotspot/cpu/arm/interp_masm_arm.cpp b/src/hotspot/cpu/arm/interp_masm_arm.cpp index 3a81fdddb3c32..b70a4b495b2cc 100644 --- a/src/hotspot/cpu/arm/interp_masm_arm.cpp +++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, 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 @@ -736,7 +736,7 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a ldrb(Rflag, do_not_unlock_if_synchronized); // get method access flags - ldr_u32(Raccess_flags, Address(Rmethod, Method::access_flags_offset())); + ldrh(Raccess_flags, Address(Rmethod, Method::access_flags_offset())); strb(zero_register(Rtemp), do_not_unlock_if_synchronized); // reset the flag diff --git a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp index 9df7a455eeb84..d84ae9d14d67a 100644 --- a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, 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 @@ -579,7 +579,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbnz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method doesn't need synchronization"); __ bind(L); @@ -588,7 +588,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tst(Rtemp, JVM_ACC_STATIC); __ ldr(R0, Address(Rlocals, Interpreter::local_offset_in_bytes(0)), eq); // get receiver (assume this is frequent case) __ b(done, eq); @@ -851,7 +851,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); { Label L; __ tbnz(Rtemp, JVM_ACC_NATIVE_BIT, L); @@ -893,7 +893,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // no synchronization necessary #ifdef ASSERT { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method needs synchronization"); __ bind(L); @@ -975,7 +975,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Pass JNIEnv and mirror for static methods { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ add(R0, Rthread, in_bytes(JavaThread::jni_environment_offset())); __ tbz(Rtemp, JVM_ACC_STATIC_BIT, L); __ load_mirror(Rtemp, Rmethod, Rtemp); @@ -1204,7 +1204,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); { Label L; __ tbz(Rtemp, JVM_ACC_NATIVE_BIT, L); @@ -1249,7 +1249,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // no synchronization necessary #ifdef ASSERT { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method needs synchronization"); __ bind(L); diff --git a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp index 67b9bdc04142f..e097adb1dbfc6 100644 --- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -681,14 +681,14 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, // Check if synchronized method or unlocking prevented by // JavaThread::do_not_unlock_if_synchronized flag. lbz(Rdo_not_unlock_flag, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); - lwz(Raccess_flags, in_bytes(Method::access_flags_offset()), R19_method); + lhz(Raccess_flags, in_bytes(Method::access_flags_offset()), R19_method); li(R0, 0); stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); // reset flag push(state); // Skip if we don't have to unlock. - rldicl_(R0, Raccess_flags, 64-JVM_ACC_SYNCHRONIZED_BIT, 63); // Extract bit and compare to 0. + testbitdi(CCR0, R0, Raccess_flags, JVM_ACC_SYNCHRONIZED_BIT); beq(CCR0, Lunlocked); cmpwi(CCR0, Rdo_not_unlock_flag, 0); diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index c2e4c2e9b55c9..bad1a037b9a20 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1202,7 +1202,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ lwz(R0, in_bytes(Method::access_flags_offset()), R19_method); + __ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method); __ andi_(R0, R0, JVM_ACC_STATIC); __ beq(CCR0, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp index 9147dfc1677ab..ec372bfb07d9d 100644 --- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -144,9 +144,9 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // TODO PPC port: requires change in shared code. //assert(in_bytes(AccessFlags::flags_offset()) == 0, // "MethodDesc._access_flags == MethodDesc._access_flags._flags"); - // _access_flags must be a 32 bit value. - assert(sizeof(AccessFlags) == 4, "wrong size"); - __ lwa(R11_scratch1/*access_flags*/, method_(access_flags)); + // _access_flags must be a 16 bit value. + assert(sizeof(AccessFlags) == 2, "wrong size"); + __ lhz(R11_scratch1/*access_flags*/, method_(access_flags)); // testbit with condition register. __ testbitdi(CCR0, R0, R11_scratch1/*access_flags*/, JVM_ACC_STATIC_BIT); __ btrue(CCR0, L); @@ -823,7 +823,7 @@ void TemplateInterpreterGenerator::lock_method(Register Rflags, Register Rscratc { if (!flags_preloaded) { - __ lwz(Rflags, method_(access_flags)); + __ lhz(Rflags, method_(access_flags)); } #ifdef ASSERT @@ -1301,8 +1301,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { assert(__ nonvolatile_accross_vthread_preemtion(access_flags), "access_flags not preserved"); // Type check. - assert(4 == sizeof(AccessFlags), "unexpected field size"); - __ lwz(access_flags, method_(access_flags)); + assert(2 == sizeof(AccessFlags), "unexpected field size"); + __ lhz(access_flags, method_(access_flags)); // We don't want to reload R19_method and access_flags after calls // to some helper functions. @@ -1769,7 +1769,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT else { Label Lok; - __ lwz(R0, in_bytes(Method::access_flags_offset()), R19_method); + __ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method); __ andi_(R0, R0, JVM_ACC_SYNCHRONIZED); __ asm_assert_eq("method needs synchronization"); __ bind(Lok); diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index e17a3765b50ec..70fec29d4f7e7 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -544,7 +544,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags ld(x11, Address(fp, frame::interpreter_frame_method_offset * wordSize)); - ld(x12, Address(x11, Method::access_flags_offset())); + load_unsigned_short(x12, Address(x11, Method::access_flags_offset())); test_bit(t0, x12, exact_log2(JVM_ACC_SYNCHRONIZED)); beqz(t0, unlocked); diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 9af1b6a9bb128..12e38d97b1342 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -641,7 +641,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ lwu(t0, Address(xmethod, Method::access_flags_offset())); + __ load_unsigned_short(t0, Address(xmethod, Method::access_flags_offset())); __ test_bit(t1, t0, exact_log2(JVM_ACC_STATIC)); __ beqz(t1, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index 5ea9077a2b72a..a2187b35bd5b1 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -714,14 +714,14 @@ void TemplateInterpreterGenerator::lock_method() { const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method doesn't need synchronization", false); #endif // ASSERT // get synchronization object { Label done; - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ andi(t0, x10, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ ld(x10, Address(xlocals, Interpreter::local_offset_in_bytes(0))); @@ -1028,7 +1028,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_NATIVE, "tried to execute non-native method as native", false); __ verify_access_flags(x10, JVM_ACC_ABSTRACT, "tried to execute abstract method in interpreter"); #endif @@ -1066,7 +1066,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { } else { // no synchronization necessary #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method needs synchronization"); #endif } @@ -1130,7 +1130,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ lwu(t, Address(xmethod, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(xmethod, Method::access_flags_offset())); __ test_bit(t0, t, exact_log2(JVM_ACC_STATIC)); __ beqz(t0, L); // get mirror @@ -1346,7 +1346,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ lwu(t, Address(xmethod, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(xmethod, Method::access_flags_offset())); __ test_bit(t0, t, exact_log2(JVM_ACC_SYNCHRONIZED)); __ beqz(t0, L); // the code below should be shared with interpreter macro @@ -1472,7 +1472,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_NATIVE, "tried to execute native method as non-native"); __ verify_access_flags(x10, JVM_ACC_ABSTRACT, "tried to execute abstract method in interpreter"); #endif @@ -1519,7 +1519,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { } else { // no synchronization necessary #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method needs synchronization"); #endif } diff --git a/src/hotspot/cpu/s390/interp_masm_s390.cpp b/src/hotspot/cpu/s390/interp_masm_s390.cpp index 5e80817aaba7b..0e31dbd33e198 100644 --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -780,7 +780,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, get_method(R_method); verify_oop(Z_tos, state); push(state); // Save tos/result. - testbit(method2_(R_method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + testbit_ushort(method2_(R_method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); z_bfalse(unlocked); // Don't unlock anything if the _do_not_unlock_if_synchronized flag diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index a069d6ceafbf0..3647aca0008b8 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * Copyright 2024 IBM Corporation. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -1015,6 +1015,18 @@ void MacroAssembler::load_and_test_long(Register dst, const Address &a) { z_ltg(dst, a); } +// Test a bit in memory for 2 byte datatype. +void MacroAssembler::testbit_ushort(const Address &a, unsigned int bit) { + assert(a.index() == noreg, "no index reg allowed in testbit"); + if (bit <= 7) { + z_tm(a.disp() + 1, a.base(), 1 << bit); + } else if (bit <= 15) { + z_tm(a.disp() + 0, a.base(), 1 << (bit - 8)); + } else { + ShouldNotReachHere(); + } +} + // Test a bit in memory. void MacroAssembler::testbit(const Address &a, unsigned int bit) { assert(a.index() == noreg, "no index reg allowed in testbit"); diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.hpp b/src/hotspot/cpu/s390/macroAssembler_s390.hpp index 159688128189a..d45f1321e0f28 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * Copyright (c) 2024 IBM Corporation. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -199,6 +199,7 @@ class MacroAssembler: public Assembler { // Test a bit in memory. Result is reflected in CC. void testbit(const Address &a, unsigned int bit); + void testbit_ushort(const Address &a, unsigned int bit); // Test a bit in a register. Result is reflected in CC. void testbit(Register r, unsigned int bitPos); diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index 2396a2a71059f..62f5c8fa524b4 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -2395,7 +2395,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ testbit(Address(Z_method, Method::access_flags_offset()), JVM_ACC_STATIC_BIT); + __ testbit_ushort(Address(Z_method, Method::access_flags_offset()), JVM_ACC_STATIC_BIT); __ z_bfalse(L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp index 1c4089d5beb07..99179bcad0611 100644 --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -164,7 +164,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // Therefore add 3 to address that byte within "_flags". // Reload method. VM call above may have destroyed register contents __ get_method(method); - __ testbit(method2_(method, access_flags), JVM_ACC_STATIC_BIT); + __ testbit_ushort(method2_(method, access_flags), JVM_ACC_STATIC_BIT); method = noreg; // end of life __ z_btrue(isStatic); @@ -883,7 +883,7 @@ void TemplateInterpreterGenerator::lock_method(void) { address reentry = nullptr; { Label L; - __ testbit(method2_(method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit_ushort(method2_(method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_btrue(L); reentry = __ stop_chain_static(reentry, "method doesn't need synchronization"); __ bind(L); @@ -897,7 +897,7 @@ void TemplateInterpreterGenerator::lock_method(void) { Label done; Label static_method; - __ testbit(method2_(method, access_flags), JVM_ACC_STATIC_BIT); + __ testbit_ushort(method2_(method, access_flags), JVM_ACC_STATIC_BIT); __ z_btrue(static_method); // non-static method: Load receiver obj from stack. @@ -1349,15 +1349,17 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Make sure method is native and not abstract. #ifdef ASSERT + // _access_flags must be a 16 bit value. + assert(sizeof(AccessFlags) == 2, "testbit_ushort will fail"); address reentry = nullptr; { Label L; - __ testbit(method_(access_flags), JVM_ACC_NATIVE_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_NATIVE_BIT); __ z_btrue(L); reentry = __ stop_chain_static(reentry, "tried to execute non-native method as native"); __ bind(L); } { Label L; - __ testbit(method_(access_flags), JVM_ACC_ABSTRACT_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_ABSTRACT_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute abstract method as non-abstract"); __ bind(L); @@ -1403,7 +1405,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; __ get_method(Z_R1_scratch); - __ testbit(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit_ushort(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "method needs synchronization"); __ bind(L); @@ -1461,7 +1463,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Pass mirror handle if static call. { Label method_is_not_static; - __ testbit(method2_(Rmethod, access_flags), JVM_ACC_STATIC_BIT); + __ testbit_ushort(method2_(Rmethod, access_flags), JVM_ACC_STATIC_BIT); __ z_bfalse(method_is_not_static); // Load mirror from interpreter frame. __ z_lg(Z_R1, _z_ijava_state_neg(mirror), Z_fp); @@ -1719,13 +1721,13 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT address reentry = nullptr; { Label L; - __ testbit(method_(access_flags), JVM_ACC_NATIVE_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_NATIVE_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute native method as non-native"); __ bind(L); } { Label L; - __ testbit(method_(access_flags), JVM_ACC_ABSTRACT_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_ABSTRACT_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute abstract method as non-abstract"); __ bind(L); @@ -1775,7 +1777,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; __ get_method(Z_R1_scratch); - __ testbit(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit_ushort(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "method needs synchronization"); __ bind(L); diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp index 3a3f01a640983..ff5b1c1454dfc 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -1030,7 +1030,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); - movl(rcx, Address(rcx, Method::access_flags_offset())); + load_unsigned_short(rcx, Address(rcx, Method::access_flags_offset())); testl(rcx, JVM_ACC_SYNCHRONIZED); jcc(Assembler::zero, unlocked); diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index ab7cbb9437453..b9901a1e95bf7 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -1099,7 +1099,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm { // Bypass the barrier for non-static methods Register flags = rscratch1; - __ movl(flags, Address(method, Method::access_flags_offset())); + __ load_unsigned_short(flags, Address(method, Method::access_flags_offset())); __ testl(flags, JVM_ACC_STATIC); __ jcc(Assembler::zero, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp index 823b965a09b51..b4e005faff3b9 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -596,7 +596,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::notZero, L); __ stop("method doesn't need synchronization"); @@ -607,7 +607,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ movptr(rax, Address(rlocals, Interpreter::local_offset_in_bytes(0))); @@ -855,7 +855,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); { Label L; __ testl(rax, JVM_ACC_NATIVE); @@ -909,7 +909,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); __ stop("method needs synchronization"); @@ -999,7 +999,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ movl(t, Address(method, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(method, Method::access_flags_offset())); __ testl(t, JVM_ACC_STATIC); __ jcc(Assembler::zero, L); // get mirror @@ -1280,7 +1280,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ movl(t, Address(method, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(method, Method::access_flags_offset())); __ testl(t, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); // the code below should be shared with interpreter macro @@ -1432,7 +1432,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); { Label L; __ testl(rax, JVM_ACC_NATIVE); @@ -1489,7 +1489,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); __ stop("method needs synchronization"); diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp index 5ea2d8eba259b..b2124c6b157f4 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -74,7 +74,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // Do Int register here switch ( i ) { case 0: - __ movl(rscratch1, Address(rbx, Method::access_flags_offset())); + __ load_unsigned_short(rscratch1, Address(rbx, Method::access_flags_offset())); __ testl(rscratch1, JVM_ACC_STATIC); __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); break; @@ -159,7 +159,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { } // Now handle integrals. Only do c_rarg1 if not static. - __ movl(c_rarg3, Address(rbx, Method::access_flags_offset())); + __ load_unsigned_short(c_rarg3, Address(rbx, Method::access_flags_offset())); __ testl(c_rarg3, JVM_ACC_STATIC); __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index 74fdf7a5b76a3..2df2fbf8adca9 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -1337,7 +1337,7 @@ void LIRGenerator::do_getModifiers(Intrinsic* x) { __ cmove(lir_cond_equal, prim_klass, recv_klass, klass, T_ADDRESS); // Get the answer. - __ move(new LIR_Address(klass, in_bytes(Klass::modifier_flags_offset()), T_INT), result); + __ move(new LIR_Address(klass, in_bytes(Klass::modifier_flags_offset()), T_CHAR), result); } void LIRGenerator::do_getObjectSize(Intrinsic* x) { diff --git a/src/hotspot/share/ci/ciFlags.cpp b/src/hotspot/share/ci/ciFlags.cpp index 1401a432a9e18..043470a32a227 100644 --- a/src/hotspot/share/ci/ciFlags.cpp +++ b/src/hotspot/share/ci/ciFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -92,5 +92,5 @@ void ciFlags::print_member_flags(outputStream* st) { // ------------------------------------------------------------------ // ciFlags::print void ciFlags::print(outputStream* st) { - st->print(" flags=%x", _flags); + st->print(" flags=%x", _flags.as_unsigned_short()); } diff --git a/src/hotspot/share/ci/ciFlags.hpp b/src/hotspot/share/ci/ciFlags.hpp index dd1df622487f3..426f953611fee 100644 --- a/src/hotspot/share/ci/ciFlags.hpp +++ b/src/hotspot/share/ci/ciFlags.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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,7 +26,6 @@ #define SHARE_CI_CIFLAGS_HPP #include "ci/ciClassList.hpp" -#include "jvm_constants.h" #include "utilities/accessFlags.hpp" #include "utilities/ostream.hpp" @@ -39,37 +38,37 @@ class ciFlags { friend class ciField; friend class ciMethod; - jint _flags; + AccessFlags _flags; bool _stable; - bool _intialized_final_update; + bool _initialized_final_update; - ciFlags() :_flags(0), _stable(false), _intialized_final_update(false) { } + ciFlags() :_flags(0), _stable(false), _initialized_final_update(false) { } ciFlags(AccessFlags flags, bool is_stable = false, bool is_initialized_final_update = false) : - _flags(flags.as_int()), _stable(is_stable), _intialized_final_update(is_initialized_final_update) { } + _flags(flags), _stable(is_stable), _initialized_final_update(is_initialized_final_update) { } public: // Java access flags - bool is_public () const { return (_flags & JVM_ACC_PUBLIC ) != 0; } - bool is_private () const { return (_flags & JVM_ACC_PRIVATE ) != 0; } - bool is_protected () const { return (_flags & JVM_ACC_PROTECTED ) != 0; } - bool is_static () const { return (_flags & JVM_ACC_STATIC ) != 0; } - bool is_final () const { return (_flags & JVM_ACC_FINAL ) != 0; } - bool is_synchronized () const { return (_flags & JVM_ACC_SYNCHRONIZED ) != 0; } - bool is_super () const { return (_flags & JVM_ACC_SUPER ) != 0; } - bool is_volatile () const { return (_flags & JVM_ACC_VOLATILE ) != 0; } - bool is_transient () const { return (_flags & JVM_ACC_TRANSIENT ) != 0; } - bool is_native () const { return (_flags & JVM_ACC_NATIVE ) != 0; } - bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; } - bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; } + bool is_public () const { return _flags.is_public(); } + bool is_private () const { return _flags.is_private(); } + bool is_protected () const { return _flags.is_protected(); } + bool is_static () const { return _flags.is_static(); } + bool is_final () const { return _flags.is_final(); } + bool is_synchronized () const { return _flags.is_synchronized(); } + bool is_super () const { return _flags.is_super(); } + bool is_volatile () const { return _flags.is_volatile(); } + bool is_transient () const { return _flags.is_transient(); } + bool is_native () const { return _flags.is_native(); } + bool is_interface () const { return _flags.is_interface(); } + bool is_abstract () const { return _flags.is_abstract(); } bool is_stable () const { return _stable; } // In case the current object represents a field, return true if // the field is modified outside of instance initializer methods // (or class/initializer methods if the field is static) and false // otherwise. - bool has_initialized_final_update() const { return _intialized_final_update; }; + bool has_initialized_final_update() const { return _initialized_final_update; }; // Conversion - jint as_int() { return _flags; } + jint as_int() { return _flags.as_unsigned_short(); } void print_klass_flags(outputStream* st = tty); void print_member_flags(outputStream* st = tty); diff --git a/src/hotspot/share/ci/ciKlass.cpp b/src/hotspot/share/ci/ciKlass.cpp index f65d4a0311c82..e14e237167d8c 100644 --- a/src/hotspot/share/ci/ciKlass.cpp +++ b/src/hotspot/share/ci/ciKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -222,7 +222,7 @@ jint ciKlass::modifier_flags() { jint ciKlass::access_flags() { assert(is_loaded(), "not loaded"); GUARDED_VM_ENTRY( - return get_Klass()->access_flags().as_int(); + return get_Klass()->access_flags().as_unsigned_short(); ) } diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index 5c58f20000616..c552e48c8b8e9 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -2981,7 +2981,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea "Class is both outer and inner class in class file %s", CHECK_0); } // Access flags - jint flags; + u2 flags; // JVM_ACC_MODULE is defined in JDK-9 and later. if (_major_version >= JAVA_9_VERSION) { flags = cfs->get_u2_fast() & (RECOGNIZED_INNER_CLASS_MODIFIERS | JVM_ACC_MODULE); @@ -2998,7 +2998,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea inner_classes->at_put(index++, inner_class_info_index); inner_classes->at_put(index++, outer_class_info_index); inner_classes->at_put(index++, inner_name_index); - inner_classes->at_put(index++, inner_access_flags.as_short()); + inner_classes->at_put(index++, inner_access_flags.as_unsigned_short()); } // Check for circular and duplicate entries. @@ -3750,7 +3750,7 @@ void ClassFileParser::apply_parsed_class_metadata( // Initialize cached modifier_flags to support Class.getModifiers(). // This must follow setting inner_class attributes. - int computed_modifiers = this_klass->compute_modifier_flags(); + u2 computed_modifiers = this_klass->compute_modifier_flags(); this_klass->set_modifier_flags(computed_modifiers); // Delay the setting of _local_interfaces and _transitive_interfaces until after @@ -5336,7 +5336,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream, assert(_stream != nullptr, "invariant"); assert(_stream->buffer() == _stream->current(), "invariant"); assert(_class_name != nullptr, "invariant"); - assert(0 == _access_flags.as_int(), "invariant"); + assert(0 == _access_flags.as_unsigned_short(), "invariant"); // Figure out whether we can skip format checking (matching classic VM behavior) _need_verify = Verifier::should_verify_for(_loader_data->class_loader()); @@ -5488,7 +5488,7 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream, stream->guarantee_more(8, CHECK); // flags, this_class, super_class, infs_len // Access flags - jint flags; + u2 flags; // JVM_ACC_MODULE is defined in JDK-9 and later. if (_major_version >= JAVA_9_VERSION) { flags = stream->get_u2_fast() & (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_MODULE); diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 1aedb43973c57..650d0a9fa744d 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -3169,7 +3169,7 @@ void java_lang_ClassFrameInfo::serialize_offsets(SerializeClosure* f) { #endif static int get_flags(const methodHandle& m) { - int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); + int flags = m->access_flags().as_method_flags(); if (m->is_object_initializer()) { flags |= java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR; } else { @@ -5537,7 +5537,7 @@ int InjectedField::compute_offset() { ik->print(); tty->print_cr("all fields:"); for (AllFieldStream fs(ik); !fs.done(); fs.next()) { - tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int()); + tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_field_flags()); } #endif //PRODUCT vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class"); diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp index 407cdafaf2017..38226d232ef66 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.cpp +++ b/src/hotspot/share/classfile/vmIntrinsics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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 @@ -36,31 +36,31 @@ #include "utilities/tribool.hpp" // These are flag-matching functions: -inline bool match_F_R(jshort flags) { +inline bool match_F_R(u2 flags) { const int req = 0; const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_Y(jshort flags) { +inline bool match_F_Y(u2 flags) { const int req = JVM_ACC_SYNCHRONIZED; const int neg = JVM_ACC_STATIC | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_RN(jshort flags) { +inline bool match_F_RN(u2 flags) { const int req = JVM_ACC_NATIVE; const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED; return (flags & (req | neg)) == req; } -inline bool match_F_S(jshort flags) { +inline bool match_F_S(u2 flags) { const int req = JVM_ACC_STATIC; const int neg = JVM_ACC_SYNCHRONIZED | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_SN(jshort flags) { +inline bool match_F_SN(u2 flags) { const int req = JVM_ACC_STATIC | JVM_ACC_NATIVE; const int neg = JVM_ACC_SYNCHRONIZED; return (flags & (req | neg)) == req; @@ -711,7 +711,7 @@ bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) { vmIntrinsics::ID vmIntrinsics::find_id_impl(vmSymbolID holder, vmSymbolID name, vmSymbolID sig, - jshort flags) { + u2 flags) { assert((int)vmSymbolID::SID_LIMIT <= (1<is_array_klass()) { // We need to change "protected" to "public". assert(flags.is_protected(), "clone not protected?"); - jint new_flags = flags.as_int(); + u2 new_flags = flags.as_method_flags(); new_flags = new_flags & (~JVM_ACC_PROTECTED); new_flags = new_flags | JVM_ACC_PUBLIC; flags.set_flags(new_flags); diff --git a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp index edb87c7fc8e41..27b01e99e5567 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, 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 @@ -72,7 +72,7 @@ const Symbol* EdgeUtils::field_name(const Edge& edge, jshort* modifiers) { JavaFieldStream jfs(ik); while (!jfs.done()) { if (offset == jfs.offset()) { - *modifiers = jfs.access_flags().as_short(); + *modifiers = jfs.access_flags().as_field_flags(); return jfs.name(); } jfs.next(); diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp index a53eaa474f3f0..bc5f97c719af9 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -227,9 +227,9 @@ static traceid method_id(KlassPtr klass, MethodPtr method) { } template -static s4 get_flags(const T* ptr) { +static u2 get_flags(const T* ptr) { assert(ptr != nullptr, "invariant"); - return ptr->access_flags().get_flags(); + return ptr->access_flags().as_unsigned_short(); } // Same as JVM_GetClassModifiers @@ -968,7 +968,7 @@ static int write_method(JfrCheckpointWriter* writer, MethodPtr method, bool leak writer->write(artifact_id(klass)); writer->write(mark_symbol(method->name(), leakp)); writer->write(mark_symbol(method->signature(), leakp)); - writer->write(static_cast(get_flags(method))); + writer->write(get_flags(method)); writer->write(get_visibility(method)); return 1; } diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 9052e6228945b..1fa3f23173ce3 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 @@ -1000,7 +1000,7 @@ C2V_VMENTRY_NULL(jobject, resolveFieldInPool, (JNIEnv* env, jobject, ARGUMENT_PA if (info.is_null() || JVMCIENV->get_length(info) != 4) { JVMCI_ERROR_NULL("info must not be null and have a length of 4"); } - JVMCIENV->put_int_at(info, 0, fd.access_flags().as_int()); + JVMCIENV->put_int_at(info, 0, fd.access_flags().as_field_flags()); JVMCIENV->put_int_at(info, 1, fd.offset()); JVMCIENV->put_int_at(info, 2, fd.index()); JVMCIENV->put_int_at(info, 3, fd.field_flags().as_uint()); diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 712745e2a021c..1a53f6b6d2cc1 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -1592,7 +1592,7 @@ JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) { HotSpotJVMCI::FieldInfo::set_nameIndex(JVMCIENV, obj_h(), (jint)fieldinfo->name_index()); HotSpotJVMCI::FieldInfo::set_signatureIndex(JVMCIENV, obj_h(), (jint)fieldinfo->signature_index()); HotSpotJVMCI::FieldInfo::set_offset(JVMCIENV, obj_h(), (jint)fieldinfo->offset()); - HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_int()); + HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_field_flags()); HotSpotJVMCI::FieldInfo::set_internalFlags(JVMCIENV, obj_h(), (jint)fieldinfo->field_flags().as_uint()); HotSpotJVMCI::FieldInfo::set_initializerIndex(JVMCIENV, obj_h(), (jint)fieldinfo->initializer_index()); return wrap(obj_h()); @@ -1603,7 +1603,7 @@ JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) { (jint)fieldinfo->name_index(), (jint)fieldinfo->signature_index(), (jint)fieldinfo->offset(), - (jint)fieldinfo->access_flags().as_int(), + (jint)fieldinfo->access_flags().as_field_flags(), (jint)fieldinfo->field_flags().as_uint(), (jint)fieldinfo->initializer_index()); diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index ba47e5599578f..97447c43b6e5a 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -273,7 +273,7 @@ nonstatic_field(Klass, _name, Symbol*) \ volatile_nonstatic_field(Klass, _next_sibling, Klass*) \ nonstatic_field(Klass, _java_mirror, OopHandle) \ - nonstatic_field(Klass, _modifier_flags, jint) \ + nonstatic_field(Klass, _modifier_flags, u2) \ nonstatic_field(Klass, _access_flags, AccessFlags) \ nonstatic_field(Klass, _class_loader_data, ClassLoaderData*) \ nonstatic_field(Klass, _secondary_supers_bitmap, uintx) \ @@ -488,7 +488,6 @@ declare_constant(InvocationEntryBci) \ declare_constant(JVMCINMethodData::SPECULATION_LENGTH_BITS) \ \ - declare_constant(JVM_ACC_WRITTEN_FLAGS) \ declare_constant(FieldInfo::FieldFlags::_ff_injected) \ declare_constant(FieldInfo::FieldFlags::_ff_stable) \ declare_preprocessor_constant("JVM_ACC_VARARGS", JVM_ACC_VARARGS) \ diff --git a/src/hotspot/share/oops/fieldInfo.cpp b/src/hotspot/share/oops/fieldInfo.cpp index 50a3b427d178e..3ae91a03b6797 100644 --- a/src/hotspot/share/oops/fieldInfo.cpp +++ b/src/hotspot/share/oops/fieldInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -34,7 +34,7 @@ void FieldInfo::print(outputStream* os, ConstantPool* cp) { name_index(), name(cp)->as_utf8(), signature_index(), signature(cp)->as_utf8(), offset(), - access_flags().as_int(), + access_flags().as_field_flags(), field_flags().as_uint(), initializer_index(), generic_signature_index(), @@ -97,7 +97,7 @@ Array* FieldInfoStream::create_FieldInfoStream(GrowableArray* fie assert(fi_ref->name_index() == fi.name_index(), "Must be"); assert(fi_ref->signature_index() == fi.signature_index(), "Must be"); assert(fi_ref->offset() == fi.offset(), "Must be"); - assert(fi_ref->access_flags().as_int() == fi.access_flags().as_int(), "Must be"); + assert(fi_ref->access_flags().as_field_flags() == fi.access_flags().as_field_flags(), "Must be"); assert(fi_ref->field_flags().as_uint() == fi.field_flags().as_uint(), " Must be"); if(fi_ref->field_flags().is_initialized()) { assert(fi_ref->initializer_index() == fi.initializer_index(), "Must be"); diff --git a/src/hotspot/share/oops/fieldInfo.inline.hpp b/src/hotspot/share/oops/fieldInfo.inline.hpp index 2e6727f1fb9f1..bf37d280510f7 100644 --- a/src/hotspot/share/oops/fieldInfo.inline.hpp +++ b/src/hotspot/share/oops/fieldInfo.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -73,7 +73,7 @@ inline void Mapper::map_field_info(const FieldInfo& fi) { _consumer->accept_uint(fi.name_index()); _consumer->accept_uint(fi.signature_index()); _consumer->accept_uint(fi.offset()); - _consumer->accept_uint(fi.access_flags().as_int()); + _consumer->accept_uint(fi.access_flags().as_field_flags()); _consumer->accept_uint(fi.field_flags().as_uint()); if(fi.field_flags().has_any_optionals()) { if (fi.field_flags().is_initialized()) { diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index ce46da55f986b..43b078a8af233 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -3339,8 +3339,8 @@ InstanceKlass* InstanceKlass::compute_enclosing_class(bool* inner_is_member, TRA return outer_klass; } -jint InstanceKlass::compute_modifier_flags() const { - jint access = access_flags().as_int(); +u2 InstanceKlass::compute_modifier_flags() const { + u2 access = access_flags().as_unsigned_short(); // But check if it happens to be member class. InnerClassesIterator iter(this); @@ -3360,7 +3360,7 @@ jint InstanceKlass::compute_modifier_flags() const { } } // Remember to strip ACC_SUPER bit - return (access & (~JVM_ACC_SUPER)) & JVM_ACC_WRITTEN_FLAGS; + return (access & (~JVM_ACC_SUPER)); } jint InstanceKlass::jvmti_class_status() const { diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 8209a692a8242..cedc17e9bafde 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -391,7 +391,7 @@ class InstanceKlass: public Klass { public: int field_offset (int index) const { return field(index).offset(); } - int field_access_flags(int index) const { return field(index).access_flags().as_int(); } + int field_access_flags(int index) const { return field(index).access_flags().as_field_flags(); } FieldInfo::FieldFlags field_flags(int index) const { return field(index).field_flags(); } FieldStatus field_status(int index) const { return fields_status()->at(index); } inline Symbol* field_name (int index) const; @@ -682,8 +682,6 @@ class InstanceKlass: public Klass { #if INCLUDE_JVMTI // Redefinition locking. Class can only be redefined by one thread at a time. - // The flag is in access_flags so that it can be set and reset using atomic - // operations, and not be reset by other misc_flag settings. bool is_being_redefined() const { return _misc_flags.is_being_redefined(); } void set_is_being_redefined(bool value) { _misc_flags.set_is_being_redefined(value); } @@ -1127,7 +1125,7 @@ class InstanceKlass: public Klass { void compute_has_loops_flag_for_methods(); #endif - jint compute_modifier_flags() const; + u2 compute_modifier_flags() const; public: // JVMTI support diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 2c75d6da3b8cb..d27665bbcc121 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -66,7 +66,7 @@ class Klass : public Metadata { friend class JVMCIVMStructs; public: // Klass Kinds for all subclasses of Klass - enum KlassKind { + enum KlassKind : u2 { InstanceKlassKind, InstanceRefKlassKind, InstanceMirrorKlassKind, @@ -113,15 +113,20 @@ class Klass : public Metadata { // // Final note: This comes first, immediately after C++ vtable, // because it is frequently queried. - jint _layout_helper; + jint _layout_helper; // Klass kind used to resolve the runtime type of the instance. // - Used to implement devirtualized oop closure dispatching. // - Various type checking in the JVM const KlassKind _kind; + AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. + // Some flags created by the JVM, not in the class file itself, + // are in _misc_flags below. // Processed access flags, for use by Class.getModifiers. - jint _modifier_flags; + u2 _modifier_flags; + + KlassFlags _misc_flags; // The fields _super_check_offset, _secondary_super_cache, _secondary_supers // and _primary_supers all help make fast subtype checks. See big discussion @@ -157,22 +162,12 @@ class Klass : public Metadata { // Provide access the corresponding instance java.lang.ClassLoader. ClassLoaderData* _class_loader_data; + markWord _prototype_header; // Used to initialize objects' header + // Bitmap and hash code used by hashed secondary supers. uintx _secondary_supers_bitmap; uint8_t _hash_slot; - markWord _prototype_header; // Used to initialize objects' header - - int _vtable_len; // vtable length. This field may be read very often when we - // have lots of itable dispatches (e.g., lambdas and streams). - // Keep it away from the beginning of a Klass to avoid cacheline - // contention that may happen when a nearby object is modified. - AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. - // Some flags created by the JVM, not in the class file itself, - // are in _misc_flags below. - - JFR_ONLY(DEFINE_TRACE_ID_FIELD;) - private: // This is an index into FileMapHeader::_shared_path_table[], to // associate this class with the JAR file where it's loaded from during @@ -200,10 +195,17 @@ class Klass : public Metadata { }; #endif - KlassFlags _misc_flags; + int _vtable_len; // vtable length. This field may be read very often when we + // have lots of itable dispatches (e.g., lambdas and streams). + // Keep it away from the beginning of a Klass to avoid cacheline + // contention that may happen when a nearby object is modified. CDS_JAVA_HEAP_ONLY(int _archived_mirror_index;) +public: + + JFR_ONLY(DEFINE_TRACE_ID_FIELD;) + protected: Klass(KlassKind kind); @@ -292,8 +294,8 @@ class Klass : public Metadata { void clear_java_mirror_handle() { _java_mirror = OopHandle(); } // modifier flags - jint modifier_flags() const { return _modifier_flags; } - void set_modifier_flags(jint flags) { _modifier_flags = flags; } + u2 modifier_flags() const { return _modifier_flags; } + void set_modifier_flags(u2 flags) { _modifier_flags = flags; } // size helper int layout_helper() const { return _layout_helper; } @@ -756,7 +758,7 @@ class Klass : public Metadata { virtual void release_C_heap_structures(bool release_constant_pool = true); public: - virtual jint compute_modifier_flags() const = 0; + virtual u2 compute_modifier_flags() const = 0; // JVMTI support virtual jint jvmti_class_status() const; diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index d0b29a4a30992..ab15379409f76 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -1652,8 +1652,8 @@ void Method::init_intrinsic_id(vmSymbolID klass_id) { && sig_id == vmSymbolID::NO_SID) { return; } - jshort flags = access_flags().as_short(); + u2 flags = access_flags().as_method_flags(); vmIntrinsics::ID id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags); if (id != vmIntrinsics::_none) { set_intrinsic_id(id); @@ -2300,7 +2300,7 @@ void Method::print_on(outputStream* st) const { st->print (" - method holder: "); method_holder()->print_value_on(st); st->cr(); st->print (" - constants: " PTR_FORMAT " ", p2i(constants())); constants()->print_value_on(st); st->cr(); - st->print (" - access: 0x%x ", access_flags().as_int()); access_flags().print_on(st); st->cr(); + st->print (" - access: 0x%x ", access_flags().as_method_flags()); access_flags().print_on(st); st->cr(); st->print (" - flags: 0x%x ", _flags.as_int()); _flags.print_on(st); st->cr(); st->print (" - name: "); name()->print_value_on(st); st->cr(); st->print (" - signature: "); signature()->print_value_on(st); st->cr(); diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index 271d8b3986378..7b13337ecafcf 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -75,8 +75,8 @@ class Method : public Metadata { MethodData* _method_data; MethodCounters* _method_counters; AdapterHandlerEntry* _adapter; - AccessFlags _access_flags; // Access flags int _vtable_index; // vtable index of this method (see VtableIndexFlag) + AccessFlags _access_flags; // Access flags MethodFlags _flags; u2 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none) diff --git a/src/hotspot/share/oops/objArrayKlass.cpp b/src/hotspot/share/oops/objArrayKlass.cpp index 04bc374e5226c..903c5660d5311 100644 --- a/src/hotspot/share/oops/objArrayKlass.cpp +++ b/src/hotspot/share/oops/objArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -341,12 +341,12 @@ void ObjArrayKlass::metaspace_pointers_do(MetaspaceClosure* it) { it->push(&_bottom_klass); } -jint ObjArrayKlass::compute_modifier_flags() const { +u2 ObjArrayKlass::compute_modifier_flags() const { // The modifier for an objectArray is the same as its element assert (element_klass() != nullptr, "should be initialized"); // Return the flags of the bottom element type. - jint element_flags = bottom_klass()->compute_modifier_flags(); + u2 element_flags = bottom_klass()->compute_modifier_flags(); return (element_flags & (JVM_ACC_PUBLIC | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED)) | (JVM_ACC_ABSTRACT | JVM_ACC_FINAL); diff --git a/src/hotspot/share/oops/objArrayKlass.hpp b/src/hotspot/share/oops/objArrayKlass.hpp index e16f1f2eb0fcd..c44c8d28f6247 100644 --- a/src/hotspot/share/oops/objArrayKlass.hpp +++ b/src/hotspot/share/oops/objArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -143,7 +143,7 @@ class ObjArrayKlass : public ArrayKlass { inline void oop_oop_iterate_elements_bounded(objArrayOop a, OopClosureType* closure, void* low, void* high); public: - jint compute_modifier_flags() const; + u2 compute_modifier_flags() const; public: // Printing diff --git a/src/hotspot/share/oops/typeArrayKlass.cpp b/src/hotspot/share/oops/typeArrayKlass.cpp index 8ca6a49fc46a4..86c4f9d7138c4 100644 --- a/src/hotspot/share/oops/typeArrayKlass.cpp +++ b/src/hotspot/share/oops/typeArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -75,7 +75,7 @@ TypeArrayKlass* TypeArrayKlass::allocate(ClassLoaderData* loader_data, BasicType return new (loader_data, size, THREAD) TypeArrayKlass(type, name); } -jint TypeArrayKlass::compute_modifier_flags() const { +u2 TypeArrayKlass::compute_modifier_flags() const { return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; } diff --git a/src/hotspot/share/oops/typeArrayKlass.hpp b/src/hotspot/share/oops/typeArrayKlass.hpp index 9dc3ed607fe3a..6ec72ae49c0c8 100644 --- a/src/hotspot/share/oops/typeArrayKlass.hpp +++ b/src/hotspot/share/oops/typeArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -73,7 +73,7 @@ class TypeArrayKlass : public ArrayKlass { // Copying void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS); - jint compute_modifier_flags() const; + u2 compute_modifier_flags() const; // Oop iterators. Since there are no oops in TypeArrayKlasses, // these functions only return the size of the object. diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 40b19eecd9f65..56cfb9fe16e7b 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -3871,7 +3871,7 @@ Node* LibraryCallKit::generate_klass_flags_guard(Node* kls, int modifier_mask, i } Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { return generate_klass_flags_guard(kls, JVM_ACC_INTERFACE, 0, region, - Klass::access_flags_offset(), TypeInt::INT, T_INT); + Klass::access_flags_offset(), TypeInt::CHAR, T_CHAR); } // Use this for testing if Klass is_hidden, has_finalizer, and is_cloneable_fast. @@ -3904,8 +3904,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { break; case vmIntrinsics::_getModifiers: prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); - assert(is_power_of_2((int)JVM_ACC_WRITTEN_FLAGS+1), "change next line"); - return_type = TypeInt::make(0, JVM_ACC_WRITTEN_FLAGS, Type::WidenMin); + return_type = TypeInt::CHAR; break; case vmIntrinsics::_isInterface: prim_return_value = intcon(0); @@ -3927,7 +3926,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { break; case vmIntrinsics::_getClassAccessFlags: prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); - return_type = TypeInt::INT; // not bool! 6297094 + return_type = TypeInt::CHAR; break; default: fatal_unexpected_iid(id); @@ -3988,7 +3987,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { case vmIntrinsics::_getModifiers: p = basic_plus_adr(kls, in_bytes(Klass::modifier_flags_offset())); - query_value = make_load(nullptr, p, TypeInt::INT, T_INT, MemNode::unordered); + query_value = make_load(nullptr, p, TypeInt::CHAR, T_CHAR, MemNode::unordered); break; case vmIntrinsics::_isInterface: @@ -4053,7 +4052,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { case vmIntrinsics::_getClassAccessFlags: p = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset())); - query_value = make_load(nullptr, p, TypeInt::INT, T_INT, MemNode::unordered); + query_value = make_load(nullptr, p, TypeInt::CHAR, T_CHAR, MemNode::unordered); break; default: diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index ad351fb81add7..78ffbe05ae492 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Alibaba Group Holding Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1976,24 +1976,24 @@ LoadNode::load_array_final_field(const TypeKlassPtr *tkls, if (tkls->offset() == in_bytes(Klass::modifier_flags_offset())) { // The field is Klass::_modifier_flags. Return its (constant) value. // (Folds up the 2nd indirection in aClassConstant.getModifiers().) - assert(this->Opcode() == Op_LoadI, "must load an int from _modifier_flags"); + assert(Opcode() == Op_LoadUS, "must load an unsigned short from _modifier_flags"); return TypeInt::make(klass->modifier_flags()); } if (tkls->offset() == in_bytes(Klass::access_flags_offset())) { // The field is Klass::_access_flags. Return its (constant) value. // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) - assert(this->Opcode() == Op_LoadI, "must load an int from _access_flags"); + assert(Opcode() == Op_LoadUS, "must load an unsigned short from _access_flags"); return TypeInt::make(klass->access_flags()); } if (tkls->offset() == in_bytes(Klass::misc_flags_offset())) { // The field is Klass::_misc_flags. Return its (constant) value. // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) - assert(this->Opcode() == Op_LoadUB, "must load an unsigned byte from _misc_flags"); + assert(Opcode() == Op_LoadUB, "must load an unsigned byte from _misc_flags"); return TypeInt::make(klass->misc_flags()); } if (tkls->offset() == in_bytes(Klass::layout_helper_offset())) { // The field is Klass::_layout_helper. Return its constant value if known. - assert(this->Opcode() == Op_LoadI, "must load an int from _layout_helper"); + assert(Opcode() == Op_LoadI, "must load an int from _layout_helper"); return TypeInt::make(klass->layout_helper()); } diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 12c7898f4cf19..198165cdd1ed9 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -1306,7 +1306,7 @@ JVM_ENTRY(jint, JVM_GetClassModifiers(JNIEnv *env, jclass cls)) } Klass* k = java_lang_Class::as_Klass(mirror); - debug_only(int computed_modifiers = k->compute_modifier_flags()); + debug_only(u2 computed_modifiers = k->compute_modifier_flags()); assert(k->modifier_flags() == computed_modifiers, "modifiers cache is OK"); return k->modifier_flags(); JVM_END @@ -1817,7 +1817,7 @@ JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)) } Klass* k = java_lang_Class::as_Klass(mirror); - return k->access_flags().as_int() & JVM_ACC_WRITTEN_FLAGS; + return k->access_flags().as_class_flags(); } JVM_END @@ -2460,14 +2460,14 @@ JVM_ENTRY(jint, JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_ind Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); Method* method = InstanceKlass::cast(k)->methods()->at(method_index); - return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + return method->access_flags().as_method_flags(); JVM_END JVM_ENTRY(jint, JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)) Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); - return InstanceKlass::cast(k)->field_access_flags(field_index) & JVM_RECOGNIZED_FIELD_MODIFIERS; + return InstanceKlass::cast(k)->field_access_flags(field_index); JVM_END @@ -2657,7 +2657,7 @@ JVM_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, j InstanceKlass* ik = InstanceKlass::cast(k_called); for (JavaFieldStream fs(ik); !fs.done(); fs.next()) { if (fs.name() == name && fs.signature() == signature) { - return fs.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS; + return fs.access_flags().as_field_flags(); } } return -1; @@ -2686,7 +2686,7 @@ JVM_ENTRY(jint, JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, for (int i = 0; i < methods_count; i++) { Method* method = methods->at(i); if (method->name() == name && method->signature() == signature) { - return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + return method->access_flags().as_method_flags(); } } return -1; diff --git a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp index ceed1d8ad952a..10fb4121472e4 100644 --- a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp +++ b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -85,7 +85,7 @@ void JvmtiClassFileReconstituter::write_field_infos() { // JVMSpec| attribute_info attributes[attributes_count]; // JVMSpec| } - write_u2(access_flags.get_flags() & JVM_RECOGNIZED_FIELD_MODIFIERS); + write_u2(access_flags.as_field_flags()); write_u2(name_index); write_u2(signature_index); u2 attr_count = 0; @@ -704,7 +704,7 @@ void JvmtiClassFileReconstituter::write_method_info(const methodHandle& method) return; } - write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS); + write_u2(access_flags.as_method_flags()); write_u2(const_method->name_index()); write_u2(const_method->signature_index()); @@ -919,7 +919,7 @@ void JvmtiClassFileReconstituter::write_class_file_format() { copy_cpool_bytes(writeable_address(cpool_size())); // JVMSpec| u2 access_flags; - write_u2(ik()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS); + write_u2(ik()->access_flags().as_class_flags()); // JVMSpec| u2 this_class; // JVMSpec| u2 super_class; diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index 554b4baf7b2a3..e97bfc300422e 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -3149,7 +3149,7 @@ jvmtiError JvmtiEnv::GetFieldModifiers(fieldDescriptor* fdesc_ptr, jint* modifiers_ptr) { AccessFlags resultFlags = fdesc_ptr->access_flags(); - jint result = resultFlags.as_int(); + jint result = resultFlags.as_field_flags(); *modifiers_ptr = result; return JVMTI_ERROR_NONE; @@ -3228,7 +3228,7 @@ JvmtiEnv::GetMethodDeclaringClass(Method* method, jclass* declaring_class_ptr) { jvmtiError JvmtiEnv::GetMethodModifiers(Method* method, jint* modifiers_ptr) { NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID); - (*modifiers_ptr) = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + (*modifiers_ptr) = method->access_flags().as_method_flags(); return JVMTI_ERROR_NONE; } /* end GetMethodModifiers */ diff --git a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp index a982ac97c4786..0a53eadbbd88b 100644 --- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -1005,8 +1005,8 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( } // Check whether class modifiers are the same. - jushort old_flags = (jushort) the_class->access_flags().get_flags(); - jushort new_flags = (jushort) scratch_class->access_flags().get_flags(); + u2 old_flags = the_class->access_flags().as_class_flags(); + u2 new_flags = scratch_class->access_flags().as_class_flags(); if (old_flags != new_flags) { log_info(redefine, class, normalize) ("redefined class %s modifiers change error: modifiers changed from %d to %d.", @@ -1040,9 +1040,9 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED; } // access - old_flags = old_fs.access_flags().as_short(); - new_flags = new_fs.access_flags().as_short(); - if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) { + old_flags = old_fs.access_flags().as_field_flags(); + new_flags = new_fs.access_flags().as_field_flags(); + if (old_flags != new_flags) { log_info(redefine, class, normalize) ("redefined class %s field %s change error: modifiers changed from %d to %d.", the_class->external_name(), name_sym2->as_C_string(), old_flags, new_flags); @@ -1147,8 +1147,8 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( switch (method_was) { case matched: // methods match, be sure modifiers do too - old_flags = (jushort) k_old_method->access_flags().get_flags(); - new_flags = (jushort) k_new_method->access_flags().get_flags(); + old_flags = k_old_method->access_flags().as_method_flags(); + new_flags = k_new_method->access_flags().as_method_flags(); if ((old_flags ^ new_flags) & ~(JVM_ACC_NATIVE)) { log_info(redefine, class, normalize) ("redefined class %s method %s modifiers error: modifiers changed from %d to %d", diff --git a/src/hotspot/share/prims/methodHandles.cpp b/src/hotspot/share/prims/methodHandles.cpp index 1e44ea957311e..5b40682851042 100644 --- a/src/hotspot/share/prims/methodHandles.cpp +++ b/src/hotspot/share/prims/methodHandles.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, 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 @@ -239,7 +239,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { assert(m.not_null(), "null method handle"); InstanceKlass* m_klass = m->method_holder(); assert(m_klass != nullptr, "null holder for method handle"); - int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); + int flags = (m->access_flags().as_method_flags()); int vmindex = Method::invalid_vtable_index; LogTarget(Debug, methodhandles, indy) lt_indy; @@ -352,7 +352,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { InstanceKlass* ik = fd.field_holder(); - int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); + int flags = fd.access_flags().as_field_flags(); flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); if (fd.is_trusted_final()) flags |= TRUSTED_FINAL; if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); @@ -404,7 +404,7 @@ bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) { Method* m = iklass->find_method(name, poly_sig); if (m != nullptr) { int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; - int flags = m->access_flags().as_int(); + int flags = m->access_flags().as_method_flags(); if ((flags & required) == required) { return true; } @@ -417,7 +417,7 @@ bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) { for (; ms < me; ms++) { Method* m = iklass->methods()->at(ms); int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; - int flags = m->access_flags().as_int(); + int flags = m->access_flags().as_method_flags(); if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) { return true; } @@ -522,7 +522,7 @@ bool MethodHandles::is_signature_polymorphic_public_name(Klass* klass, Symbol* n for (; ms < me; ms++) { Method* m = iklass->methods()->at(ms); int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS | JVM_ACC_PUBLIC; - int flags = m->access_flags().as_int(); + int flags = m->access_flags().as_method_flags(); if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) { return true; } diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp index 7739cff03bf23..3aef7028a7970 100644 --- a/src/hotspot/share/runtime/reflection.cpp +++ b/src/hotspot/share/runtime/reflection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -778,7 +778,7 @@ oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_ac Handle name = Handle(THREAD, name_oop); if (name == nullptr) return nullptr; - const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + const int modifiers = method->access_flags().as_method_flags(); Handle mh = java_lang_reflect_Method::create(CHECK_NULL); @@ -819,7 +819,7 @@ oop Reflection::new_constructor(const methodHandle& method, TRAPS) { objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); assert(!exception_types.is_null(), "cannot return null"); - const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + const int modifiers = method->access_flags().as_method_flags(); Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL); @@ -859,7 +859,7 @@ oop Reflection::new_field(fieldDescriptor* fd, TRAPS) { java_lang_reflect_Field::set_trusted_final(rh()); } // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here. - java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); + java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_field_flags()); java_lang_reflect_Field::set_override(rh(), false); if (fd->has_generic_signature()) { Symbol* gs = fd->generic_signature(); diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index f5cb2805c8ed9..b6e5457551929 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -263,7 +263,7 @@ nonstatic_field(Klass, _secondary_supers, Array*) \ nonstatic_field(Klass, _primary_supers[0], Klass*) \ nonstatic_field(Klass, _java_mirror, OopHandle) \ - nonstatic_field(Klass, _modifier_flags, jint) \ + nonstatic_field(Klass, _modifier_flags, u2) \ nonstatic_field(Klass, _super, Klass*) \ volatile_nonstatic_field(Klass, _subklass, Klass*) \ nonstatic_field(Klass, _layout_helper, jint) \ @@ -1017,7 +1017,7 @@ nonstatic_field(vframeArrayElement, _bci, int) \ nonstatic_field(vframeArrayElement, _method, Method*) \ \ - nonstatic_field(AccessFlags, _flags, jint) \ + nonstatic_field(AccessFlags, _flags, u2) \ nonstatic_field(elapsedTimer, _counter, jlong) \ nonstatic_field(elapsedTimer, _active, bool) \ nonstatic_field(InvocationCounter, _counter, unsigned int) \ diff --git a/src/hotspot/share/utilities/accessFlags.cpp b/src/hotspot/share/utilities/accessFlags.cpp index ec68d1244889c..fc11491174f71 100644 --- a/src/hotspot/share/utilities/accessFlags.cpp +++ b/src/hotspot/share/utilities/accessFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -47,5 +47,5 @@ void AccessFlags::print_on(outputStream* st) const { #endif // !PRODUCT || INCLUDE_JVMTI void accessFlags_init() { - assert(sizeof(AccessFlags) == sizeof(jint), "just checking size of flags"); + assert(sizeof(AccessFlags) == sizeof(u2), "just checking size of flags"); } diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index 74ccbd20ac142..a752c09cb4272 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -30,28 +30,19 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" -// AccessFlags is an abstraction over Java access flags. +// AccessFlags is an abstraction over Java ACC flags. +// See generated file classfile_constants.h for shared JVM_ACC_XXX access flags class outputStream; -enum { - // See jvm.h for shared JVM_ACC_XXX access flags - - // flags actually put in .class file - JVM_ACC_WRITTEN_FLAGS = 0x00007FFF, - - // Do not add new ACC flags here. -}; - - class AccessFlags { friend class VMStructs; private: - jint _flags; // TODO: move 4 access flags above to Klass and change to u2 + u2 _flags; public: AccessFlags() : _flags(0) {} - explicit AccessFlags(jint flags) : _flags(flags) {} + explicit AccessFlags(u2 flags) : _flags(flags) {} // Java access flags bool is_public () const { return (_flags & JVM_ACC_PUBLIC ) != 0; } @@ -70,15 +61,10 @@ class AccessFlags { // Attribute flags bool is_synthetic () const { return (_flags & JVM_ACC_SYNTHETIC ) != 0; } - // get .class file flags - jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); } + // get as integral value + u2 as_unsigned_short() const { return _flags; } - // Initialization - void set_field_flags(jint flags) { - assert((flags & JVM_RECOGNIZED_FIELD_MODIFIERS) == flags, "only recognized flags"); - _flags = (flags & JVM_RECOGNIZED_FIELD_MODIFIERS); - } - void set_flags(jint flags) { _flags = (flags & JVM_ACC_WRITTEN_FLAGS); } + void set_flags(u2 flags) { _flags = flags; } private: friend class Klass; @@ -90,11 +76,22 @@ class AccessFlags { void set_is_synthetic() { _flags |= JVM_ACC_SYNTHETIC; } public: - // Conversion - jshort as_short() const { return (jshort)_flags; } - jint as_int() const { return _flags; } + inline friend AccessFlags accessFlags_from(u2 flags); - inline friend AccessFlags accessFlags_from(jint flags); + u2 as_method_flags() const { + assert((_flags & JVM_RECOGNIZED_METHOD_MODIFIERS) == _flags, "only recognized flags"); + return _flags; + } + + u2 as_field_flags() const { + assert((_flags & JVM_RECOGNIZED_FIELD_MODIFIERS) == _flags, "only recognized flags"); + return _flags; + } + + u2 as_class_flags() const { + assert((_flags & JVM_RECOGNIZED_CLASS_MODIFIERS) == _flags, "only recognized flags"); + return _flags; + } // Printing/debugging #if INCLUDE_JVMTI @@ -104,7 +101,7 @@ class AccessFlags { #endif }; -inline AccessFlags accessFlags_from(jint flags) { +inline AccessFlags accessFlags_from(u2 flags) { AccessFlags af; af._flags = flags; return af; diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java index 2f310effc87f4..66ebd6551a4fd 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -75,9 +75,4 @@ public void printOn(PrintStream tty) { if (isStrict ()) tty.print("strict " ); if (isSynthetic ()) tty.print("synthetic " ); } - - // get flags written to .class files - public int getStandardFlags() { - return (int) (flags & JVM_ACC_WRITTEN_FLAGS); - } } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java index 25f40ec443f50..7f9a6b4b49d2a 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, 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 @@ -98,16 +98,7 @@ public interface ClassConstants public static final long JVM_ACC_ENUM = 0x4000; /* field is declared as element of enum */ - // from accessFlags.hpp - hotspot internal flags - - // flags actually put in .class file - public static final long JVM_ACC_WRITTEN_FLAGS = 0x00007FFF; - - // flags accepted by set_field_flags - public static final long JVM_ACC_FIELD_FLAGS = 0x00008000 | JVM_ACC_WRITTEN_FLAGS; - // from jvm.h - public static final long JVM_RECOGNIZED_CLASS_MODIFIERS = (JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_SUPER | From ddb58819640dc8f1930d243d6eb07ce88ef79b22 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Tue, 7 Jan 2025 23:14:04 +0000 Subject: [PATCH 034/286] 8329549: Remove FORMAT64_MODIFIER Reviewed-by: dholmes, kbarrett --- src/hotspot/share/runtime/os.cpp | 6 +++--- src/hotspot/share/utilities/globalDefinitions.hpp | 4 +++- .../share/utilities/globalDefinitions_gcc.hpp | 13 +------------ .../share/utilities/globalDefinitions_visCPP.hpp | 5 +---- .../gtest/utilities/test_globalDefinitions.cpp | 5 ++++- 5 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index f9f3c4e145848..9c73e255db2e1 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -971,7 +971,7 @@ static void print_hex_location(outputStream* st, const_address p, int unitsize, const uint64_t value = LITTLE_ENDIAN_ONLY((((uint64_t)i2) << 32) | i1) BIG_ENDIAN_ONLY((((uint64_t)i1) << 32) | i2); - st->print("%016" FORMAT64_MODIFIER "x", value); + st->print(UINT64_FORMAT_0, value); print_ascii_form(ascii_form, value, unitsize); } else { st->print_raw("????????????????"); @@ -995,7 +995,7 @@ static void print_hex_location(outputStream* st, const_address p, int unitsize, case 1: st->print("%02x", (u1)value); break; case 2: st->print("%04x", (u2)value); break; case 4: st->print("%08x", (u4)value); break; - case 8: st->print("%016" FORMAT64_MODIFIER "x", (u8)value); break; + case 8: st->print(UINT64_FORMAT_0, (u8)value); break; } print_ascii_form(ascii_form, value, unitsize); } else { diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index ce864119d75fd..86bee7a071f7e 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -99,6 +99,7 @@ class oopDesc; // _X_0 - print as hexadecimal, with leading 0s: 0x00012345 // _W(w) - prints w sized string with the given value right // adjusted. Use -w to print left adjusted. +// _0 - print as hexadecimal, with leading 0s, without 0x prefix: 0012345 // // Note that the PTR format specifiers print using 0x with leading zeros, // just like the _X_0 version for integers. @@ -131,6 +132,7 @@ class oopDesc; #define UINT64_FORMAT_X "0x%" PRIx64 #define UINT64_FORMAT_X_0 "0x%016" PRIx64 #define UINT64_FORMAT_W(width) "%" #width PRIu64 +#define UINT64_FORMAT_0 "%016" PRIx64 // Format integers which change size between 32- and 64-bit. #define SSIZE_FORMAT "%" PRIdPTR diff --git a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp index 863e588d18032..a2fbc3be3636b 100644 --- a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -90,17 +90,6 @@ inline int g_isfinite(jfloat f) { return isfinite(f); } inline int g_isfinite(jdouble f) { return isfinite(f); } -// Formatting. -#ifdef _LP64 -# ifdef __APPLE__ -# define FORMAT64_MODIFIER "ll" -# else -# define FORMAT64_MODIFIER "l" -# endif -#else // !_LP64 -#define FORMAT64_MODIFIER "ll" -#endif // _LP64 - // gcc warns about applying offsetof() to non-POD object or calculating // offset directly when base address is null. The -Wno-invalid-offsetof // option could be used to suppress this warning, but we instead just diff --git a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp index 3f22948118df9..83d075572877a 100644 --- a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -103,9 +103,6 @@ inline int g_isnan(jdouble f) { return _isnan(f); } inline int g_isfinite(jfloat f) { return _finite(f); } inline int g_isfinite(jdouble f) { return _finite(f); } -// Formatting. -#define FORMAT64_MODIFIER "ll" - #define offset_of(klass,field) offsetof(klass,field) #define THREAD_LOCAL __declspec(thread) diff --git a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp index 5dc43fb543f95..9cadc91aeb94d 100644 --- a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp +++ b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -289,4 +289,7 @@ TEST(globalDefinitions, format_specifiers) { check_format(INTPTR_FORMAT, (intptr_t)0x123, "0x" LP64_ONLY("00000000") "00000123"); check_format(PTR_FORMAT, (uintptr_t)0x123, "0x" LP64_ONLY("00000000") "00000123"); + + // Check all platforms print this compatibly without leading 0x. + check_format(UINT64_FORMAT_0, (u8)0x123, "0000000000000123"); } From 021c476409c52c65cc7b40516d81dedef040fe83 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 8 Jan 2025 00:37:27 +0000 Subject: [PATCH 035/286] 8347148: [BACKOUT] AccessFlags can be u2 in metadata Reviewed-by: coleenp --- .../cpu/aarch64/interp_masm_aarch64.cpp | 4 +- .../cpu/aarch64/sharedRuntime_aarch64.cpp | 4 +- .../templateInterpreterGenerator_aarch64.cpp | 18 +++---- src/hotspot/cpu/arm/interp_masm_arm.cpp | 4 +- .../arm/templateInterpreterGenerator_arm.cpp | 16 +++--- src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp | 6 +-- src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp | 4 +- .../ppc/templateInterpreterGenerator_ppc.cpp | 16 +++--- src/hotspot/cpu/riscv/interp_masm_riscv.cpp | 4 +- src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp | 4 +- .../templateInterpreterGenerator_riscv.cpp | 18 +++---- src/hotspot/cpu/s390/interp_masm_s390.cpp | 4 +- src/hotspot/cpu/s390/macroAssembler_s390.cpp | 14 +---- src/hotspot/cpu/s390/macroAssembler_s390.hpp | 3 +- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 4 +- .../templateInterpreterGenerator_s390.cpp | 24 ++++----- src/hotspot/cpu/x86/interp_masm_x86.cpp | 4 +- src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp | 4 +- .../x86/templateInterpreterGenerator_x86.cpp | 18 +++---- .../templateInterpreterGenerator_x86_64.cpp | 6 +-- src/hotspot/share/c1/c1_LIRGenerator.cpp | 4 +- src/hotspot/share/ci/ciFlags.cpp | 4 +- src/hotspot/share/ci/ciFlags.hpp | 39 +++++++------- src/hotspot/share/ci/ciKlass.cpp | 4 +- .../share/classfile/classFileParser.cpp | 12 ++--- src/hotspot/share/classfile/javaClasses.cpp | 6 +-- src/hotspot/share/classfile/vmIntrinsics.cpp | 14 ++--- src/hotspot/share/classfile/vmIntrinsics.hpp | 6 +-- .../share/interpreter/linkResolver.cpp | 4 +- .../jfr/leakprofiler/chains/edgeUtils.cpp | 4 +- .../recorder/checkpoint/types/jfrTypeSet.cpp | 8 +-- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 4 +- src/hotspot/share/jvmci/jvmciEnv.cpp | 6 +-- src/hotspot/share/jvmci/vmStructs_jvmci.cpp | 5 +- src/hotspot/share/oops/fieldInfo.cpp | 6 +-- src/hotspot/share/oops/fieldInfo.inline.hpp | 4 +- src/hotspot/share/oops/instanceKlass.cpp | 8 +-- src/hotspot/share/oops/instanceKlass.hpp | 8 +-- src/hotspot/share/oops/klass.hpp | 42 ++++++++------- src/hotspot/share/oops/method.cpp | 6 +-- src/hotspot/share/oops/method.hpp | 4 +- src/hotspot/share/oops/objArrayKlass.cpp | 6 +-- src/hotspot/share/oops/objArrayKlass.hpp | 4 +- src/hotspot/share/oops/typeArrayKlass.cpp | 4 +- src/hotspot/share/oops/typeArrayKlass.hpp | 4 +- src/hotspot/share/opto/library_call.cpp | 13 ++--- src/hotspot/share/opto/memnode.cpp | 10 ++-- src/hotspot/share/prims/jvm.cpp | 14 ++--- .../prims/jvmtiClassFileReconstituter.cpp | 8 +-- src/hotspot/share/prims/jvmtiEnv.cpp | 6 +-- .../share/prims/jvmtiRedefineClasses.cpp | 16 +++--- src/hotspot/share/prims/methodHandles.cpp | 12 ++--- src/hotspot/share/runtime/reflection.cpp | 8 +-- src/hotspot/share/runtime/vmStructs.cpp | 6 +-- src/hotspot/share/utilities/accessFlags.cpp | 4 +- src/hotspot/share/utilities/accessFlags.hpp | 51 ++++++++++--------- .../sun/jvm/hotspot/oops/AccessFlags.java | 7 ++- .../jvm/hotspot/runtime/ClassConstants.java | 11 +++- 58 files changed, 283 insertions(+), 278 deletions(-) diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp index 017e86a9dc30f..836caa86cb0af 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -503,7 +503,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags ldr(r1, Address(rfp, frame::interpreter_frame_method_offset * wordSize)); - ldrh(r2, Address(r1, Method::access_flags_offset())); + ldr(r2, Address(r1, Method::access_flags_offset())); tbz(r2, exact_log2(JVM_ACC_SYNCHRONIZED), unlocked); // Don't unlock anything if the _do_not_unlock_if_synchronized flag diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 6010ddd25fe33..fa48092fd505a 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -760,7 +760,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ ldrh(rscratch1, Address(rmethod, Method::access_flags_offset())); + __ ldrw(rscratch1, Address(rmethod, Method::access_flags_offset())); __ andsw(zr, rscratch1, JVM_ACC_STATIC); __ br(Assembler::EQ, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index 0a3240fa56efc..f70450b722223 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -809,7 +809,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ ldrh(r0, access_flags); + __ ldrw(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::NE, L); __ stop("method doesn't need synchronization"); @@ -820,7 +820,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ ldrh(r0, access_flags); + __ ldrw(r0, access_flags); __ tst(r0, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ ldr(r0, Address(rlocals, Interpreter::local_offset_in_bytes(0))); @@ -1225,7 +1225,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ ldrh(r0, access_flags); + __ ldrw(r0, access_flags); { Label L; __ tst(r0, JVM_ACC_NATIVE); @@ -1277,7 +1277,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ ldrh(r0, access_flags); + __ ldrw(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::EQ, L); __ stop("method needs synchronization"); @@ -1354,7 +1354,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ ldrh(t, Address(rmethod, Method::access_flags_offset())); + __ ldrw(t, Address(rmethod, Method::access_flags_offset())); __ tbz(t, exact_log2(JVM_ACC_STATIC), L); // get mirror __ load_mirror(t, rmethod, r10, rscratch2); @@ -1564,7 +1564,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ ldrh(t, Address(rmethod, Method::access_flags_offset())); + __ ldrw(t, Address(rmethod, Method::access_flags_offset())); __ tbz(t, exact_log2(JVM_ACC_SYNCHRONIZED), L); // the code below should be shared with interpreter macro // assembler implementation @@ -1695,7 +1695,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ ldrh(r0, access_flags); + __ ldrw(r0, access_flags); { Label L; __ tst(r0, JVM_ACC_NATIVE); @@ -1751,7 +1751,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ ldrh(r0, access_flags); + __ ldrw(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::EQ, L); __ stop("method needs synchronization"); diff --git a/src/hotspot/cpu/arm/interp_masm_arm.cpp b/src/hotspot/cpu/arm/interp_masm_arm.cpp index b70a4b495b2cc..3a81fdddb3c32 100644 --- a/src/hotspot/cpu/arm/interp_masm_arm.cpp +++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -736,7 +736,7 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a ldrb(Rflag, do_not_unlock_if_synchronized); // get method access flags - ldrh(Raccess_flags, Address(Rmethod, Method::access_flags_offset())); + ldr_u32(Raccess_flags, Address(Rmethod, Method::access_flags_offset())); strb(zero_register(Rtemp), do_not_unlock_if_synchronized); // reset the flag diff --git a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp index d84ae9d14d67a..9df7a455eeb84 100644 --- a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -579,7 +579,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbnz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method doesn't need synchronization"); __ bind(L); @@ -588,7 +588,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tst(Rtemp, JVM_ACC_STATIC); __ ldr(R0, Address(Rlocals, Interpreter::local_offset_in_bytes(0)), eq); // get receiver (assume this is frequent case) __ b(done, eq); @@ -851,7 +851,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); { Label L; __ tbnz(Rtemp, JVM_ACC_NATIVE_BIT, L); @@ -893,7 +893,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // no synchronization necessary #ifdef ASSERT { Label L; - __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method needs synchronization"); __ bind(L); @@ -975,7 +975,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Pass JNIEnv and mirror for static methods { Label L; - __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ add(R0, Rthread, in_bytes(JavaThread::jni_environment_offset())); __ tbz(Rtemp, JVM_ACC_STATIC_BIT, L); __ load_mirror(Rtemp, Rmethod, Rtemp); @@ -1204,7 +1204,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); { Label L; __ tbz(Rtemp, JVM_ACC_NATIVE_BIT, L); @@ -1249,7 +1249,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // no synchronization necessary #ifdef ASSERT { Label L; - __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method needs synchronization"); __ bind(L); diff --git a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp index e097adb1dbfc6..67b9bdc04142f 100644 --- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -681,14 +681,14 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, // Check if synchronized method or unlocking prevented by // JavaThread::do_not_unlock_if_synchronized flag. lbz(Rdo_not_unlock_flag, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); - lhz(Raccess_flags, in_bytes(Method::access_flags_offset()), R19_method); + lwz(Raccess_flags, in_bytes(Method::access_flags_offset()), R19_method); li(R0, 0); stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); // reset flag push(state); // Skip if we don't have to unlock. - testbitdi(CCR0, R0, Raccess_flags, JVM_ACC_SYNCHRONIZED_BIT); + rldicl_(R0, Raccess_flags, 64-JVM_ACC_SYNCHRONIZED_BIT, 63); // Extract bit and compare to 0. beq(CCR0, Lunlocked); cmpwi(CCR0, Rdo_not_unlock_flag, 0); diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index bad1a037b9a20..c2e4c2e9b55c9 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1202,7 +1202,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method); + __ lwz(R0, in_bytes(Method::access_flags_offset()), R19_method); __ andi_(R0, R0, JVM_ACC_STATIC); __ beq(CCR0, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp index ec372bfb07d9d..9147dfc1677ab 100644 --- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -144,9 +144,9 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // TODO PPC port: requires change in shared code. //assert(in_bytes(AccessFlags::flags_offset()) == 0, // "MethodDesc._access_flags == MethodDesc._access_flags._flags"); - // _access_flags must be a 16 bit value. - assert(sizeof(AccessFlags) == 2, "wrong size"); - __ lhz(R11_scratch1/*access_flags*/, method_(access_flags)); + // _access_flags must be a 32 bit value. + assert(sizeof(AccessFlags) == 4, "wrong size"); + __ lwa(R11_scratch1/*access_flags*/, method_(access_flags)); // testbit with condition register. __ testbitdi(CCR0, R0, R11_scratch1/*access_flags*/, JVM_ACC_STATIC_BIT); __ btrue(CCR0, L); @@ -823,7 +823,7 @@ void TemplateInterpreterGenerator::lock_method(Register Rflags, Register Rscratc { if (!flags_preloaded) { - __ lhz(Rflags, method_(access_flags)); + __ lwz(Rflags, method_(access_flags)); } #ifdef ASSERT @@ -1301,8 +1301,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { assert(__ nonvolatile_accross_vthread_preemtion(access_flags), "access_flags not preserved"); // Type check. - assert(2 == sizeof(AccessFlags), "unexpected field size"); - __ lhz(access_flags, method_(access_flags)); + assert(4 == sizeof(AccessFlags), "unexpected field size"); + __ lwz(access_flags, method_(access_flags)); // We don't want to reload R19_method and access_flags after calls // to some helper functions. @@ -1769,7 +1769,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT else { Label Lok; - __ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method); + __ lwz(R0, in_bytes(Method::access_flags_offset()), R19_method); __ andi_(R0, R0, JVM_ACC_SYNCHRONIZED); __ asm_assert_eq("method needs synchronization"); __ bind(Lok); diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index 70fec29d4f7e7..e17a3765b50ec 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -544,7 +544,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags ld(x11, Address(fp, frame::interpreter_frame_method_offset * wordSize)); - load_unsigned_short(x12, Address(x11, Method::access_flags_offset())); + ld(x12, Address(x11, Method::access_flags_offset())); test_bit(t0, x12, exact_log2(JVM_ACC_SYNCHRONIZED)); beqz(t0, unlocked); diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 12e38d97b1342..9af1b6a9bb128 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -641,7 +641,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ load_unsigned_short(t0, Address(xmethod, Method::access_flags_offset())); + __ lwu(t0, Address(xmethod, Method::access_flags_offset())); __ test_bit(t1, t0, exact_log2(JVM_ACC_STATIC)); __ beqz(t1, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index a2187b35bd5b1..5ea9077a2b72a 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -714,14 +714,14 @@ void TemplateInterpreterGenerator::lock_method() { const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); #ifdef ASSERT - __ load_unsigned_short(x10, access_flags); + __ lwu(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method doesn't need synchronization", false); #endif // ASSERT // get synchronization object { Label done; - __ load_unsigned_short(x10, access_flags); + __ lwu(x10, access_flags); __ andi(t0, x10, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ ld(x10, Address(xlocals, Interpreter::local_offset_in_bytes(0))); @@ -1028,7 +1028,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ load_unsigned_short(x10, access_flags); + __ lwu(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_NATIVE, "tried to execute non-native method as native", false); __ verify_access_flags(x10, JVM_ACC_ABSTRACT, "tried to execute abstract method in interpreter"); #endif @@ -1066,7 +1066,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { } else { // no synchronization necessary #ifdef ASSERT - __ load_unsigned_short(x10, access_flags); + __ lwu(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method needs synchronization"); #endif } @@ -1130,7 +1130,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ load_unsigned_short(t, Address(xmethod, Method::access_flags_offset())); + __ lwu(t, Address(xmethod, Method::access_flags_offset())); __ test_bit(t0, t, exact_log2(JVM_ACC_STATIC)); __ beqz(t0, L); // get mirror @@ -1346,7 +1346,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ load_unsigned_short(t, Address(xmethod, Method::access_flags_offset())); + __ lwu(t, Address(xmethod, Method::access_flags_offset())); __ test_bit(t0, t, exact_log2(JVM_ACC_SYNCHRONIZED)); __ beqz(t0, L); // the code below should be shared with interpreter macro @@ -1472,7 +1472,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ load_unsigned_short(x10, access_flags); + __ lwu(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_NATIVE, "tried to execute native method as non-native"); __ verify_access_flags(x10, JVM_ACC_ABSTRACT, "tried to execute abstract method in interpreter"); #endif @@ -1519,7 +1519,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { } else { // no synchronization necessary #ifdef ASSERT - __ load_unsigned_short(x10, access_flags); + __ lwu(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method needs synchronization"); #endif } diff --git a/src/hotspot/cpu/s390/interp_masm_s390.cpp b/src/hotspot/cpu/s390/interp_masm_s390.cpp index 0e31dbd33e198..5e80817aaba7b 100644 --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -780,7 +780,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, get_method(R_method); verify_oop(Z_tos, state); push(state); // Save tos/result. - testbit_ushort(method2_(R_method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + testbit(method2_(R_method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); z_bfalse(unlocked); // Don't unlock anything if the _do_not_unlock_if_synchronized flag diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index 3647aca0008b8..a069d6ceafbf0 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * Copyright 2024 IBM Corporation. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -1015,18 +1015,6 @@ void MacroAssembler::load_and_test_long(Register dst, const Address &a) { z_ltg(dst, a); } -// Test a bit in memory for 2 byte datatype. -void MacroAssembler::testbit_ushort(const Address &a, unsigned int bit) { - assert(a.index() == noreg, "no index reg allowed in testbit"); - if (bit <= 7) { - z_tm(a.disp() + 1, a.base(), 1 << bit); - } else if (bit <= 15) { - z_tm(a.disp() + 0, a.base(), 1 << (bit - 8)); - } else { - ShouldNotReachHere(); - } -} - // Test a bit in memory. void MacroAssembler::testbit(const Address &a, unsigned int bit) { assert(a.index() == noreg, "no index reg allowed in testbit"); diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.hpp b/src/hotspot/cpu/s390/macroAssembler_s390.hpp index d45f1321e0f28..159688128189a 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * Copyright (c) 2024 IBM Corporation. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -199,7 +199,6 @@ class MacroAssembler: public Assembler { // Test a bit in memory. Result is reflected in CC. void testbit(const Address &a, unsigned int bit); - void testbit_ushort(const Address &a, unsigned int bit); // Test a bit in a register. Result is reflected in CC. void testbit(Register r, unsigned int bitPos); diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index 62f5c8fa524b4..2396a2a71059f 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -2395,7 +2395,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ testbit_ushort(Address(Z_method, Method::access_flags_offset()), JVM_ACC_STATIC_BIT); + __ testbit(Address(Z_method, Method::access_flags_offset()), JVM_ACC_STATIC_BIT); __ z_bfalse(L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp index 99179bcad0611..1c4089d5beb07 100644 --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -164,7 +164,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // Therefore add 3 to address that byte within "_flags". // Reload method. VM call above may have destroyed register contents __ get_method(method); - __ testbit_ushort(method2_(method, access_flags), JVM_ACC_STATIC_BIT); + __ testbit(method2_(method, access_flags), JVM_ACC_STATIC_BIT); method = noreg; // end of life __ z_btrue(isStatic); @@ -883,7 +883,7 @@ void TemplateInterpreterGenerator::lock_method(void) { address reentry = nullptr; { Label L; - __ testbit_ushort(method2_(method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit(method2_(method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_btrue(L); reentry = __ stop_chain_static(reentry, "method doesn't need synchronization"); __ bind(L); @@ -897,7 +897,7 @@ void TemplateInterpreterGenerator::lock_method(void) { Label done; Label static_method; - __ testbit_ushort(method2_(method, access_flags), JVM_ACC_STATIC_BIT); + __ testbit(method2_(method, access_flags), JVM_ACC_STATIC_BIT); __ z_btrue(static_method); // non-static method: Load receiver obj from stack. @@ -1349,17 +1349,15 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Make sure method is native and not abstract. #ifdef ASSERT - // _access_flags must be a 16 bit value. - assert(sizeof(AccessFlags) == 2, "testbit_ushort will fail"); address reentry = nullptr; { Label L; - __ testbit_ushort(method_(access_flags), JVM_ACC_NATIVE_BIT); + __ testbit(method_(access_flags), JVM_ACC_NATIVE_BIT); __ z_btrue(L); reentry = __ stop_chain_static(reentry, "tried to execute non-native method as native"); __ bind(L); } { Label L; - __ testbit_ushort(method_(access_flags), JVM_ACC_ABSTRACT_BIT); + __ testbit(method_(access_flags), JVM_ACC_ABSTRACT_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute abstract method as non-abstract"); __ bind(L); @@ -1405,7 +1403,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; __ get_method(Z_R1_scratch); - __ testbit_ushort(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "method needs synchronization"); __ bind(L); @@ -1463,7 +1461,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Pass mirror handle if static call. { Label method_is_not_static; - __ testbit_ushort(method2_(Rmethod, access_flags), JVM_ACC_STATIC_BIT); + __ testbit(method2_(Rmethod, access_flags), JVM_ACC_STATIC_BIT); __ z_bfalse(method_is_not_static); // Load mirror from interpreter frame. __ z_lg(Z_R1, _z_ijava_state_neg(mirror), Z_fp); @@ -1721,13 +1719,13 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT address reentry = nullptr; { Label L; - __ testbit_ushort(method_(access_flags), JVM_ACC_NATIVE_BIT); + __ testbit(method_(access_flags), JVM_ACC_NATIVE_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute native method as non-native"); __ bind(L); } { Label L; - __ testbit_ushort(method_(access_flags), JVM_ACC_ABSTRACT_BIT); + __ testbit(method_(access_flags), JVM_ACC_ABSTRACT_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute abstract method as non-abstract"); __ bind(L); @@ -1777,7 +1775,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; __ get_method(Z_R1_scratch); - __ testbit_ushort(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "method needs synchronization"); __ bind(L); diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp index ff5b1c1454dfc..3a3f01a640983 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1030,7 +1030,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); - load_unsigned_short(rcx, Address(rcx, Method::access_flags_offset())); + movl(rcx, Address(rcx, Method::access_flags_offset())); testl(rcx, JVM_ACC_SYNCHRONIZED); jcc(Assembler::zero, unlocked); diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index b9901a1e95bf7..ab7cbb9437453 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -1099,7 +1099,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm { // Bypass the barrier for non-static methods Register flags = rscratch1; - __ load_unsigned_short(flags, Address(method, Method::access_flags_offset())); + __ movl(flags, Address(method, Method::access_flags_offset())); __ testl(flags, JVM_ACC_STATIC); __ jcc(Assembler::zero, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp index b4e005faff3b9..823b965a09b51 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -596,7 +596,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ load_unsigned_short(rax, access_flags); + __ movl(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::notZero, L); __ stop("method doesn't need synchronization"); @@ -607,7 +607,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ load_unsigned_short(rax, access_flags); + __ movl(rax, access_flags); __ testl(rax, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ movptr(rax, Address(rlocals, Interpreter::local_offset_in_bytes(0))); @@ -855,7 +855,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ load_unsigned_short(rax, access_flags); + __ movl(rax, access_flags); { Label L; __ testl(rax, JVM_ACC_NATIVE); @@ -909,7 +909,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ load_unsigned_short(rax, access_flags); + __ movl(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); __ stop("method needs synchronization"); @@ -999,7 +999,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ load_unsigned_short(t, Address(method, Method::access_flags_offset())); + __ movl(t, Address(method, Method::access_flags_offset())); __ testl(t, JVM_ACC_STATIC); __ jcc(Assembler::zero, L); // get mirror @@ -1280,7 +1280,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ load_unsigned_short(t, Address(method, Method::access_flags_offset())); + __ movl(t, Address(method, Method::access_flags_offset())); __ testl(t, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); // the code below should be shared with interpreter macro @@ -1432,7 +1432,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ load_unsigned_short(rax, access_flags); + __ movl(rax, access_flags); { Label L; __ testl(rax, JVM_ACC_NATIVE); @@ -1489,7 +1489,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ load_unsigned_short(rax, access_flags); + __ movl(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); __ stop("method needs synchronization"); diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp index b2124c6b157f4..5ea2d8eba259b 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -74,7 +74,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // Do Int register here switch ( i ) { case 0: - __ load_unsigned_short(rscratch1, Address(rbx, Method::access_flags_offset())); + __ movl(rscratch1, Address(rbx, Method::access_flags_offset())); __ testl(rscratch1, JVM_ACC_STATIC); __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); break; @@ -159,7 +159,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { } // Now handle integrals. Only do c_rarg1 if not static. - __ load_unsigned_short(c_rarg3, Address(rbx, Method::access_flags_offset())); + __ movl(c_rarg3, Address(rbx, Method::access_flags_offset())); __ testl(c_rarg3, JVM_ACC_STATIC); __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index 2df2fbf8adca9..74fdf7a5b76a3 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -1337,7 +1337,7 @@ void LIRGenerator::do_getModifiers(Intrinsic* x) { __ cmove(lir_cond_equal, prim_klass, recv_klass, klass, T_ADDRESS); // Get the answer. - __ move(new LIR_Address(klass, in_bytes(Klass::modifier_flags_offset()), T_CHAR), result); + __ move(new LIR_Address(klass, in_bytes(Klass::modifier_flags_offset()), T_INT), result); } void LIRGenerator::do_getObjectSize(Intrinsic* x) { diff --git a/src/hotspot/share/ci/ciFlags.cpp b/src/hotspot/share/ci/ciFlags.cpp index 043470a32a227..1401a432a9e18 100644 --- a/src/hotspot/share/ci/ciFlags.cpp +++ b/src/hotspot/share/ci/ciFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,5 +92,5 @@ void ciFlags::print_member_flags(outputStream* st) { // ------------------------------------------------------------------ // ciFlags::print void ciFlags::print(outputStream* st) { - st->print(" flags=%x", _flags.as_unsigned_short()); + st->print(" flags=%x", _flags); } diff --git a/src/hotspot/share/ci/ciFlags.hpp b/src/hotspot/share/ci/ciFlags.hpp index 426f953611fee..dd1df622487f3 100644 --- a/src/hotspot/share/ci/ciFlags.hpp +++ b/src/hotspot/share/ci/ciFlags.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2023, 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,7 @@ #define SHARE_CI_CIFLAGS_HPP #include "ci/ciClassList.hpp" +#include "jvm_constants.h" #include "utilities/accessFlags.hpp" #include "utilities/ostream.hpp" @@ -38,37 +39,37 @@ class ciFlags { friend class ciField; friend class ciMethod; - AccessFlags _flags; + jint _flags; bool _stable; - bool _initialized_final_update; + bool _intialized_final_update; - ciFlags() :_flags(0), _stable(false), _initialized_final_update(false) { } + ciFlags() :_flags(0), _stable(false), _intialized_final_update(false) { } ciFlags(AccessFlags flags, bool is_stable = false, bool is_initialized_final_update = false) : - _flags(flags), _stable(is_stable), _initialized_final_update(is_initialized_final_update) { } + _flags(flags.as_int()), _stable(is_stable), _intialized_final_update(is_initialized_final_update) { } public: // Java access flags - bool is_public () const { return _flags.is_public(); } - bool is_private () const { return _flags.is_private(); } - bool is_protected () const { return _flags.is_protected(); } - bool is_static () const { return _flags.is_static(); } - bool is_final () const { return _flags.is_final(); } - bool is_synchronized () const { return _flags.is_synchronized(); } - bool is_super () const { return _flags.is_super(); } - bool is_volatile () const { return _flags.is_volatile(); } - bool is_transient () const { return _flags.is_transient(); } - bool is_native () const { return _flags.is_native(); } - bool is_interface () const { return _flags.is_interface(); } - bool is_abstract () const { return _flags.is_abstract(); } + bool is_public () const { return (_flags & JVM_ACC_PUBLIC ) != 0; } + bool is_private () const { return (_flags & JVM_ACC_PRIVATE ) != 0; } + bool is_protected () const { return (_flags & JVM_ACC_PROTECTED ) != 0; } + bool is_static () const { return (_flags & JVM_ACC_STATIC ) != 0; } + bool is_final () const { return (_flags & JVM_ACC_FINAL ) != 0; } + bool is_synchronized () const { return (_flags & JVM_ACC_SYNCHRONIZED ) != 0; } + bool is_super () const { return (_flags & JVM_ACC_SUPER ) != 0; } + bool is_volatile () const { return (_flags & JVM_ACC_VOLATILE ) != 0; } + bool is_transient () const { return (_flags & JVM_ACC_TRANSIENT ) != 0; } + bool is_native () const { return (_flags & JVM_ACC_NATIVE ) != 0; } + bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; } + bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; } bool is_stable () const { return _stable; } // In case the current object represents a field, return true if // the field is modified outside of instance initializer methods // (or class/initializer methods if the field is static) and false // otherwise. - bool has_initialized_final_update() const { return _initialized_final_update; }; + bool has_initialized_final_update() const { return _intialized_final_update; }; // Conversion - jint as_int() { return _flags.as_unsigned_short(); } + jint as_int() { return _flags; } void print_klass_flags(outputStream* st = tty); void print_member_flags(outputStream* st = tty); diff --git a/src/hotspot/share/ci/ciKlass.cpp b/src/hotspot/share/ci/ciKlass.cpp index e14e237167d8c..f65d4a0311c82 100644 --- a/src/hotspot/share/ci/ciKlass.cpp +++ b/src/hotspot/share/ci/ciKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -222,7 +222,7 @@ jint ciKlass::modifier_flags() { jint ciKlass::access_flags() { assert(is_loaded(), "not loaded"); GUARDED_VM_ENTRY( - return get_Klass()->access_flags().as_unsigned_short(); + return get_Klass()->access_flags().as_int(); ) } diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index c552e48c8b8e9..5c58f20000616 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -2981,7 +2981,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea "Class is both outer and inner class in class file %s", CHECK_0); } // Access flags - u2 flags; + jint flags; // JVM_ACC_MODULE is defined in JDK-9 and later. if (_major_version >= JAVA_9_VERSION) { flags = cfs->get_u2_fast() & (RECOGNIZED_INNER_CLASS_MODIFIERS | JVM_ACC_MODULE); @@ -2998,7 +2998,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea inner_classes->at_put(index++, inner_class_info_index); inner_classes->at_put(index++, outer_class_info_index); inner_classes->at_put(index++, inner_name_index); - inner_classes->at_put(index++, inner_access_flags.as_unsigned_short()); + inner_classes->at_put(index++, inner_access_flags.as_short()); } // Check for circular and duplicate entries. @@ -3750,7 +3750,7 @@ void ClassFileParser::apply_parsed_class_metadata( // Initialize cached modifier_flags to support Class.getModifiers(). // This must follow setting inner_class attributes. - u2 computed_modifiers = this_klass->compute_modifier_flags(); + int computed_modifiers = this_klass->compute_modifier_flags(); this_klass->set_modifier_flags(computed_modifiers); // Delay the setting of _local_interfaces and _transitive_interfaces until after @@ -5336,7 +5336,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream, assert(_stream != nullptr, "invariant"); assert(_stream->buffer() == _stream->current(), "invariant"); assert(_class_name != nullptr, "invariant"); - assert(0 == _access_flags.as_unsigned_short(), "invariant"); + assert(0 == _access_flags.as_int(), "invariant"); // Figure out whether we can skip format checking (matching classic VM behavior) _need_verify = Verifier::should_verify_for(_loader_data->class_loader()); @@ -5488,7 +5488,7 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream, stream->guarantee_more(8, CHECK); // flags, this_class, super_class, infs_len // Access flags - u2 flags; + jint flags; // JVM_ACC_MODULE is defined in JDK-9 and later. if (_major_version >= JAVA_9_VERSION) { flags = stream->get_u2_fast() & (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_MODULE); diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 650d0a9fa744d..1aedb43973c57 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -3169,7 +3169,7 @@ void java_lang_ClassFrameInfo::serialize_offsets(SerializeClosure* f) { #endif static int get_flags(const methodHandle& m) { - int flags = m->access_flags().as_method_flags(); + int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); if (m->is_object_initializer()) { flags |= java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR; } else { @@ -5537,7 +5537,7 @@ int InjectedField::compute_offset() { ik->print(); tty->print_cr("all fields:"); for (AllFieldStream fs(ik); !fs.done(); fs.next()) { - tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_field_flags()); + tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int()); } #endif //PRODUCT vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class"); diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp index 38226d232ef66..407cdafaf2017 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.cpp +++ b/src/hotspot/share/classfile/vmIntrinsics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -36,31 +36,31 @@ #include "utilities/tribool.hpp" // These are flag-matching functions: -inline bool match_F_R(u2 flags) { +inline bool match_F_R(jshort flags) { const int req = 0; const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_Y(u2 flags) { +inline bool match_F_Y(jshort flags) { const int req = JVM_ACC_SYNCHRONIZED; const int neg = JVM_ACC_STATIC | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_RN(u2 flags) { +inline bool match_F_RN(jshort flags) { const int req = JVM_ACC_NATIVE; const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED; return (flags & (req | neg)) == req; } -inline bool match_F_S(u2 flags) { +inline bool match_F_S(jshort flags) { const int req = JVM_ACC_STATIC; const int neg = JVM_ACC_SYNCHRONIZED | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_SN(u2 flags) { +inline bool match_F_SN(jshort flags) { const int req = JVM_ACC_STATIC | JVM_ACC_NATIVE; const int neg = JVM_ACC_SYNCHRONIZED; return (flags & (req | neg)) == req; @@ -711,7 +711,7 @@ bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) { vmIntrinsics::ID vmIntrinsics::find_id_impl(vmSymbolID holder, vmSymbolID name, vmSymbolID sig, - u2 flags) { + jshort flags) { assert((int)vmSymbolID::SID_LIMIT <= (1<is_array_klass()) { // We need to change "protected" to "public". assert(flags.is_protected(), "clone not protected?"); - u2 new_flags = flags.as_method_flags(); + jint new_flags = flags.as_int(); new_flags = new_flags & (~JVM_ACC_PROTECTED); new_flags = new_flags | JVM_ACC_PUBLIC; flags.set_flags(new_flags); diff --git a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp index 27b01e99e5567..edb87c7fc8e41 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, 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 @@ -72,7 +72,7 @@ const Symbol* EdgeUtils::field_name(const Edge& edge, jshort* modifiers) { JavaFieldStream jfs(ik); while (!jfs.done()) { if (offset == jfs.offset()) { - *modifiers = jfs.access_flags().as_field_flags(); + *modifiers = jfs.access_flags().as_short(); return jfs.name(); } jfs.next(); diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp index bc5f97c719af9..a53eaa474f3f0 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -227,9 +227,9 @@ static traceid method_id(KlassPtr klass, MethodPtr method) { } template -static u2 get_flags(const T* ptr) { +static s4 get_flags(const T* ptr) { assert(ptr != nullptr, "invariant"); - return ptr->access_flags().as_unsigned_short(); + return ptr->access_flags().get_flags(); } // Same as JVM_GetClassModifiers @@ -968,7 +968,7 @@ static int write_method(JfrCheckpointWriter* writer, MethodPtr method, bool leak writer->write(artifact_id(klass)); writer->write(mark_symbol(method->name(), leakp)); writer->write(mark_symbol(method->signature(), leakp)); - writer->write(get_flags(method)); + writer->write(static_cast(get_flags(method))); writer->write(get_visibility(method)); return 1; } diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 1fa3f23173ce3..9052e6228945b 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -1000,7 +1000,7 @@ C2V_VMENTRY_NULL(jobject, resolveFieldInPool, (JNIEnv* env, jobject, ARGUMENT_PA if (info.is_null() || JVMCIENV->get_length(info) != 4) { JVMCI_ERROR_NULL("info must not be null and have a length of 4"); } - JVMCIENV->put_int_at(info, 0, fd.access_flags().as_field_flags()); + JVMCIENV->put_int_at(info, 0, fd.access_flags().as_int()); JVMCIENV->put_int_at(info, 1, fd.offset()); JVMCIENV->put_int_at(info, 2, fd.index()); JVMCIENV->put_int_at(info, 3, fd.field_flags().as_uint()); diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 1a53f6b6d2cc1..712745e2a021c 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -1592,7 +1592,7 @@ JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) { HotSpotJVMCI::FieldInfo::set_nameIndex(JVMCIENV, obj_h(), (jint)fieldinfo->name_index()); HotSpotJVMCI::FieldInfo::set_signatureIndex(JVMCIENV, obj_h(), (jint)fieldinfo->signature_index()); HotSpotJVMCI::FieldInfo::set_offset(JVMCIENV, obj_h(), (jint)fieldinfo->offset()); - HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_field_flags()); + HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_int()); HotSpotJVMCI::FieldInfo::set_internalFlags(JVMCIENV, obj_h(), (jint)fieldinfo->field_flags().as_uint()); HotSpotJVMCI::FieldInfo::set_initializerIndex(JVMCIENV, obj_h(), (jint)fieldinfo->initializer_index()); return wrap(obj_h()); @@ -1603,7 +1603,7 @@ JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) { (jint)fieldinfo->name_index(), (jint)fieldinfo->signature_index(), (jint)fieldinfo->offset(), - (jint)fieldinfo->access_flags().as_field_flags(), + (jint)fieldinfo->access_flags().as_int(), (jint)fieldinfo->field_flags().as_uint(), (jint)fieldinfo->initializer_index()); diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 97447c43b6e5a..ba47e5599578f 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -273,7 +273,7 @@ nonstatic_field(Klass, _name, Symbol*) \ volatile_nonstatic_field(Klass, _next_sibling, Klass*) \ nonstatic_field(Klass, _java_mirror, OopHandle) \ - nonstatic_field(Klass, _modifier_flags, u2) \ + nonstatic_field(Klass, _modifier_flags, jint) \ nonstatic_field(Klass, _access_flags, AccessFlags) \ nonstatic_field(Klass, _class_loader_data, ClassLoaderData*) \ nonstatic_field(Klass, _secondary_supers_bitmap, uintx) \ @@ -488,6 +488,7 @@ declare_constant(InvocationEntryBci) \ declare_constant(JVMCINMethodData::SPECULATION_LENGTH_BITS) \ \ + declare_constant(JVM_ACC_WRITTEN_FLAGS) \ declare_constant(FieldInfo::FieldFlags::_ff_injected) \ declare_constant(FieldInfo::FieldFlags::_ff_stable) \ declare_preprocessor_constant("JVM_ACC_VARARGS", JVM_ACC_VARARGS) \ diff --git a/src/hotspot/share/oops/fieldInfo.cpp b/src/hotspot/share/oops/fieldInfo.cpp index 3ae91a03b6797..50a3b427d178e 100644 --- a/src/hotspot/share/oops/fieldInfo.cpp +++ b/src/hotspot/share/oops/fieldInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -34,7 +34,7 @@ void FieldInfo::print(outputStream* os, ConstantPool* cp) { name_index(), name(cp)->as_utf8(), signature_index(), signature(cp)->as_utf8(), offset(), - access_flags().as_field_flags(), + access_flags().as_int(), field_flags().as_uint(), initializer_index(), generic_signature_index(), @@ -97,7 +97,7 @@ Array* FieldInfoStream::create_FieldInfoStream(GrowableArray* fie assert(fi_ref->name_index() == fi.name_index(), "Must be"); assert(fi_ref->signature_index() == fi.signature_index(), "Must be"); assert(fi_ref->offset() == fi.offset(), "Must be"); - assert(fi_ref->access_flags().as_field_flags() == fi.access_flags().as_field_flags(), "Must be"); + assert(fi_ref->access_flags().as_int() == fi.access_flags().as_int(), "Must be"); assert(fi_ref->field_flags().as_uint() == fi.field_flags().as_uint(), " Must be"); if(fi_ref->field_flags().is_initialized()) { assert(fi_ref->initializer_index() == fi.initializer_index(), "Must be"); diff --git a/src/hotspot/share/oops/fieldInfo.inline.hpp b/src/hotspot/share/oops/fieldInfo.inline.hpp index bf37d280510f7..2e6727f1fb9f1 100644 --- a/src/hotspot/share/oops/fieldInfo.inline.hpp +++ b/src/hotspot/share/oops/fieldInfo.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -73,7 +73,7 @@ inline void Mapper::map_field_info(const FieldInfo& fi) { _consumer->accept_uint(fi.name_index()); _consumer->accept_uint(fi.signature_index()); _consumer->accept_uint(fi.offset()); - _consumer->accept_uint(fi.access_flags().as_field_flags()); + _consumer->accept_uint(fi.access_flags().as_int()); _consumer->accept_uint(fi.field_flags().as_uint()); if(fi.field_flags().has_any_optionals()) { if (fi.field_flags().is_initialized()) { diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index 43b078a8af233..ce46da55f986b 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -3339,8 +3339,8 @@ InstanceKlass* InstanceKlass::compute_enclosing_class(bool* inner_is_member, TRA return outer_klass; } -u2 InstanceKlass::compute_modifier_flags() const { - u2 access = access_flags().as_unsigned_short(); +jint InstanceKlass::compute_modifier_flags() const { + jint access = access_flags().as_int(); // But check if it happens to be member class. InnerClassesIterator iter(this); @@ -3360,7 +3360,7 @@ u2 InstanceKlass::compute_modifier_flags() const { } } // Remember to strip ACC_SUPER bit - return (access & (~JVM_ACC_SUPER)); + return (access & (~JVM_ACC_SUPER)) & JVM_ACC_WRITTEN_FLAGS; } jint InstanceKlass::jvmti_class_status() const { diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index cedc17e9bafde..8209a692a8242 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -391,7 +391,7 @@ class InstanceKlass: public Klass { public: int field_offset (int index) const { return field(index).offset(); } - int field_access_flags(int index) const { return field(index).access_flags().as_field_flags(); } + int field_access_flags(int index) const { return field(index).access_flags().as_int(); } FieldInfo::FieldFlags field_flags(int index) const { return field(index).field_flags(); } FieldStatus field_status(int index) const { return fields_status()->at(index); } inline Symbol* field_name (int index) const; @@ -682,6 +682,8 @@ class InstanceKlass: public Klass { #if INCLUDE_JVMTI // Redefinition locking. Class can only be redefined by one thread at a time. + // The flag is in access_flags so that it can be set and reset using atomic + // operations, and not be reset by other misc_flag settings. bool is_being_redefined() const { return _misc_flags.is_being_redefined(); } void set_is_being_redefined(bool value) { _misc_flags.set_is_being_redefined(value); } @@ -1125,7 +1127,7 @@ class InstanceKlass: public Klass { void compute_has_loops_flag_for_methods(); #endif - u2 compute_modifier_flags() const; + jint compute_modifier_flags() const; public: // JVMTI support diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index d27665bbcc121..2c75d6da3b8cb 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -66,7 +66,7 @@ class Klass : public Metadata { friend class JVMCIVMStructs; public: // Klass Kinds for all subclasses of Klass - enum KlassKind : u2 { + enum KlassKind { InstanceKlassKind, InstanceRefKlassKind, InstanceMirrorKlassKind, @@ -113,20 +113,15 @@ class Klass : public Metadata { // // Final note: This comes first, immediately after C++ vtable, // because it is frequently queried. - jint _layout_helper; + jint _layout_helper; // Klass kind used to resolve the runtime type of the instance. // - Used to implement devirtualized oop closure dispatching. // - Various type checking in the JVM const KlassKind _kind; - AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. - // Some flags created by the JVM, not in the class file itself, - // are in _misc_flags below. // Processed access flags, for use by Class.getModifiers. - u2 _modifier_flags; - - KlassFlags _misc_flags; + jint _modifier_flags; // The fields _super_check_offset, _secondary_super_cache, _secondary_supers // and _primary_supers all help make fast subtype checks. See big discussion @@ -162,12 +157,22 @@ class Klass : public Metadata { // Provide access the corresponding instance java.lang.ClassLoader. ClassLoaderData* _class_loader_data; - markWord _prototype_header; // Used to initialize objects' header - // Bitmap and hash code used by hashed secondary supers. uintx _secondary_supers_bitmap; uint8_t _hash_slot; + markWord _prototype_header; // Used to initialize objects' header + + int _vtable_len; // vtable length. This field may be read very often when we + // have lots of itable dispatches (e.g., lambdas and streams). + // Keep it away from the beginning of a Klass to avoid cacheline + // contention that may happen when a nearby object is modified. + AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. + // Some flags created by the JVM, not in the class file itself, + // are in _misc_flags below. + + JFR_ONLY(DEFINE_TRACE_ID_FIELD;) + private: // This is an index into FileMapHeader::_shared_path_table[], to // associate this class with the JAR file where it's loaded from during @@ -195,17 +200,10 @@ class Klass : public Metadata { }; #endif - int _vtable_len; // vtable length. This field may be read very often when we - // have lots of itable dispatches (e.g., lambdas and streams). - // Keep it away from the beginning of a Klass to avoid cacheline - // contention that may happen when a nearby object is modified. + KlassFlags _misc_flags; CDS_JAVA_HEAP_ONLY(int _archived_mirror_index;) -public: - - JFR_ONLY(DEFINE_TRACE_ID_FIELD;) - protected: Klass(KlassKind kind); @@ -294,8 +292,8 @@ class Klass : public Metadata { void clear_java_mirror_handle() { _java_mirror = OopHandle(); } // modifier flags - u2 modifier_flags() const { return _modifier_flags; } - void set_modifier_flags(u2 flags) { _modifier_flags = flags; } + jint modifier_flags() const { return _modifier_flags; } + void set_modifier_flags(jint flags) { _modifier_flags = flags; } // size helper int layout_helper() const { return _layout_helper; } @@ -758,7 +756,7 @@ class Klass : public Metadata { virtual void release_C_heap_structures(bool release_constant_pool = true); public: - virtual u2 compute_modifier_flags() const = 0; + virtual jint compute_modifier_flags() const = 0; // JVMTI support virtual jint jvmti_class_status() const; diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index ab15379409f76..d0b29a4a30992 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1652,8 +1652,8 @@ void Method::init_intrinsic_id(vmSymbolID klass_id) { && sig_id == vmSymbolID::NO_SID) { return; } + jshort flags = access_flags().as_short(); - u2 flags = access_flags().as_method_flags(); vmIntrinsics::ID id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags); if (id != vmIntrinsics::_none) { set_intrinsic_id(id); @@ -2300,7 +2300,7 @@ void Method::print_on(outputStream* st) const { st->print (" - method holder: "); method_holder()->print_value_on(st); st->cr(); st->print (" - constants: " PTR_FORMAT " ", p2i(constants())); constants()->print_value_on(st); st->cr(); - st->print (" - access: 0x%x ", access_flags().as_method_flags()); access_flags().print_on(st); st->cr(); + st->print (" - access: 0x%x ", access_flags().as_int()); access_flags().print_on(st); st->cr(); st->print (" - flags: 0x%x ", _flags.as_int()); _flags.print_on(st); st->cr(); st->print (" - name: "); name()->print_value_on(st); st->cr(); st->print (" - signature: "); signature()->print_value_on(st); st->cr(); diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index 7b13337ecafcf..271d8b3986378 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,8 +75,8 @@ class Method : public Metadata { MethodData* _method_data; MethodCounters* _method_counters; AdapterHandlerEntry* _adapter; - int _vtable_index; // vtable index of this method (see VtableIndexFlag) AccessFlags _access_flags; // Access flags + int _vtable_index; // vtable index of this method (see VtableIndexFlag) MethodFlags _flags; u2 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none) diff --git a/src/hotspot/share/oops/objArrayKlass.cpp b/src/hotspot/share/oops/objArrayKlass.cpp index 903c5660d5311..04bc374e5226c 100644 --- a/src/hotspot/share/oops/objArrayKlass.cpp +++ b/src/hotspot/share/oops/objArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -341,12 +341,12 @@ void ObjArrayKlass::metaspace_pointers_do(MetaspaceClosure* it) { it->push(&_bottom_klass); } -u2 ObjArrayKlass::compute_modifier_flags() const { +jint ObjArrayKlass::compute_modifier_flags() const { // The modifier for an objectArray is the same as its element assert (element_klass() != nullptr, "should be initialized"); // Return the flags of the bottom element type. - u2 element_flags = bottom_klass()->compute_modifier_flags(); + jint element_flags = bottom_klass()->compute_modifier_flags(); return (element_flags & (JVM_ACC_PUBLIC | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED)) | (JVM_ACC_ABSTRACT | JVM_ACC_FINAL); diff --git a/src/hotspot/share/oops/objArrayKlass.hpp b/src/hotspot/share/oops/objArrayKlass.hpp index c44c8d28f6247..e16f1f2eb0fcd 100644 --- a/src/hotspot/share/oops/objArrayKlass.hpp +++ b/src/hotspot/share/oops/objArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -143,7 +143,7 @@ class ObjArrayKlass : public ArrayKlass { inline void oop_oop_iterate_elements_bounded(objArrayOop a, OopClosureType* closure, void* low, void* high); public: - u2 compute_modifier_flags() const; + jint compute_modifier_flags() const; public: // Printing diff --git a/src/hotspot/share/oops/typeArrayKlass.cpp b/src/hotspot/share/oops/typeArrayKlass.cpp index 86c4f9d7138c4..8ca6a49fc46a4 100644 --- a/src/hotspot/share/oops/typeArrayKlass.cpp +++ b/src/hotspot/share/oops/typeArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -75,7 +75,7 @@ TypeArrayKlass* TypeArrayKlass::allocate(ClassLoaderData* loader_data, BasicType return new (loader_data, size, THREAD) TypeArrayKlass(type, name); } -u2 TypeArrayKlass::compute_modifier_flags() const { +jint TypeArrayKlass::compute_modifier_flags() const { return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; } diff --git a/src/hotspot/share/oops/typeArrayKlass.hpp b/src/hotspot/share/oops/typeArrayKlass.hpp index 6ec72ae49c0c8..9dc3ed607fe3a 100644 --- a/src/hotspot/share/oops/typeArrayKlass.hpp +++ b/src/hotspot/share/oops/typeArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -73,7 +73,7 @@ class TypeArrayKlass : public ArrayKlass { // Copying void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS); - u2 compute_modifier_flags() const; + jint compute_modifier_flags() const; // Oop iterators. Since there are no oops in TypeArrayKlasses, // these functions only return the size of the object. diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 56cfb9fe16e7b..40b19eecd9f65 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -3871,7 +3871,7 @@ Node* LibraryCallKit::generate_klass_flags_guard(Node* kls, int modifier_mask, i } Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { return generate_klass_flags_guard(kls, JVM_ACC_INTERFACE, 0, region, - Klass::access_flags_offset(), TypeInt::CHAR, T_CHAR); + Klass::access_flags_offset(), TypeInt::INT, T_INT); } // Use this for testing if Klass is_hidden, has_finalizer, and is_cloneable_fast. @@ -3904,7 +3904,8 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { break; case vmIntrinsics::_getModifiers: prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); - return_type = TypeInt::CHAR; + assert(is_power_of_2((int)JVM_ACC_WRITTEN_FLAGS+1), "change next line"); + return_type = TypeInt::make(0, JVM_ACC_WRITTEN_FLAGS, Type::WidenMin); break; case vmIntrinsics::_isInterface: prim_return_value = intcon(0); @@ -3926,7 +3927,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { break; case vmIntrinsics::_getClassAccessFlags: prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); - return_type = TypeInt::CHAR; + return_type = TypeInt::INT; // not bool! 6297094 break; default: fatal_unexpected_iid(id); @@ -3987,7 +3988,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { case vmIntrinsics::_getModifiers: p = basic_plus_adr(kls, in_bytes(Klass::modifier_flags_offset())); - query_value = make_load(nullptr, p, TypeInt::CHAR, T_CHAR, MemNode::unordered); + query_value = make_load(nullptr, p, TypeInt::INT, T_INT, MemNode::unordered); break; case vmIntrinsics::_isInterface: @@ -4052,7 +4053,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { case vmIntrinsics::_getClassAccessFlags: p = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset())); - query_value = make_load(nullptr, p, TypeInt::CHAR, T_CHAR, MemNode::unordered); + query_value = make_load(nullptr, p, TypeInt::INT, T_INT, MemNode::unordered); break; default: diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index 78ffbe05ae492..ad351fb81add7 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Alibaba Group Holding Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1976,24 +1976,24 @@ LoadNode::load_array_final_field(const TypeKlassPtr *tkls, if (tkls->offset() == in_bytes(Klass::modifier_flags_offset())) { // The field is Klass::_modifier_flags. Return its (constant) value. // (Folds up the 2nd indirection in aClassConstant.getModifiers().) - assert(Opcode() == Op_LoadUS, "must load an unsigned short from _modifier_flags"); + assert(this->Opcode() == Op_LoadI, "must load an int from _modifier_flags"); return TypeInt::make(klass->modifier_flags()); } if (tkls->offset() == in_bytes(Klass::access_flags_offset())) { // The field is Klass::_access_flags. Return its (constant) value. // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) - assert(Opcode() == Op_LoadUS, "must load an unsigned short from _access_flags"); + assert(this->Opcode() == Op_LoadI, "must load an int from _access_flags"); return TypeInt::make(klass->access_flags()); } if (tkls->offset() == in_bytes(Klass::misc_flags_offset())) { // The field is Klass::_misc_flags. Return its (constant) value. // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) - assert(Opcode() == Op_LoadUB, "must load an unsigned byte from _misc_flags"); + assert(this->Opcode() == Op_LoadUB, "must load an unsigned byte from _misc_flags"); return TypeInt::make(klass->misc_flags()); } if (tkls->offset() == in_bytes(Klass::layout_helper_offset())) { // The field is Klass::_layout_helper. Return its constant value if known. - assert(Opcode() == Op_LoadI, "must load an int from _layout_helper"); + assert(this->Opcode() == Op_LoadI, "must load an int from _layout_helper"); return TypeInt::make(klass->layout_helper()); } diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 198165cdd1ed9..12c7898f4cf19 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1306,7 +1306,7 @@ JVM_ENTRY(jint, JVM_GetClassModifiers(JNIEnv *env, jclass cls)) } Klass* k = java_lang_Class::as_Klass(mirror); - debug_only(u2 computed_modifiers = k->compute_modifier_flags()); + debug_only(int computed_modifiers = k->compute_modifier_flags()); assert(k->modifier_flags() == computed_modifiers, "modifiers cache is OK"); return k->modifier_flags(); JVM_END @@ -1817,7 +1817,7 @@ JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)) } Klass* k = java_lang_Class::as_Klass(mirror); - return k->access_flags().as_class_flags(); + return k->access_flags().as_int() & JVM_ACC_WRITTEN_FLAGS; } JVM_END @@ -2460,14 +2460,14 @@ JVM_ENTRY(jint, JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_ind Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); Method* method = InstanceKlass::cast(k)->methods()->at(method_index); - return method->access_flags().as_method_flags(); + return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; JVM_END JVM_ENTRY(jint, JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)) Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); - return InstanceKlass::cast(k)->field_access_flags(field_index); + return InstanceKlass::cast(k)->field_access_flags(field_index) & JVM_RECOGNIZED_FIELD_MODIFIERS; JVM_END @@ -2657,7 +2657,7 @@ JVM_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, j InstanceKlass* ik = InstanceKlass::cast(k_called); for (JavaFieldStream fs(ik); !fs.done(); fs.next()) { if (fs.name() == name && fs.signature() == signature) { - return fs.access_flags().as_field_flags(); + return fs.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS; } } return -1; @@ -2686,7 +2686,7 @@ JVM_ENTRY(jint, JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, for (int i = 0; i < methods_count; i++) { Method* method = methods->at(i); if (method->name() == name && method->signature() == signature) { - return method->access_flags().as_method_flags(); + return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; } } return -1; diff --git a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp index 10fb4121472e4..ceed1d8ad952a 100644 --- a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp +++ b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -85,7 +85,7 @@ void JvmtiClassFileReconstituter::write_field_infos() { // JVMSpec| attribute_info attributes[attributes_count]; // JVMSpec| } - write_u2(access_flags.as_field_flags()); + write_u2(access_flags.get_flags() & JVM_RECOGNIZED_FIELD_MODIFIERS); write_u2(name_index); write_u2(signature_index); u2 attr_count = 0; @@ -704,7 +704,7 @@ void JvmtiClassFileReconstituter::write_method_info(const methodHandle& method) return; } - write_u2(access_flags.as_method_flags()); + write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS); write_u2(const_method->name_index()); write_u2(const_method->signature_index()); @@ -919,7 +919,7 @@ void JvmtiClassFileReconstituter::write_class_file_format() { copy_cpool_bytes(writeable_address(cpool_size())); // JVMSpec| u2 access_flags; - write_u2(ik()->access_flags().as_class_flags()); + write_u2(ik()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS); // JVMSpec| u2 this_class; // JVMSpec| u2 super_class; diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index e97bfc300422e..554b4baf7b2a3 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -3149,7 +3149,7 @@ jvmtiError JvmtiEnv::GetFieldModifiers(fieldDescriptor* fdesc_ptr, jint* modifiers_ptr) { AccessFlags resultFlags = fdesc_ptr->access_flags(); - jint result = resultFlags.as_field_flags(); + jint result = resultFlags.as_int(); *modifiers_ptr = result; return JVMTI_ERROR_NONE; @@ -3228,7 +3228,7 @@ JvmtiEnv::GetMethodDeclaringClass(Method* method, jclass* declaring_class_ptr) { jvmtiError JvmtiEnv::GetMethodModifiers(Method* method, jint* modifiers_ptr) { NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID); - (*modifiers_ptr) = method->access_flags().as_method_flags(); + (*modifiers_ptr) = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; return JVMTI_ERROR_NONE; } /* end GetMethodModifiers */ diff --git a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp index 0a53eadbbd88b..a982ac97c4786 100644 --- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -1005,8 +1005,8 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( } // Check whether class modifiers are the same. - u2 old_flags = the_class->access_flags().as_class_flags(); - u2 new_flags = scratch_class->access_flags().as_class_flags(); + jushort old_flags = (jushort) the_class->access_flags().get_flags(); + jushort new_flags = (jushort) scratch_class->access_flags().get_flags(); if (old_flags != new_flags) { log_info(redefine, class, normalize) ("redefined class %s modifiers change error: modifiers changed from %d to %d.", @@ -1040,9 +1040,9 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED; } // access - old_flags = old_fs.access_flags().as_field_flags(); - new_flags = new_fs.access_flags().as_field_flags(); - if (old_flags != new_flags) { + old_flags = old_fs.access_flags().as_short(); + new_flags = new_fs.access_flags().as_short(); + if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) { log_info(redefine, class, normalize) ("redefined class %s field %s change error: modifiers changed from %d to %d.", the_class->external_name(), name_sym2->as_C_string(), old_flags, new_flags); @@ -1147,8 +1147,8 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( switch (method_was) { case matched: // methods match, be sure modifiers do too - old_flags = k_old_method->access_flags().as_method_flags(); - new_flags = k_new_method->access_flags().as_method_flags(); + old_flags = (jushort) k_old_method->access_flags().get_flags(); + new_flags = (jushort) k_new_method->access_flags().get_flags(); if ((old_flags ^ new_flags) & ~(JVM_ACC_NATIVE)) { log_info(redefine, class, normalize) ("redefined class %s method %s modifiers error: modifiers changed from %d to %d", diff --git a/src/hotspot/share/prims/methodHandles.cpp b/src/hotspot/share/prims/methodHandles.cpp index 5b40682851042..1e44ea957311e 100644 --- a/src/hotspot/share/prims/methodHandles.cpp +++ b/src/hotspot/share/prims/methodHandles.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -239,7 +239,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { assert(m.not_null(), "null method handle"); InstanceKlass* m_klass = m->method_holder(); assert(m_klass != nullptr, "null holder for method handle"); - int flags = (m->access_flags().as_method_flags()); + int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); int vmindex = Method::invalid_vtable_index; LogTarget(Debug, methodhandles, indy) lt_indy; @@ -352,7 +352,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { InstanceKlass* ik = fd.field_holder(); - int flags = fd.access_flags().as_field_flags(); + int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); if (fd.is_trusted_final()) flags |= TRUSTED_FINAL; if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); @@ -404,7 +404,7 @@ bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) { Method* m = iklass->find_method(name, poly_sig); if (m != nullptr) { int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; - int flags = m->access_flags().as_method_flags(); + int flags = m->access_flags().as_int(); if ((flags & required) == required) { return true; } @@ -417,7 +417,7 @@ bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) { for (; ms < me; ms++) { Method* m = iklass->methods()->at(ms); int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; - int flags = m->access_flags().as_method_flags(); + int flags = m->access_flags().as_int(); if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) { return true; } @@ -522,7 +522,7 @@ bool MethodHandles::is_signature_polymorphic_public_name(Klass* klass, Symbol* n for (; ms < me; ms++) { Method* m = iklass->methods()->at(ms); int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS | JVM_ACC_PUBLIC; - int flags = m->access_flags().as_method_flags(); + int flags = m->access_flags().as_int(); if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) { return true; } diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp index 3aef7028a7970..7739cff03bf23 100644 --- a/src/hotspot/share/runtime/reflection.cpp +++ b/src/hotspot/share/runtime/reflection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -778,7 +778,7 @@ oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_ac Handle name = Handle(THREAD, name_oop); if (name == nullptr) return nullptr; - const int modifiers = method->access_flags().as_method_flags(); + const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; Handle mh = java_lang_reflect_Method::create(CHECK_NULL); @@ -819,7 +819,7 @@ oop Reflection::new_constructor(const methodHandle& method, TRAPS) { objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); assert(!exception_types.is_null(), "cannot return null"); - const int modifiers = method->access_flags().as_method_flags(); + const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL); @@ -859,7 +859,7 @@ oop Reflection::new_field(fieldDescriptor* fd, TRAPS) { java_lang_reflect_Field::set_trusted_final(rh()); } // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here. - java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_field_flags()); + java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); java_lang_reflect_Field::set_override(rh(), false); if (fd->has_generic_signature()) { Symbol* gs = fd->generic_signature(); diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index b6e5457551929..f5cb2805c8ed9 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -263,7 +263,7 @@ nonstatic_field(Klass, _secondary_supers, Array*) \ nonstatic_field(Klass, _primary_supers[0], Klass*) \ nonstatic_field(Klass, _java_mirror, OopHandle) \ - nonstatic_field(Klass, _modifier_flags, u2) \ + nonstatic_field(Klass, _modifier_flags, jint) \ nonstatic_field(Klass, _super, Klass*) \ volatile_nonstatic_field(Klass, _subklass, Klass*) \ nonstatic_field(Klass, _layout_helper, jint) \ @@ -1017,7 +1017,7 @@ nonstatic_field(vframeArrayElement, _bci, int) \ nonstatic_field(vframeArrayElement, _method, Method*) \ \ - nonstatic_field(AccessFlags, _flags, u2) \ + nonstatic_field(AccessFlags, _flags, jint) \ nonstatic_field(elapsedTimer, _counter, jlong) \ nonstatic_field(elapsedTimer, _active, bool) \ nonstatic_field(InvocationCounter, _counter, unsigned int) \ diff --git a/src/hotspot/share/utilities/accessFlags.cpp b/src/hotspot/share/utilities/accessFlags.cpp index fc11491174f71..ec68d1244889c 100644 --- a/src/hotspot/share/utilities/accessFlags.cpp +++ b/src/hotspot/share/utilities/accessFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -47,5 +47,5 @@ void AccessFlags::print_on(outputStream* st) const { #endif // !PRODUCT || INCLUDE_JVMTI void accessFlags_init() { - assert(sizeof(AccessFlags) == sizeof(u2), "just checking size of flags"); + assert(sizeof(AccessFlags) == sizeof(jint), "just checking size of flags"); } diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index a752c09cb4272..74ccbd20ac142 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -30,19 +30,28 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" -// AccessFlags is an abstraction over Java ACC flags. -// See generated file classfile_constants.h for shared JVM_ACC_XXX access flags +// AccessFlags is an abstraction over Java access flags. class outputStream; +enum { + // See jvm.h for shared JVM_ACC_XXX access flags + + // flags actually put in .class file + JVM_ACC_WRITTEN_FLAGS = 0x00007FFF, + + // Do not add new ACC flags here. +}; + + class AccessFlags { friend class VMStructs; private: - u2 _flags; + jint _flags; // TODO: move 4 access flags above to Klass and change to u2 public: AccessFlags() : _flags(0) {} - explicit AccessFlags(u2 flags) : _flags(flags) {} + explicit AccessFlags(jint flags) : _flags(flags) {} // Java access flags bool is_public () const { return (_flags & JVM_ACC_PUBLIC ) != 0; } @@ -61,10 +70,15 @@ class AccessFlags { // Attribute flags bool is_synthetic () const { return (_flags & JVM_ACC_SYNTHETIC ) != 0; } - // get as integral value - u2 as_unsigned_short() const { return _flags; } + // get .class file flags + jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); } - void set_flags(u2 flags) { _flags = flags; } + // Initialization + void set_field_flags(jint flags) { + assert((flags & JVM_RECOGNIZED_FIELD_MODIFIERS) == flags, "only recognized flags"); + _flags = (flags & JVM_RECOGNIZED_FIELD_MODIFIERS); + } + void set_flags(jint flags) { _flags = (flags & JVM_ACC_WRITTEN_FLAGS); } private: friend class Klass; @@ -76,22 +90,11 @@ class AccessFlags { void set_is_synthetic() { _flags |= JVM_ACC_SYNTHETIC; } public: - inline friend AccessFlags accessFlags_from(u2 flags); + // Conversion + jshort as_short() const { return (jshort)_flags; } + jint as_int() const { return _flags; } - u2 as_method_flags() const { - assert((_flags & JVM_RECOGNIZED_METHOD_MODIFIERS) == _flags, "only recognized flags"); - return _flags; - } - - u2 as_field_flags() const { - assert((_flags & JVM_RECOGNIZED_FIELD_MODIFIERS) == _flags, "only recognized flags"); - return _flags; - } - - u2 as_class_flags() const { - assert((_flags & JVM_RECOGNIZED_CLASS_MODIFIERS) == _flags, "only recognized flags"); - return _flags; - } + inline friend AccessFlags accessFlags_from(jint flags); // Printing/debugging #if INCLUDE_JVMTI @@ -101,7 +104,7 @@ class AccessFlags { #endif }; -inline AccessFlags accessFlags_from(u2 flags) { +inline AccessFlags accessFlags_from(jint flags) { AccessFlags af; af._flags = flags; return af; diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java index 66ebd6551a4fd..2f310effc87f4 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -75,4 +75,9 @@ public void printOn(PrintStream tty) { if (isStrict ()) tty.print("strict " ); if (isSynthetic ()) tty.print("synthetic " ); } + + // get flags written to .class files + public int getStandardFlags() { + return (int) (flags & JVM_ACC_WRITTEN_FLAGS); + } } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java index 7f9a6b4b49d2a..25f40ec443f50 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -98,7 +98,16 @@ public interface ClassConstants public static final long JVM_ACC_ENUM = 0x4000; /* field is declared as element of enum */ + // from accessFlags.hpp - hotspot internal flags + + // flags actually put in .class file + public static final long JVM_ACC_WRITTEN_FLAGS = 0x00007FFF; + + // flags accepted by set_field_flags + public static final long JVM_ACC_FIELD_FLAGS = 0x00008000 | JVM_ACC_WRITTEN_FLAGS; + // from jvm.h + public static final long JVM_RECOGNIZED_CLASS_MODIFIERS = (JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_SUPER | From 40f0a398fa9b1b39a43640973eaffb041bb7b63d Mon Sep 17 00:00:00 2001 From: Taizo Kurashige Date: Wed, 8 Jan 2025 01:15:44 +0000 Subject: [PATCH 036/286] 8343342: java/io/File/GetXSpace.java fails on Windows with CD-ROM drive Reviewed-by: bpb, aturbanov --- test/jdk/java/io/File/GetXSpace.java | 56 ++++++++++++++++++++++++++-- test/jdk/java/io/File/libGetXSpace.c | 29 +++++++++++++- 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/test/jdk/java/io/File/GetXSpace.java b/test/jdk/java/io/File/GetXSpace.java index d76000dbef553..512ea51780b36 100644 --- a/test/jdk/java/io/File/GetXSpace.java +++ b/test/jdk/java/io/File/GetXSpace.java @@ -54,6 +54,8 @@ public class GetXSpace { System.loadLibrary("GetXSpace"); } + private static final Pattern DF_PATTERN = Pattern.compile("([^\\s]+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+\\d+%\\s+([^\\s].*)\n"); + private static int fail = 0; private static int pass = 0; private static Throwable first; @@ -104,8 +106,17 @@ private static class Space { Space(String name) { this.name = name; long[] sizes = new long[4]; - if (getSpace0(name, sizes)) - System.err.println("WARNING: total space is estimated"); + if (Platform.isWindows() & isCDDrive(name)) { + try { + getCDDriveSpace(name, sizes); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("can't get CDDrive sizes"); + } + } else { + if (getSpace0(name, sizes)) + System.err.println("WARNING: total space is estimated"); + } this.size = sizes[0]; this.total = sizes[1]; this.free = sizes[2]; @@ -167,7 +178,8 @@ private static void compare(Space s) { out.format("%s (%d):%n", s.name(), s.size()); String fmt = " %-4s total = %12d free = %12d usable = %12d%n"; - out.format(fmt, "getSpace0", s.total(), s.free(), s.available()); + String method = Platform.isWindows() & isCDDrive(s.name()) ? "getCDDriveSpace" : "getSpace0"; + out.format(fmt, method, s.total(), s.free(), s.available()); out.format(fmt, "getXSpace", ts, fs, us); // If the file system can dynamically change size, this check will fail. @@ -324,7 +336,7 @@ private static int testFile(Path dir) { private static int testVolumes() { out.println("--- Testing volumes"); // Find all of the partitions on the machine and verify that the sizes - // returned by File::getXSpace are equivalent to those from getSpace0 + // returned by File::getXSpace are equivalent to those from getSpace0 or getCDDriveSpace ArrayList l; try { l = paths(); @@ -397,4 +409,40 @@ public static void main(String[] args) throws Exception { // size[3] usable space: number of bytes available to the caller // private static native boolean getSpace0(String root, long[] space); + + private static native boolean isCDDrive(String root); + + private static void getCDDriveSpace(String root, long[] sizes) + throws IOException { + String[] cmd = new String[] {"df", "-k", "-P", root}; + Process p = Runtime.getRuntime().exec(cmd); + StringBuilder sb = new StringBuilder(); + + try (BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()))) { + String s; + int i = 0; + while ((s = in.readLine()) != null) { + // skip header + if (i++ == 0) continue; + sb.append(s).append("\n"); + } + } + out.println(sb); + + Matcher m = DF_PATTERN.matcher(sb); + int j = 0; + while (j < sb.length()) { + if (m.find(j)) { + sizes[0] = Long.parseLong(m.group(2)) * 1024; + sizes[1] = Long.parseLong(m.group(3)) * 1024; + sizes[2] = sizes[0] - sizes[1]; + sizes[3] = Long.parseLong(m.group(4)) * 1024; + j = m.end(); + } else { + throw new RuntimeException("unrecognized df output format: " + + "charAt(" + j + ") = '" + + sb.charAt(j) + "'"); + } + } + } } diff --git a/test/jdk/java/io/File/libGetXSpace.c b/test/jdk/java/io/File/libGetXSpace.c index a4e36bd24316d..c45aea146910e 100644 --- a/test/jdk/java/io/File/libGetXSpace.c +++ b/test/jdk/java/io/File/libGetXSpace.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -159,6 +159,33 @@ Java_GetXSpace_getSpace0 (*env)->SetLongArrayRegion(env, sizes, 0, 4, array); return totalSpaceIsEstimated; } + +JNIEXPORT jboolean JNICALL +Java_GetXSpace_isCDDrive + (JNIEnv *env, jclass cls, jstring root) +{ +#ifdef WINDOWS + const jchar* strchars = (*env)->GetStringChars(env, root, NULL); + if (strchars == NULL) { + JNU_ThrowByNameWithLastError(env, "java/lang/RuntimeException", + "GetStringChars"); + return JNI_FALSE; + } + + LPCWSTR path = (LPCWSTR)strchars; + UINT driveType = GetDriveTypeW(path); + + (*env)->ReleaseStringChars(env, root, strchars); + + if (driveType != DRIVE_CDROM) { + return JNI_FALSE; + } + + return JNI_TRUE; +#else + return JNI_FALSE; +#endif +} #ifdef __cplusplus } #endif From bcefab5e55d4527a38dcab550581a734c1564608 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Wed, 8 Jan 2025 03:37:28 +0000 Subject: [PATCH 037/286] 8342468: Improve API documentation for java.lang.classfile.constantpool Reviewed-by: asotona --- .../lang/classfile/BootstrapMethodEntry.java | 30 +- .../java/lang/classfile/ClassFile.java | 53 ++- .../AnnotationConstantValueEntry.java | 16 +- .../classfile/constantpool/ClassEntry.java | 63 ++- .../constantpool/ConstantDynamicEntry.java | 56 ++- .../classfile/constantpool/ConstantPool.java | 32 +- .../constantpool/ConstantPoolBuilder.java | 444 ++++++++++-------- .../constantpool/ConstantPoolException.java | 28 +- .../constantpool/ConstantValueEntry.java | 13 +- .../classfile/constantpool/DoubleEntry.java | 26 +- .../DynamicConstantPoolEntry.java | 55 ++- .../classfile/constantpool/FieldRefEntry.java | 24 +- .../classfile/constantpool/FloatEntry.java | 23 +- .../classfile/constantpool/IntegerEntry.java | 20 +- .../constantpool/InterfaceMethodRefEntry.java | 26 +- .../constantpool/InvokeDynamicEntry.java | 43 +- .../constantpool/LoadableConstantEntry.java | 24 +- .../classfile/constantpool/LongEntry.java | 21 +- .../constantpool/MemberRefEntry.java | 40 +- .../constantpool/MethodHandleEntry.java | 44 +- .../constantpool/MethodRefEntry.java | 24 +- .../constantpool/MethodTypeEntry.java | 30 +- .../classfile/constantpool/ModuleEntry.java | 23 +- .../constantpool/NameAndTypeEntry.java | 36 +- .../classfile/constantpool/PackageEntry.java | 26 +- .../classfile/constantpool/PoolEntry.java | 52 +- .../classfile/constantpool/StringEntry.java | 22 +- .../classfile/constantpool/Utf8Entry.java | 44 +- .../classfile/constantpool/package-info.java | 54 ++- .../snippet-files/PackageSnippets.java | 43 ++ test/jdk/jdk/classfile/SnippetsTest.java | 6 +- 31 files changed, 1070 insertions(+), 371 deletions(-) create mode 100644 src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java diff --git a/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java b/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java index 1608e77bee697..ab246a8653bb8 100644 --- a/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,7 +25,9 @@ package java.lang.classfile; +import java.lang.classfile.attribute.BootstrapMethodsAttribute; import java.lang.classfile.constantpool.ConstantPool; +import java.lang.classfile.constantpool.ConstantPoolBuilder; import java.lang.classfile.constantpool.LoadableConstantEntry; import java.lang.classfile.constantpool.MethodHandleEntry; import java.util.List; @@ -34,10 +36,20 @@ /** * Models an entry in the bootstrap method table. The bootstrap method table - * is stored in the {@code BootstrapMethods} attribute, but is modeled by - * the {@link ConstantPool}, since the bootstrap method table is logically - * part of the constant pool. + * is stored in the {@link BootstrapMethodsAttribute BootstrapMethods} + * attribute, but is modeled by the {@link ConstantPool}, since the bootstrap + * method table is logically part of the constant pool. + *

    + * A bootstrap method entry is composite: + * {@snippet lang=text : + * // @link substring="BootstrapMethodEntry" target="ConstantPoolBuilder#bsmEntry(MethodHandleEntry, List)" : + * BootstrapMethodEntry( + * MethodHandleEntry bootstrapMethod, // @link substring="bootstrapMethod" target="#bootstrapMethod" + * List arguments // @link substring="arguments" target="#arguments()" + * ) + * } * + * @see ConstantPoolBuilder#bsmEntry ConstantPoolBuilder::bsmEntry * @since 24 */ public sealed interface BootstrapMethodEntry @@ -45,11 +57,19 @@ public sealed interface BootstrapMethodEntry /** * {@return the constant pool associated with this entry} + * + * @apiNote + * Given a {@link ConstantPoolBuilder} {@code builder} and a {@code + * BootstrapMethodEntry} {@code entry}, use {@link + * ConstantPoolBuilder#canWriteDirect + * builder.canWriteDirect(entry.constantPool())} instead of object equality + * of the constant pool to determine if an entry is compatible. */ ConstantPool constantPool(); /** - * {@return the index into the bootstrap method table corresponding to this entry} + * {@return the index into the bootstrap method table corresponding to this + * entry} */ int bsmIndex(); diff --git a/src/java.base/share/classes/java/lang/classfile/ClassFile.java b/src/java.base/share/classes/java/lang/classfile/ClassFile.java index c98991ecf7a92..43fb1927b3873 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassFile.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -140,21 +140,56 @@ static ClassHierarchyResolverOption of(ClassHierarchyResolver classHierarchyReso /** * Option describing whether to preserve the original constant pool when - * transforming a classfile. Reusing the constant pool enables significant - * optimizations in processing time and minimizes differences between the - * original and transformed classfile, but may result in a bigger classfile - * when a classfile is significantly transformed. - * Default is {@code SHARED_POOL} to preserve the original constant - * pool. + * transforming a {@code class} file. Reusing the constant pool enables + * significant optimizations in processing time and minimizes differences + * between the original and transformed {@code class} files, but may result + * in a bigger transformed {@code class} file when many elements of the + * original {@code class} file are dropped and many original constant + * pool entries become unused. Default is {@link #SHARED_POOL} to preserve + * the original constant pool. * + * @see ConstantPoolBuilder + * @see #build(ClassEntry, ConstantPoolBuilder, Consumer) + * @see #transformClass(ClassModel, ClassTransform) * @since 24 */ enum ConstantPoolSharingOption implements Option { - /** Preserves the original constant pool when transforming classfile */ + /** + * Preserves the original constant pool when transforming the {@code + * class} file. + *

    + * These two transformations below are equivalent: + * {@snippet lang=java : + * ClassModel originalClass = null; // @replace substring=null; replacement=... + * ClassDesc resultClassName = null; // @replace substring=null; replacement=... + * ClassTransform classTransform = null; // @replace substring=null; replacement=... + * var resultOne = ClassFile.of(ConstantPoolSharingOption.SHARED_POOL) + * .transformClass(originalClass, resultClassName, classTransform); + * var resultTwo = ClassFile.of().build(resultClassName, ConstantPoolBuilder.of(originalClass), + * clb -> clb.transform(originalClass, classTransform)); + * } + * + * @see ConstantPoolBuilder#of(ClassModel) ConstantPoolBuilder::of(ClassModel) + */ SHARED_POOL, - /** Creates a new constant pool when transforming classfile */ + /** + * Creates a new constant pool when transforming the {@code class} file. + *

    + * These two transformations below are equivalent: + * {@snippet lang=java : + * ClassModel originalClass = null; // @replace substring=null; replacement=... + * ClassDesc resultClassName = null; // @replace substring=null; replacement=... + * ClassTransform classTransform = null; // @replace substring=null; replacement=... + * var resultOne = ClassFile.of(ConstantPoolSharingOption.NEW_POOL) + * .transformClass(originalClass, resultClassName, classTransform); + * var resultTwo = ClassFile.of().build(resultClassName, ConstantPoolBuilder.of(), + * clb -> clb.transform(originalClass, classTransform)); + * } + * + * @see ConstantPoolBuilder#of() ConstantPoolBuilder::of() + */ NEW_POOL } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java index 5255ceb1ef727..c4b6546fe20e8 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,10 +28,9 @@ import java.lang.constant.ConstantDesc; /** - * A constant pool entry that may be used by annotation constant values, - * which includes the four kinds of primitive constants and UTF8 constants. - * These entries are also the only entries that do not refer to other - * constant pool entries. + * Marker interface for constant pool entries that can represent constant values + * associated with elements of annotations. They are also the only entries that + * do not refer to other constant pool entries. * * @apiNote * An annotation constant value entry alone is not sufficient to determine @@ -40,6 +39,7 @@ * in {@link AnnotationValue.OfInt}. * * @see AnnotationValue.OfConstant + * @jvms 4.7.16.1 The {@code element_value} structure * @sealedGraph * @since 24 */ @@ -47,9 +47,9 @@ public sealed interface AnnotationConstantValueEntry extends PoolEntry permits DoubleEntry, FloatEntry, IntegerEntry, LongEntry, Utf8Entry { /** - * {@return the constant value} The constant value will be an {@link Integer}, - * {@link Long}, {@link Float}, {@link Double} for the primitive constants, - * or {@link String} for UTF8 constants. + * {@return the constant value} The constant value will be an {@link + * Integer}, {@link Long}, {@link Float}, {@link Double} for the primitive + * constants, or {@link String} for UTF8 constants. */ ConstantDesc constantValue(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java index 2a3bd95da22f9..5017838d68eba 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -30,33 +30,82 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Class_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.1 The CONSTANT_Class_info Structure + * Models a {@code CONSTANT_Class_info} structure, representing a reference + * type, in the constant pool of a {@code class} file. + *

    + * The use of a {@code ClassEntry} is modeled by a {@link ClassDesc} that is not + * primitive. Conversions are through {@link ConstantPoolBuilder#classEntry( + * ClassDesc)} and {@link #asSymbol()}. + *

    + * A {@code ClassEntry} is composite: + * {@snippet lang=text : + * // @link substring="ClassEntry" target="ConstantPoolBuilder#classEntry(Utf8Entry)" : + * ClassEntry(Utf8Entry name) // @link substring="name" target="#name" + * } + * where {@code name} represents: + *

      + *
    • The internal form of a binary name (JVMS {@jvms 4.2.1}), if and only if + * this {@code ClassEntry} represents a class or interface, such as {@code + * java/lang/String} for the {@link String} class. + *
    • A field descriptor string (JVMS {@jvms 4.3.2}) representing an array type, + * if and only if this {@code ClassEntry} represents an array type, such as + * {@code [I} for the {@code int[]} type, or {@code [Ljava/lang/String;} for the + * {@code String[]} type. + *
    + * A field descriptor string for an array type can be distinguished by its + * leading {@code '['} character. * + * @apiNote + * The internal form of a binary name, where all occurrences of {@code .} in the + * name are replaced by {@code /}, is informally known as an {@index + * "internal name"}. This concept also applies to package names in + * addition to class and interface names. + * + * @see ConstantPoolBuilder#classEntry ConstantPoolBuilder::classEntry + * @see ClassDesc + * @jvms 4.4.1 The {@code CONSTANT_Class_info} Structure * @since 24 */ public sealed interface ClassEntry extends LoadableConstantEntry permits AbstractPoolEntry.ClassEntryImpl { + /** + * {@inheritDoc} + *

    + * This is equivalent to {@link #asSymbol() asSymbol()}. + */ @Override default ConstantDesc constantValue() { return asSymbol(); } /** - * {@return the UTF8 constant pool entry for the class name} + * {@return the {@code Utf8Entry} referred by this structure} If the + * value of the UTF8 starts with a {@code [}, this represents an array type + * and the value is a descriptor string; otherwise, this represents a class + * or interface and the value is the {@linkplain ##internalname internal + * form} of a binary name. + * + * @see ConstantPoolBuilder#classEntry(Utf8Entry) + * ConstantPoolBuilder::classEntry(Utf8Entry) */ Utf8Entry name(); /** - * {@return the class name, as an internal binary name} + * {@return the represented reference type, as the {@linkplain + * ##internalname internal form} of a binary name or an array descriptor + * string} This is a shortcut for {@link #name() name().stringValue()}. */ String asInternalName(); /** - * {@return the class name, as a symbolic descriptor} + * {@return the represented reference type, as a symbolic descriptor} The + * returned descriptor is never {@linkplain ClassDesc#isPrimitive() + * primitive}. + * + * @see ConstantPoolBuilder#classEntry(ClassDesc) + * ConstantPoolBuilder::classEntry(ClassDesc) */ ClassDesc asSymbol(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java index 72050cd9b8f6f..bbd03c8829270 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -33,10 +33,36 @@ import jdk.internal.classfile.impl.Util; /** - * Models a {@code CONSTANT_Dynamic_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures + * Models a {@code CONSTANT_Dynamic_info} structure, representing a {@index + * "dynamically-computed constant"}, in the constant pool of a {@code + * class} file. + *

    + * The use of a {@code ConstantDynamicEntry} is modeled by a {@link + * DynamicConstantDesc}. Conversions are through {@link #asSymbol()} and {@link + * ConstantPoolBuilder#constantDynamicEntry(DynamicConstantDesc)}. + *

    + * A dynamic constant entry is composite: + * {@snippet lang=text : + * // @link substring="ConstantDynamicEntry" target="ConstantPoolBuilder#constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry)" : + * ConstantDynamicEntry( + * BootstrapMethodEntry bootstrap, // @link substring="bootstrap" target="#bootstrap()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } + * where {@link #type() nameAndType.type()} is a {@linkplain #typeSymbol() + * field descriptor} string. * + * @apiNote + * A dynamically-computed constant is frequently called a {@index "dynamic + * constant"}, or a {@index "condy"}, from the abbreviation of + * "constant dynamic". + * + * @see ConstantPoolBuilder#constantDynamicEntry + * ConstantPoolBuilder::constantDynamicEntry + * @see DynamicConstantDesc + * @see java.lang.invoke##condycon Dynamically-computed constants + * @jvms 4.4.10 The {@code CONSTANT_Dynamic_info} and {@code + * CONSTANT_InvokeDynamic_info} Structures * @since 24 */ public sealed interface ConstantDynamicEntry @@ -44,19 +70,28 @@ public sealed interface ConstantDynamicEntry permits AbstractPoolEntry.ConstantDynamicEntryImpl { /** - * {@return a symbolic descriptor for the dynamic constant's type} + * {@return a symbolic descriptor for the {@linkplain #type() field type} of + * this dynamically-computed constant} */ default ClassDesc typeSymbol() { return Util.fieldTypeSymbol(type()); } + /** + * {@inheritDoc} + *

    + * This is equivalent to {@link #asSymbol() asSymbol()}. + */ @Override default ConstantDesc constantValue() { return asSymbol(); } /** - * {@return the symbolic descriptor for the {@code invokedynamic} constant} + * {@return a symbolic descriptor for this dynamically-computed constant} + * + * @see ConstantPoolBuilder#constantDynamicEntry(DynamicConstantDesc) + * ConstantPoolBuilder::constantDynamicEntry(DynamicConstantDesc) */ default DynamicConstantDesc asSymbol() { return DynamicConstantDesc.ofNamed(bootstrap().bootstrapMethod().asSymbol(), @@ -68,10 +103,15 @@ default DynamicConstantDesc asSymbol() { } /** - * {@return the type of the constant} + * {@inheritDoc} + * + * @apiNote + * The data type of a dynamically-computed constant depends on its + * {@linkplain #type() descriptor}, while the data type of all other + * constants can be determined by their {@linkplain #tag() constant type}. */ @Override default TypeKind typeKind() { - return TypeKind.fromDescriptor(type().stringValue()); + return TypeKind.fromDescriptor(type()); } } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java index 91dc8906b7bf5..6fed8dad8b79e 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -27,14 +27,22 @@ import java.lang.classfile.BootstrapMethodEntry; import java.lang.classfile.ClassReader; +import java.lang.classfile.attribute.BootstrapMethodsAttribute; import java.util.Iterator; import java.util.NoSuchElementException; /** - * Provides read access to the constant pool and bootstrap method table of a - * classfile. - * @jvms 4.4 The Constant Pool + * Provides read access to the constant pool and the bootstrap method table of a + * {@code class} file. + * + *

    Index in the Constant Pool

    + * The constant pool entries are accessed by index. A valid index is in the + * range of {@link #size() [1, size())}. It is {@linkplain PoolEntry#width() + * unusable} if a {@link LongEntry} or {@link DoubleEntry} is at its previous + * index. * + * @see BootstrapMethodsAttribute + * @jvms 4.4 The Constant Pool * @sealedGraph * @since 24 */ @@ -46,7 +54,7 @@ public sealed interface ConstantPool extends Iterable * * @apiNote * If only a particular type of entry is expected, use {@link #entryByIndex( - * int, Class) entryByIndex(int, Class)}. + * int, Class)}. * * @param index the index within the pool of the desired entry * @throws ConstantPoolException if the index is out of range of the @@ -55,7 +63,11 @@ public sealed interface ConstantPool extends Iterable PoolEntry entryByIndex(int index); /** - * {@return the size of the constant pool} + * {@return the exclusive upper bound of the valid indices of this constant + * pool} The actual number of entries is lower because {@code 0}, {@code + * size()} are not valid, and a valid index may be unusable. + * + * @see ##index Index in the Constant Pool */ int size(); @@ -66,12 +78,17 @@ public sealed interface ConstantPool extends Iterable * @param index the index within the pool of the desired entry * @param cls the entry type * @throws ConstantPoolException if the index is out of range of the - * constant pool, or the entry is not of the given type + * constant pool or considered unusable, or the entry is not + * of the given type */ T entryByIndex(int index, Class cls); /** * {@return an iterator over pool entries} + * + * @apiNote + * This skips any unusable index and is less error-prone than iterating by + * raw index. See {@linkplain ##index Index in the Constant Pool}. */ @Override default Iterator iterator() { @@ -93,7 +110,6 @@ public PoolEntry next() { }; } - /** * {@return the {@link BootstrapMethodEntry} at the specified index within * the bootstrap method table} diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java index 2dc2a390bd1d3..e1518ab6a02eb 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,10 +25,16 @@ package java.lang.classfile.constantpool; import java.lang.classfile.BootstrapMethodEntry; -import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassFileBuilder; import java.lang.classfile.ClassModel; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.attribute.ConstantValueAttribute; +import java.lang.classfile.instruction.ConstantInstruction; import java.lang.constant.*; +import java.lang.invoke.MethodHandleInfo; import java.util.List; +import java.util.function.Consumer; import jdk.internal.classfile.impl.AbstractPoolEntry.ClassEntryImpl; import jdk.internal.classfile.impl.ClassReaderImpl; @@ -39,14 +45,45 @@ import static java.util.Objects.requireNonNull; /** - * Builder for the constant pool of a classfile. Provides read and write access - * to the constant pool that is being built. Writing is append-only and idempotent - * (entry-bearing methods will return an existing entry if there is one). + * Builder for the constant pool of a {@code class} file. Provides read and + * write access to the constant pool that is {@linkplain ClassFileBuilder#constantPool() + * being built}. Writing is append-only (the index of new entries monotonically + * increase) and idempotent (entry-bearing methods will return an existing entry + * if there is a suitable one). + *

    + * For {@code class} file building, an overload of {@link ClassFile#build( + * ClassEntry, ConstantPoolBuilder, Consumer) ClassFile::build} takes a + * {@code ConstantPoolBuilder}. For {@code class} file transformations via + * {@link ClassFile#transformClass ClassFile::transformClass}, the {@link + * ClassFile.ConstantPoolSharingOption} controls how the constant pool builder + * of the resulting {@code class} is created. * - * A {@linkplain ConstantPoolBuilder} is associated with a {@link ClassBuilder}. - * The {@linkplain ConstantPoolBuilder} also provides access to some of the - * state of the {@linkplain ClassBuilder}, such as classfile processing options. + *

    Alien Constant Pool Entries

    + * In {@code class} file building and constant pool building, some constant pool + * entries supplied may be {@linkplain #canWriteDirect(ConstantPool) alien} + * to this constant pool builder of the active class file builder. For example, + * {@link #classEntry(Utf8Entry) classEntry(Utf8Entry)} may be called with an + * alien UTF8 entry. Alien entries will be converted to a pool entry in + * this constant pool builder, reusing equivalent entries or adding new entries + * if there is none. As a result, all pool entries returned by entry-bearing + * methods in this constant pool builder belong to this constant pool. + *

    + * Some {@link ClassFileBuilder} methods may have their outputs adjusted if they + * receive pool entries alien to {@linkplain ClassFileBuilder#constantPool + * their constant pools}. For example, if an {@link ConstantInstruction#ofLoad + * ldc_w} instruction with an alien entry is written to a {@link CodeBuilder}, + * the {@code CodeBuilder} may emit a functionally equivalent {@code ldc} + * instruction instead, if the converted entry can be encoded in such an + * instruction. + *

    + * To avoid the conversion of alien constant pool entries, such as for the + * accuracy of the generated {@code class} file, users can always supply + * constant pool entries obtained by calling the constant pool builder + * entry-bearing methods of the constant pools associated with the {@code + * ClassFileBuilder}. Otherwise, the conversions have no impact on the + * behaviors of the generated {@code class} files. * + * @see ClassFileBuilder#constantPool() * @since 24 */ public sealed interface ConstantPoolBuilder @@ -55,10 +92,14 @@ public sealed interface ConstantPoolBuilder /** * {@return a new constant pool builder} The new constant pool builder will - * be pre-populated with the contents of the constant pool associated with - * the class reader. + * be pre-populated with the contents of the constant pool {@linkplain + * ClassModel#constantPool() associated with} the given class model. The + * index of new entries will start from the {@link ConstantPool#size() + * size()} of the source pool. * * @param classModel the class to copy from + * @see ClassFile#build(ClassEntry, ConstantPoolBuilder, Consumer) + * @see ClassFile.ConstantPoolSharingOption#SHARED_POOL */ static ConstantPoolBuilder of(ClassModel classModel) { return new SplitConstantPool((ClassReaderImpl) classModel.constantPool()); @@ -66,35 +107,47 @@ static ConstantPoolBuilder of(ClassModel classModel) { /** * {@return a new constant pool builder} The new constant pool builder - * will be empty. + * will be empty. The index of new entries will start from {@code 1}. + * + * @see ClassFile.ConstantPoolSharingOption#NEW_POOL */ static ConstantPoolBuilder of() { return new SplitConstantPool(); } /** - * {@return whether the provided constant pool is index-compatible with this - * one} This may be because they are the same constant pool, or because this - * constant pool was copied from the other. + * {@return {@code true} if the index of any entry in the given constant + * pool refers to the same entry in this builder} This may be because they + * are the same builder, or because this builder was {@linkplain + * #of(ClassModel) pre-populated} from the given constant pool. + *

    + * If the constant pool of an entry is not directly writable to this pool, + * it is alien to this pool, and a {@link ClassFileBuilder} associated + * with this constant pool will convert that alien constant pool entry. * - * @param constantPool the other constant pool + * @param constantPool the given constant pool + * @see ClassFileBuilder#constantPool() ClassFileBuilder::constantPool + * @see ##alien Alien Constant Pool Entries */ boolean canWriteDirect(ConstantPool constantPool); /** - * {@return A {@link Utf8Entry} describing the provided {@linkplain String}} - * If a UTF8 entry in the pool already describes this string, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link Utf8Entry} describing the provided {@link String}} * * @param s the string + * @see Utf8Entry#stringValue() Utf8Entry::stringValue */ Utf8Entry utf8Entry(String s); /** - * {@return A {@link Utf8Entry} describing the field descriptor of the provided - * {@linkplain ClassDesc}} - * If a UTF8 entry in the pool already describes this field descriptor, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link Utf8Entry} describing the {@linkplain + * ClassDesc#descriptorString() field descriptor string} of the provided + * {@link ClassDesc}} + * + * @apiNote + * The resulting {@code Utf8Entry} is usually not {@linkplain + * #classEntry(Utf8Entry) referable by} a {@link ClassEntry}, which uses + * internal form of binary names. * * @param desc the symbolic descriptor for the class */ @@ -103,10 +156,9 @@ default Utf8Entry utf8Entry(ClassDesc desc) { } /** - * {@return A {@link Utf8Entry} describing the method descriptor of the provided - * {@linkplain MethodTypeDesc}} - * If a UTF8 entry in the pool already describes this field descriptor, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link Utf8Entry} describing the {@linkplain + * MethodTypeDesc#descriptorString() method descriptor string} of the + * provided {@link MethodTypeDesc}} * * @param desc the symbolic descriptor for the method type */ @@ -115,25 +167,24 @@ default Utf8Entry utf8Entry(MethodTypeDesc desc) { } /** - * {@return A {@link ClassEntry} describing the class whose internal name - * is encoded in the provided {@linkplain Utf8Entry}} - * If a Class entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ClassEntry} referring to the provided {@link + * Utf8Entry}} The {@code Utf8Entry} describes the internal form + * of the binary name of a class or interface or the field descriptor + * string of an array type. * - * @param ne the constant pool entry describing the internal name of the class + * @param ne the {@code Utf8Entry} + * @see ClassEntry#name() ClassEntry::name */ ClassEntry classEntry(Utf8Entry ne); /** - * {@return A {@link ClassEntry} describing the class described by - * provided {@linkplain ClassDesc}} - * If a Class entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ClassEntry} describing the same reference type + * as the provided {@link ClassDesc}} * - * @param classDesc the symbolic descriptor for the class - * @throws IllegalArgumentException if {@code classDesc} represents a primitive type + * @param classDesc the symbolic descriptor for the reference type + * @throws IllegalArgumentException if {@code classDesc} represents a + * primitive type + * @see ClassEntry#asSymbol() ClassEntry::asSymbol */ default ClassEntry classEntry(ClassDesc classDesc) { if (requireNonNull(classDesc).isPrimitive()) { @@ -145,196 +196,191 @@ default ClassEntry classEntry(ClassDesc classDesc) { } /** - * {@return A {@link PackageEntry} describing the class whose internal name - * is encoded in the provided {@linkplain Utf8Entry}} - * If a Package entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link PackageEntry} referring to the provided {@link + * Utf8Entry}} The {@code Utf8Entry} describes the internal form + * of the name of a package. * - * @param nameEntry the constant pool entry describing the internal name of - * the package + * @param nameEntry the {@code Utf8Entry} + * @see PackageEntry#name() PackageEntry::name */ PackageEntry packageEntry(Utf8Entry nameEntry); /** - * {@return A {@link PackageEntry} describing the class described by - * provided {@linkplain PackageDesc}} - * If a Package entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link PackageEntry} describing the same package as the + * provided {@link PackageDesc}} * - * @param packageDesc the symbolic descriptor for the class + * @param packageDesc the symbolic descriptor for the package + * @see PackageEntry#asSymbol() PackageEntry::asSymbol */ default PackageEntry packageEntry(PackageDesc packageDesc) { return packageEntry(utf8Entry(packageDesc.internalName())); } /** - * {@return A {@link ModuleEntry} describing the module whose name - * is encoded in the provided {@linkplain Utf8Entry}} - * If a module entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ModuleEntry} referring to the provided {@link + * Utf8Entry}} The {@code Utf8Entry} describes the module name. * * @param moduleName the constant pool entry describing the module name + * @see ModuleEntry#name() ModuleEntry::name */ ModuleEntry moduleEntry(Utf8Entry moduleName); /** - * {@return A {@link ModuleEntry} describing the module described by - * provided {@linkplain ModuleDesc}} - * If a module entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ModuleEntry} describing the same module as the provided + * {@link ModuleDesc}} * - * @param moduleDesc the symbolic descriptor for the class + * @param moduleDesc the symbolic descriptor for the module + * @see ModuleEntry#asSymbol() ModuleEntry::asSymbol */ default ModuleEntry moduleEntry(ModuleDesc moduleDesc) { return moduleEntry(utf8Entry(moduleDesc.name())); } /** - * {@return A {@link NameAndTypeEntry} describing the provided name and type} - * If a NameAndType entry in the pool already describes this name and type, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link NameAndTypeEntry} referring to the provided name and + * type {@link Utf8Entry}} The name {@code Utf8Entry} describes an + * unqualified name or the special name {@value ConstantDescs#INIT_NAME}, + * and the type {@code Utf8Entry} describes a field or method descriptor + * string. * - * @param nameEntry the member name - * @param typeEntry the member field or method descriptor + * @param nameEntry the name {@code Utf8Entry} + * @param typeEntry the type {@code Utf8Entry} + * @see NameAndTypeEntry#name() NameAndTypeEntry::name + * @see NameAndTypeEntry#type() NameAndTypeEntry::type */ NameAndTypeEntry nameAndTypeEntry(Utf8Entry nameEntry, Utf8Entry typeEntry); /** - * {@return A {@link NameAndTypeEntry} describing the provided name and type} - * If a NameAndType entry in the pool already describes this name and type, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link NameAndTypeEntry} describing the provided unqualified + * name and field descriptor} * - * @param name the member name - * @param type the symbolic descriptor for a field type + * @param name the unqualified name + * @param type the field descriptor */ default NameAndTypeEntry nameAndTypeEntry(String name, ClassDesc type) { return nameAndTypeEntry(utf8Entry(name), utf8Entry(type)); } /** - * {@return A {@link NameAndTypeEntry} describing the provided name and type} - * If a NameAndType entry in the pool already describes this name and type, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link NameAndTypeEntry} describing the provided name and + * method descriptor} The name can be an unqualified name or the + * special name {@value ConstantDescs#INIT_NAME}. * - * @param name the member name - * @param type the symbolic descriptor for a method type + * @param name the unqualified name, or {@value ConstantDescs#INIT_NAME} + * @param type the method descriptor */ default NameAndTypeEntry nameAndTypeEntry(String name, MethodTypeDesc type) { return nameAndTypeEntry(utf8Entry(name), utf8Entry(type)); } /** - * {@return A {@link FieldRefEntry} describing a field of a class} - * If a FieldRef entry in the pool already describes this field, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link FieldRefEntry} referring to a {@link ClassEntry} and a + * {@link NameAndTypeEntry}} The {@code ClassEntry} describes a class or + * interface that has this field as a member, and the {@code + * NameAndTypeEntry} describes the unqualified name and the field descriptor + * for this field. * - * @param owner the class the field is a member of - * @param nameAndType the name and type of the field + * @param owner the {@code ClassEntry} + * @param nameAndType the {@code NameAndTypeEntry} + * @see FieldRefEntry#owner() FieldRefEntry::owner + * @see FieldRefEntry#nameAndType() FieldRefEntry::nameAndType */ FieldRefEntry fieldRefEntry(ClassEntry owner, NameAndTypeEntry nameAndType); /** - * {@return A {@link FieldRefEntry} describing a field of a class} - * If a FieldRef entry in the pool already describes this field, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link FieldRefEntry} describing a field of a class} * - * @param owner the class the field is a member of - * @param name the name of the field - * @param type the type of the field + * @param owner the class or interface the field is a member of + * @param name the unqualified name of the field + * @param type the field descriptor * @throws IllegalArgumentException if {@code owner} represents a primitive type + * @see FieldRefEntry#typeSymbol() FieldRefEntry::typeSymbol */ default FieldRefEntry fieldRefEntry(ClassDesc owner, String name, ClassDesc type) { return fieldRefEntry(classEntry(owner), nameAndTypeEntry(name, type)); } /** - * {@return A {@link MethodRefEntry} describing a method of a class} - * If a MethodRefEntry entry in the pool already describes this method, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodRefEntry} referring to a {@link ClassEntry} and a + * {@link NameAndTypeEntry}} The {@code ClassEntry} describes a class that + * has this method as a member, and the {@code NameAndTypeEntry} describes + * the unqualified name or the special name {@value ConstantDescs#INIT_NAME} + * and the method descriptor for this method. * - * @param owner the class the method is a member of - * @param nameAndType the name and type of the method + * @param owner the {@code ClassEntry} + * @param nameAndType the {@code NameAndTypeEntry} + * @see MethodRefEntry#owner() MethodRefEntry::owner + * @see MethodRefEntry#nameAndType() MethodRefEntry::nameAndType */ MethodRefEntry methodRefEntry(ClassEntry owner, NameAndTypeEntry nameAndType); /** - * {@return A {@link MethodRefEntry} describing a method of a class} - * If a MethodRefEntry entry in the pool already describes this method, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodRefEntry} describing a method of a class} * * @param owner the class the method is a member of - * @param name the name of the method - * @param type the type of the method + * @param name the unqualified name, or special name {@value + * ConstantDescs#INIT_NAME}, of the method + * @param type the method descriptor * @throws IllegalArgumentException if {@code owner} represents a primitive type + * @see MethodRefEntry#typeSymbol() MethodRefEntry::typeSymbol */ default MethodRefEntry methodRefEntry(ClassDesc owner, String name, MethodTypeDesc type) { return methodRefEntry(classEntry(owner), nameAndTypeEntry(name, type)); } /** - * {@return A {@link InterfaceMethodRefEntry} describing a method of a class} - * If a InterfaceMethodRefEntry entry in the pool already describes this method, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return an {@link InterfaceMethodRefEntry} referring to a {@link + * ClassEntry} and a {@link NameAndTypeEntry}} The {@code ClassEntry} + * describes an interface that has this method as a member, and the {@code + * NameAndTypeEntry} describes the unqualified name and the method + * descriptor for this method. * - * @param owner the class the method is a member of - * @param nameAndType the name and type of the method + * @param owner the {@code ClassEntry} + * @param nameAndType the {@code NameAndTypeEntry} + * @see InterfaceMethodRefEntry#owner() InterfaceMethodRefEntry::owner + * @see InterfaceMethodRefEntry#nameAndType() + * InterfaceMethodRefEntry::nameAndType */ InterfaceMethodRefEntry interfaceMethodRefEntry(ClassEntry owner, NameAndTypeEntry nameAndType); /** - * {@return A {@link InterfaceMethodRefEntry} describing a method of a class} - * If a InterfaceMethodRefEntry entry in the pool already describes this method, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return an {@link InterfaceMethodRefEntry} describing a method of an + * interface} * - * @param owner the class the method is a member of - * @param name the name of the method - * @param type the type of the method + * @param owner the interface the method is a member of + * @param name the unqualified name of the method + * @param type the method descriptor * @throws IllegalArgumentException if {@code owner} represents a primitive type + * @see InterfaceMethodRefEntry#typeSymbol() InterfaceMethodRefEntry::typeSymbol */ default InterfaceMethodRefEntry interfaceMethodRefEntry(ClassDesc owner, String name, MethodTypeDesc type) { return interfaceMethodRefEntry(classEntry(owner), nameAndTypeEntry(name, type)); } /** - * {@return A {@link MethodTypeEntry} describing a method type} - * If a MethodType entry in the pool already describes this method type, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodTypeEntry} describing the same method type as + * the provided {@link MethodTypeDesc}} * * @param descriptor the symbolic descriptor of the method type + * @see MethodTypeEntry#asSymbol() MethodTypeEntry::asSymbol */ MethodTypeEntry methodTypeEntry(MethodTypeDesc descriptor); /** - * {@return A {@link MethodTypeEntry} describing a method type} - * If a MethodType entry in the pool already describes this method type, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodTypeEntry} referring to a {@link Utf8Entry}} + * The {@code Utf8Entry} represents a method descriptor string. * - * @param descriptor the constant pool entry for the method type descriptor + * @param descriptor the {@code Utf8Entry} + * @see MethodTypeEntry#descriptor() MethodTypeEntry::descriptor */ MethodTypeEntry methodTypeEntry(Utf8Entry descriptor); /** - * {@return A {@link MethodHandleEntry} describing a direct method handle} - * If a MethodHandle entry in the pool already describes this method handle, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodHandleEntry} describing the same method handle as + * the given {@link DirectMethodHandleDesc}} * * @param descriptor the symbolic descriptor of the method handle + * @see MethodHandleEntry#asSymbol() MethodHandleEntry::asSymbol */ default MethodHandleEntry methodHandleEntry(DirectMethodHandleDesc descriptor) { var owner = classEntry(descriptor.owner()); @@ -347,125 +393,133 @@ default MethodHandleEntry methodHandleEntry(DirectMethodHandleDesc descriptor) { } /** - * {@return A {@link MethodHandleEntry} describing a field accessor or method} - * If a MethodHandle entry in the pool already describes this method handle, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodHandleEntry} encoding a reference kind and + * referring to a {@link MemberRefEntry}} The reference kind must be + * in {@code [1, 9]}, and the {@code MemberRefEntry} is subject to + * various restrictions based on the reference kind (JVMS {@jvms 4.4.8}). * - * @param refKind the reference kind of the method handle (JVMS {@jvms 4.4.8}) - * @param reference the constant pool entry describing the field or method + * @param refKind the reference kind of the method handle + * @param reference the {@code MemberRefEntry} + * @see MethodHandleInfo##refKinds Reference kinds + * @see MethodHandleEntry#kind() MethodHandleEntry::kind + * @see MethodHandleEntry#reference() MethodHandleEntry::reference */ MethodHandleEntry methodHandleEntry(int refKind, MemberRefEntry reference); /** - * {@return An {@link InvokeDynamicEntry} describing a dynamic call site} - * If an InvokeDynamic entry in the pool already describes this site, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return an {@link InvokeDynamicEntry} describing the same dynamic call + * site as the provided {@link DynamicCallSiteDesc}} * - * @param dcsd the symbolic descriptor of the method handle + * @param dcsd the symbolic descriptor of the dynamic call site + * @see InvokeDynamicEntry#asSymbol() InvokeDynamicEntry::asSymbol */ default InvokeDynamicEntry invokeDynamicEntry(DynamicCallSiteDesc dcsd) { return invokeDynamicEntry(bsmEntry((DirectMethodHandleDesc)dcsd.bootstrapMethod(), List.of(dcsd.bootstrapArgs())), nameAndTypeEntry(dcsd.invocationName(), dcsd.invocationType())); } /** - * {@return An {@link InvokeDynamicEntry} describing a dynamic call site} - * If an InvokeDynamic entry in the pool already describes this site, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return an {@link InvokeDynamicEntry} referring to a {@link + * BootstrapMethodEntry} and a {@link NameAndTypeEntry}} + * The {@code BootstrapMethodEntry} describes the bootstrap method + * and its invocation arguments in addition to the name and type, + * and the {@code NameAndTypeEntry} a name and a method descriptor. * - * @param bootstrapMethodEntry the entry in the bootstrap method table - * @param nameAndType the invocation name and type + * @param bootstrapMethodEntry the {@code BootstrapMethodEntry} + * @param nameAndType the {@code NameAndTypeEntry} + * @see InvokeDynamicEntry#bootstrap() InvokeDynamicEntry::bootstrap + * @see InvokeDynamicEntry#nameAndType() InvokeDynamicEntry::nameAndType */ InvokeDynamicEntry invokeDynamicEntry(BootstrapMethodEntry bootstrapMethodEntry, NameAndTypeEntry nameAndType); /** - * {@return A {@link ConstantDynamicEntry} describing a dynamic constant} - * If a ConstantDynamic entry in the pool already describes this site, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ConstantDynamicEntry} describing the dynamic constant + * as the provided {@link DynamicConstantDesc}} * * @param dcd the symbolic descriptor of the constant + * @see ConstantDynamicEntry#asSymbol() ConstantDynamicEntry::asSymbol */ default ConstantDynamicEntry constantDynamicEntry(DynamicConstantDesc dcd) { return constantDynamicEntry(bsmEntry(dcd.bootstrapMethod(), List.of(dcd.bootstrapArgs())), nameAndTypeEntry(dcd.constantName(), dcd.constantType())); } /** - * {@return A {@link ConstantDynamicEntry} describing a dynamic constant} - * If a ConstantDynamic entry in the pool already describes this site, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ConstantDynamicEntry} referring to a {@link + * BootstrapMethodEntry} and a {@link NameAndTypeEntry}} + * The {@code BootstrapMethodEntry} describes the bootstrap method + * and its invocation arguments in addition to the name and type, + * and the {@code NameAndTypeEntry} a name and a field descriptor. * - * @param bootstrapMethodEntry the entry in the bootstrap method table - * @param nameAndType the invocation name and type + * @param bootstrapMethodEntry the {@code BootstrapMethodEntry} + * @param nameAndType the {@code NameAndTypeEntry} + * @see ConstantDynamicEntry#bootstrap() ConstantDynamicEntry::bootstrap + * @see ConstantDynamicEntry#nameAndType() ConstantDynamicEntry::nameAndType */ ConstantDynamicEntry constantDynamicEntry(BootstrapMethodEntry bootstrapMethodEntry, NameAndTypeEntry nameAndType); /** - * {@return An {@link IntegerEntry} describing the provided value} - * If an integer entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return an {@link IntegerEntry} describing the provided value} * * @param value the value + * @see IntegerEntry#intValue() IntegerEntry::intValue */ IntegerEntry intEntry(int value); /** - * {@return A {@link FloatEntry} describing the provided value} - * If a float entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link FloatEntry} describing the provided value} * * @param value the value + * @see FloatEntry#floatValue() FloatEntry::floatValue */ FloatEntry floatEntry(float value); /** - * {@return A {@link LongEntry} describing the provided value} - * If a long entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link LongEntry} describing the provided value} * * @param value the value + * @see LongEntry#longValue() LongEntry::longValue */ LongEntry longEntry(long value); /** - * {@return A {@link DoubleEntry} describing the provided value} - * If a double entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link DoubleEntry} describing the provided value} * * @param value the value + * @see DoubleEntry#doubleValue() DoubleEntry::doubleValue */ DoubleEntry doubleEntry(double value); /** - * {@return A {@link StringEntry} referencing the provided UTF8 entry} - * If a String entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link StringEntry} referring to a {@link Utf8Entry}} + * The {@code Utf8Entry} describes the string value. * - * @param utf8 the UTF8 entry describing the string + * @param utf8 the {@code Utf8Entry} + * @see StringEntry#utf8() StringEntry::utf8 */ StringEntry stringEntry(Utf8Entry utf8); /** - * {@return A {@link StringEntry} describing the provided value} - * If a string entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link StringEntry} describing the provided value} * * @param value the value + * @see StringEntry#stringValue() StringEntry::stringValue */ default StringEntry stringEntry(String value) { return stringEntry(utf8Entry(value)); } /** - * {@return A {@link ConstantValueEntry} describing the provided - * Integer, Long, Float, Double, or String constant} + * {@return a {@link ConstantValueEntry} describing the provided constant + * {@link Integer}, {@link Long}, {@link Float}, {@link Double}, or {@link + * String} value} * - * @param c the constant - * @see ConstantValueEntry#constantValue() + * @param c the provided constant value + * @throws IllegalArgumentException if the value is not one of {@code + * Integer}, {@code Long}, {@code Float}, {@code Double}, or {@code + * String} + * @see ConstantValueEntry#constantValue() ConstantValueEntry::constantValue + * @see ConstantValueAttribute#of(ConstantDesc) + * ConstantValueAttribute::of(ConstantDesc) */ default ConstantValueEntry constantValueEntry(ConstantDesc c) { if (c instanceof Integer i) return intEntry(i); @@ -477,13 +531,10 @@ default ConstantValueEntry constantValueEntry(ConstantDesc c) { } /** - * {@return A {@link LoadableConstantEntry} describing the provided - * constant} The constant should be an Integer, String, Long, Float, - * Double, ClassDesc (for a Class constant), MethodTypeDesc (for a MethodType - * constant), DirectMethodHandleDesc (for a MethodHandle constant), or - * a DynamicConstantDesc (for a dynamic constant.) + * {@return a {@link LoadableConstantEntry} describing the provided constant + * value} * - * @param c the constant + * @param c the nominal descriptor for the constant */ default LoadableConstantEntry loadableConstantEntry(ConstantDesc c) { if (c instanceof Integer i) return intEntry(i); @@ -500,10 +551,10 @@ default LoadableConstantEntry loadableConstantEntry(ConstantDesc c) { /** * {@return a {@link BootstrapMethodEntry} describing the provided - * bootstrap method and static arguments} + * bootstrap method and arguments} * * @param methodReference the bootstrap method - * @param arguments the bootstrap arguments + * @param arguments the arguments */ default BootstrapMethodEntry bsmEntry(DirectMethodHandleDesc methodReference, List arguments) { @@ -512,11 +563,16 @@ default BootstrapMethodEntry bsmEntry(DirectMethodHandleDesc methodReference, } /** - * {@return a {@link BootstrapMethodEntry} describing the provided - * bootstrap method and static arguments} + * {@return a {@link BootstrapMethodEntry} referring to a {@link + * MethodHandleEntry} and a list of {@link LoadableConstantEntry}} + * The {@code MethodHandleEntry} is the bootstrap method, and the + * list of {@code LoadableConstantEntry} is the arguments. * - * @param methodReference the bootstrap method - * @param arguments the bootstrap arguments + * @param methodReference the {@code MethodHandleEntry} + * @param arguments the list of {@code LoadableConstantEntry} + * @see BootstrapMethodEntry#bootstrapMethod() + * BootstrapMethodEntry::bootstrapMethod + * @see BootstrapMethodEntry#arguments() BootstrapMethodEntry::arguments */ BootstrapMethodEntry bsmEntry(MethodHandleEntry methodReference, List arguments); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java index ce5ed26c4c94f..bb3b33ba21c59 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -27,7 +27,9 @@ /** * Thrown to indicate that requested entry cannot be obtained from the constant - * pool. + * pool or the bootstrap method table. This is also thrown when the lazy + * evaluation of constant pool or bootstrap method table entries encounter + * format errors. * * @since 24 */ @@ -47,7 +49,8 @@ public ConstantPoolException() { * Constructs a {@code ConstantPoolException} with the specified detail * message. * - * @param message the detail message. + * @param message the detail message, may be {@code null} for no detail + * message */ public ConstantPoolException(String message) { super(message); @@ -55,11 +58,10 @@ public ConstantPoolException(String message) { /** * Constructs a {@code ConstantPoolException} with the specified cause and - * a detail message of {@code (cause==null ? null : cause.toString())}. - * @param cause the cause (which is saved for later retrieval by the - * {@link Throwable#getCause()} method). (A {@code null} value is - * permitted, and indicates that the cause is nonexistent or - * unknown.) + * a detail message of {@code cause == null ? null : cause.toString()}. + * + * @param cause the cause, may be {@code null} for nonexistent or unknown + * cause */ public ConstantPoolException(Throwable cause) { super(cause); @@ -69,12 +71,10 @@ public ConstantPoolException(Throwable cause) { * Constructs a {@code ConstantPoolException} with the specified detail * message and cause. * - * @param message the detail message (which is saved for later retrieval - * by the {@link Throwable#getMessage()} method). - * @param cause the cause (which is saved for later retrieval by the - * {@link Throwable#getCause()} method). (A {@code null} value - * is permitted, and indicates that the cause is nonexistent or - * unknown.) + * @param message the detail message, may be {@code null} for no detail + * message + * @param cause the cause, may be {@code null} for nonexistent or unknown + * cause */ public ConstantPoolException(String message, Throwable cause) { super(message, cause); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java index ae746042aa478..8613fdd2cb9d6 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,10 +28,11 @@ import java.lang.constant.ConstantDesc; /** - * Models a constant pool entry that can be used as the constant in a - * {@link Attributes#constantValue() ConstantValue} attribute; this includes the four - * primitive constant types and {@linkplain String} constants. + * Marker interface for constant pool entries that can represent constant values + * in the {@link Attributes#constantValue() ConstantValue} attribute. * + * @see ConstantPoolBuilder#constantValueEntry + * ConstantPoolBuilder::constantValueEntry * @sealedGraph * @since 24 */ @@ -39,8 +40,8 @@ public sealed interface ConstantValueEntry extends LoadableConstantEntry permits DoubleEntry, FloatEntry, IntegerEntry, LongEntry, StringEntry { /** - * {@return the constant value} The constant value will be an {@link Integer}, - * {@link Long}, {@link Float}, {@link Double}, or {@link String}. + * {@return the constant value} The constant value will be an {@link + * Integer}, {@link Long}, {@link Float}, {@link Double}, or {@link String}. * * @see ConstantPoolBuilder#constantValueEntry(ConstantDesc) */ diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java index ebc3a837bb014..bc6956b5bf513 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -29,10 +29,20 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Double_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.5 The CONSTANT_Long_info and CONSTANT_Double_info Structures + * Models a {@code CONSTANT_Double_info} structure, representing a {@code + * double} constant, in the constant pool of a {@code class} file. + *

    + * The use of a {@code DoubleEntry} is modeled by a {@code double}. Conversions + * are through {@link ConstantPoolBuilder#doubleEntry} and {@link #doubleValue()}. + * In the conversions, all NaN values of the {@code double} may be collapsed + * into a single {@linkplain Double#NaN "canonical" NaN value}. + *

    + * A double entry has a {@linkplain #width() width} of {@code 2}, making its + * subsequent constant pool index valid and unusable. * + * @see ConstantPoolBuilder#doubleEntry ConstantPoolBuilder::doubleEntry + * @jvms 4.4.5 The {@code CONSTANT_Long_info} and {@code CONSTANT_Double_info} + * Structures * @since 24 */ public sealed interface DoubleEntry @@ -40,13 +50,13 @@ public sealed interface DoubleEntry permits AbstractPoolEntry.DoubleEntryImpl { /** - * {@return the double value} + * {@return the {@code double} value} + * + * @see ConstantPoolBuilder#doubleEntry(double) + * ConstantPoolBuilder::doubleEntry(double) */ double doubleValue(); - /** - * {@return the type of the constant} - */ @Override default TypeKind typeKind() { return TypeKind.DOUBLE; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java index 3ec4fbbdbee54..b72424db44e07 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -27,10 +27,27 @@ import java.lang.classfile.BootstrapMethodEntry; /** - * Models a dynamic constant pool entry, which is either {@link ConstantDynamicEntry} - * or {@link InvokeDynamicEntry}. - * @jvms 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures + * Superinterface modeling dynamically-computed constant pool entries, which + * include {@link ConstantDynamicEntry} and {@link InvokeDynamicEntry}, in the + * constant pool of a {@code class} file. + *

    + * Different types of dynamically-computed constant pool entries bear structural + * similarities, but they appear in distinct locations. As a result, their uses + * are represented by different symbolic descriptors, specific to each subtype. + *

    + * A dynamic constant entry is composite: + * {@snippet lang=text : + * DynamicConstantPoolEntry( + * BootstrapMethodEntry bootstrap, // @link substring="bootstrap" target="#bootstrap()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } * + * @see java.lang.invoke##jvm_mods Dynamic resolution of call sites and + * constants + * @jvms 4.4.10 The {@code CONSTANT_Dynamic_info} and {@code + * CONSTANT_InvokeDynamic_info} Structures + * @jvms 5.4.3.6 Dynamically-Computed Constant and Call Site Resolution * @sealedGraph * @since 24 */ @@ -39,28 +56,50 @@ public sealed interface DynamicConstantPoolEntry extends PoolEntry /** * {@return the entry in the bootstrap method table for this constant} + * + * @see java.lang.invoke##bsm Execution of bootstrap methods + * @see ConstantPoolBuilder#constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * ConstantPoolBuilder::constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * @see ConstantPoolBuilder#invokeDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * ConstantPoolBuilder::invokeDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) */ BootstrapMethodEntry bootstrap(); /** - * {@return index of the entry in the bootstrap method table for this constant} + * {@return index of the entry in the bootstrap method table for this + * constant} The return value is equivalent to {@code + * bootstrap().bsmIndex()}. */ int bootstrapMethodIndex(); /** - * {@return the invocation name and type} + * {@return the name and the descriptor string indicated by this symbolic + * reference} + * + * @see java.lang.invoke##bsm Execution of bootstrap methods + * @see ConstantPoolBuilder#constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * ConstantPoolBuilder::constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * @see ConstantPoolBuilder#invokeDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * ConstantPoolBuilder::invokeDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) */ NameAndTypeEntry nameAndType(); /** - * {@return the invocation name} + * {@return the name indicated by this symbolic reference} */ default Utf8Entry name() { return nameAndType().name(); } /** - * {@return the invocation type} + * {@return the descriptor string indicated by this symbolic reference} + * This is a field descriptor string if this entry is a {@link + * ConstantDynamicEntry}, or a method descriptor string if this entry is a + * {@link InvokeDynamicEntry}. + * + * @apiNote + * Each subinterface has its specific accessor named {@code typeSymbol} for + * the symbolic descriptor derived from this descriptor string. */ default Utf8Entry type() { return nameAndType().type(); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java index 47f5b6710d809..9f984acd7ba72 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -30,17 +30,31 @@ import jdk.internal.classfile.impl.Util; /** - * Models a {@code CONSTANT_Fieldref_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.2 The CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_InterfaceMethodref_info Structures + * Models a {@code CONSTANT_Fieldref_info} structure, or a symbolic reference + * to a field, in the constant pool of a {@code class} file. + *

    + * A field reference constant pool entry is composite: + * {@snippet lang=text : + * // @link substring="FieldRefEntry" target="ConstantPoolBuilder#fieldRefEntry(ClassEntry, NameAndTypeEntry)" : + * FieldRefEntry( + * ClassEntry owner, // @link substring="owner" target="#owner()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } + * where the {@link #type() nameAndType.type()} represents a {@linkplain + * #typeSymbol() field descriptor} string. * + * @see ConstantPoolBuilder#fieldRefEntry ConstantPoolBuilder::fieldRefEntry + * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code + * CONSTANT_Methodref_info}, and {@code + * CONSTANT_InterfaceMethodref_info} Structures * @since 24 */ public sealed interface FieldRefEntry extends MemberRefEntry permits AbstractPoolEntry.FieldRefEntryImpl { /** - * {@return a symbolic descriptor for the field's type} + * {@return a symbolic descriptor for the {@linkplain #type() field type}} */ default ClassDesc typeSymbol() { return Util.fieldTypeSymbol(type()); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java index eeb44e92b7c80..2ccf3fb94e49a 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -29,10 +29,17 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Float_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.4 The CONSTANT_Integer_info and CONSTANT_Float_info Structures + * Models a {@code CONSTANT_Float_info} structure, or a {@code float} constant, + * in the constant pool of a {@code class} file. + *

    + * The use of a {@code FloatEntry} is modeled by a {@code float}. Conversions + * are through {@link ConstantPoolBuilder#floatEntry} and {@link #floatValue()}. + * In the conversions, all NaN values of the {@code float} may be collapsed into + * a single {@linkplain Float#NaN "canonical" NaN value}. * + * @see ConstantPoolBuilder#floatEntry ConstantPoolBuilder::floatEntry + * @jvms 4.4.4 The {@code CONSTANT_Integer_info} and {@code CONSTANT_Float_info} + * Structures * @since 24 */ public sealed interface FloatEntry @@ -40,14 +47,12 @@ public sealed interface FloatEntry permits AbstractPoolEntry.FloatEntryImpl { /** - * {@return the float value} + * {@return the {@code float} value} + * + * @see ConstantPoolBuilder#floatEntry(float) */ - float floatValue(); - /** - * {@return the type of the constant} - */ @Override default TypeKind typeKind() { return TypeKind.FLOAT; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java index 908f17d1cb752..d6d2c28ed57be 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -29,10 +29,15 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Integer_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.4 The CONSTANT_Integer_info and CONSTANT_Float_info Structures + * Models a {@code CONSTANT_Integer_info} structure, or an {@code int} constant, + * in the constant pool of a {@code class} file. + *

    + * The use of a {@code IntegerEntry} is modeled by an {@code int}. Conversions + * are through {@link ConstantPoolBuilder#intEntry(int)} and {@link #intValue()}. * + * @see ConstantPoolBuilder#intEntry ConstantPoolBuilder::intEntry + * @jvms 4.4.4 The {@code CONSTANT_Integer_info} and {@code CONSTANT_Float_info} + * Structures * @since 24 */ public sealed interface IntegerEntry @@ -40,13 +45,12 @@ public sealed interface IntegerEntry permits AbstractPoolEntry.IntegerEntryImpl { /** - * {@return the integer value} + * {@return the {@code int} value} + * + * @see ConstantPoolBuilder#intEntry(int) */ int intValue(); - /** - * {@return the type of the constant} - */ @Override default TypeKind typeKind() { return TypeKind.INT; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java index 7b1a94f123a4a..e29c9f5b6f9ad 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -30,10 +30,26 @@ import jdk.internal.classfile.impl.Util; /** - * Models a {@code CONSTANT_InterfaceMethodRef_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.2 The CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_InterfaceMethodref_info Structures + * Models a {@code CONSTANT_InterfaceMethodRef_info} structure, or a symbolic + * reference to an interface method, in the constant pool of a {@code class} + * file. + *

    + * An interface method reference entry is composite: + * {@snippet lang=text : + * // @link substring="InterfaceMethodRefEntry" target="ConstantPoolBuilder#interfaceMethodRefEntry(ClassEntry, NameAndTypeEntry)" : + * InterfaceMethodRefEntry( + * ClassEntry owner, // @link substring="owner" target="#owner()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } + * where the {@link #type() type} in the {@code nameAndType} is a {@linkplain + * #typeSymbol() method descriptor} string. * + * @see ConstantPoolBuilder#interfaceMethodRefEntry + * ConstantPoolBuilder::interfaceMethodRefEntry + * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code + * CONSTANT_Methodref_info}, and {@code + * CONSTANT_InterfaceMethodref_info} Structures * @since 24 */ public sealed interface InterfaceMethodRefEntry @@ -41,7 +57,7 @@ public sealed interface InterfaceMethodRefEntry permits AbstractPoolEntry.InterfaceMethodRefEntryImpl { /** - * {@return a symbolic descriptor for the interface method's type} + * {@return a symbolic descriptor for the {@linkplain #type() method type}} */ default MethodTypeDesc typeSymbol() { return Util.methodTypeSymbol(type()); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java index 0cc8b6823df07..02c2fce2e027f 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -32,9 +32,38 @@ import jdk.internal.classfile.impl.Util; /** - * Models a constant pool entry for a dynamic call site. - * @jvms 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures + * Models a {@code CONSTANT_InvokeDynamic_info} structure, or the symbolic + * reference to a {@index "dynamically-computed call site"}, in the + * constant pool of a {@code class} file. + *

    + * The use of a {@code InvokeDynamicEntry} is modeled by a {@link + * DynamicCallSiteDesc} symbolic descriptor. It can be obtained from {@link + * #asSymbol() InvokeDynamicEntry::asSymbol} and converted back to a constant + * pool entry through {@link ConstantPoolBuilder#invokeDynamicEntry(DynamicCallSiteDesc) + * ConstantPoolBuilder::invokeDynamicEntry}. + *

    + * An invoke dynamic entry is composite: + * {@snippet lang=text : + * // @link substring="InvokeDynamicEntry" target="ConstantPoolBuilder#invokeDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry)" : + * InvokeDynamicEntry( + * BootstrapMethodEntry bootstrap, // @link substring="bootstrap" target="#bootstrap()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } + * where the {@link #type() type} in the {@code nameAndType} is a {@linkplain + * #typeSymbol() method descriptor} string. * + * @apiNote + * A dynamically-computed call site is frequently called a {@index "dynamic + * call site"}, or an {@index "indy"}, from the abbreviation of + * "invoke dynamic". + * + * @see ConstantPoolBuilder#invokeDynamicEntry + * ConstantPoolBuilder::invokeDynamicEntry + * @see DynamicCallSiteDesc + * @see java.lang.invoke##indyinsn Dynamically-computed call sites + * @jvms 4.4.10 The {@code CONSTANT_Dynamic_info} and {@code + * CONSTANT_InvokeDynamic_info} Structures * @since 24 */ public sealed interface InvokeDynamicEntry @@ -42,14 +71,18 @@ public sealed interface InvokeDynamicEntry permits AbstractPoolEntry.InvokeDynamicEntryImpl { /** - * {@return a symbolic descriptor for the call site's invocation type} + * {@return a symbolic descriptor for the {@linkplain #type() invocation + * type} of this dynamic call site} */ default MethodTypeDesc typeSymbol() { return Util.methodTypeSymbol(type()); } /** - * {@return a symbolic descriptor for the dynamic call site} + * {@return a symbolic descriptor for this dynamic call site} + * + * @see ConstantPoolBuilder#invokeDynamicEntry(DynamicCallSiteDesc) + * ConstantPoolBuilder::invokeDynamicEntry(DynamicCallSiteDesc) */ default DynamicCallSiteDesc asSymbol() { return DynamicCallSiteDesc.of(bootstrap().bootstrapMethod().asSymbol(), diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java index 32f85f64c7ed0..9137bebea352f 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,13 +24,22 @@ */ package java.lang.classfile.constantpool; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.Opcode; import java.lang.classfile.TypeKind; +import java.lang.classfile.instruction.ConstantInstruction; import java.lang.constant.ConstantDesc; /** * Marker interface for constant pool entries suitable for loading via the - * {@code LDC} instructions. + * {@link ConstantInstruction.LoadConstantInstruction ldc} instructions. + *

    + * The use of a {@code LoadableConstantEntry} is modeled by a {@link ConstantDesc}. + * Conversions are through {@link ConstantPoolBuilder#loadableConstantEntry(ConstantDesc)} + * and {@link #constantValue()}. * + * @see CodeBuilder#ldc(LoadableConstantEntry) + * @jvms 4.4 The Constant Pool * @sealedGraph * @since 24 */ @@ -38,12 +47,19 @@ public sealed interface LoadableConstantEntry extends PoolEntry permits ClassEntry, ConstantDynamicEntry, ConstantValueEntry, MethodHandleEntry, MethodTypeEntry { /** - * {@return the constant described by this entry} + * {@return a symbolic descriptor of this constant} + * + * @see ConstantPoolBuilder#loadableConstantEntry(ConstantDesc) */ ConstantDesc constantValue(); /** - * {@return the type of the constant} + * {@return the data type of this constant} + *

    + * If the data type is of {@linkplain TypeKind#slotSize() category} 2, this + * constant must be loaded with {@link Opcode#LDC2_W ldc2_w}; otherwise, the + * data type is of category 1, and this constant must be loaded with {@link + * Opcode#LDC ldc} or {@link Opcode#LDC_W ldc_w}. */ default TypeKind typeKind() { return TypeKind.REFERENCE; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java index cd38dcfe0146a..dbf947d1f1d72 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -29,10 +29,18 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Long_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.5 The CONSTANT_Long_info and CONSTANT_Double_info Structures + * Models a {@code CONSTANT_Long_info} structure, or a {@code long} constant, in + * the constant pool of a {@code class} file. + *

    + * The use of a {@code LongEntry} is modeled by a {@code long}. Conversions are + * through {@link ConstantPoolBuilder#longEntry(long)} and {@link #longValue()}. + *

    + * A long entry has a {@linkplain #width() width} of {@code 2}, making its + * subsequent constant pool index valid and unusable. * + * @see ConstantPoolBuilder#longEntry ConstantPoolBuilder::longEntry + * @jvms 4.4.5 The {@code CONSTANT_Long_info} and {@code CONSTANT_Double_info} + * Structures * @since 24 */ public sealed interface LongEntry @@ -40,7 +48,10 @@ public sealed interface LongEntry permits AbstractPoolEntry.LongEntryImpl { /** - * {@return the long value} + * {@return the {@code long} value} + * + * @see ConstantPoolBuilder#longEntry(long) + * ConstantPoolBuilder::longEntry(long) */ long longValue(); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java index 12d68796dd7cb..3d59a3c96c9e8 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,24 +24,45 @@ */ package java.lang.classfile.constantpool; +import java.lang.classfile.Opcode; + import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a member reference constant in the constant pool of a classfile, - * which includes references to fields, methods, and interface methods. + * Superinterface modeling symbolic references to a member of a class or interface + * in the constant pool of a {@code class} file, which include references to + * {@linkplain FieldRefEntry fields}, {@linkplain MethodRefEntry class methods}, + * and {@linkplain InterfaceMethodRefEntry interface methods}. + *

    + * Different types of symbolic references to a member of a class or interface + * bear structural similarities and share parts of the resolution processes, and + * they can sometimes appear in the same locations. For example, both {@link + * MethodRefEntry} and {@link InterfaceMethodRefEntry} can appear in an {@link + * Opcode#INVOKESTATIC invokestatic} instruction. + *

    + * A member reference entry is composite: + * {@snippet lang=text : + * MemberRefEntry( + * ClassEntry owner, // @link substring="owner" target="#owner()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } * + * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code + * CONSTANT_Methodref_info}, and {@code + * CONSTANT_InterfaceMethodref_info} Structures * @sealedGraph * @since 24 */ public sealed interface MemberRefEntry extends PoolEntry permits FieldRefEntry, InterfaceMethodRefEntry, MethodRefEntry, AbstractPoolEntry.AbstractMemberRefEntry { /** - * {@return the class in which this member ref lives} + * {@return the class or interface which this member belongs to} */ ClassEntry owner(); /** - * {@return the name and type of the member} + * {@return the name and descriptor string of the member} */ NameAndTypeEntry nameAndType(); @@ -53,7 +74,14 @@ default Utf8Entry name() { } /** - * {@return the type of the member} + * {@return the descriptor string of the member} This is a field descriptor + * string if this entry is a {@link FieldRefEntry}, or a method descriptor + * string if this entry is a {@link MethodRefEntry} or {@link + * InterfaceMethodRefEntry}. + * + * @apiNote + * Each subinterface defines a {@code typeSymbol()} accessor for the + * symbolic descriptor for the member type. */ default Utf8Entry type() { return nameAndType().type(); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java index d2e08ef178c12..22c07236e8a3e 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,13 +26,35 @@ import java.lang.constant.ConstantDesc; import java.lang.constant.DirectMethodHandleDesc; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandleInfo; import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_MethodHandle_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.8 The CONSTANT_MethodHandle_info Structure + * Models a {@code CONSTANT_MethodHandle_info} structure, or a symbolic + * reference to a {@linkplain MethodHandle method handle}, in the constant pool + * of a {@code class} file. The method handle directly accesses an accessible + * method, field, or constructor. + *

    + * The use of a {@code MethodHandleEntry} is modeled by a {@link + * DirectMethodHandleDesc}. Conversions are through {@link + * ConstantPoolBuilder#methodHandleEntry(DirectMethodHandleDesc)} and {@link + * #asSymbol()}. + *

    + * A method handle entry is composite: + * {@snippet lang=text : + * // @link substring="MethodHandleEntry" target="ConstantPoolBuilder#methodHandleEntry(int, MemberRefEntry)" : + * MethodHandleEntry( + * int refKind, // @link substring="refKind" target="#kind()" + * MemberRefEntry reference // @link substring="reference" target="#reference()" + * ) + * } + * where {@code refKind} is in the range {@code [1, 9]}. + * + * @see ConstantPoolBuilder#methodHandleEntry + * ConstantPoolBuilder::methodHandleEntry + * @jvms 4.4.8 The {@code CONSTANT_MethodHandle_info} Structure * * @since 24 */ @@ -40,6 +62,11 @@ public sealed interface MethodHandleEntry extends LoadableConstantEntry permits AbstractPoolEntry.MethodHandleEntryImpl { + /** + * {@inheritDoc} + *

    + * This is equivalent to {@link #asSymbol() asSymbol()}. + */ @Override default ConstantDesc constantValue() { return asSymbol(); @@ -47,17 +74,22 @@ default ConstantDesc constantValue() { /** * {@return the reference kind of this method handle (JVMS {@jvms 4.4.8})} - * @see java.lang.invoke.MethodHandleInfo + * + * @see MethodHandleInfo##refkinds Reference kinds */ int kind(); /** - * {@return the constant pool entry describing the method} + * {@return the constant pool entry describing the field or method, + * according to the {@linkplain #kind() reference kind}} */ MemberRefEntry reference(); /** * {@return a symbolic descriptor for this method handle} + * + * @see ConstantPoolBuilder#methodHandleEntry(DirectMethodHandleDesc) + * ConstantPoolBuilder::methodHandleEntry(DirectMethodHandleDesc) */ DirectMethodHandleDesc asSymbol(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java index 5be9e88fa2f66..29503741ec308 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -30,17 +30,31 @@ import jdk.internal.classfile.impl.Util; /** - * Models a {@code CONSTANT_MethodRef_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.2 The CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_InterfaceMethodref_info Structures + * Models a {@code CONSTANT_MethodRef_info} structure, or a symbolic reference + * to a class method, in the constant pool of a {@code class} file. + *

    + * A class method reference entry is composite: + * {@snippet lang=text : + * // @link substring="MethodRefEntry" target="ConstantPoolBuilder#methodRefEntry(ClassEntry, NameAndTypeEntry)" : + * MethodRefEntry( + * ClassEntry owner, // @link substring="owner" target="#owner()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } + * where the type in the {@code NameAndTypeEntry} is a {@linkplain #typeSymbol() + * method descriptor} string. * + * @see ConstantPoolBuilder#methodRefEntry ConstantPoolBuilder::methodRefEntry + * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code + * CONSTANT_Methodref_info}, and {@code + * CONSTANT_InterfaceMethodref_info} Structures * @since 24 */ public sealed interface MethodRefEntry extends MemberRefEntry permits AbstractPoolEntry.MethodRefEntryImpl { /** - * {@return a symbolic descriptor for the method's type} + * {@return a symbolic descriptor for the {@linkplain #type() method type}} */ default MethodTypeDesc typeSymbol() { return Util.methodTypeSymbol(type()); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java index b6fad856358fb..5da3650267825 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -30,28 +30,46 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_MethodType_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.9 The CONSTANT_MethodType_info Structure + * Models a {@code CONSTANT_MethodType_info} structure, or a symbolic reference + * to a method type, in the constant pool of a {@code class} file. + *

    + * The use of a {@code MethodTypeEntry} is modeled by a {@link MethodTypeDesc}. + * Conversions are through {@link ConstantPoolBuilder#methodTypeEntry(MethodTypeDesc)} + * and {@link #asSymbol()}. + *

    + * A method type entry is composite: + * {@snippet lang=text : + * // @link substring="MethodTypeEntry" target="ConstantPoolBuilder#methodTypeEntry(Utf8Entry)" : + * MethodTypeEntry(Utf8Entry descriptor) // @link substring="descriptor" target="#descriptor()" + * } + * where {@code descriptor} is a {@linkplain #asSymbol() method descriptor} + * string. * + * @jvms 4.4.9 The {@code CONSTANT_MethodType_info} Structure * @since 24 */ public sealed interface MethodTypeEntry extends LoadableConstantEntry permits AbstractPoolEntry.MethodTypeEntryImpl { + /** + * {@inheritDoc} + *

    + * This is equivalent to {@link #asSymbol() asSymbol()}. + */ @Override default ConstantDesc constantValue() { return asSymbol(); } /** - * {@return the constant pool entry describing the method type} + * {@return the {@linkplain #asSymbol() method descriptor} string} */ Utf8Entry descriptor(); /** - * {@return a symbolic descriptor for the method type} + * {@return a symbolic descriptor for the {@linkplain #descriptor() method + * type}} */ MethodTypeDesc asSymbol(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java index d0cdae5678fdb..fd920aa12316f 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -29,21 +29,32 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Module_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.11 The CONSTANT_Module_info Structure + * Models a {@code CONSTANT_Module_info} structure, denoting a module, in the + * constant pool of a {@code class} file. + *

    + * The use of a {@code ModuleEntry} is modeled by a {@link ModuleDesc}. + * Conversions are through {@link ConstantPoolBuilder#moduleEntry(ModuleDesc)} + * and {@link #asSymbol()}. + *

    + * A module entry is composite: + * {@snippet lang=text : + * // @link substring="ModuleEntry" target="ConstantPoolBuilder#moduleEntry(Utf8Entry)" : + * ModuleEntry(Utf8Entry name) // @link substring="name" target="#name()" + * } + * where {@code name} is a {@linkplain #asSymbol() module name}. * + * @jvms 4.4.11 The {@code CONSTANT_Module_info} Structure * @since 24 */ public sealed interface ModuleEntry extends PoolEntry permits AbstractPoolEntry.ModuleEntryImpl { /** - * {@return the name of the module} + * {@return the name of the {@linkplain #asSymbol() module}} */ Utf8Entry name(); /** - * {@return a symbolic descriptor for the module} + * {@return a symbolic descriptor for the {@linkplain #name() module name}} */ ModuleDesc asSymbol(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java index eff7e3456d143..38a23b0940eb0 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,13 +24,36 @@ */ package java.lang.classfile.constantpool; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; +import java.lang.invoke.TypeDescriptor; + import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_NameAndType_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.6 The CONSTANT_NameAndType_info Structure + * Models a {@code CONSTANT_NameAndType_info} structure, representing a field or + * method, in the constant pool of a {@code class} file. + *

    + * The use of a {@code NameAndTypeEntry} is symbolically represented as a + * {@code String name}, and a {@link ConstantPoolBuilder#nameAndTypeEntry(String, + * ClassDesc) ClassDesc} or a {@link ConstantPoolBuilder#nameAndTypeEntry(String, + * MethodTypeDesc) MethodTypeDesc} {@code type}, depending on where this {@code + * NameAndTypeEntry} appears. The accessors to the symbolic descriptors for the + * {@code type} is defined on a per-use-site basis, such as {@link + * FieldRefEntry#typeSymbol()} returning a {@code ClassDesc}, and {@link + * MethodRefEntry#typeSymbol()} returning a {@code MethodTypeDesc}. + *

    + * A name and type entry is composite: + * {@snippet lang=text : + * NameAndTypeEntry( // @link substring="NameAndTypeEntry" target="ConstantPoolBuilder#nameAndTypeEntry(Utf8Entry, Utf8Entry)" + * Utf8Entry name, // @link substring="name" target="#name()" + * Utf8Entry type // @link substring="type" target="#type()" + * ) + * } + * where {@code name} is an unqualified name, and {@code type} is a field or + * method descriptor string. * + * @jvms 4.4.6 The {@code CONSTANT_NameAndType_info} Structure * @since 24 */ public sealed interface NameAndTypeEntry extends PoolEntry @@ -42,7 +65,10 @@ public sealed interface NameAndTypeEntry extends PoolEntry Utf8Entry name(); /** - * {@return the field or method descriptor} + * {@return the field or method {@linkplain TypeDescriptor descriptor} + * string} It is a method descriptor strings if it starts with {@code (}. + * Otherwise, it is a field descriptor string, and must start with one of + * the {@code BCDFIJSZL[} characters. */ Utf8Entry type(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java index 54ea2fc38e5a7..ec56d0a4870cc 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -29,21 +29,35 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Package_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.12 The CONSTANT_Package_info Structure + * Models a {@code CONSTANT_Package_info}, representing a package, in the + * constant pool of a {@code class} file. + *

    + * The use of a {@code PackageEntry} is represented by a {@link PackageDesc} + * that does not represent the unnamed package. Conversions are through + * {@link ConstantPoolBuilder#packageEntry(PackageDesc)} and + * {@link #asSymbol()}. + *

    + * A package entry is composite: + * {@snippet lang=text : + * // @link substring="PackageEntry" target="ConstantPoolBuilder#packageEntry(Utf8Entry)" : + * PackageEntry(Utf8Entry name) // @link substring="name" target="#name()" + * } + * where {@code name} is the {@linkplain ClassEntry##internalname internal form} + * of a binary package name and is not empty. * + * @jvms 4.4.12 The {@code CONSTANT_Package_info} Structure * @since 24 */ public sealed interface PackageEntry extends PoolEntry permits AbstractPoolEntry.PackageEntryImpl { /** - * {@return the package name} + * {@return the {@linkplain ClassEntry##internalname internal form} of the + * {@linkplain #asSymbol() package} name} */ Utf8Entry name(); /** - * {@return a symbolic descriptor for the package name} + * {@return a symbolic descriptor for the {@linkplain #name() package name}} */ PackageDesc asSymbol(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java index 5762a92a061d7..5d27e54e67999 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,9 +24,28 @@ */ package java.lang.classfile.constantpool; +import java.lang.classfile.Attribute; +import java.lang.classfile.ClassFileBuilder; +import java.lang.classfile.Opcode; +import java.lang.classfile.TypeKind; + /** - * Models an entry in the constant pool of a classfile. + * Models an entry in the constant pool of a {@code class} file. Entries are + * read from {@code class} files, and can be created with a {@link + * ConstantPoolBuilder} to write to {@code class} files. + * + * @implNote + *

    Unbound Constant Pool Entries

    + * Implementations may create unbound constant pool entries not belonging to + * an actual constant pool. They conveniently represent constant pool entries + * referred by unbound {@linkplain Attribute attributes} not read from a {@code + * class} file. Their {@link #index() index()} return a non-positive invalid + * value, and behaviors of their {@link #constantPool() constantPool()} are + * unspecified. They are considered alien to any {@linkplain + * ClassFileBuilder#constantPool() contextual constant pool} and will be + * converted when they are written to {@code class} files. * + * @see ConstantPoolBuilder##alien Alien Constant Pool Entries * @sealedGraph * @since 24 */ @@ -88,6 +107,14 @@ public sealed interface PoolEntry /** * {@return the constant pool this entry is from} + * + * @apiNote + * Given a {@link ConstantPoolBuilder} {@code builder} and a {@code + * PoolEntry entry}, use {@link ConstantPoolBuilder#canWriteDirect + * builder.canWriteDirect(entry.constantPool())} instead of object equality + * of the constant pool to determine if an entry belongs to the builder. + * + * @see ##unbound Unbound Constant Pool Entries */ ConstantPool constantPool(); @@ -102,11 +129,32 @@ public sealed interface PoolEntry /** * {@return the index within the constant pool corresponding to this entry} + * A valid index is always positive; if the index is non-positive, this + * entry is {@linkplain ##unbound unbound}. + * + * @see ##unbound Unbound Constant Pool Entries */ int index(); /** * {@return the number of constant pool slots this entry consumes} + *

    + * All pool entries except {@link LongEntry CONSTANT_Long} and {@link + * DoubleEntry CONSTANT_Double} have width {@code 1}. These two exceptions + * have width {@code 2}, and their subsequent indices at {@link #index() + * index() + 1} are considered unusable. + * + * @apiNote + * If this entry is {@linkplain LoadableConstantEntry loadable}, the width + * of this entry does not decide if this entry should be loaded with {@link + * Opcode#LDC ldc} or {@link Opcode#LDC2_W ldc2_w}. For example, {@link + * ConstantDynamicEntry} always has width {@code 1}, but it must be loaded + * with {@code ldc2_w} if its {@linkplain ConstantDynamicEntry#typeKind() + * type} is {@link TypeKind#LONG long} or {@link TypeKind#DOUBLE double}. + * Use {@link LoadableConstantEntry#typeKind() typeKind().slotSize()} to + * determine the loading instruction instead. + * + * @see ConstantPool##index Index in the Constant Pool */ int width(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java index 03ff7652f6765..8a0bbb4b0150d 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -27,10 +27,20 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_String_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.3 The CONSTANT_String_info Structure + * Models a {@code CONSTANT_String_info} structure, or a string constant, in the + * constant pool of a {@code class} file. + *

    + * The use of a {@code StringEntry} is represented by a {@link String}. + * Conversions are through {@link ConstantPoolBuilder#stringEntry(String)} and + * {@link #stringValue()}. + *

    + * A string entry is composite: + * {@snippet lang=text : + * // @link substring="StringEntry" target="ConstantPoolBuilder#stringEntry(Utf8Entry)" : + * StringEntry(Utf8Entry utf8) // @link substring="utf8" target="#utf8()" + * } * + * @jvms 4.4.3 The {@code CONSTANT_String_info} Structure * @since 24 */ public sealed interface StringEntry @@ -38,11 +48,15 @@ public sealed interface StringEntry permits AbstractPoolEntry.StringEntryImpl { /** * {@return the UTF constant pool entry describing the string contents} + * + * @see ConstantPoolBuilder#stringEntry(Utf8Entry) */ Utf8Entry utf8(); /** * {@return the string value for this entry} + * + * @see ConstantPoolBuilder#stringEntry(String) */ String stringValue(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java index db03bf6a403ff..1d885051b2b1a 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,13 +24,40 @@ */ package java.lang.classfile.constantpool; +import java.io.DataInput; +import java.lang.classfile.AnnotationValue; +import java.lang.classfile.MethodModel; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; +import java.lang.invoke.TypeDescriptor; + import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_UTF8_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.7 The CONSTANT_Utf8_info Structure + * Models a {@code CONSTANT_UTF8_info} constant, representing strings, in the + * constant pool of a {@code class} file. This describes strings in the + * {@linkplain DataInput##modified-utf-8 Modified UTF-8} format. + *

    + * The use of a {@code Utf8Entry} is represented by a {@link String}. + * Conversions are through {@link ConstantPoolBuilder#utf8Entry(String)} and + * {@link #stringValue()}. + *

    + * Some uses of {@code Utf8Entry} represent field or method {@linkplain + * TypeDescriptor#descriptorString() descriptor strings}, symbolically + * represented as {@link ClassDesc} or {@link MethodTypeDesc}, depending on + * where a {@code Utf8Entry} appear. Entries representing such uses are created + * with {@link ConstantPoolBuilder#utf8Entry(ClassDesc)} and {@link + * ConstantPoolBuilder#utf8Entry(MethodTypeDesc)}, and they can be converted to + * symbolic descriptors on a per-use-site basis, such as in {@link + * AnnotationValue.OfClass#classSymbol()} and {@link MethodModel#methodTypeSymbol()}. + *

    + * Unlike most constant pool entries, a UTF-8 entry is of flexible length: it is + * represented as an array structure, with an {@code u2} for the data length in + * bytes, followed by that number of bytes of Modified UTF-8 data. It can + * represent at most 65535 bytes of data due to the physical restrictions. * + * @jvms 4.4.7 The {@code CONSTANT_Utf8_info} Structure + * @see DataInput##modified-utf-8 Modified UTF-8 * @since 24 */ public sealed interface Utf8Entry @@ -39,6 +66,15 @@ public sealed interface Utf8Entry /** * {@return the string value for this entry} + * + * @apiNote + * A {@code Utf8Entry} can be used directly as a {@link CharSequence} if + * {@code String} functionalities are not strictly desired. If only string + * equivalence is desired, {@link #equalsString(String) equalsString} should + * be used. Reduction of string processing can significantly improve {@code + * class} file reading performance. + * + * @see ConstantPoolBuilder#utf8Entry(String) */ String stringValue(); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java b/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java index 83039c6565c04..66e72496d3a31 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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,11 +24,59 @@ */ /** - *

    Provides interfaces describing classfile constant pool entries for the {@link java.lang.classfile} library.

    + *

    Provides interfaces describing constant pool entries for the {@link java.lang.classfile} library.

    * - * The {@code java.lang.classfile.constantpool} package contains interfaces describing classfile constant pool entries. + * The {@code java.lang.classfile.constantpool} package contains interfaces describing constant pool entries in the + * {@code class} file format. Constant pool entries are low-level models to faithfully represent the exact structure + * of a {@code class} file. + *

    + * Unless otherwise specified, passing {@code null} or an array or collection containing a {@code null} element as an + * argument to a constructor or method of any Class-File API class or interface will cause a {@link NullPointerException} + * to be thrown. * + *

    Reading the constant pool entries

    + * When read from {@code class} files, the pool entries are lazily inflated; the contents of these entries, besides the + * bare structure, are not evaluated to speed up parsing. Entries to users interest, usually accessed from other models + * and elements, have their contents read on demand. For example, to search for methods, a user should filter first by + * access flags and then by method name, and use {@link Utf8Entry#equalsString(String)} instead of checking equality + * against {@link Utf8Entry#stringValue()}. This avoids inflation of UTF-8 entries as much as possible: + * {@snippet lang="java" class="PackageSnippets" region="isStaticWorkMethod"} + *

    + * The entries also define accessors to validated symbolic information with nominal descriptor abstractions from the + * {@link java.lang.constant} package. These symbolic information accessors perform validation against the read + * {@code class} files, and throw {@link IllegalArgumentException} when the accessed constant pool entry contains + * invalid data. The nominal descriptors represent validated data, which saves users from extra validations in future + * processing. + *

    + * Due to the lazy nature of {@code class} file parsing, {@link IllegalArgumentException} indicating malformed + * {@code class} file data can be thrown at any method invocation. For example, an exception may come from a {@link + * ClassEntry} when it is first read from the constant pool (referring to an invalid index or wrong type of entry), when + * its referred UTF-8 entry is expanded (malformed UTF-8 data), or when its symbolic information is accessed (the string + * is not valid for a class entry). + * + *

    Writing the constant pool entries

    + * In general, users do not need to worry about working with the constant pool and its entries when writing {@code + * class} files. Most Class-File API models and elements have two sets of factory methods: one that accepts symbolic + * information representing the uses, and another that accepts constant pool entries. The constant pool builder + * associated with {@code class} file builders, {@link ClassFileBuilder#constantPool}, automatically creates or reuses + * pool entries from the symbolic information. Validated data in symbolic information helps {@code class} file + * generation by avoiding extraneous parsing of raw constant pool entry data. + *

    + * As always, users can use factories that accept constant pool entries if they already have them by hand, or if they + * desire fine-grained control over {@code class} file generation. + *

    + * If many models and elements are reused from another {@link ClassModel} in class building, the class building process + * can use a constant pool builder that extends from the given {@code ClassModel}, available through {@link + * ConstantPoolBuilder#of(ClassModel) ConstantPoolBuilder::of(ClassModel)}, so that byte data with constant pool + * references can be copied in batch, speeding up class building. This is especially applicable to class transformations, + * and {@link ClassFile.ConstantPoolSharingOption ConstantPoolSharingOption} exists to control this behavior. + * + * @jvms 4.4 The Constant Pool * @since 24 */ package java.lang.classfile.constantpool; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassFileBuilder; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java b/src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java new file mode 100644 index 0000000000000..983aa1adb4c14 --- /dev/null +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025, 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 java.lang.classfile.constantpool.snippet; + +import java.lang.classfile.ClassFile; +import java.lang.classfile.MethodModel; +import java.lang.classfile.constantpool.Utf8Entry; + +class PackageSnippets { + + // @start region=isStaticWorkMethod + boolean isStaticWorkMethod(MethodModel method) { + // check static flag first to avoid unnecessary evaluation of UTF-8 entry + return (method.flags().flagsMask() & ClassFile.ACC_STATIC) != 0 + // use equalsString to avoid full conversion to String for comparison + // the Utf8Entry can also act as a basic CharSequence without full conversion + // @link substring="methodName" target="MethodModel#methodName" : + && method.methodName().equalsString("work"); // @link substring="equalsString" target="Utf8Entry#equalsString" + } + // @end +} diff --git a/test/jdk/jdk/classfile/SnippetsTest.java b/test/jdk/jdk/classfile/SnippetsTest.java index f6fa2281e14ee..2b84820e9b948 100644 --- a/test/jdk/jdk/classfile/SnippetsTest.java +++ b/test/jdk/jdk/classfile/SnippetsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -42,7 +42,9 @@ public class SnippetsTest { @ParameterizedTest @ValueSource(strings = { "src/java.base/share/classes/java/lang/classfile/snippet-files/PackageSnippets.java", - "src/java.base/share/classes/jdk/internal/classfile/components/snippet-files/PackageSnippets.java"}) + "src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java", + "src/java.base/share/classes/jdk/internal/classfile/components/snippet-files/PackageSnippets.java" + }) void testSnippet(String source) throws Exception { var p = Paths.get(System.getProperty("test.src", ".")).toAbsolutePath(); while ((p = p.getParent()) != null) { From b0c935c03ebb34f20f15dd8c7616c6c4526073cd Mon Sep 17 00:00:00 2001 From: Per Minborg Date: Wed, 8 Jan 2025 08:44:22 +0000 Subject: [PATCH 038/286] 8347047: Cleanup action passed to MemorySegment::reinterpret keeps old segment alive Reviewed-by: mcimadamore --- .../internal/foreign/AbstractMemorySegmentImpl.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index e51e158c93c97..9ccaf92b8d6be 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -145,12 +145,17 @@ private NativeMemorySegmentImpl reinterpretInternal(Class callerClass, long n Reflection.ensureNativeAccess(callerClass, MemorySegment.class, "reinterpret", false); Utils.checkNonNegativeArgument(newSize, "newSize"); if (!isNative()) throw new UnsupportedOperationException("Not a native segment"); - Runnable action = cleanup != null ? - () -> cleanup.accept(SegmentFactories.makeNativeSegmentUnchecked(address(), newSize)) : - null; + Runnable action = cleanupAction(address(), newSize, cleanup); return SegmentFactories.makeNativeSegmentUnchecked(address(), newSize, scope, readOnly, action); } + // Using a static helper method ensures there is no unintended lambda capturing of `this` + private static Runnable cleanupAction(long address, long newSize, Consumer cleanup) { + return cleanup != null ? + () -> cleanup.accept(SegmentFactories.makeNativeSegmentUnchecked(address, newSize)) : + null; + } + private AbstractMemorySegmentImpl asSliceNoCheck(long offset, long newSize) { return dup(offset, newSize, readOnly, scope); } From b741f3fe5b54755d19c5abeca76fdceeccafd448 Mon Sep 17 00:00:00 2001 From: Shaojin Wen Date: Wed, 8 Jan 2025 09:40:17 +0000 Subject: [PATCH 039/286] 8343629: More MergeStore benchmark Reviewed-by: epeter --- .../bench/vm/compiler/MergeLoadBench.java | 515 ++++++++++ .../bench/vm/compiler/MergeStoreBench.java | 913 +++++------------- 2 files changed, 770 insertions(+), 658 deletions(-) create mode 100644 test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java diff --git a/test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java b/test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java new file mode 100644 index 0000000000000..e29b5373791d3 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import jdk.internal.misc.Unsafe; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS) +@Fork(value = 1, jvmArgs = {"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"}) +public class MergeLoadBench { + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + + final static VarHandle + INT_L = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.LITTLE_ENDIAN), + INT_B = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.BIG_ENDIAN), + LONG_L = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN), + LONG_B = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN), + CHAR_L = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.LITTLE_ENDIAN), + CHAR_B = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.BIG_ENDIAN); + + final static int NUMBERS = 8192; + + final byte[] bytes4 = new byte[NUMBERS * 4]; + final byte[] bytes8 = new byte[NUMBERS * 8]; + final int [] ints = new int [NUMBERS ]; + final long[] longs = new long[NUMBERS ]; + + @Setup + public void setup() { + Random r = new Random(); + for (int i = 0; i < ints.length; i++) { + ints[i] = r.nextInt(); + INT_L.set(bytes4, i * 4, i); + } + + for (int i = 0; i < longs.length; i++) { + longs[i] = r.nextLong(); + LONG_L.set(bytes8, i * 8, i); + } + } + + /* + * The names of these cases have the following `B/L/V/U` suffixes, which are: + * ``` + * B BigEndian + * L LittleEndian + * V VarHandle + * U Unsafe + * R ReverseBytes + * C Unsafe.getChar & putChar + * S Unsafe.getShort & putShort + * ``` + */ + + @Benchmark + public void getIntB(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntB(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntBU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntBU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntBV(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (int) INT_B.get(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntL(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntL(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntLU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntLU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntLV(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (int) INT_L.get(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRB(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRB(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRBU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRBU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRL(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRL(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRLU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRLU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += Integer.reverseBytes( + UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4)); + } + BH.consume(sum); + } + + @Benchmark + public void getIntU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getLongB(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongB(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongBU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongBU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongBV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (long) LONG_B.get(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongL(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongL(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongLU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongLU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongLV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (long) LONG_L.get(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRB(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRB(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRBU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRBU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRL(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRL(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRLU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRLU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += Long.reverseBytes( + UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8)); + } + BH.consume(sum); + } + + @Benchmark + public void getLongU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getCharB(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharB(bytes4, i); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharBV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = (char) CHAR_B.get(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharBU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharBU(bytes4, i); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharL(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharL(bytes4, i); + sum += c; + } + BH.consume(sum); + } + @Benchmark + public void getCharLU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharLU(bytes4, i); + sum += c; + } + BH.consume(sum); + } + + + @Benchmark + public void getCharLV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = (char) CHAR_L.get(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharC(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = UNSAFE.getChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); + sum += c; + } + BH.consume(sum); + } + + static int getIntB(byte[] array, int offset) { + return ((array[offset ] & 0xff) << 24) + | ((array[offset + 1] & 0xff) << 16) + | ((array[offset + 2] & 0xff) << 8) + | ((array[offset + 3] & 0xff) ); + } + + static int getIntBU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return ((UNSAFE.getByte(array, address ) & 0xff) << 24) + | ((UNSAFE.getByte(array, address + 1) & 0xff) << 16) + | ((UNSAFE.getByte(array, address + 2) & 0xff) << 8) + | ((UNSAFE.getByte(array, address + 3) & 0xff) ); + } + + static int getIntL(byte[] array, int offset) { + return ((array[offset ] & 0xff) ) + | ((array[offset + 1] & 0xff) << 8) + | ((array[offset + 2] & 0xff) << 16) + | ((array[offset + 3] & 0xff) << 24); + } + + static int getIntRB(byte[] array, int offset) { + return Integer.reverseBytes(getIntB(array, offset)); + } + + static int getIntRBU(byte[] array, int offset) { + return Integer.reverseBytes(getIntBU(array, offset)); + } + + static int getIntRL(byte[] array, int offset) { + return Integer.reverseBytes(getIntL(array, offset)); + } + + static int getIntRLU(byte[] array, int offset) { + return Integer.reverseBytes(getIntLU(array, offset)); + } + + static long getLongB(byte[] array, int offset) { + return (((long) array[offset ] & 0xff) << 56) + | (((long) array[offset + 1] & 0xff) << 48) + | (((long) array[offset + 2] & 0xff) << 40) + | (((long) array[offset + 3] & 0xff) << 32) + | (((long) array[offset + 4] & 0xff) << 24) + | (((long) array[offset + 5] & 0xff) << 16) + | (((long) array[offset + 6] & 0xff) << 8) + | (((long) array[offset + 7] & 0xff) ); + } + + static long getLongBU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return (((long)(UNSAFE.getByte(array, address) & 0xff)) << 56) + | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 48) + | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 40) + | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 32) + | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 24) + | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 16) + | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 8) + | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) ); + } + + public static long getLongL(byte[] array, int offset) { + return (((long) array[offset ] & 0xff) ) + | (((long) array[offset + 1] & 0xff) << 8) + | (((long) array[offset + 2] & 0xff) << 16) + | (((long) array[offset + 3] & 0xff) << 24) + | (((long) array[offset + 4] & 0xff) << 32) + | (((long) array[offset + 5] & 0xff) << 40) + | (((long) array[offset + 6] & 0xff) << 48) + | (((long) array[offset + 7] & 0xff) << 56); + } + + static long getLongLU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return (((long)(UNSAFE.getByte(array, address ) & 0xff)) ) + | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 8) + | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 16) + | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 24) + | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 32) + | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 40) + | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 48) + | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) << 56); + } + + static long getLongRB(byte[] array, int offset) { + return getLongB(array, offset); + } + + static long getLongRBU(byte[] array, int offset) { + return getLongBU(array, offset); + } + + static long getLongRL(byte[] array, int offset) { + return getLongL(array, offset); + } + + static long getLongRLU(byte[] array, int offset) { + return getLongLU(array, offset); + } + + public static int getIntLU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return ((UNSAFE.getByte(array, address ) & 0xff) ) + | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8) + | ((UNSAFE.getByte(array, address + 2) & 0xff) << 16) + | ((UNSAFE.getByte(array, address + 3) & 0xff) << 24); + } + + public static char getCharB(byte[] val, int index) { + index <<= 1; + return (char)(((val[index ] & 0xff) << 8) + | ((val[index + 1] & 0xff))); + } + + public static char getCharBR(byte[] val, int index) { + return Character.reverseBytes(getCharB(val, index)); + } + + public static char getCharL(byte[] val, int index) { + index <<= 1; + return (char)(((val[index ] & 0xff)) + | ((val[index + 1] & 0xff) << 8)); + } + + public static char getCharLR(byte[] val, int index) { + return Character.reverseBytes(getCharL(val, index)); + } + + public static char getCharBU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + return (char) (((UNSAFE.getByte(array, address ) & 0xff) << 8) + | ((UNSAFE.getByte(array, address + 1) & 0xff) )); + } + + public static char getCharLU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + return (char) (((UNSAFE.getByte(array, address ) & 0xff) ) + | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8)); + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java b/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java index 870422de25683..88b6886881363 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java +++ b/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java @@ -25,13 +25,9 @@ import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; -import java.lang.reflect.Field; import java.nio.ByteOrder; import java.util.Random; import java.util.concurrent.TimeUnit; @@ -41,18 +37,19 @@ @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) -@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS) @Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS) -@Fork(value = 3, jvmArgs = {"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"}) +@Fork(value = 1, jvmArgs = {"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"}) public class MergeStoreBench { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); - final static VarHandle INT_L = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.LITTLE_ENDIAN); - final static VarHandle INT_B = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.BIG_ENDIAN); - final static VarHandle LONG_L = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN); - final static VarHandle LONG_B = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN); - final static VarHandle CHAR_L = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.LITTLE_ENDIAN); - final static VarHandle CHAR_B = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.BIG_ENDIAN); + final static VarHandle + INT_L = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.LITTLE_ENDIAN), + INT_B = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.BIG_ENDIAN), + LONG_L = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN), + LONG_B = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN), + CHAR_L = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.LITTLE_ENDIAN), + CHAR_B = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.BIG_ENDIAN); final static int NUMBERS = 8192; @@ -89,115 +86,6 @@ public void setup() { * ``` */ - @Benchmark - public void getIntB(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntB(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntBU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntBU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntBV(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (int) INT_B.get(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntL(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntL(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntLU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntLU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntLV(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (int) INT_L.get(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRB(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRB(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRBU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRBU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRL(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRL(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRLU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRLU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += Integer.reverseBytes( - UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4)); - } - BH.consume(sum); - } - - @Benchmark - public void getIntU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4); - } - BH.consume(sum); - } - @Benchmark public void setIntB(Blackhole BH) { int sum = 0; @@ -211,613 +99,396 @@ public void setIntB(Blackhole BH) { @Benchmark public void setIntBU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntBU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntBU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntBV(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - INT_B.set(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + INT_B.set(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntL(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntL(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntL(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntLU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntLU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntLU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - INT_L.set(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + INT_L.set(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRB(bytes4, i * 4, ints[i]); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRB(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRBU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRBU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRL(bytes4, i * 4, ints[i]); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRL(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRLU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRLU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - v = Integer.reverseBytes(v); - UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, Integer.reverseBytes(ints[i])); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4, v); - sum += v; - } - BH.consume(sum); - } - - @Benchmark - public void getLongB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongB(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongBU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (long) LONG_B.get(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongL(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongLU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (long) LONG_L.get(bytes8, i * 8); + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, ints[i]); + off += 4; } - BH.consume(sum); - } - - @Benchmark - public void getLongRB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRB(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRBU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRL(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRLU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += Long.reverseBytes( - UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8)); - } - BH.consume(sum); - } - - @Benchmark - public void getLongU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8); - } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongB(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongB(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongBU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongBU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - LONG_B.set(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + LONG_B.set(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongL(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongL(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongLU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongLU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - LONG_L.set(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + LONG_L.set(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRB(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRB(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRBU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRBU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRL(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRL(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRLU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRLU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - v = Long.reverseBytes(v); - UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, Long.reverseBytes(longs[i])); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8, v); - sum += v; - } - BH.consume(sum); - } - - @Benchmark - public void getCharB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharB(bytes4, i); - sum += c; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void getCharBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = (char) CHAR_B.get(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); - sum += c; - } - BH.consume(sum); - } - - @Benchmark - public void getCharBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharBU(bytes4, i); - sum += c; + public void setCharBS(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + putShortB(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void getCharL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharL(bytes4, i); - sum += c; - } - BH.consume(sum); - } - @Benchmark - public void getCharLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharLU(bytes4, i); - sum += c; + public void setCharBV(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + CHAR_B.set(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } - @Benchmark - public void getCharLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = (char) CHAR_L.get(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); - sum += c; + public void setCharLS(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + putShortL(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void getCharC(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = UNSAFE.getChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); - sum += c; + public void setCharLV(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + CHAR_L.set(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharBS(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - putShortB(bytes4, i * 2, c); - sum += c; + public void setCharC(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + UNSAFE.putChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } + /* + * putChars4 and putBytes4 Test whether four constant chars can be MergeStored + * + */ @Benchmark - public void setCharBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - CHAR_B.set(bytes4, i * 2, c); - sum += c; + public void putBytes4(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putBytes4(bytes4, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharLS(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - putShortL(bytes4, i * 2, c); - sum += c; + public void putBytes4X(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putBytes4X(bytes4, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - CHAR_L.set(bytes4, i * 2, c); - sum += c; + public void putBytes4U(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putBytes4U(bytes4, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharC(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - UNSAFE.putChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2, c); - sum += c; + @SuppressWarnings("deprecation") + public void putBytes4GetBytes(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + "null".getBytes(0, 4, bytes4, off); + off += 4; } - BH.consume(sum); + BH.consume(off); } - /* - * putChars4 Test whether four constant chars can be MergeStored - * - */ @Benchmark public void putChars4B(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4B(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4B(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4BU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4BU(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4BU(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4BV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4BV(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4BV(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4L(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4L(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4L(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4LU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4LU(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4LU(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4LV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4LV(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4LV(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4C(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4C(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4C(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4S(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4S(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4S(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); - } - - static int getIntB(byte[] array, int offset) { - return ((array[offset ] & 0xff) << 24) - | ((array[offset + 1] & 0xff) << 16) - | ((array[offset + 2] & 0xff) << 8) - | ((array[offset + 3] & 0xff) ); - } - - static int getIntBU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return ((UNSAFE.getByte(array, address ) & 0xff) << 24) - | ((UNSAFE.getByte(array, address + 1) & 0xff) << 16) - | ((UNSAFE.getByte(array, address + 2) & 0xff) << 8) - | ((UNSAFE.getByte(array, address + 3) & 0xff) ); - } - - static int getIntL(byte[] array, int offset) { - return ((array[offset ] & 0xff) ) - | ((array[offset + 1] & 0xff) << 8) - | ((array[offset + 2] & 0xff) << 16) - | ((array[offset + 3] & 0xff) << 24); - } - - static int getIntRB(byte[] array, int offset) { - return Integer.reverseBytes(getIntB(array, offset)); - } - - static int getIntRBU(byte[] array, int offset) { - return Integer.reverseBytes(getIntBU(array, offset)); - } - - static int getIntRL(byte[] array, int offset) { - return Integer.reverseBytes(getIntL(array, offset)); - } - - static int getIntRLU(byte[] array, int offset) { - return Integer.reverseBytes(getIntLU(array, offset)); + BH.consume(off); } static void setIntB(byte[] array, int offset, int value) { @@ -870,68 +541,6 @@ public static void setIntRBU(byte[] array, int offset, int value) { setIntBU(array, offset, value); } - static long getLongB(byte[] array, int offset) { - return (((long) array[offset ] & 0xff) << 56) - | (((long) array[offset + 1] & 0xff) << 48) - | (((long) array[offset + 2] & 0xff) << 40) - | (((long) array[offset + 3] & 0xff) << 32) - | (((long) array[offset + 4] & 0xff) << 24) - | (((long) array[offset + 5] & 0xff) << 16) - | (((long) array[offset + 6] & 0xff) << 8) - | (((long) array[offset + 7] & 0xff) ); - } - - static long getLongBU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return (((long)(UNSAFE.getByte(array, address) & 0xff)) << 56) - | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 48) - | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 40) - | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 32) - | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 24) - | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 16) - | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 8) - | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) ); - } - - public static long getLongL(byte[] array, int offset) { - return (((long) array[offset ] & 0xff) ) - | (((long) array[offset + 1] & 0xff) << 8) - | (((long) array[offset + 2] & 0xff) << 16) - | (((long) array[offset + 3] & 0xff) << 24) - | (((long) array[offset + 4] & 0xff) << 32) - | (((long) array[offset + 5] & 0xff) << 40) - | (((long) array[offset + 6] & 0xff) << 48) - | (((long) array[offset + 7] & 0xff) << 56); - } - - static long getLongLU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return (((long)(UNSAFE.getByte(array, address ) & 0xff)) ) - | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 8) - | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 16) - | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 24) - | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 32) - | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 40) - | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 48) - | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) << 56); - } - - static long getLongRB(byte[] array, int offset) { - return getLongB(array, offset); - } - - static long getLongRBU(byte[] array, int offset) { - return getLongBU(array, offset); - } - - static long getLongRL(byte[] array, int offset) { - return getLongL(array, offset); - } - - static long getLongRLU(byte[] array, int offset) { - return getLongLU(array, offset); - } - static void setLongB(byte[] array, int offset, long value) { array[offset] = (byte) (value >> 56); array[offset + 1] = (byte) (value >> 48); @@ -998,112 +607,95 @@ public static void setLongLU(byte[] array, int offset, long value) { UNSAFE.putByte(array, address + 7, (byte) (value >> 56)); } - public static int getIntLU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return ((UNSAFE.getByte(array, address ) & 0xff) ) - | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8) - | ((UNSAFE.getByte(array, address + 2) & 0xff) << 16) - | ((UNSAFE.getByte(array, address + 3) & 0xff) << 24); - } - - public static char getCharB(byte[] val, int index) { - index <<= 1; - return (char)(((val[index ] & 0xff) << 8) - | ((val[index + 1] & 0xff))); - } - - public static char getCharBR(byte[] val, int index) { - return Character.reverseBytes(getCharB(val, index)); - } - - public static char getCharL(byte[] val, int index) { - index <<= 1; - return (char)(((val[index ] & 0xff)) - | ((val[index + 1] & 0xff) << 8)); + public int putBytes4(byte[] bytes, int offset, int c0, int c1, int c2, int c3) { + bytes[offset ] = (byte) c0; + bytes[offset + 1] = (byte) c1; + bytes[offset + 2] = (byte) c2; + bytes[offset + 3] = (byte) c3; + return offset + 4; } - public static char getCharLR(byte[] val, int index) { - return Character.reverseBytes(getCharL(val, index)); + public int putBytes4X(byte[] bytes, int offset, int c0, int c1, int c2, int c3) { + bytes[offset++] = (byte) c0; + bytes[offset++] = (byte) c1; + bytes[offset++] = (byte) c2; + bytes[offset++] = (byte) c3; + return offset; } - public static char getCharBU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); - return (char) (((UNSAFE.getByte(array, address ) & 0xff) << 8) - | ((UNSAFE.getByte(array, address + 1) & 0xff) )); - } - - public static char getCharLU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); - return (char) (((UNSAFE.getByte(array, address ) & 0xff) ) - | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8)); + public int putBytes4U(byte[] bytes, int offset, int c0, int c1, int c2, int c3) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + UNSAFE.putByte(bytes, address , (byte) c0); + UNSAFE.putByte(bytes, address + 1, (byte) c1); + UNSAFE.putByte(bytes, address + 2, (byte) c2); + UNSAFE.putByte(bytes, address + 3, (byte) c3); + return offset + 4; } - public void putChars4B(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4B(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortB(bytes, offset , c0); putShortB(bytes, offset + 1, c1); putShortB(bytes, offset + 2, c2); putShortB(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4BU(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4BU(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortBU(bytes, offset , c0); putShortBU(bytes, offset + 1, c1); putShortBU(bytes, offset + 2, c2); putShortBU(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4BV(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - offset <<= 1; - CHAR_B.set(bytes, offset , c0); + public int putChars4BV(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { + CHAR_B.set(bytes, offset , c0); CHAR_B.set(bytes, offset + 2, c1); CHAR_B.set(bytes, offset + 4, c2); CHAR_B.set(bytes, offset + 6, c3); + return offset + 8; } - public void putChars4L(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4L(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortL(bytes, offset , c0); putShortL(bytes, offset + 1, c1); putShortL(bytes, offset + 2, c2); putShortL(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4LV(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - offset <<= 1; + public int putChars4LV(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { CHAR_L.set(bytes, offset , c0); CHAR_L.set(bytes, offset + 2, c1); CHAR_L.set(bytes, offset + 4, c2); CHAR_L.set(bytes, offset + 6, c3); + return offset + 8; } - public void putChars4LU(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4LU(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortLU(bytes, offset , c0); putShortLU(bytes, offset + 1, c1); putShortLU(bytes, offset + 2, c2); putShortLU(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4C(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + public int putChars4C(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; UNSAFE.putChar(bytes, address , c0); UNSAFE.putChar(bytes, address + 2, c1); UNSAFE.putChar(bytes, address + 4, c2); UNSAFE.putChar(bytes, address + 6, c3); + return offset + 8; } - public void putChars4S(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + public int putChars4S(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; UNSAFE.putShort(bytes, address , (short) c0); UNSAFE.putShort(bytes, address + 2, (short) c1); UNSAFE.putShort(bytes, address + 4, (short) c2); UNSAFE.putShort(bytes, address + 6, (short) c3); + return offset + 8; } private static void putShortB(byte[] val, int index, int c) { @@ -1129,4 +721,9 @@ public static void putShortLU(byte[] array, int offset, int c) { UNSAFE.putByte(array, address , (byte) (c )); UNSAFE.putByte(array, address + 1, (byte) (c >> 8)); } + + @Fork(value = 1, jvmArgs = { + "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", "-XX:+UnlockDiagnosticVMOptions", "-XX:-MergeStores" + }) + public static class MergeStoresDisabled extends MergeStoreBench {} } From 98724219a87c1cdb1e7942ade1a4d49b201a0a94 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Wed, 8 Jan 2025 09:45:08 +0000 Subject: [PATCH 040/286] 8347094: Inline CollectedHeap::increment_total_full_collections Reviewed-by: stefank, eosterlund, gli --- src/hotspot/share/gc/shared/collectedHeap.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp index 036bc0230c877..31a224597a048 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp @@ -383,12 +383,10 @@ class CollectedHeap : public CHeapObj { void increment_total_collections(bool full = false) { _total_collections++; if (full) { - increment_total_full_collections(); + _total_full_collections++; } } - void increment_total_full_collections() { _total_full_collections++; } - // Return the SoftRefPolicy for the heap; SoftRefPolicy* soft_ref_policy() { return &_soft_ref_policy; } From cbabc0451505a00dfe77c163190736460c53820f Mon Sep 17 00:00:00 2001 From: Fredrik Bredberg Date: Wed, 8 Jan 2025 09:50:35 +0000 Subject: [PATCH 041/286] 8332506: SIGFPE In ObjectSynchronizer::is_async_deflation_needed() Reviewed-by: coleenp, dholmes --- src/hotspot/share/runtime/synchronizer.cpp | 53 ++++++++++++++-------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp index 941309ca2acc9..fdce6d21531e9 100644 --- a/src/hotspot/share/runtime/synchronizer.cpp +++ b/src/hotspot/share/runtime/synchronizer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -1264,36 +1264,49 @@ static bool monitors_used_above_threshold(MonitorList* list) { if (MonitorUsedDeflationThreshold == 0) { // disabled case is easy return false; } - // Start with ceiling based on a per-thread estimate: - size_t ceiling = ObjectSynchronizer::in_use_list_ceiling(); - size_t old_ceiling = ceiling; - if (ceiling < list->max()) { - // The max used by the system has exceeded the ceiling so use that: - ceiling = list->max(); - } size_t monitors_used = list->count(); if (monitors_used == 0) { // empty list is easy return false; } - if (NoAsyncDeflationProgressMax != 0 && - _no_progress_cnt >= NoAsyncDeflationProgressMax) { - double remainder = (100.0 - MonitorUsedDeflationThreshold) / 100.0; - size_t new_ceiling = ceiling + (size_t)((double)ceiling * remainder) + 1; - ObjectSynchronizer::set_in_use_list_ceiling(new_ceiling); - log_info(monitorinflation)("Too many deflations without progress; " - "bumping in_use_list_ceiling from " SIZE_FORMAT - " to " SIZE_FORMAT, old_ceiling, new_ceiling); - _no_progress_cnt = 0; - ceiling = new_ceiling; - } + size_t old_ceiling = ObjectSynchronizer::in_use_list_ceiling(); + // Make sure that we use a ceiling value that is not lower than + // previous, not lower than the recorded max used by the system, and + // not lower than the current number of monitors in use (which can + // race ahead of max). The result is guaranteed > 0. + size_t ceiling = MAX3(old_ceiling, list->max(), monitors_used); // Check if our monitor usage is above the threshold: size_t monitor_usage = (monitors_used * 100LL) / ceiling; if (int(monitor_usage) > MonitorUsedDeflationThreshold) { + // Deflate monitors if over the threshold percentage, unless no + // progress on previous deflations. + bool is_above_threshold = true; + + // Check if it's time to adjust the in_use_list_ceiling up, due + // to too many async deflation attempts without any progress. + if (NoAsyncDeflationProgressMax != 0 && + _no_progress_cnt >= NoAsyncDeflationProgressMax) { + double remainder = (100.0 - MonitorUsedDeflationThreshold) / 100.0; + size_t delta = (size_t)(ceiling * remainder) + 1; + size_t new_ceiling = (ceiling > SIZE_MAX - delta) + ? SIZE_MAX // Overflow, let's clamp new_ceiling. + : ceiling + delta; + + ObjectSynchronizer::set_in_use_list_ceiling(new_ceiling); + log_info(monitorinflation)("Too many deflations without progress; " + "bumping in_use_list_ceiling from " SIZE_FORMAT + " to " SIZE_FORMAT, old_ceiling, new_ceiling); + _no_progress_cnt = 0; + ceiling = new_ceiling; + + // Check if our monitor usage is still above the threshold: + monitor_usage = (monitors_used * 100LL) / ceiling; + is_above_threshold = int(monitor_usage) > MonitorUsedDeflationThreshold; + } log_info(monitorinflation)("monitors_used=" SIZE_FORMAT ", ceiling=" SIZE_FORMAT ", monitor_usage=" SIZE_FORMAT ", threshold=%d", monitors_used, ceiling, monitor_usage, MonitorUsedDeflationThreshold); - return true; + return is_above_threshold; } return false; From f696d9c521fa13969cb81381dc8586bcdccf67d9 Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Wed, 8 Jan 2025 10:39:13 +0000 Subject: [PATCH 042/286] 8346239: Improve memory efficiency of JimageDiffGenerator Reviewed-by: mbaesken --- .../runtimelink/JimageDiffGenerator.java | 59 +++++++++++++++++-- .../runtimelink/ResourcePoolReader.java | 6 ++ .../jlink/runtimeImage/AddOptionsTest.java | 2 +- .../BasicJlinkMissingJavaBase.java | 2 +- .../jlink/runtimeImage/BasicJlinkTest.java | 2 +- .../runtimeImage/CustomModuleJlinkTest.java | 2 +- .../runtimeImage/GenerateJLIClassesTest.java | 2 +- .../runtimeImage/JavaSEReproducibleTest.java | 2 +- .../KeepPackagedModulesFailTest.java | 2 +- .../runtimeImage/ModifiedFilesExitTest.java | 2 +- .../ModifiedFilesWarningTest.java | 2 +- .../jlink/runtimeImage/MultiHopTest.java | 2 +- ...PackagedModulesVsRuntimeImageLinkTest.java | 3 +- .../PatchedJDKModuleJlinkTest.java | 2 +- .../jlink/runtimeImage/SystemModulesTest.java | 2 +- .../runtimeImage/SystemModulesTest2.java | 2 +- 16 files changed, 74 insertions(+), 20 deletions(-) diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/JimageDiffGenerator.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/JimageDiffGenerator.java index 3ef42fb9aa085..60014e2bbd763 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/JimageDiffGenerator.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/JimageDiffGenerator.java @@ -24,6 +24,9 @@ */ package jdk.tools.jlink.internal.runtimelink; +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -49,6 +52,7 @@ public class JimageDiffGenerator { public interface ImageResource extends AutoCloseable { public List getEntries(); public byte[] getResourceBytes(String name); + public InputStream getResource(String name); } /** @@ -71,7 +75,6 @@ public List generateDiff(ImageResource base, ImageResource image) resources.addAll(image.getEntries()); baseResources = base.getEntries(); for (String item: baseResources) { - byte[] baseBytes = base.getResourceBytes(item); // First check that every item in the base image exist in // the optimized image as well. If it does not, it's a removed // item in the optimized image. @@ -82,19 +85,18 @@ public List generateDiff(ImageResource base, ImageResource image) ResourceDiff.Builder builder = new ResourceDiff.Builder(); ResourceDiff diff = builder.setKind(ResourceDiff.Kind.REMOVED) .setName(item) - .setResourceBytes(baseBytes) + .setResourceBytes(base.getResourceBytes(item)) .build(); diffs.add(diff); continue; } // Verify resource bytes are equal if present in both images - boolean contentEquals = Arrays.equals(baseBytes, image.getResourceBytes(item)); - if (!contentEquals) { + if (!compareStreams(base.getResource(item), image.getResource(item))) { // keep track of original bytes (non-optimized) ResourceDiff.Builder builder = new ResourceDiff.Builder(); ResourceDiff diff = builder.setKind(ResourceDiff.Kind.MODIFIED) .setName(item) - .setResourceBytes(baseBytes) + .setResourceBytes(base.getResourceBytes(item)) .build(); diffs.add(diff); } @@ -112,4 +114,51 @@ public List generateDiff(ImageResource base, ImageResource image) return diffs; } + /** + * Compare the contents of the two input streams (byte-by-byte). + * + * @param is1 The first input stream + * @param is2 The second input stream + * @return {@code true} iff the two streams contain the same number of + * bytes and each byte of the streams are equal. {@code false} + * otherwise. + */ + private boolean compareStreams(InputStream is1, InputStream is2) { + byte[] buf1 = new byte[1024]; + byte[] buf2 = new byte[1024]; + int bytesRead1, bytesRead2 = 0; + try { + try (is1; is2) { + while ((bytesRead1 = is1.read(buf1)) != -1 && + (bytesRead2 = is2.read(buf2)) != -1) { + if (bytesRead1 != bytesRead2) { + return false; + } + if (bytesRead1 == buf1.length) { + if (!Arrays.equals(buf1, buf2)) { + return false; + } + } else { + for (int i = 0; i < bytesRead1; i++) { + if (buf1[i] != buf2[i]) { + return false; + } + } + } + } + // ensure we read both to the end + if (bytesRead1 == -1) { + bytesRead2 = is2.read(buf2); + if (bytesRead2 != -1) { + return false; + } + return true; + } + } + } catch (IOException e) { + throw new UncheckedIOException("IO exception when comparing bytes", e); + } + return false; + } + } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/ResourcePoolReader.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/ResourcePoolReader.java index 910fe57b75aba..c4c16579906a2 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/ResourcePoolReader.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/ResourcePoolReader.java @@ -25,6 +25,7 @@ package jdk.tools.jlink.internal.runtimelink; +import java.io.InputStream; import java.util.List; import java.util.Objects; @@ -56,4 +57,9 @@ public byte[] getResourceBytes(String name) { return pool.findEntry(name).orElseThrow().contentBytes(); } + @Override + public InputStream getResource(String name) { + return pool.findEntry(name).orElseThrow().content(); + } + } diff --git a/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java b/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java index 827f7da624d30..1ffe1240d07e7 100644 --- a/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java +++ b/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m AddOptionsTest + * @run main/othervm -Xmx1g AddOptionsTest */ public class AddOptionsTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java b/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java index ebf5b060665fc..b0d2a2d66f5b3 100644 --- a/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java +++ b/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m BasicJlinkMissingJavaBase + * @run main/othervm -Xmx1g BasicJlinkMissingJavaBase */ public class BasicJlinkMissingJavaBase extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java index 8cbd74e5ed1cb..b97ebff9b4906 100644 --- a/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m BasicJlinkTest false + * @run main/othervm -Xmx1g BasicJlinkTest false */ public class BasicJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java index d6c237a173b72..369bccfecfce4 100644 --- a/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m CustomModuleJlinkTest + * @run main/othervm -Xmx1g CustomModuleJlinkTest */ public class CustomModuleJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java b/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java index e59d18bd6f05c..533a8db30d0cc 100644 --- a/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java +++ b/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m GenerateJLIClassesTest + * @run main/othervm -Xmx1g GenerateJLIClassesTest */ public class GenerateJLIClassesTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java b/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java index a376d075ecd07..d923358aed90d 100644 --- a/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java +++ b/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m JavaSEReproducibleTest + * @run main/othervm -Xmx1g JavaSEReproducibleTest */ public class JavaSEReproducibleTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java b/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java index 6fdaf5a9824b8..8094579ecd505 100644 --- a/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java +++ b/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m KeepPackagedModulesFailTest + * @run main/othervm -Xmx1g KeepPackagedModulesFailTest */ public class KeepPackagedModulesFailTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java index 777ce302ce799..443cbbaec3c9d 100644 --- a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java +++ b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m ModifiedFilesExitTest + * @run main/othervm -Xmx1g ModifiedFilesExitTest */ public class ModifiedFilesExitTest extends ModifiedFilesTest { diff --git a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java index c871024f37cfa..619c67e01b4b4 100644 --- a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java +++ b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m ModifiedFilesWarningTest + * @run main/othervm -Xmx1g ModifiedFilesWarningTest */ public class ModifiedFilesWarningTest extends ModifiedFilesTest { diff --git a/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java b/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java index 0e2cabe7425c8..88f91f238bd87 100644 --- a/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java +++ b/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m MultiHopTest + * @run main/othervm -Xmx1g MultiHopTest */ public class MultiHopTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java b/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java index d276e80702b40..ef7030d2e62fa 100644 --- a/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java @@ -49,7 +49,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm/timeout=1200 -Xmx1400m PackagedModulesVsRuntimeImageLinkTest + * @run main/othervm/timeout=1200 -Xmx1g PackagedModulesVsRuntimeImageLinkTest */ public class PackagedModulesVsRuntimeImageLinkTest extends AbstractLinkableRuntimeTest { @@ -76,7 +76,6 @@ void runTest(Helper helper, boolean isLinkableRuntime) throws Exception { .output(helper.createNewImageDir("java-se-jmodfull")) .addMods("java.se").call().assertSuccess(); - System.out.println("Now comparing jmod-less and jmod-full) images"); compareRecursively(javaSEruntimeLink, javaSEJmodFull); } diff --git a/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java index d4654ec98bdc3..81579e0754bca 100644 --- a/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java @@ -42,7 +42,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m PatchedJDKModuleJlinkTest + * @run main/othervm -Xmx1g PatchedJDKModuleJlinkTest */ public class PatchedJDKModuleJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java index d0a6234eec0ce..fac8cac112d14 100644 --- a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java +++ b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m SystemModulesTest + * @run main/othervm -Xmx1g SystemModulesTest */ public class SystemModulesTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java index ee22a55f3a751..6be4ad7321cea 100644 --- a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java +++ b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java @@ -42,7 +42,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m SystemModulesTest2 + * @run main/othervm -Xmx1g SystemModulesTest2 */ public class SystemModulesTest2 extends AbstractLinkableRuntimeTest { From afe543414f58a04832d4f07dea88881d64954a0b Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Wed, 8 Jan 2025 10:56:48 +0000 Subject: [PATCH 043/286] 8347163: Javadoc error in ConstantPoolBuilder after JDK-8342468 Reviewed-by: jpai, shade --- .../java/lang/classfile/constantpool/ConstantPoolBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java index e1518ab6a02eb..260fc982dab07 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java @@ -400,7 +400,7 @@ default MethodHandleEntry methodHandleEntry(DirectMethodHandleDesc descriptor) { * * @param refKind the reference kind of the method handle * @param reference the {@code MemberRefEntry} - * @see MethodHandleInfo##refKinds Reference kinds + * @see MethodHandleInfo##refkinds Reference kinds * @see MethodHandleEntry#kind() MethodHandleEntry::kind * @see MethodHandleEntry#reference() MethodHandleEntry::reference */ From 672c413c61d9b155020a0fd4bd1c2bc0661a60fb Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 8 Jan 2025 12:44:53 +0000 Subject: [PATCH 044/286] 8345337: JFR: jfr view should display all direct subfields for an event type Reviewed-by: mgronlun --- .../share/classes/jdk/jfr/internal/query/FieldBuilder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java index c6916bc52efea..391db7cc9306a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java @@ -353,9 +353,10 @@ record WildcardElement(String name, String label, ValueDescriptor field) { var subFields = we.field().getFields().reversed(); if (!subFields.isEmpty() && !KNOWN_TYPES.contains(we.field().getTypeName())) { for (ValueDescriptor subField : subFields) { - String n = we.name + "." + subField.getName(); - String l = we.label + " : " + makeLabel(subField, false); - if (stack.size() < 2) { // Limit depth to 2 + // Limit depth to 2 + if (!we.name.contains(".")) { + String n = we.name + "." + subField.getName(); + String l = we.label + " : " + makeLabel(subField, false); stack.push(new WildcardElement(n, l, subField)); } } From 92ad8a1d96c749d1f9c15e5b96244cd72a6e71be Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 8 Jan 2025 14:40:13 +0000 Subject: [PATCH 045/286] 8346052: JFR: Incorrect average value in 'jfr view' Reviewed-by: mgronlun --- .../share/classes/jdk/jfr/internal/query/Function.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java index 29d55e95673f5..767202bdae874 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java @@ -175,9 +175,9 @@ public void add(Object value) { @Override public Object result() { if (count != 0) { - long s = seconds / count; - long n = nanos / count; - return Duration.ofSeconds(s, n); + double total = 1_000_000_000.0 * seconds + nanos; + double average = total / count; + return Duration.ofNanos(Math.round(average)); } else { return null; } From 4d18e5a1e26e04beb550d01ba5a3dbb8c0c37fa0 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Wed, 8 Jan 2025 14:44:10 +0000 Subject: [PATCH 046/286] 8346872: tools/jpackage/windows/WinLongPathTest.java fails Reviewed-by: almatvee, mbaesken --- .../jpackage/windows/WinLongPathTest.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/test/jdk/tools/jpackage/windows/WinLongPathTest.java b/test/jdk/tools/jpackage/windows/WinLongPathTest.java index e9e5ef8ce038e..10e713f02a8cf 100644 --- a/test/jdk/tools/jpackage/windows/WinLongPathTest.java +++ b/test/jdk/tools/jpackage/windows/WinLongPathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, 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 @@ -30,6 +30,7 @@ import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Executor; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.RunnablePackageTest.Action; import jdk.jpackage.test.TKit; @@ -39,8 +40,10 @@ * @bug 8289771 * @summary jpackage with long paths on windows * @library /test/jdk/tools/jpackage/helpers + * @library /test/lib * @key jpackagePlatformPackage * @build jdk.jpackage.test.* + * @build jtreg.SkippedException * @requires (os.family == "windows") * @compile WinLongPathTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main @@ -64,6 +67,8 @@ public static List input() { @Test public void test() throws IOException { + verifyDosNamesSupported(); + if (appImage) { var cmd = JPackageCommand.helloAppImage(); setOptionLongPath(cmd, optionName); @@ -84,4 +89,23 @@ private static void setOptionLongPath(JPackageCommand cmd, String option) throws Files.createDirectories(longPath); cmd.setArgumentValue(option, longPath); } + + private static void verifyDosNamesSupported() throws IOException { + // Pick the file's name long enough to make Windows shorten it. + final var probeDosNameFile = TKit.createTempFile(Path.of("probeDosName")); + + // The output should be a DOS variant of the `probeDosNameFile` path. + // The filename should differ if the volume owning `probeDosNameFile` file supports DOS names. + final var dosPath = new Executor() + .addArguments("/c", String.format("for %%P in (\"%s\") do @echo %%~sP", probeDosNameFile)) + .setExecutable("cmd") + .dumpOutput() + .executeAndGetFirstLineOfOutput(); + + if (Path.of(dosPath).getFileName().equals(probeDosNameFile.getFileName())) { + TKit.throwSkippedException(String.format("The volume %s owning the test work directory doesn't support DOS paths", + probeDosNameFile.toAbsolutePath().getRoot())); + } + } + } From ae3fc464563ad1ba59883ccf60d235b42f5ad7fa Mon Sep 17 00:00:00 2001 From: Yagmur Eren Date: Wed, 8 Jan 2025 15:14:14 +0000 Subject: [PATCH 047/286] 8345580: Remove const from Node::_idx which is modified Reviewed-by: epeter, qamai --- src/hotspot/share/opto/node.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp index 50ae1deecbf44..101006d9afc44 100644 --- a/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp @@ -345,7 +345,7 @@ class Node { // The PhaseRenumberLive phase renumbers nodes based on liveness information. // Therefore, it updates the value of the _idx field. The parse-time _idx is // preserved in _parse_idx. - const node_idx_t _idx; + node_idx_t _idx; DEBUG_ONLY(const node_idx_t _parse_idx;) // IGV node identifier. Two nodes, possibly in different compilation phases, // have the same IGV identifier if (and only if) they are the very same node @@ -586,8 +586,7 @@ class Node { // Set this node's index, used by cisc_version to replace current node void set_idx(uint new_idx) { - const node_idx_t* ref = &_idx; - *(node_idx_t*)ref = new_idx; + _idx = new_idx; } // Swap input edge order. (Edge indexes i1 and i2 are usually 1 and 2.) void swap_edges(uint i1, uint i2) { From 55bcf4c054c95af2a073818cd8c392de02b3ee01 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 8 Jan 2025 15:53:22 +0000 Subject: [PATCH 048/286] 8346047: JFR: Incorrect percentile value in 'jfr view' Reviewed-by: mgronlun --- .../share/classes/jdk/jfr/internal/query/Function.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java index 767202bdae874..0c9ca96ee201a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java @@ -89,7 +89,7 @@ public static Function create(Field field) { return createPercentile(field, 0.99); } if (aggregator == Aggregator.P999) { - return createPercentile(field, 0.9999); + return createPercentile(field, 0.999); } if (aggregator == Aggregator.MAXIMUM) { return new Maximum(); @@ -578,7 +578,7 @@ public Object result() { double doubleIndex = (size + 1) * percentile; int valueIndex = (int) doubleIndex - 1; int valueNextIndex = (int) doubleIndex; - double fraction = doubleIndex - valueIndex; + double fraction = doubleIndex - (int) doubleIndex; if (valueIndex < 0) { return numbers.getFirst(); From 3fe08186b1d6dbc17d4f14d8288ce3c7c6651004 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 8 Jan 2025 16:03:40 +0000 Subject: [PATCH 049/286] 8346099: JFR: Query for 'jfr view' can't handle wildcard with multiple event types Reviewed-by: mgronlun --- .../classes/jdk/jfr/internal/query/FieldBuilder.java | 1 - .../classes/jdk/jfr/internal/query/QueryResolver.java | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java index 391db7cc9306a..df6fb9f2a9a6b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java @@ -370,7 +370,6 @@ record WildcardElement(String name, String label, ValueDescriptor field) { FieldBuilder fb = new FieldBuilder(eventTypes, type, we.name()); Field field = fb.build().getFirst(); field.label = we.label; - field.index = result.size(); field.visible = true; field.sourceFields.add(field); result.add(field); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/QueryResolver.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/QueryResolver.java index 4d947eea9a5f5..1b68a038a1755 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/QueryResolver.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/QueryResolver.java @@ -98,11 +98,19 @@ public List resolve() throws QueryException { resolveGroupBy(); resolveOrderBy(); resolveWhere(); + applyIndex(); applyColumn(); applyFormat(); return resultFields; } + private void applyIndex() { + int index = 0; + for (Field field : resultFields) { + field.index = index++; + } + } + private void resolveWhere() throws QuerySyntaxException { for (Condition condition : where) { List fields = new ArrayList<>(); @@ -238,7 +246,6 @@ private Field addField(String name, List types) throws QueryExcept } } for (Field field: fields) { - field.index = resultFields.size(); primary.sourceFields.add(field); // Convert to String if field data types mismatch if (mixedTypes) { From 49ee4df375f57ef2d06ff7d54aaefed77d60c40b Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Wed, 8 Jan 2025 16:48:44 +0000 Subject: [PATCH 050/286] 8166983: Remove old/legacy unused tzdata files Reviewed-by: iris, rriggs --- src/java.base/share/data/tzdata/solar87 | 413 ------- src/java.base/share/data/tzdata/solar88 | 413 ------- src/java.base/share/data/tzdata/solar89 | 418 ------- src/java.base/share/data/tzdata/zone.tab | 470 -------- .../java/util/TimeZone/tools/share/Makefile | 5 +- test/jdk/sun/util/calendar/zi/BackEnd.java | 66 -- test/jdk/sun/util/calendar/zi/Beyond2037.java | 73 -- test/jdk/sun/util/calendar/zi/Checksum.java | 65 - test/jdk/sun/util/calendar/zi/DayOfWeek.java | 52 - test/jdk/sun/util/calendar/zi/Gen.java | 342 ------ test/jdk/sun/util/calendar/zi/GenDoc.java | 776 ------------ test/jdk/sun/util/calendar/zi/Main.java | 232 ---- test/jdk/sun/util/calendar/zi/Mappings.java | 193 --- test/jdk/sun/util/calendar/zi/Month.java | 87 -- test/jdk/sun/util/calendar/zi/Rule.java | 189 --- test/jdk/sun/util/calendar/zi/RuleDay.java | 184 --- test/jdk/sun/util/calendar/zi/RuleRec.java | 229 ---- test/jdk/sun/util/calendar/zi/Simple.java | 184 --- .../sun/util/calendar/zi/TestZoneInfo310.java | 283 ----- test/jdk/sun/util/calendar/zi/Time.java | 339 ------ test/jdk/sun/util/calendar/zi/Timezone.java | 450 ------- .../sun/util/calendar/zi/TzIDOldMapping.java | 64 - test/jdk/sun/util/calendar/zi/Zone.java | 164 --- .../sun/util/calendar/zi/ZoneInfoFile.java | 1049 ----------------- .../jdk/sun/util/calendar/zi/ZoneInfoOld.java | 1022 ---------------- test/jdk/sun/util/calendar/zi/ZoneRec.java | 248 ---- test/jdk/sun/util/calendar/zi/Zoneinfo.java | 579 --------- .../calendar/zi/tzdata_jdk/jdk11_backward | 78 -- 28 files changed, 2 insertions(+), 8665 deletions(-) delete mode 100644 src/java.base/share/data/tzdata/solar87 delete mode 100644 src/java.base/share/data/tzdata/solar88 delete mode 100644 src/java.base/share/data/tzdata/solar89 delete mode 100644 src/java.base/share/data/tzdata/zone.tab delete mode 100644 test/jdk/sun/util/calendar/zi/BackEnd.java delete mode 100644 test/jdk/sun/util/calendar/zi/Beyond2037.java delete mode 100644 test/jdk/sun/util/calendar/zi/Checksum.java delete mode 100644 test/jdk/sun/util/calendar/zi/DayOfWeek.java delete mode 100644 test/jdk/sun/util/calendar/zi/Gen.java delete mode 100644 test/jdk/sun/util/calendar/zi/GenDoc.java delete mode 100644 test/jdk/sun/util/calendar/zi/Main.java delete mode 100644 test/jdk/sun/util/calendar/zi/Mappings.java delete mode 100644 test/jdk/sun/util/calendar/zi/Month.java delete mode 100644 test/jdk/sun/util/calendar/zi/Rule.java delete mode 100644 test/jdk/sun/util/calendar/zi/RuleDay.java delete mode 100644 test/jdk/sun/util/calendar/zi/RuleRec.java delete mode 100644 test/jdk/sun/util/calendar/zi/Simple.java delete mode 100644 test/jdk/sun/util/calendar/zi/TestZoneInfo310.java delete mode 100644 test/jdk/sun/util/calendar/zi/Time.java delete mode 100644 test/jdk/sun/util/calendar/zi/Timezone.java delete mode 100644 test/jdk/sun/util/calendar/zi/TzIDOldMapping.java delete mode 100644 test/jdk/sun/util/calendar/zi/Zone.java delete mode 100644 test/jdk/sun/util/calendar/zi/ZoneInfoFile.java delete mode 100644 test/jdk/sun/util/calendar/zi/ZoneInfoOld.java delete mode 100644 test/jdk/sun/util/calendar/zi/ZoneRec.java delete mode 100644 test/jdk/sun/util/calendar/zi/Zoneinfo.java delete mode 100644 test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward diff --git a/src/java.base/share/data/tzdata/solar87 b/src/java.base/share/data/tzdata/solar87 deleted file mode 100644 index 0512ca410c107..0000000000000 --- a/src/java.base/share/data/tzdata/solar87 +++ /dev/null @@ -1,413 +0,0 @@ -# -# 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. -# -#

    -# This file is in the public domain, so clarified as of
    -# 2009-05-17 by Arthur David Olson.
    -
    -# So much for footnotes about Saudi Arabia.
    -# Apparent noon times below are for Riyadh; your mileage will vary.
    -# Times were computed using formulas in the U.S. Naval Observatory's
    -# Almanac for Computers 1987; the formulas "will give EqT to an accuracy of
    -# [plus or minus two] seconds during the current year."
    -#
    -# Rounding to the nearest five seconds results in fewer than
    -# 256 different "time types"--a limit that's faced because time types are
    -# stored on disk as unsigned chars.
    -
    -# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
    -Rule	sol87	1987	only	-	Jan	1	12:03:20s -0:03:20 -
    -Rule	sol87	1987	only	-	Jan	2	12:03:50s -0:03:50 -
    -Rule	sol87	1987	only	-	Jan	3	12:04:15s -0:04:15 -
    -Rule	sol87	1987	only	-	Jan	4	12:04:45s -0:04:45 -
    -Rule	sol87	1987	only	-	Jan	5	12:05:10s -0:05:10 -
    -Rule	sol87	1987	only	-	Jan	6	12:05:40s -0:05:40 -
    -Rule	sol87	1987	only	-	Jan	7	12:06:05s -0:06:05 -
    -Rule	sol87	1987	only	-	Jan	8	12:06:30s -0:06:30 -
    -Rule	sol87	1987	only	-	Jan	9	12:06:55s -0:06:55 -
    -Rule	sol87	1987	only	-	Jan	10	12:07:20s -0:07:20 -
    -Rule	sol87	1987	only	-	Jan	11	12:07:45s -0:07:45 -
    -Rule	sol87	1987	only	-	Jan	12	12:08:10s -0:08:10 -
    -Rule	sol87	1987	only	-	Jan	13	12:08:30s -0:08:30 -
    -Rule	sol87	1987	only	-	Jan	14	12:08:55s -0:08:55 -
    -Rule	sol87	1987	only	-	Jan	15	12:09:15s -0:09:15 -
    -Rule	sol87	1987	only	-	Jan	16	12:09:35s -0:09:35 -
    -Rule	sol87	1987	only	-	Jan	17	12:09:55s -0:09:55 -
    -Rule	sol87	1987	only	-	Jan	18	12:10:15s -0:10:15 -
    -Rule	sol87	1987	only	-	Jan	19	12:10:35s -0:10:35 -
    -Rule	sol87	1987	only	-	Jan	20	12:10:55s -0:10:55 -
    -Rule	sol87	1987	only	-	Jan	21	12:11:10s -0:11:10 -
    -Rule	sol87	1987	only	-	Jan	22	12:11:30s -0:11:30 -
    -Rule	sol87	1987	only	-	Jan	23	12:11:45s -0:11:45 -
    -Rule	sol87	1987	only	-	Jan	24	12:12:00s -0:12:00 -
    -Rule	sol87	1987	only	-	Jan	25	12:12:15s -0:12:15 -
    -Rule	sol87	1987	only	-	Jan	26	12:12:30s -0:12:30 -
    -Rule	sol87	1987	only	-	Jan	27	12:12:40s -0:12:40 -
    -Rule	sol87	1987	only	-	Jan	28	12:12:55s -0:12:55 -
    -Rule	sol87	1987	only	-	Jan	29	12:13:05s -0:13:05 -
    -Rule	sol87	1987	only	-	Jan	30	12:13:15s -0:13:15 -
    -Rule	sol87	1987	only	-	Jan	31	12:13:25s -0:13:25 -
    -Rule	sol87	1987	only	-	Feb	1	12:13:35s -0:13:35 -
    -Rule	sol87	1987	only	-	Feb	2	12:13:40s -0:13:40 -
    -Rule	sol87	1987	only	-	Feb	3	12:13:50s -0:13:50 -
    -Rule	sol87	1987	only	-	Feb	4	12:13:55s -0:13:55 -
    -Rule	sol87	1987	only	-	Feb	5	12:14:00s -0:14:00 -
    -Rule	sol87	1987	only	-	Feb	6	12:14:05s -0:14:05 -
    -Rule	sol87	1987	only	-	Feb	7	12:14:10s -0:14:10 -
    -Rule	sol87	1987	only	-	Feb	8	12:14:10s -0:14:10 -
    -Rule	sol87	1987	only	-	Feb	9	12:14:15s -0:14:15 -
    -Rule	sol87	1987	only	-	Feb	10	12:14:15s -0:14:15 -
    -Rule	sol87	1987	only	-	Feb	11	12:14:15s -0:14:15 -
    -Rule	sol87	1987	only	-	Feb	12	12:14:15s -0:14:15 -
    -Rule	sol87	1987	only	-	Feb	13	12:14:15s -0:14:15 -
    -Rule	sol87	1987	only	-	Feb	14	12:14:15s -0:14:15 -
    -Rule	sol87	1987	only	-	Feb	15	12:14:10s -0:14:10 -
    -Rule	sol87	1987	only	-	Feb	16	12:14:10s -0:14:10 -
    -Rule	sol87	1987	only	-	Feb	17	12:14:05s -0:14:05 -
    -Rule	sol87	1987	only	-	Feb	18	12:14:00s -0:14:00 -
    -Rule	sol87	1987	only	-	Feb	19	12:13:55s -0:13:55 -
    -Rule	sol87	1987	only	-	Feb	20	12:13:50s -0:13:50 -
    -Rule	sol87	1987	only	-	Feb	21	12:13:45s -0:13:45 -
    -Rule	sol87	1987	only	-	Feb	22	12:13:35s -0:13:35 -
    -Rule	sol87	1987	only	-	Feb	23	12:13:30s -0:13:30 -
    -Rule	sol87	1987	only	-	Feb	24	12:13:20s -0:13:20 -
    -Rule	sol87	1987	only	-	Feb	25	12:13:10s -0:13:10 -
    -Rule	sol87	1987	only	-	Feb	26	12:13:00s -0:13:00 -
    -Rule	sol87	1987	only	-	Feb	27	12:12:50s -0:12:50 -
    -Rule	sol87	1987	only	-	Feb	28	12:12:40s -0:12:40 -
    -Rule	sol87	1987	only	-	Mar	1	12:12:30s -0:12:30 -
    -Rule	sol87	1987	only	-	Mar	2	12:12:20s -0:12:20 -
    -Rule	sol87	1987	only	-	Mar	3	12:12:05s -0:12:05 -
    -Rule	sol87	1987	only	-	Mar	4	12:11:55s -0:11:55 -
    -Rule	sol87	1987	only	-	Mar	5	12:11:40s -0:11:40 -
    -Rule	sol87	1987	only	-	Mar	6	12:11:25s -0:11:25 -
    -Rule	sol87	1987	only	-	Mar	7	12:11:15s -0:11:15 -
    -Rule	sol87	1987	only	-	Mar	8	12:11:00s -0:11:00 -
    -Rule	sol87	1987	only	-	Mar	9	12:10:45s -0:10:45 -
    -Rule	sol87	1987	only	-	Mar	10	12:10:30s -0:10:30 -
    -Rule	sol87	1987	only	-	Mar	11	12:10:15s -0:10:15 -
    -Rule	sol87	1987	only	-	Mar	12	12:09:55s -0:09:55 -
    -Rule	sol87	1987	only	-	Mar	13	12:09:40s -0:09:40 -
    -Rule	sol87	1987	only	-	Mar	14	12:09:25s -0:09:25 -
    -Rule	sol87	1987	only	-	Mar	15	12:09:10s -0:09:10 -
    -Rule	sol87	1987	only	-	Mar	16	12:08:50s -0:08:50 -
    -Rule	sol87	1987	only	-	Mar	17	12:08:35s -0:08:35 -
    -Rule	sol87	1987	only	-	Mar	18	12:08:15s -0:08:15 -
    -Rule	sol87	1987	only	-	Mar	19	12:08:00s -0:08:00 -
    -Rule	sol87	1987	only	-	Mar	20	12:07:40s -0:07:40 -
    -Rule	sol87	1987	only	-	Mar	21	12:07:25s -0:07:25 -
    -Rule	sol87	1987	only	-	Mar	22	12:07:05s -0:07:05 -
    -Rule	sol87	1987	only	-	Mar	23	12:06:50s -0:06:50 -
    -Rule	sol87	1987	only	-	Mar	24	12:06:30s -0:06:30 -
    -Rule	sol87	1987	only	-	Mar	25	12:06:10s -0:06:10 -
    -Rule	sol87	1987	only	-	Mar	26	12:05:55s -0:05:55 -
    -Rule	sol87	1987	only	-	Mar	27	12:05:35s -0:05:35 -
    -Rule	sol87	1987	only	-	Mar	28	12:05:15s -0:05:15 -
    -Rule	sol87	1987	only	-	Mar	29	12:05:00s -0:05:00 -
    -Rule	sol87	1987	only	-	Mar	30	12:04:40s -0:04:40 -
    -Rule	sol87	1987	only	-	Mar	31	12:04:25s -0:04:25 -
    -Rule	sol87	1987	only	-	Apr	1	12:04:05s -0:04:05 -
    -Rule	sol87	1987	only	-	Apr	2	12:03:45s -0:03:45 -
    -Rule	sol87	1987	only	-	Apr	3	12:03:30s -0:03:30 -
    -Rule	sol87	1987	only	-	Apr	4	12:03:10s -0:03:10 -
    -Rule	sol87	1987	only	-	Apr	5	12:02:55s -0:02:55 -
    -Rule	sol87	1987	only	-	Apr	6	12:02:35s -0:02:35 -
    -Rule	sol87	1987	only	-	Apr	7	12:02:20s -0:02:20 -
    -Rule	sol87	1987	only	-	Apr	8	12:02:05s -0:02:05 -
    -Rule	sol87	1987	only	-	Apr	9	12:01:45s -0:01:45 -
    -Rule	sol87	1987	only	-	Apr	10	12:01:30s -0:01:30 -
    -Rule	sol87	1987	only	-	Apr	11	12:01:15s -0:01:15 -
    -Rule	sol87	1987	only	-	Apr	12	12:00:55s -0:00:55 -
    -Rule	sol87	1987	only	-	Apr	13	12:00:40s -0:00:40 -
    -Rule	sol87	1987	only	-	Apr	14	12:00:25s -0:00:25 -
    -Rule	sol87	1987	only	-	Apr	15	12:00:10s -0:00:10 -
    -Rule	sol87	1987	only	-	Apr	16	11:59:55s 0:00:05 -
    -Rule	sol87	1987	only	-	Apr	17	11:59:45s 0:00:15 -
    -Rule	sol87	1987	only	-	Apr	18	11:59:30s 0:00:30 -
    -Rule	sol87	1987	only	-	Apr	19	11:59:15s 0:00:45 -
    -Rule	sol87	1987	only	-	Apr	20	11:59:05s 0:00:55 -
    -Rule	sol87	1987	only	-	Apr	21	11:58:50s 0:01:10 -
    -Rule	sol87	1987	only	-	Apr	22	11:58:40s 0:01:20 -
    -Rule	sol87	1987	only	-	Apr	23	11:58:25s 0:01:35 -
    -Rule	sol87	1987	only	-	Apr	24	11:58:15s 0:01:45 -
    -Rule	sol87	1987	only	-	Apr	25	11:58:05s 0:01:55 -
    -Rule	sol87	1987	only	-	Apr	26	11:57:55s 0:02:05 -
    -Rule	sol87	1987	only	-	Apr	27	11:57:45s 0:02:15 -
    -Rule	sol87	1987	only	-	Apr	28	11:57:35s 0:02:25 -
    -Rule	sol87	1987	only	-	Apr	29	11:57:25s 0:02:35 -
    -Rule	sol87	1987	only	-	Apr	30	11:57:15s 0:02:45 -
    -Rule	sol87	1987	only	-	May	1	11:57:10s 0:02:50 -
    -Rule	sol87	1987	only	-	May	2	11:57:00s 0:03:00 -
    -Rule	sol87	1987	only	-	May	3	11:56:55s 0:03:05 -
    -Rule	sol87	1987	only	-	May	4	11:56:50s 0:03:10 -
    -Rule	sol87	1987	only	-	May	5	11:56:45s 0:03:15 -
    -Rule	sol87	1987	only	-	May	6	11:56:40s 0:03:20 -
    -Rule	sol87	1987	only	-	May	7	11:56:35s 0:03:25 -
    -Rule	sol87	1987	only	-	May	8	11:56:30s 0:03:30 -
    -Rule	sol87	1987	only	-	May	9	11:56:25s 0:03:35 -
    -Rule	sol87	1987	only	-	May	10	11:56:25s 0:03:35 -
    -Rule	sol87	1987	only	-	May	11	11:56:20s 0:03:40 -
    -Rule	sol87	1987	only	-	May	12	11:56:20s 0:03:40 -
    -Rule	sol87	1987	only	-	May	13	11:56:20s 0:03:40 -
    -Rule	sol87	1987	only	-	May	14	11:56:20s 0:03:40 -
    -Rule	sol87	1987	only	-	May	15	11:56:20s 0:03:40 -
    -Rule	sol87	1987	only	-	May	16	11:56:20s 0:03:40 -
    -Rule	sol87	1987	only	-	May	17	11:56:20s 0:03:40 -
    -Rule	sol87	1987	only	-	May	18	11:56:20s 0:03:40 -
    -Rule	sol87	1987	only	-	May	19	11:56:25s 0:03:35 -
    -Rule	sol87	1987	only	-	May	20	11:56:25s 0:03:35 -
    -Rule	sol87	1987	only	-	May	21	11:56:30s 0:03:30 -
    -Rule	sol87	1987	only	-	May	22	11:56:35s 0:03:25 -
    -Rule	sol87	1987	only	-	May	23	11:56:40s 0:03:20 -
    -Rule	sol87	1987	only	-	May	24	11:56:45s 0:03:15 -
    -Rule	sol87	1987	only	-	May	25	11:56:50s 0:03:10 -
    -Rule	sol87	1987	only	-	May	26	11:56:55s 0:03:05 -
    -Rule	sol87	1987	only	-	May	27	11:57:00s 0:03:00 -
    -Rule	sol87	1987	only	-	May	28	11:57:10s 0:02:50 -
    -Rule	sol87	1987	only	-	May	29	11:57:15s 0:02:45 -
    -Rule	sol87	1987	only	-	May	30	11:57:25s 0:02:35 -
    -Rule	sol87	1987	only	-	May	31	11:57:30s 0:02:30 -
    -Rule	sol87	1987	only	-	Jun	1	11:57:40s 0:02:20 -
    -Rule	sol87	1987	only	-	Jun	2	11:57:50s 0:02:10 -
    -Rule	sol87	1987	only	-	Jun	3	11:58:00s 0:02:00 -
    -Rule	sol87	1987	only	-	Jun	4	11:58:10s 0:01:50 -
    -Rule	sol87	1987	only	-	Jun	5	11:58:20s 0:01:40 -
    -Rule	sol87	1987	only	-	Jun	6	11:58:30s 0:01:30 -
    -Rule	sol87	1987	only	-	Jun	7	11:58:40s 0:01:20 -
    -Rule	sol87	1987	only	-	Jun	8	11:58:50s 0:01:10 -
    -Rule	sol87	1987	only	-	Jun	9	11:59:05s 0:00:55 -
    -Rule	sol87	1987	only	-	Jun	10	11:59:15s 0:00:45 -
    -Rule	sol87	1987	only	-	Jun	11	11:59:30s 0:00:30 -
    -Rule	sol87	1987	only	-	Jun	12	11:59:40s 0:00:20 -
    -Rule	sol87	1987	only	-	Jun	13	11:59:50s 0:00:10 -
    -Rule	sol87	1987	only	-	Jun	14	12:00:05s -0:00:05 -
    -Rule	sol87	1987	only	-	Jun	15	12:00:15s -0:00:15 -
    -Rule	sol87	1987	only	-	Jun	16	12:00:30s -0:00:30 -
    -Rule	sol87	1987	only	-	Jun	17	12:00:45s -0:00:45 -
    -Rule	sol87	1987	only	-	Jun	18	12:00:55s -0:00:55 -
    -Rule	sol87	1987	only	-	Jun	19	12:01:10s -0:01:10 -
    -Rule	sol87	1987	only	-	Jun	20	12:01:20s -0:01:20 -
    -Rule	sol87	1987	only	-	Jun	21	12:01:35s -0:01:35 -
    -Rule	sol87	1987	only	-	Jun	22	12:01:50s -0:01:50 -
    -Rule	sol87	1987	only	-	Jun	23	12:02:00s -0:02:00 -
    -Rule	sol87	1987	only	-	Jun	24	12:02:15s -0:02:15 -
    -Rule	sol87	1987	only	-	Jun	25	12:02:25s -0:02:25 -
    -Rule	sol87	1987	only	-	Jun	26	12:02:40s -0:02:40 -
    -Rule	sol87	1987	only	-	Jun	27	12:02:50s -0:02:50 -
    -Rule	sol87	1987	only	-	Jun	28	12:03:05s -0:03:05 -
    -Rule	sol87	1987	only	-	Jun	29	12:03:15s -0:03:15 -
    -Rule	sol87	1987	only	-	Jun	30	12:03:30s -0:03:30 -
    -Rule	sol87	1987	only	-	Jul	1	12:03:40s -0:03:40 -
    -Rule	sol87	1987	only	-	Jul	2	12:03:50s -0:03:50 -
    -Rule	sol87	1987	only	-	Jul	3	12:04:05s -0:04:05 -
    -Rule	sol87	1987	only	-	Jul	4	12:04:15s -0:04:15 -
    -Rule	sol87	1987	only	-	Jul	5	12:04:25s -0:04:25 -
    -Rule	sol87	1987	only	-	Jul	6	12:04:35s -0:04:35 -
    -Rule	sol87	1987	only	-	Jul	7	12:04:45s -0:04:45 -
    -Rule	sol87	1987	only	-	Jul	8	12:04:55s -0:04:55 -
    -Rule	sol87	1987	only	-	Jul	9	12:05:05s -0:05:05 -
    -Rule	sol87	1987	only	-	Jul	10	12:05:15s -0:05:15 -
    -Rule	sol87	1987	only	-	Jul	11	12:05:20s -0:05:20 -
    -Rule	sol87	1987	only	-	Jul	12	12:05:30s -0:05:30 -
    -Rule	sol87	1987	only	-	Jul	13	12:05:40s -0:05:40 -
    -Rule	sol87	1987	only	-	Jul	14	12:05:45s -0:05:45 -
    -Rule	sol87	1987	only	-	Jul	15	12:05:50s -0:05:50 -
    -Rule	sol87	1987	only	-	Jul	16	12:06:00s -0:06:00 -
    -Rule	sol87	1987	only	-	Jul	17	12:06:05s -0:06:05 -
    -Rule	sol87	1987	only	-	Jul	18	12:06:10s -0:06:10 -
    -Rule	sol87	1987	only	-	Jul	19	12:06:15s -0:06:15 -
    -Rule	sol87	1987	only	-	Jul	20	12:06:15s -0:06:15 -
    -Rule	sol87	1987	only	-	Jul	21	12:06:20s -0:06:20 -
    -Rule	sol87	1987	only	-	Jul	22	12:06:25s -0:06:25 -
    -Rule	sol87	1987	only	-	Jul	23	12:06:25s -0:06:25 -
    -Rule	sol87	1987	only	-	Jul	24	12:06:25s -0:06:25 -
    -Rule	sol87	1987	only	-	Jul	25	12:06:30s -0:06:30 -
    -Rule	sol87	1987	only	-	Jul	26	12:06:30s -0:06:30 -
    -Rule	sol87	1987	only	-	Jul	27	12:06:30s -0:06:30 -
    -Rule	sol87	1987	only	-	Jul	28	12:06:30s -0:06:30 -
    -Rule	sol87	1987	only	-	Jul	29	12:06:25s -0:06:25 -
    -Rule	sol87	1987	only	-	Jul	30	12:06:25s -0:06:25 -
    -Rule	sol87	1987	only	-	Jul	31	12:06:25s -0:06:25 -
    -Rule	sol87	1987	only	-	Aug	1	12:06:20s -0:06:20 -
    -Rule	sol87	1987	only	-	Aug	2	12:06:15s -0:06:15 -
    -Rule	sol87	1987	only	-	Aug	3	12:06:10s -0:06:10 -
    -Rule	sol87	1987	only	-	Aug	4	12:06:05s -0:06:05 -
    -Rule	sol87	1987	only	-	Aug	5	12:06:00s -0:06:00 -
    -Rule	sol87	1987	only	-	Aug	6	12:05:55s -0:05:55 -
    -Rule	sol87	1987	only	-	Aug	7	12:05:50s -0:05:50 -
    -Rule	sol87	1987	only	-	Aug	8	12:05:40s -0:05:40 -
    -Rule	sol87	1987	only	-	Aug	9	12:05:35s -0:05:35 -
    -Rule	sol87	1987	only	-	Aug	10	12:05:25s -0:05:25 -
    -Rule	sol87	1987	only	-	Aug	11	12:05:15s -0:05:15 -
    -Rule	sol87	1987	only	-	Aug	12	12:05:05s -0:05:05 -
    -Rule	sol87	1987	only	-	Aug	13	12:04:55s -0:04:55 -
    -Rule	sol87	1987	only	-	Aug	14	12:04:45s -0:04:45 -
    -Rule	sol87	1987	only	-	Aug	15	12:04:35s -0:04:35 -
    -Rule	sol87	1987	only	-	Aug	16	12:04:25s -0:04:25 -
    -Rule	sol87	1987	only	-	Aug	17	12:04:10s -0:04:10 -
    -Rule	sol87	1987	only	-	Aug	18	12:04:00s -0:04:00 -
    -Rule	sol87	1987	only	-	Aug	19	12:03:45s -0:03:45 -
    -Rule	sol87	1987	only	-	Aug	20	12:03:30s -0:03:30 -
    -Rule	sol87	1987	only	-	Aug	21	12:03:15s -0:03:15 -
    -Rule	sol87	1987	only	-	Aug	22	12:03:00s -0:03:00 -
    -Rule	sol87	1987	only	-	Aug	23	12:02:45s -0:02:45 -
    -Rule	sol87	1987	only	-	Aug	24	12:02:30s -0:02:30 -
    -Rule	sol87	1987	only	-	Aug	25	12:02:15s -0:02:15 -
    -Rule	sol87	1987	only	-	Aug	26	12:02:00s -0:02:00 -
    -Rule	sol87	1987	only	-	Aug	27	12:01:40s -0:01:40 -
    -Rule	sol87	1987	only	-	Aug	28	12:01:25s -0:01:25 -
    -Rule	sol87	1987	only	-	Aug	29	12:01:05s -0:01:05 -
    -Rule	sol87	1987	only	-	Aug	30	12:00:50s -0:00:50 -
    -Rule	sol87	1987	only	-	Aug	31	12:00:30s -0:00:30 -
    -Rule	sol87	1987	only	-	Sep	1	12:00:10s -0:00:10 -
    -Rule	sol87	1987	only	-	Sep	2	11:59:50s 0:00:10 -
    -Rule	sol87	1987	only	-	Sep	3	11:59:35s 0:00:25 -
    -Rule	sol87	1987	only	-	Sep	4	11:59:15s 0:00:45 -
    -Rule	sol87	1987	only	-	Sep	5	11:58:55s 0:01:05 -
    -Rule	sol87	1987	only	-	Sep	6	11:58:35s 0:01:25 -
    -Rule	sol87	1987	only	-	Sep	7	11:58:15s 0:01:45 -
    -Rule	sol87	1987	only	-	Sep	8	11:57:55s 0:02:05 -
    -Rule	sol87	1987	only	-	Sep	9	11:57:30s 0:02:30 -
    -Rule	sol87	1987	only	-	Sep	10	11:57:10s 0:02:50 -
    -Rule	sol87	1987	only	-	Sep	11	11:56:50s 0:03:10 -
    -Rule	sol87	1987	only	-	Sep	12	11:56:30s 0:03:30 -
    -Rule	sol87	1987	only	-	Sep	13	11:56:10s 0:03:50 -
    -Rule	sol87	1987	only	-	Sep	14	11:55:45s 0:04:15 -
    -Rule	sol87	1987	only	-	Sep	15	11:55:25s 0:04:35 -
    -Rule	sol87	1987	only	-	Sep	16	11:55:05s 0:04:55 -
    -Rule	sol87	1987	only	-	Sep	17	11:54:45s 0:05:15 -
    -Rule	sol87	1987	only	-	Sep	18	11:54:20s 0:05:40 -
    -Rule	sol87	1987	only	-	Sep	19	11:54:00s 0:06:00 -
    -Rule	sol87	1987	only	-	Sep	20	11:53:40s 0:06:20 -
    -Rule	sol87	1987	only	-	Sep	21	11:53:15s 0:06:45 -
    -Rule	sol87	1987	only	-	Sep	22	11:52:55s 0:07:05 -
    -Rule	sol87	1987	only	-	Sep	23	11:52:35s 0:07:25 -
    -Rule	sol87	1987	only	-	Sep	24	11:52:15s 0:07:45 -
    -Rule	sol87	1987	only	-	Sep	25	11:51:55s 0:08:05 -
    -Rule	sol87	1987	only	-	Sep	26	11:51:35s 0:08:25 -
    -Rule	sol87	1987	only	-	Sep	27	11:51:10s 0:08:50 -
    -Rule	sol87	1987	only	-	Sep	28	11:50:50s 0:09:10 -
    -Rule	sol87	1987	only	-	Sep	29	11:50:30s 0:09:30 -
    -Rule	sol87	1987	only	-	Sep	30	11:50:10s 0:09:50 -
    -Rule	sol87	1987	only	-	Oct	1	11:49:50s 0:10:10 -
    -Rule	sol87	1987	only	-	Oct	2	11:49:35s 0:10:25 -
    -Rule	sol87	1987	only	-	Oct	3	11:49:15s 0:10:45 -
    -Rule	sol87	1987	only	-	Oct	4	11:48:55s 0:11:05 -
    -Rule	sol87	1987	only	-	Oct	5	11:48:35s 0:11:25 -
    -Rule	sol87	1987	only	-	Oct	6	11:48:20s 0:11:40 -
    -Rule	sol87	1987	only	-	Oct	7	11:48:00s 0:12:00 -
    -Rule	sol87	1987	only	-	Oct	8	11:47:45s 0:12:15 -
    -Rule	sol87	1987	only	-	Oct	9	11:47:25s 0:12:35 -
    -Rule	sol87	1987	only	-	Oct	10	11:47:10s 0:12:50 -
    -Rule	sol87	1987	only	-	Oct	11	11:46:55s 0:13:05 -
    -Rule	sol87	1987	only	-	Oct	12	11:46:40s 0:13:20 -
    -Rule	sol87	1987	only	-	Oct	13	11:46:25s 0:13:35 -
    -Rule	sol87	1987	only	-	Oct	14	11:46:10s 0:13:50 -
    -Rule	sol87	1987	only	-	Oct	15	11:45:55s 0:14:05 -
    -Rule	sol87	1987	only	-	Oct	16	11:45:45s 0:14:15 -
    -Rule	sol87	1987	only	-	Oct	17	11:45:30s 0:14:30 -
    -Rule	sol87	1987	only	-	Oct	18	11:45:20s 0:14:40 -
    -Rule	sol87	1987	only	-	Oct	19	11:45:05s 0:14:55 -
    -Rule	sol87	1987	only	-	Oct	20	11:44:55s 0:15:05 -
    -Rule	sol87	1987	only	-	Oct	21	11:44:45s 0:15:15 -
    -Rule	sol87	1987	only	-	Oct	22	11:44:35s 0:15:25 -
    -Rule	sol87	1987	only	-	Oct	23	11:44:25s 0:15:35 -
    -Rule	sol87	1987	only	-	Oct	24	11:44:20s 0:15:40 -
    -Rule	sol87	1987	only	-	Oct	25	11:44:10s 0:15:50 -
    -Rule	sol87	1987	only	-	Oct	26	11:44:05s 0:15:55 -
    -Rule	sol87	1987	only	-	Oct	27	11:43:55s 0:16:05 -
    -Rule	sol87	1987	only	-	Oct	28	11:43:50s 0:16:10 -
    -Rule	sol87	1987	only	-	Oct	29	11:43:45s 0:16:15 -
    -Rule	sol87	1987	only	-	Oct	30	11:43:45s 0:16:15 -
    -Rule	sol87	1987	only	-	Oct	31	11:43:40s 0:16:20 -
    -Rule	sol87	1987	only	-	Nov	1	11:43:40s 0:16:20 -
    -Rule	sol87	1987	only	-	Nov	2	11:43:35s 0:16:25 -
    -Rule	sol87	1987	only	-	Nov	3	11:43:35s 0:16:25 -
    -Rule	sol87	1987	only	-	Nov	4	11:43:35s 0:16:25 -
    -Rule	sol87	1987	only	-	Nov	5	11:43:35s 0:16:25 -
    -Rule	sol87	1987	only	-	Nov	6	11:43:40s 0:16:20 -
    -Rule	sol87	1987	only	-	Nov	7	11:43:40s 0:16:20 -
    -Rule	sol87	1987	only	-	Nov	8	11:43:45s 0:16:15 -
    -Rule	sol87	1987	only	-	Nov	9	11:43:50s 0:16:10 -
    -Rule	sol87	1987	only	-	Nov	10	11:43:55s 0:16:05 -
    -Rule	sol87	1987	only	-	Nov	11	11:44:00s 0:16:00 -
    -Rule	sol87	1987	only	-	Nov	12	11:44:05s 0:15:55 -
    -Rule	sol87	1987	only	-	Nov	13	11:44:15s 0:15:45 -
    -Rule	sol87	1987	only	-	Nov	14	11:44:20s 0:15:40 -
    -Rule	sol87	1987	only	-	Nov	15	11:44:30s 0:15:30 -
    -Rule	sol87	1987	only	-	Nov	16	11:44:40s 0:15:20 -
    -Rule	sol87	1987	only	-	Nov	17	11:44:50s 0:15:10 -
    -Rule	sol87	1987	only	-	Nov	18	11:45:05s 0:14:55 -
    -Rule	sol87	1987	only	-	Nov	19	11:45:15s 0:14:45 -
    -Rule	sol87	1987	only	-	Nov	20	11:45:30s 0:14:30 -
    -Rule	sol87	1987	only	-	Nov	21	11:45:45s 0:14:15 -
    -Rule	sol87	1987	only	-	Nov	22	11:46:00s 0:14:00 -
    -Rule	sol87	1987	only	-	Nov	23	11:46:15s 0:13:45 -
    -Rule	sol87	1987	only	-	Nov	24	11:46:30s 0:13:30 -
    -Rule	sol87	1987	only	-	Nov	25	11:46:50s 0:13:10 -
    -Rule	sol87	1987	only	-	Nov	26	11:47:10s 0:12:50 -
    -Rule	sol87	1987	only	-	Nov	27	11:47:25s 0:12:35 -
    -Rule	sol87	1987	only	-	Nov	28	11:47:45s 0:12:15 -
    -Rule	sol87	1987	only	-	Nov	29	11:48:05s 0:11:55 -
    -Rule	sol87	1987	only	-	Nov	30	11:48:30s 0:11:30 -
    -Rule	sol87	1987	only	-	Dec	1	11:48:50s 0:11:10 -
    -Rule	sol87	1987	only	-	Dec	2	11:49:10s 0:10:50 -
    -Rule	sol87	1987	only	-	Dec	3	11:49:35s 0:10:25 -
    -Rule	sol87	1987	only	-	Dec	4	11:50:00s 0:10:00 -
    -Rule	sol87	1987	only	-	Dec	5	11:50:25s 0:09:35 -
    -Rule	sol87	1987	only	-	Dec	6	11:50:50s 0:09:10 -
    -Rule	sol87	1987	only	-	Dec	7	11:51:15s 0:08:45 -
    -Rule	sol87	1987	only	-	Dec	8	11:51:40s 0:08:20 -
    -Rule	sol87	1987	only	-	Dec	9	11:52:05s 0:07:55 -
    -Rule	sol87	1987	only	-	Dec	10	11:52:30s 0:07:30 -
    -Rule	sol87	1987	only	-	Dec	11	11:53:00s 0:07:00 -
    -Rule	sol87	1987	only	-	Dec	12	11:53:25s 0:06:35 -
    -Rule	sol87	1987	only	-	Dec	13	11:53:55s 0:06:05 -
    -Rule	sol87	1987	only	-	Dec	14	11:54:25s 0:05:35 -
    -Rule	sol87	1987	only	-	Dec	15	11:54:50s 0:05:10 -
    -Rule	sol87	1987	only	-	Dec	16	11:55:20s 0:04:40 -
    -Rule	sol87	1987	only	-	Dec	17	11:55:50s 0:04:10 -
    -Rule	sol87	1987	only	-	Dec	18	11:56:20s 0:03:40 -
    -Rule	sol87	1987	only	-	Dec	19	11:56:50s 0:03:10 -
    -Rule	sol87	1987	only	-	Dec	20	11:57:20s 0:02:40 -
    -Rule	sol87	1987	only	-	Dec	21	11:57:50s 0:02:10 -
    -Rule	sol87	1987	only	-	Dec	22	11:58:20s 0:01:40 -
    -Rule	sol87	1987	only	-	Dec	23	11:58:50s 0:01:10 -
    -Rule	sol87	1987	only	-	Dec	24	11:59:20s 0:00:40 -
    -Rule	sol87	1987	only	-	Dec	25	11:59:50s 0:00:10 -
    -Rule	sol87	1987	only	-	Dec	26	12:00:20s -0:00:20 -
    -Rule	sol87	1987	only	-	Dec	27	12:00:45s -0:00:45 -
    -Rule	sol87	1987	only	-	Dec	28	12:01:15s -0:01:15 -
    -Rule	sol87	1987	only	-	Dec	29	12:01:45s -0:01:45 -
    -Rule	sol87	1987	only	-	Dec	30	12:02:15s -0:02:15 -
    -Rule	sol87	1987	only	-	Dec	31	12:02:45s -0:02:45 -
    -
    -# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
    -# Before and after 1987, we'll operate on local mean solar time.
    -
    -# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
    -Zone	Asia/Riyadh87	3:07:04	-		zzz	1987
    -			3:07:04	sol87		zzz	1988
    -			3:07:04	-		zzz
    -# For backward compatibility...
    -Link	Asia/Riyadh87	Mideast/Riyadh87
    diff --git a/src/java.base/share/data/tzdata/solar88 b/src/java.base/share/data/tzdata/solar88
    deleted file mode 100644
    index 3314cb1d64017..0000000000000
    --- a/src/java.base/share/data/tzdata/solar88
    +++ /dev/null
    @@ -1,413 +0,0 @@
    -#
    -# 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.
    -#
    -# 
    -# This file is in the public domain, so clarified as of
    -# 2009-05-17 by Arthur David Olson.
    -
    -# Apparent noon times below are for Riyadh; they're a bit off for other places.
    -# Times were computed using formulas in the U.S. Naval Observatory's
    -# Almanac for Computers 1988; the formulas "will give EqT to an accuracy of
    -# [plus or minus two] seconds during the current year."
    -#
    -# Rounding to the nearest five seconds results in fewer than
    -# 256 different "time types"--a limit that's faced because time types are
    -# stored on disk as unsigned chars.
    -
    -# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
    -Rule	sol88	1988	only	-	Jan	1	12:03:15s -0:03:15 -
    -Rule	sol88	1988	only	-	Jan	2	12:03:40s -0:03:40 -
    -Rule	sol88	1988	only	-	Jan	3	12:04:10s -0:04:10 -
    -Rule	sol88	1988	only	-	Jan	4	12:04:40s -0:04:40 -
    -Rule	sol88	1988	only	-	Jan	5	12:05:05s -0:05:05 -
    -Rule	sol88	1988	only	-	Jan	6	12:05:30s -0:05:30 -
    -Rule	sol88	1988	only	-	Jan	7	12:06:00s -0:06:00 -
    -Rule	sol88	1988	only	-	Jan	8	12:06:25s -0:06:25 -
    -Rule	sol88	1988	only	-	Jan	9	12:06:50s -0:06:50 -
    -Rule	sol88	1988	only	-	Jan	10	12:07:15s -0:07:15 -
    -Rule	sol88	1988	only	-	Jan	11	12:07:40s -0:07:40 -
    -Rule	sol88	1988	only	-	Jan	12	12:08:05s -0:08:05 -
    -Rule	sol88	1988	only	-	Jan	13	12:08:25s -0:08:25 -
    -Rule	sol88	1988	only	-	Jan	14	12:08:50s -0:08:50 -
    -Rule	sol88	1988	only	-	Jan	15	12:09:10s -0:09:10 -
    -Rule	sol88	1988	only	-	Jan	16	12:09:30s -0:09:30 -
    -Rule	sol88	1988	only	-	Jan	17	12:09:50s -0:09:50 -
    -Rule	sol88	1988	only	-	Jan	18	12:10:10s -0:10:10 -
    -Rule	sol88	1988	only	-	Jan	19	12:10:30s -0:10:30 -
    -Rule	sol88	1988	only	-	Jan	20	12:10:50s -0:10:50 -
    -Rule	sol88	1988	only	-	Jan	21	12:11:05s -0:11:05 -
    -Rule	sol88	1988	only	-	Jan	22	12:11:25s -0:11:25 -
    -Rule	sol88	1988	only	-	Jan	23	12:11:40s -0:11:40 -
    -Rule	sol88	1988	only	-	Jan	24	12:11:55s -0:11:55 -
    -Rule	sol88	1988	only	-	Jan	25	12:12:10s -0:12:10 -
    -Rule	sol88	1988	only	-	Jan	26	12:12:25s -0:12:25 -
    -Rule	sol88	1988	only	-	Jan	27	12:12:40s -0:12:40 -
    -Rule	sol88	1988	only	-	Jan	28	12:12:50s -0:12:50 -
    -Rule	sol88	1988	only	-	Jan	29	12:13:00s -0:13:00 -
    -Rule	sol88	1988	only	-	Jan	30	12:13:10s -0:13:10 -
    -Rule	sol88	1988	only	-	Jan	31	12:13:20s -0:13:20 -
    -Rule	sol88	1988	only	-	Feb	1	12:13:30s -0:13:30 -
    -Rule	sol88	1988	only	-	Feb	2	12:13:40s -0:13:40 -
    -Rule	sol88	1988	only	-	Feb	3	12:13:45s -0:13:45 -
    -Rule	sol88	1988	only	-	Feb	4	12:13:55s -0:13:55 -
    -Rule	sol88	1988	only	-	Feb	5	12:14:00s -0:14:00 -
    -Rule	sol88	1988	only	-	Feb	6	12:14:05s -0:14:05 -
    -Rule	sol88	1988	only	-	Feb	7	12:14:10s -0:14:10 -
    -Rule	sol88	1988	only	-	Feb	8	12:14:10s -0:14:10 -
    -Rule	sol88	1988	only	-	Feb	9	12:14:15s -0:14:15 -
    -Rule	sol88	1988	only	-	Feb	10	12:14:15s -0:14:15 -
    -Rule	sol88	1988	only	-	Feb	11	12:14:15s -0:14:15 -
    -Rule	sol88	1988	only	-	Feb	12	12:14:15s -0:14:15 -
    -Rule	sol88	1988	only	-	Feb	13	12:14:15s -0:14:15 -
    -Rule	sol88	1988	only	-	Feb	14	12:14:15s -0:14:15 -
    -Rule	sol88	1988	only	-	Feb	15	12:14:10s -0:14:10 -
    -Rule	sol88	1988	only	-	Feb	16	12:14:10s -0:14:10 -
    -Rule	sol88	1988	only	-	Feb	17	12:14:05s -0:14:05 -
    -Rule	sol88	1988	only	-	Feb	18	12:14:00s -0:14:00 -
    -Rule	sol88	1988	only	-	Feb	19	12:13:55s -0:13:55 -
    -Rule	sol88	1988	only	-	Feb	20	12:13:50s -0:13:50 -
    -Rule	sol88	1988	only	-	Feb	21	12:13:45s -0:13:45 -
    -Rule	sol88	1988	only	-	Feb	22	12:13:40s -0:13:40 -
    -Rule	sol88	1988	only	-	Feb	23	12:13:30s -0:13:30 -
    -Rule	sol88	1988	only	-	Feb	24	12:13:20s -0:13:20 -
    -Rule	sol88	1988	only	-	Feb	25	12:13:15s -0:13:15 -
    -Rule	sol88	1988	only	-	Feb	26	12:13:05s -0:13:05 -
    -Rule	sol88	1988	only	-	Feb	27	12:12:55s -0:12:55 -
    -Rule	sol88	1988	only	-	Feb	28	12:12:45s -0:12:45 -
    -Rule	sol88	1988	only	-	Feb	29	12:12:30s -0:12:30 -
    -Rule	sol88	1988	only	-	Mar	1	12:12:20s -0:12:20 -
    -Rule	sol88	1988	only	-	Mar	2	12:12:10s -0:12:10 -
    -Rule	sol88	1988	only	-	Mar	3	12:11:55s -0:11:55 -
    -Rule	sol88	1988	only	-	Mar	4	12:11:45s -0:11:45 -
    -Rule	sol88	1988	only	-	Mar	5	12:11:30s -0:11:30 -
    -Rule	sol88	1988	only	-	Mar	6	12:11:15s -0:11:15 -
    -Rule	sol88	1988	only	-	Mar	7	12:11:00s -0:11:00 -
    -Rule	sol88	1988	only	-	Mar	8	12:10:45s -0:10:45 -
    -Rule	sol88	1988	only	-	Mar	9	12:10:30s -0:10:30 -
    -Rule	sol88	1988	only	-	Mar	10	12:10:15s -0:10:15 -
    -Rule	sol88	1988	only	-	Mar	11	12:10:00s -0:10:00 -
    -Rule	sol88	1988	only	-	Mar	12	12:09:45s -0:09:45 -
    -Rule	sol88	1988	only	-	Mar	13	12:09:30s -0:09:30 -
    -Rule	sol88	1988	only	-	Mar	14	12:09:10s -0:09:10 -
    -Rule	sol88	1988	only	-	Mar	15	12:08:55s -0:08:55 -
    -Rule	sol88	1988	only	-	Mar	16	12:08:40s -0:08:40 -
    -Rule	sol88	1988	only	-	Mar	17	12:08:20s -0:08:20 -
    -Rule	sol88	1988	only	-	Mar	18	12:08:05s -0:08:05 -
    -Rule	sol88	1988	only	-	Mar	19	12:07:45s -0:07:45 -
    -Rule	sol88	1988	only	-	Mar	20	12:07:30s -0:07:30 -
    -Rule	sol88	1988	only	-	Mar	21	12:07:10s -0:07:10 -
    -Rule	sol88	1988	only	-	Mar	22	12:06:50s -0:06:50 -
    -Rule	sol88	1988	only	-	Mar	23	12:06:35s -0:06:35 -
    -Rule	sol88	1988	only	-	Mar	24	12:06:15s -0:06:15 -
    -Rule	sol88	1988	only	-	Mar	25	12:06:00s -0:06:00 -
    -Rule	sol88	1988	only	-	Mar	26	12:05:40s -0:05:40 -
    -Rule	sol88	1988	only	-	Mar	27	12:05:20s -0:05:20 -
    -Rule	sol88	1988	only	-	Mar	28	12:05:05s -0:05:05 -
    -Rule	sol88	1988	only	-	Mar	29	12:04:45s -0:04:45 -
    -Rule	sol88	1988	only	-	Mar	30	12:04:25s -0:04:25 -
    -Rule	sol88	1988	only	-	Mar	31	12:04:10s -0:04:10 -
    -Rule	sol88	1988	only	-	Apr	1	12:03:50s -0:03:50 -
    -Rule	sol88	1988	only	-	Apr	2	12:03:35s -0:03:35 -
    -Rule	sol88	1988	only	-	Apr	3	12:03:15s -0:03:15 -
    -Rule	sol88	1988	only	-	Apr	4	12:03:00s -0:03:00 -
    -Rule	sol88	1988	only	-	Apr	5	12:02:40s -0:02:40 -
    -Rule	sol88	1988	only	-	Apr	6	12:02:25s -0:02:25 -
    -Rule	sol88	1988	only	-	Apr	7	12:02:05s -0:02:05 -
    -Rule	sol88	1988	only	-	Apr	8	12:01:50s -0:01:50 -
    -Rule	sol88	1988	only	-	Apr	9	12:01:35s -0:01:35 -
    -Rule	sol88	1988	only	-	Apr	10	12:01:15s -0:01:15 -
    -Rule	sol88	1988	only	-	Apr	11	12:01:00s -0:01:00 -
    -Rule	sol88	1988	only	-	Apr	12	12:00:45s -0:00:45 -
    -Rule	sol88	1988	only	-	Apr	13	12:00:30s -0:00:30 -
    -Rule	sol88	1988	only	-	Apr	14	12:00:15s -0:00:15 -
    -Rule	sol88	1988	only	-	Apr	15	12:00:00s 0:00:00 -
    -Rule	sol88	1988	only	-	Apr	16	11:59:45s 0:00:15 -
    -Rule	sol88	1988	only	-	Apr	17	11:59:30s 0:00:30 -
    -Rule	sol88	1988	only	-	Apr	18	11:59:20s 0:00:40 -
    -Rule	sol88	1988	only	-	Apr	19	11:59:05s 0:00:55 -
    -Rule	sol88	1988	only	-	Apr	20	11:58:55s 0:01:05 -
    -Rule	sol88	1988	only	-	Apr	21	11:58:40s 0:01:20 -
    -Rule	sol88	1988	only	-	Apr	22	11:58:30s 0:01:30 -
    -Rule	sol88	1988	only	-	Apr	23	11:58:15s 0:01:45 -
    -Rule	sol88	1988	only	-	Apr	24	11:58:05s 0:01:55 -
    -Rule	sol88	1988	only	-	Apr	25	11:57:55s 0:02:05 -
    -Rule	sol88	1988	only	-	Apr	26	11:57:45s 0:02:15 -
    -Rule	sol88	1988	only	-	Apr	27	11:57:35s 0:02:25 -
    -Rule	sol88	1988	only	-	Apr	28	11:57:30s 0:02:30 -
    -Rule	sol88	1988	only	-	Apr	29	11:57:20s 0:02:40 -
    -Rule	sol88	1988	only	-	Apr	30	11:57:10s 0:02:50 -
    -Rule	sol88	1988	only	-	May	1	11:57:05s 0:02:55 -
    -Rule	sol88	1988	only	-	May	2	11:56:55s 0:03:05 -
    -Rule	sol88	1988	only	-	May	3	11:56:50s 0:03:10 -
    -Rule	sol88	1988	only	-	May	4	11:56:45s 0:03:15 -
    -Rule	sol88	1988	only	-	May	5	11:56:40s 0:03:20 -
    -Rule	sol88	1988	only	-	May	6	11:56:35s 0:03:25 -
    -Rule	sol88	1988	only	-	May	7	11:56:30s 0:03:30 -
    -Rule	sol88	1988	only	-	May	8	11:56:25s 0:03:35 -
    -Rule	sol88	1988	only	-	May	9	11:56:25s 0:03:35 -
    -Rule	sol88	1988	only	-	May	10	11:56:20s 0:03:40 -
    -Rule	sol88	1988	only	-	May	11	11:56:20s 0:03:40 -
    -Rule	sol88	1988	only	-	May	12	11:56:20s 0:03:40 -
    -Rule	sol88	1988	only	-	May	13	11:56:20s 0:03:40 -
    -Rule	sol88	1988	only	-	May	14	11:56:20s 0:03:40 -
    -Rule	sol88	1988	only	-	May	15	11:56:20s 0:03:40 -
    -Rule	sol88	1988	only	-	May	16	11:56:20s 0:03:40 -
    -Rule	sol88	1988	only	-	May	17	11:56:20s 0:03:40 -
    -Rule	sol88	1988	only	-	May	18	11:56:25s 0:03:35 -
    -Rule	sol88	1988	only	-	May	19	11:56:25s 0:03:35 -
    -Rule	sol88	1988	only	-	May	20	11:56:30s 0:03:30 -
    -Rule	sol88	1988	only	-	May	21	11:56:35s 0:03:25 -
    -Rule	sol88	1988	only	-	May	22	11:56:40s 0:03:20 -
    -Rule	sol88	1988	only	-	May	23	11:56:45s 0:03:15 -
    -Rule	sol88	1988	only	-	May	24	11:56:50s 0:03:10 -
    -Rule	sol88	1988	only	-	May	25	11:56:55s 0:03:05 -
    -Rule	sol88	1988	only	-	May	26	11:57:00s 0:03:00 -
    -Rule	sol88	1988	only	-	May	27	11:57:05s 0:02:55 -
    -Rule	sol88	1988	only	-	May	28	11:57:15s 0:02:45 -
    -Rule	sol88	1988	only	-	May	29	11:57:20s 0:02:40 -
    -Rule	sol88	1988	only	-	May	30	11:57:30s 0:02:30 -
    -Rule	sol88	1988	only	-	May	31	11:57:40s 0:02:20 -
    -Rule	sol88	1988	only	-	Jun	1	11:57:50s 0:02:10 -
    -Rule	sol88	1988	only	-	Jun	2	11:57:55s 0:02:05 -
    -Rule	sol88	1988	only	-	Jun	3	11:58:05s 0:01:55 -
    -Rule	sol88	1988	only	-	Jun	4	11:58:15s 0:01:45 -
    -Rule	sol88	1988	only	-	Jun	5	11:58:30s 0:01:30 -
    -Rule	sol88	1988	only	-	Jun	6	11:58:40s 0:01:20 -
    -Rule	sol88	1988	only	-	Jun	7	11:58:50s 0:01:10 -
    -Rule	sol88	1988	only	-	Jun	8	11:59:00s 0:01:00 -
    -Rule	sol88	1988	only	-	Jun	9	11:59:15s 0:00:45 -
    -Rule	sol88	1988	only	-	Jun	10	11:59:25s 0:00:35 -
    -Rule	sol88	1988	only	-	Jun	11	11:59:35s 0:00:25 -
    -Rule	sol88	1988	only	-	Jun	12	11:59:50s 0:00:10 -
    -Rule	sol88	1988	only	-	Jun	13	12:00:00s 0:00:00 -
    -Rule	sol88	1988	only	-	Jun	14	12:00:15s -0:00:15 -
    -Rule	sol88	1988	only	-	Jun	15	12:00:25s -0:00:25 -
    -Rule	sol88	1988	only	-	Jun	16	12:00:40s -0:00:40 -
    -Rule	sol88	1988	only	-	Jun	17	12:00:55s -0:00:55 -
    -Rule	sol88	1988	only	-	Jun	18	12:01:05s -0:01:05 -
    -Rule	sol88	1988	only	-	Jun	19	12:01:20s -0:01:20 -
    -Rule	sol88	1988	only	-	Jun	20	12:01:30s -0:01:30 -
    -Rule	sol88	1988	only	-	Jun	21	12:01:45s -0:01:45 -
    -Rule	sol88	1988	only	-	Jun	22	12:02:00s -0:02:00 -
    -Rule	sol88	1988	only	-	Jun	23	12:02:10s -0:02:10 -
    -Rule	sol88	1988	only	-	Jun	24	12:02:25s -0:02:25 -
    -Rule	sol88	1988	only	-	Jun	25	12:02:35s -0:02:35 -
    -Rule	sol88	1988	only	-	Jun	26	12:02:50s -0:02:50 -
    -Rule	sol88	1988	only	-	Jun	27	12:03:00s -0:03:00 -
    -Rule	sol88	1988	only	-	Jun	28	12:03:15s -0:03:15 -
    -Rule	sol88	1988	only	-	Jun	29	12:03:25s -0:03:25 -
    -Rule	sol88	1988	only	-	Jun	30	12:03:40s -0:03:40 -
    -Rule	sol88	1988	only	-	Jul	1	12:03:50s -0:03:50 -
    -Rule	sol88	1988	only	-	Jul	2	12:04:00s -0:04:00 -
    -Rule	sol88	1988	only	-	Jul	3	12:04:10s -0:04:10 -
    -Rule	sol88	1988	only	-	Jul	4	12:04:25s -0:04:25 -
    -Rule	sol88	1988	only	-	Jul	5	12:04:35s -0:04:35 -
    -Rule	sol88	1988	only	-	Jul	6	12:04:45s -0:04:45 -
    -Rule	sol88	1988	only	-	Jul	7	12:04:55s -0:04:55 -
    -Rule	sol88	1988	only	-	Jul	8	12:05:05s -0:05:05 -
    -Rule	sol88	1988	only	-	Jul	9	12:05:10s -0:05:10 -
    -Rule	sol88	1988	only	-	Jul	10	12:05:20s -0:05:20 -
    -Rule	sol88	1988	only	-	Jul	11	12:05:30s -0:05:30 -
    -Rule	sol88	1988	only	-	Jul	12	12:05:35s -0:05:35 -
    -Rule	sol88	1988	only	-	Jul	13	12:05:45s -0:05:45 -
    -Rule	sol88	1988	only	-	Jul	14	12:05:50s -0:05:50 -
    -Rule	sol88	1988	only	-	Jul	15	12:05:55s -0:05:55 -
    -Rule	sol88	1988	only	-	Jul	16	12:06:00s -0:06:00 -
    -Rule	sol88	1988	only	-	Jul	17	12:06:05s -0:06:05 -
    -Rule	sol88	1988	only	-	Jul	18	12:06:10s -0:06:10 -
    -Rule	sol88	1988	only	-	Jul	19	12:06:15s -0:06:15 -
    -Rule	sol88	1988	only	-	Jul	20	12:06:20s -0:06:20 -
    -Rule	sol88	1988	only	-	Jul	21	12:06:25s -0:06:25 -
    -Rule	sol88	1988	only	-	Jul	22	12:06:25s -0:06:25 -
    -Rule	sol88	1988	only	-	Jul	23	12:06:25s -0:06:25 -
    -Rule	sol88	1988	only	-	Jul	24	12:06:30s -0:06:30 -
    -Rule	sol88	1988	only	-	Jul	25	12:06:30s -0:06:30 -
    -Rule	sol88	1988	only	-	Jul	26	12:06:30s -0:06:30 -
    -Rule	sol88	1988	only	-	Jul	27	12:06:30s -0:06:30 -
    -Rule	sol88	1988	only	-	Jul	28	12:06:30s -0:06:30 -
    -Rule	sol88	1988	only	-	Jul	29	12:06:25s -0:06:25 -
    -Rule	sol88	1988	only	-	Jul	30	12:06:25s -0:06:25 -
    -Rule	sol88	1988	only	-	Jul	31	12:06:20s -0:06:20 -
    -Rule	sol88	1988	only	-	Aug	1	12:06:15s -0:06:15 -
    -Rule	sol88	1988	only	-	Aug	2	12:06:15s -0:06:15 -
    -Rule	sol88	1988	only	-	Aug	3	12:06:10s -0:06:10 -
    -Rule	sol88	1988	only	-	Aug	4	12:06:05s -0:06:05 -
    -Rule	sol88	1988	only	-	Aug	5	12:05:55s -0:05:55 -
    -Rule	sol88	1988	only	-	Aug	6	12:05:50s -0:05:50 -
    -Rule	sol88	1988	only	-	Aug	7	12:05:45s -0:05:45 -
    -Rule	sol88	1988	only	-	Aug	8	12:05:35s -0:05:35 -
    -Rule	sol88	1988	only	-	Aug	9	12:05:25s -0:05:25 -
    -Rule	sol88	1988	only	-	Aug	10	12:05:20s -0:05:20 -
    -Rule	sol88	1988	only	-	Aug	11	12:05:10s -0:05:10 -
    -Rule	sol88	1988	only	-	Aug	12	12:05:00s -0:05:00 -
    -Rule	sol88	1988	only	-	Aug	13	12:04:50s -0:04:50 -
    -Rule	sol88	1988	only	-	Aug	14	12:04:35s -0:04:35 -
    -Rule	sol88	1988	only	-	Aug	15	12:04:25s -0:04:25 -
    -Rule	sol88	1988	only	-	Aug	16	12:04:15s -0:04:15 -
    -Rule	sol88	1988	only	-	Aug	17	12:04:00s -0:04:00 -
    -Rule	sol88	1988	only	-	Aug	18	12:03:50s -0:03:50 -
    -Rule	sol88	1988	only	-	Aug	19	12:03:35s -0:03:35 -
    -Rule	sol88	1988	only	-	Aug	20	12:03:20s -0:03:20 -
    -Rule	sol88	1988	only	-	Aug	21	12:03:05s -0:03:05 -
    -Rule	sol88	1988	only	-	Aug	22	12:02:50s -0:02:50 -
    -Rule	sol88	1988	only	-	Aug	23	12:02:35s -0:02:35 -
    -Rule	sol88	1988	only	-	Aug	24	12:02:20s -0:02:20 -
    -Rule	sol88	1988	only	-	Aug	25	12:02:00s -0:02:00 -
    -Rule	sol88	1988	only	-	Aug	26	12:01:45s -0:01:45 -
    -Rule	sol88	1988	only	-	Aug	27	12:01:30s -0:01:30 -
    -Rule	sol88	1988	only	-	Aug	28	12:01:10s -0:01:10 -
    -Rule	sol88	1988	only	-	Aug	29	12:00:50s -0:00:50 -
    -Rule	sol88	1988	only	-	Aug	30	12:00:35s -0:00:35 -
    -Rule	sol88	1988	only	-	Aug	31	12:00:15s -0:00:15 -
    -Rule	sol88	1988	only	-	Sep	1	11:59:55s 0:00:05 -
    -Rule	sol88	1988	only	-	Sep	2	11:59:35s 0:00:25 -
    -Rule	sol88	1988	only	-	Sep	3	11:59:20s 0:00:40 -
    -Rule	sol88	1988	only	-	Sep	4	11:59:00s 0:01:00 -
    -Rule	sol88	1988	only	-	Sep	5	11:58:40s 0:01:20 -
    -Rule	sol88	1988	only	-	Sep	6	11:58:20s 0:01:40 -
    -Rule	sol88	1988	only	-	Sep	7	11:58:00s 0:02:00 -
    -Rule	sol88	1988	only	-	Sep	8	11:57:35s 0:02:25 -
    -Rule	sol88	1988	only	-	Sep	9	11:57:15s 0:02:45 -
    -Rule	sol88	1988	only	-	Sep	10	11:56:55s 0:03:05 -
    -Rule	sol88	1988	only	-	Sep	11	11:56:35s 0:03:25 -
    -Rule	sol88	1988	only	-	Sep	12	11:56:15s 0:03:45 -
    -Rule	sol88	1988	only	-	Sep	13	11:55:50s 0:04:10 -
    -Rule	sol88	1988	only	-	Sep	14	11:55:30s 0:04:30 -
    -Rule	sol88	1988	only	-	Sep	15	11:55:10s 0:04:50 -
    -Rule	sol88	1988	only	-	Sep	16	11:54:50s 0:05:10 -
    -Rule	sol88	1988	only	-	Sep	17	11:54:25s 0:05:35 -
    -Rule	sol88	1988	only	-	Sep	18	11:54:05s 0:05:55 -
    -Rule	sol88	1988	only	-	Sep	19	11:53:45s 0:06:15 -
    -Rule	sol88	1988	only	-	Sep	20	11:53:25s 0:06:35 -
    -Rule	sol88	1988	only	-	Sep	21	11:53:00s 0:07:00 -
    -Rule	sol88	1988	only	-	Sep	22	11:52:40s 0:07:20 -
    -Rule	sol88	1988	only	-	Sep	23	11:52:20s 0:07:40 -
    -Rule	sol88	1988	only	-	Sep	24	11:52:00s 0:08:00 -
    -Rule	sol88	1988	only	-	Sep	25	11:51:40s 0:08:20 -
    -Rule	sol88	1988	only	-	Sep	26	11:51:15s 0:08:45 -
    -Rule	sol88	1988	only	-	Sep	27	11:50:55s 0:09:05 -
    -Rule	sol88	1988	only	-	Sep	28	11:50:35s 0:09:25 -
    -Rule	sol88	1988	only	-	Sep	29	11:50:15s 0:09:45 -
    -Rule	sol88	1988	only	-	Sep	30	11:49:55s 0:10:05 -
    -Rule	sol88	1988	only	-	Oct	1	11:49:35s 0:10:25 -
    -Rule	sol88	1988	only	-	Oct	2	11:49:20s 0:10:40 -
    -Rule	sol88	1988	only	-	Oct	3	11:49:00s 0:11:00 -
    -Rule	sol88	1988	only	-	Oct	4	11:48:40s 0:11:20 -
    -Rule	sol88	1988	only	-	Oct	5	11:48:25s 0:11:35 -
    -Rule	sol88	1988	only	-	Oct	6	11:48:05s 0:11:55 -
    -Rule	sol88	1988	only	-	Oct	7	11:47:50s 0:12:10 -
    -Rule	sol88	1988	only	-	Oct	8	11:47:30s 0:12:30 -
    -Rule	sol88	1988	only	-	Oct	9	11:47:15s 0:12:45 -
    -Rule	sol88	1988	only	-	Oct	10	11:47:00s 0:13:00 -
    -Rule	sol88	1988	only	-	Oct	11	11:46:45s 0:13:15 -
    -Rule	sol88	1988	only	-	Oct	12	11:46:30s 0:13:30 -
    -Rule	sol88	1988	only	-	Oct	13	11:46:15s 0:13:45 -
    -Rule	sol88	1988	only	-	Oct	14	11:46:00s 0:14:00 -
    -Rule	sol88	1988	only	-	Oct	15	11:45:45s 0:14:15 -
    -Rule	sol88	1988	only	-	Oct	16	11:45:35s 0:14:25 -
    -Rule	sol88	1988	only	-	Oct	17	11:45:20s 0:14:40 -
    -Rule	sol88	1988	only	-	Oct	18	11:45:10s 0:14:50 -
    -Rule	sol88	1988	only	-	Oct	19	11:45:00s 0:15:00 -
    -Rule	sol88	1988	only	-	Oct	20	11:44:45s 0:15:15 -
    -Rule	sol88	1988	only	-	Oct	21	11:44:40s 0:15:20 -
    -Rule	sol88	1988	only	-	Oct	22	11:44:30s 0:15:30 -
    -Rule	sol88	1988	only	-	Oct	23	11:44:20s 0:15:40 -
    -Rule	sol88	1988	only	-	Oct	24	11:44:10s 0:15:50 -
    -Rule	sol88	1988	only	-	Oct	25	11:44:05s 0:15:55 -
    -Rule	sol88	1988	only	-	Oct	26	11:44:00s 0:16:00 -
    -Rule	sol88	1988	only	-	Oct	27	11:43:55s 0:16:05 -
    -Rule	sol88	1988	only	-	Oct	28	11:43:50s 0:16:10 -
    -Rule	sol88	1988	only	-	Oct	29	11:43:45s 0:16:15 -
    -Rule	sol88	1988	only	-	Oct	30	11:43:40s 0:16:20 -
    -Rule	sol88	1988	only	-	Oct	31	11:43:40s 0:16:20 -
    -Rule	sol88	1988	only	-	Nov	1	11:43:35s 0:16:25 -
    -Rule	sol88	1988	only	-	Nov	2	11:43:35s 0:16:25 -
    -Rule	sol88	1988	only	-	Nov	3	11:43:35s 0:16:25 -
    -Rule	sol88	1988	only	-	Nov	4	11:43:35s 0:16:25 -
    -Rule	sol88	1988	only	-	Nov	5	11:43:40s 0:16:20 -
    -Rule	sol88	1988	only	-	Nov	6	11:43:40s 0:16:20 -
    -Rule	sol88	1988	only	-	Nov	7	11:43:45s 0:16:15 -
    -Rule	sol88	1988	only	-	Nov	8	11:43:45s 0:16:15 -
    -Rule	sol88	1988	only	-	Nov	9	11:43:50s 0:16:10 -
    -Rule	sol88	1988	only	-	Nov	10	11:44:00s 0:16:00 -
    -Rule	sol88	1988	only	-	Nov	11	11:44:05s 0:15:55 -
    -Rule	sol88	1988	only	-	Nov	12	11:44:10s 0:15:50 -
    -Rule	sol88	1988	only	-	Nov	13	11:44:20s 0:15:40 -
    -Rule	sol88	1988	only	-	Nov	14	11:44:30s 0:15:30 -
    -Rule	sol88	1988	only	-	Nov	15	11:44:40s 0:15:20 -
    -Rule	sol88	1988	only	-	Nov	16	11:44:50s 0:15:10 -
    -Rule	sol88	1988	only	-	Nov	17	11:45:00s 0:15:00 -
    -Rule	sol88	1988	only	-	Nov	18	11:45:15s 0:14:45 -
    -Rule	sol88	1988	only	-	Nov	19	11:45:25s 0:14:35 -
    -Rule	sol88	1988	only	-	Nov	20	11:45:40s 0:14:20 -
    -Rule	sol88	1988	only	-	Nov	21	11:45:55s 0:14:05 -
    -Rule	sol88	1988	only	-	Nov	22	11:46:10s 0:13:50 -
    -Rule	sol88	1988	only	-	Nov	23	11:46:30s 0:13:30 -
    -Rule	sol88	1988	only	-	Nov	24	11:46:45s 0:13:15 -
    -Rule	sol88	1988	only	-	Nov	25	11:47:05s 0:12:55 -
    -Rule	sol88	1988	only	-	Nov	26	11:47:20s 0:12:40 -
    -Rule	sol88	1988	only	-	Nov	27	11:47:40s 0:12:20 -
    -Rule	sol88	1988	only	-	Nov	28	11:48:00s 0:12:00 -
    -Rule	sol88	1988	only	-	Nov	29	11:48:25s 0:11:35 -
    -Rule	sol88	1988	only	-	Nov	30	11:48:45s 0:11:15 -
    -Rule	sol88	1988	only	-	Dec	1	11:49:05s 0:10:55 -
    -Rule	sol88	1988	only	-	Dec	2	11:49:30s 0:10:30 -
    -Rule	sol88	1988	only	-	Dec	3	11:49:55s 0:10:05 -
    -Rule	sol88	1988	only	-	Dec	4	11:50:15s 0:09:45 -
    -Rule	sol88	1988	only	-	Dec	5	11:50:40s 0:09:20 -
    -Rule	sol88	1988	only	-	Dec	6	11:51:05s 0:08:55 -
    -Rule	sol88	1988	only	-	Dec	7	11:51:35s 0:08:25 -
    -Rule	sol88	1988	only	-	Dec	8	11:52:00s 0:08:00 -
    -Rule	sol88	1988	only	-	Dec	9	11:52:25s 0:07:35 -
    -Rule	sol88	1988	only	-	Dec	10	11:52:55s 0:07:05 -
    -Rule	sol88	1988	only	-	Dec	11	11:53:20s 0:06:40 -
    -Rule	sol88	1988	only	-	Dec	12	11:53:50s 0:06:10 -
    -Rule	sol88	1988	only	-	Dec	13	11:54:15s 0:05:45 -
    -Rule	sol88	1988	only	-	Dec	14	11:54:45s 0:05:15 -
    -Rule	sol88	1988	only	-	Dec	15	11:55:15s 0:04:45 -
    -Rule	sol88	1988	only	-	Dec	16	11:55:45s 0:04:15 -
    -Rule	sol88	1988	only	-	Dec	17	11:56:15s 0:03:45 -
    -Rule	sol88	1988	only	-	Dec	18	11:56:40s 0:03:20 -
    -Rule	sol88	1988	only	-	Dec	19	11:57:10s 0:02:50 -
    -Rule	sol88	1988	only	-	Dec	20	11:57:40s 0:02:20 -
    -Rule	sol88	1988	only	-	Dec	21	11:58:10s 0:01:50 -
    -Rule	sol88	1988	only	-	Dec	22	11:58:40s 0:01:20 -
    -Rule	sol88	1988	only	-	Dec	23	11:59:10s 0:00:50 -
    -Rule	sol88	1988	only	-	Dec	24	11:59:40s 0:00:20 -
    -Rule	sol88	1988	only	-	Dec	25	12:00:10s -0:00:10 -
    -Rule	sol88	1988	only	-	Dec	26	12:00:40s -0:00:40 -
    -Rule	sol88	1988	only	-	Dec	27	12:01:10s -0:01:10 -
    -Rule	sol88	1988	only	-	Dec	28	12:01:40s -0:01:40 -
    -Rule	sol88	1988	only	-	Dec	29	12:02:10s -0:02:10 -
    -Rule	sol88	1988	only	-	Dec	30	12:02:35s -0:02:35 -
    -Rule	sol88	1988	only	-	Dec	31	12:03:05s -0:03:05 -
    -
    -# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
    -# Before and after 1988, we'll operate on local mean solar time.
    -
    -# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
    -Zone	Asia/Riyadh88	3:07:04	-		zzz	1988
    -			3:07:04	sol88		zzz	1989
    -			3:07:04	-		zzz
    -# For backward compatibility...
    -Link	Asia/Riyadh88	Mideast/Riyadh88
    diff --git a/src/java.base/share/data/tzdata/solar89 b/src/java.base/share/data/tzdata/solar89
    deleted file mode 100644
    index 3aa88cf0893b8..0000000000000
    --- a/src/java.base/share/data/tzdata/solar89
    +++ /dev/null
    @@ -1,418 +0,0 @@
    -#
    -# 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.
    -#
    -# 
    -# This file is in the public domain, so clarified as of
    -# 2009-05-17 by Arthur David Olson.
    -
    -# Apparent noon times below are for Riyadh; they're a bit off for other places.
    -# Times were computed using a formula provided by the U. S. Naval Observatory:
    -#	eqt = -105.8 * sin(l) + 596.2 * sin(2 * l) + 4.4 * sin(3 * l)
    -#		-12.7 * sin(4 * l) - 429.0 * cos(l) - 2.1 * cos (2 * l)
    -#		+ 19.3 * cos(3 * l);
    -# where l is the "mean longitude of the Sun" given by
    -#	l = 279.642 degrees + 0.985647 * d
    -# and d is the interval in days from January 0, 0 hours Universal Time
    -# (equaling the day of the year plus the fraction of a day from zero hours).
    -# The accuracy of the formula is plus or minus three seconds.
    -#
    -# Rounding to the nearest five seconds results in fewer than
    -# 256 different "time types"--a limit that's faced because time types are
    -# stored on disk as unsigned chars.
    -
    -# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
    -Rule	sol89	1989	only	-	Jan	1	12:03:35s -0:03:35 -
    -Rule	sol89	1989	only	-	Jan	2	12:04:05s -0:04:05 -
    -Rule	sol89	1989	only	-	Jan	3	12:04:30s -0:04:30 -
    -Rule	sol89	1989	only	-	Jan	4	12:05:00s -0:05:00 -
    -Rule	sol89	1989	only	-	Jan	5	12:05:25s -0:05:25 -
    -Rule	sol89	1989	only	-	Jan	6	12:05:50s -0:05:50 -
    -Rule	sol89	1989	only	-	Jan	7	12:06:15s -0:06:15 -
    -Rule	sol89	1989	only	-	Jan	8	12:06:45s -0:06:45 -
    -Rule	sol89	1989	only	-	Jan	9	12:07:10s -0:07:10 -
    -Rule	sol89	1989	only	-	Jan	10	12:07:35s -0:07:35 -
    -Rule	sol89	1989	only	-	Jan	11	12:07:55s -0:07:55 -
    -Rule	sol89	1989	only	-	Jan	12	12:08:20s -0:08:20 -
    -Rule	sol89	1989	only	-	Jan	13	12:08:45s -0:08:45 -
    -Rule	sol89	1989	only	-	Jan	14	12:09:05s -0:09:05 -
    -Rule	sol89	1989	only	-	Jan	15	12:09:25s -0:09:25 -
    -Rule	sol89	1989	only	-	Jan	16	12:09:45s -0:09:45 -
    -Rule	sol89	1989	only	-	Jan	17	12:10:05s -0:10:05 -
    -Rule	sol89	1989	only	-	Jan	18	12:10:25s -0:10:25 -
    -Rule	sol89	1989	only	-	Jan	19	12:10:45s -0:10:45 -
    -Rule	sol89	1989	only	-	Jan	20	12:11:05s -0:11:05 -
    -Rule	sol89	1989	only	-	Jan	21	12:11:20s -0:11:20 -
    -Rule	sol89	1989	only	-	Jan	22	12:11:35s -0:11:35 -
    -Rule	sol89	1989	only	-	Jan	23	12:11:55s -0:11:55 -
    -Rule	sol89	1989	only	-	Jan	24	12:12:10s -0:12:10 -
    -Rule	sol89	1989	only	-	Jan	25	12:12:20s -0:12:20 -
    -Rule	sol89	1989	only	-	Jan	26	12:12:35s -0:12:35 -
    -Rule	sol89	1989	only	-	Jan	27	12:12:50s -0:12:50 -
    -Rule	sol89	1989	only	-	Jan	28	12:13:00s -0:13:00 -
    -Rule	sol89	1989	only	-	Jan	29	12:13:10s -0:13:10 -
    -Rule	sol89	1989	only	-	Jan	30	12:13:20s -0:13:20 -
    -Rule	sol89	1989	only	-	Jan	31	12:13:30s -0:13:30 -
    -Rule	sol89	1989	only	-	Feb	1	12:13:40s -0:13:40 -
    -Rule	sol89	1989	only	-	Feb	2	12:13:45s -0:13:45 -
    -Rule	sol89	1989	only	-	Feb	3	12:13:55s -0:13:55 -
    -Rule	sol89	1989	only	-	Feb	4	12:14:00s -0:14:00 -
    -Rule	sol89	1989	only	-	Feb	5	12:14:05s -0:14:05 -
    -Rule	sol89	1989	only	-	Feb	6	12:14:10s -0:14:10 -
    -Rule	sol89	1989	only	-	Feb	7	12:14:10s -0:14:10 -
    -Rule	sol89	1989	only	-	Feb	8	12:14:15s -0:14:15 -
    -Rule	sol89	1989	only	-	Feb	9	12:14:15s -0:14:15 -
    -Rule	sol89	1989	only	-	Feb	10	12:14:20s -0:14:20 -
    -Rule	sol89	1989	only	-	Feb	11	12:14:20s -0:14:20 -
    -Rule	sol89	1989	only	-	Feb	12	12:14:20s -0:14:20 -
    -Rule	sol89	1989	only	-	Feb	13	12:14:15s -0:14:15 -
    -Rule	sol89	1989	only	-	Feb	14	12:14:15s -0:14:15 -
    -Rule	sol89	1989	only	-	Feb	15	12:14:10s -0:14:10 -
    -Rule	sol89	1989	only	-	Feb	16	12:14:10s -0:14:10 -
    -Rule	sol89	1989	only	-	Feb	17	12:14:05s -0:14:05 -
    -Rule	sol89	1989	only	-	Feb	18	12:14:00s -0:14:00 -
    -Rule	sol89	1989	only	-	Feb	19	12:13:55s -0:13:55 -
    -Rule	sol89	1989	only	-	Feb	20	12:13:50s -0:13:50 -
    -Rule	sol89	1989	only	-	Feb	21	12:13:40s -0:13:40 -
    -Rule	sol89	1989	only	-	Feb	22	12:13:35s -0:13:35 -
    -Rule	sol89	1989	only	-	Feb	23	12:13:25s -0:13:25 -
    -Rule	sol89	1989	only	-	Feb	24	12:13:15s -0:13:15 -
    -Rule	sol89	1989	only	-	Feb	25	12:13:05s -0:13:05 -
    -Rule	sol89	1989	only	-	Feb	26	12:12:55s -0:12:55 -
    -Rule	sol89	1989	only	-	Feb	27	12:12:45s -0:12:45 -
    -Rule	sol89	1989	only	-	Feb	28	12:12:35s -0:12:35 -
    -Rule	sol89	1989	only	-	Mar	1	12:12:25s -0:12:25 -
    -Rule	sol89	1989	only	-	Mar	2	12:12:10s -0:12:10 -
    -Rule	sol89	1989	only	-	Mar	3	12:12:00s -0:12:00 -
    -Rule	sol89	1989	only	-	Mar	4	12:11:45s -0:11:45 -
    -Rule	sol89	1989	only	-	Mar	5	12:11:35s -0:11:35 -
    -Rule	sol89	1989	only	-	Mar	6	12:11:20s -0:11:20 -
    -Rule	sol89	1989	only	-	Mar	7	12:11:05s -0:11:05 -
    -Rule	sol89	1989	only	-	Mar	8	12:10:50s -0:10:50 -
    -Rule	sol89	1989	only	-	Mar	9	12:10:35s -0:10:35 -
    -Rule	sol89	1989	only	-	Mar	10	12:10:20s -0:10:20 -
    -Rule	sol89	1989	only	-	Mar	11	12:10:05s -0:10:05 -
    -Rule	sol89	1989	only	-	Mar	12	12:09:50s -0:09:50 -
    -Rule	sol89	1989	only	-	Mar	13	12:09:30s -0:09:30 -
    -Rule	sol89	1989	only	-	Mar	14	12:09:15s -0:09:15 -
    -Rule	sol89	1989	only	-	Mar	15	12:09:00s -0:09:00 -
    -Rule	sol89	1989	only	-	Mar	16	12:08:40s -0:08:40 -
    -Rule	sol89	1989	only	-	Mar	17	12:08:25s -0:08:25 -
    -Rule	sol89	1989	only	-	Mar	18	12:08:05s -0:08:05 -
    -Rule	sol89	1989	only	-	Mar	19	12:07:50s -0:07:50 -
    -Rule	sol89	1989	only	-	Mar	20	12:07:30s -0:07:30 -
    -Rule	sol89	1989	only	-	Mar	21	12:07:15s -0:07:15 -
    -Rule	sol89	1989	only	-	Mar	22	12:06:55s -0:06:55 -
    -Rule	sol89	1989	only	-	Mar	23	12:06:35s -0:06:35 -
    -Rule	sol89	1989	only	-	Mar	24	12:06:20s -0:06:20 -
    -Rule	sol89	1989	only	-	Mar	25	12:06:00s -0:06:00 -
    -Rule	sol89	1989	only	-	Mar	26	12:05:40s -0:05:40 -
    -Rule	sol89	1989	only	-	Mar	27	12:05:25s -0:05:25 -
    -Rule	sol89	1989	only	-	Mar	28	12:05:05s -0:05:05 -
    -Rule	sol89	1989	only	-	Mar	29	12:04:50s -0:04:50 -
    -Rule	sol89	1989	only	-	Mar	30	12:04:30s -0:04:30 -
    -Rule	sol89	1989	only	-	Mar	31	12:04:10s -0:04:10 -
    -Rule	sol89	1989	only	-	Apr	1	12:03:55s -0:03:55 -
    -Rule	sol89	1989	only	-	Apr	2	12:03:35s -0:03:35 -
    -Rule	sol89	1989	only	-	Apr	3	12:03:20s -0:03:20 -
    -Rule	sol89	1989	only	-	Apr	4	12:03:00s -0:03:00 -
    -Rule	sol89	1989	only	-	Apr	5	12:02:45s -0:02:45 -
    -Rule	sol89	1989	only	-	Apr	6	12:02:25s -0:02:25 -
    -Rule	sol89	1989	only	-	Apr	7	12:02:10s -0:02:10 -
    -Rule	sol89	1989	only	-	Apr	8	12:01:50s -0:01:50 -
    -Rule	sol89	1989	only	-	Apr	9	12:01:35s -0:01:35 -
    -Rule	sol89	1989	only	-	Apr	10	12:01:20s -0:01:20 -
    -Rule	sol89	1989	only	-	Apr	11	12:01:05s -0:01:05 -
    -Rule	sol89	1989	only	-	Apr	12	12:00:50s -0:00:50 -
    -Rule	sol89	1989	only	-	Apr	13	12:00:35s -0:00:35 -
    -Rule	sol89	1989	only	-	Apr	14	12:00:20s -0:00:20 -
    -Rule	sol89	1989	only	-	Apr	15	12:00:05s -0:00:05 -
    -Rule	sol89	1989	only	-	Apr	16	11:59:50s 0:00:10 -
    -Rule	sol89	1989	only	-	Apr	17	11:59:35s 0:00:25 -
    -Rule	sol89	1989	only	-	Apr	18	11:59:20s 0:00:40 -
    -Rule	sol89	1989	only	-	Apr	19	11:59:10s 0:00:50 -
    -Rule	sol89	1989	only	-	Apr	20	11:58:55s 0:01:05 -
    -Rule	sol89	1989	only	-	Apr	21	11:58:45s 0:01:15 -
    -Rule	sol89	1989	only	-	Apr	22	11:58:30s 0:01:30 -
    -Rule	sol89	1989	only	-	Apr	23	11:58:20s 0:01:40 -
    -Rule	sol89	1989	only	-	Apr	24	11:58:10s 0:01:50 -
    -Rule	sol89	1989	only	-	Apr	25	11:58:00s 0:02:00 -
    -Rule	sol89	1989	only	-	Apr	26	11:57:50s 0:02:10 -
    -Rule	sol89	1989	only	-	Apr	27	11:57:40s 0:02:20 -
    -Rule	sol89	1989	only	-	Apr	28	11:57:30s 0:02:30 -
    -Rule	sol89	1989	only	-	Apr	29	11:57:20s 0:02:40 -
    -Rule	sol89	1989	only	-	Apr	30	11:57:15s 0:02:45 -
    -Rule	sol89	1989	only	-	May	1	11:57:05s 0:02:55 -
    -Rule	sol89	1989	only	-	May	2	11:57:00s 0:03:00 -
    -Rule	sol89	1989	only	-	May	3	11:56:50s 0:03:10 -
    -Rule	sol89	1989	only	-	May	4	11:56:45s 0:03:15 -
    -Rule	sol89	1989	only	-	May	5	11:56:40s 0:03:20 -
    -Rule	sol89	1989	only	-	May	6	11:56:35s 0:03:25 -
    -Rule	sol89	1989	only	-	May	7	11:56:30s 0:03:30 -
    -Rule	sol89	1989	only	-	May	8	11:56:30s 0:03:30 -
    -Rule	sol89	1989	only	-	May	9	11:56:25s 0:03:35 -
    -Rule	sol89	1989	only	-	May	10	11:56:25s 0:03:35 -
    -Rule	sol89	1989	only	-	May	11	11:56:20s 0:03:40 -
    -Rule	sol89	1989	only	-	May	12	11:56:20s 0:03:40 -
    -Rule	sol89	1989	only	-	May	13	11:56:20s 0:03:40 -
    -Rule	sol89	1989	only	-	May	14	11:56:20s 0:03:40 -
    -Rule	sol89	1989	only	-	May	15	11:56:20s 0:03:40 -
    -Rule	sol89	1989	only	-	May	16	11:56:20s 0:03:40 -
    -Rule	sol89	1989	only	-	May	17	11:56:20s 0:03:40 -
    -Rule	sol89	1989	only	-	May	18	11:56:25s 0:03:35 -
    -Rule	sol89	1989	only	-	May	19	11:56:25s 0:03:35 -
    -Rule	sol89	1989	only	-	May	20	11:56:30s 0:03:30 -
    -Rule	sol89	1989	only	-	May	21	11:56:35s 0:03:25 -
    -Rule	sol89	1989	only	-	May	22	11:56:35s 0:03:25 -
    -Rule	sol89	1989	only	-	May	23	11:56:40s 0:03:20 -
    -Rule	sol89	1989	only	-	May	24	11:56:45s 0:03:15 -
    -Rule	sol89	1989	only	-	May	25	11:56:55s 0:03:05 -
    -Rule	sol89	1989	only	-	May	26	11:57:00s 0:03:00 -
    -Rule	sol89	1989	only	-	May	27	11:57:05s 0:02:55 -
    -Rule	sol89	1989	only	-	May	28	11:57:15s 0:02:45 -
    -Rule	sol89	1989	only	-	May	29	11:57:20s 0:02:40 -
    -Rule	sol89	1989	only	-	May	30	11:57:30s 0:02:30 -
    -Rule	sol89	1989	only	-	May	31	11:57:35s 0:02:25 -
    -Rule	sol89	1989	only	-	Jun	1	11:57:45s 0:02:15 -
    -Rule	sol89	1989	only	-	Jun	2	11:57:55s 0:02:05 -
    -Rule	sol89	1989	only	-	Jun	3	11:58:05s 0:01:55 -
    -Rule	sol89	1989	only	-	Jun	4	11:58:15s 0:01:45 -
    -Rule	sol89	1989	only	-	Jun	5	11:58:25s 0:01:35 -
    -Rule	sol89	1989	only	-	Jun	6	11:58:35s 0:01:25 -
    -Rule	sol89	1989	only	-	Jun	7	11:58:45s 0:01:15 -
    -Rule	sol89	1989	only	-	Jun	8	11:59:00s 0:01:00 -
    -Rule	sol89	1989	only	-	Jun	9	11:59:10s 0:00:50 -
    -Rule	sol89	1989	only	-	Jun	10	11:59:20s 0:00:40 -
    -Rule	sol89	1989	only	-	Jun	11	11:59:35s 0:00:25 -
    -Rule	sol89	1989	only	-	Jun	12	11:59:45s 0:00:15 -
    -Rule	sol89	1989	only	-	Jun	13	12:00:00s 0:00:00 -
    -Rule	sol89	1989	only	-	Jun	14	12:00:10s -0:00:10 -
    -Rule	sol89	1989	only	-	Jun	15	12:00:25s -0:00:25 -
    -Rule	sol89	1989	only	-	Jun	16	12:00:35s -0:00:35 -
    -Rule	sol89	1989	only	-	Jun	17	12:00:50s -0:00:50 -
    -Rule	sol89	1989	only	-	Jun	18	12:01:05s -0:01:05 -
    -Rule	sol89	1989	only	-	Jun	19	12:01:15s -0:01:15 -
    -Rule	sol89	1989	only	-	Jun	20	12:01:30s -0:01:30 -
    -Rule	sol89	1989	only	-	Jun	21	12:01:40s -0:01:40 -
    -Rule	sol89	1989	only	-	Jun	22	12:01:55s -0:01:55 -
    -Rule	sol89	1989	only	-	Jun	23	12:02:10s -0:02:10 -
    -Rule	sol89	1989	only	-	Jun	24	12:02:20s -0:02:20 -
    -Rule	sol89	1989	only	-	Jun	25	12:02:35s -0:02:35 -
    -Rule	sol89	1989	only	-	Jun	26	12:02:45s -0:02:45 -
    -Rule	sol89	1989	only	-	Jun	27	12:03:00s -0:03:00 -
    -Rule	sol89	1989	only	-	Jun	28	12:03:10s -0:03:10 -
    -Rule	sol89	1989	only	-	Jun	29	12:03:25s -0:03:25 -
    -Rule	sol89	1989	only	-	Jun	30	12:03:35s -0:03:35 -
    -Rule	sol89	1989	only	-	Jul	1	12:03:45s -0:03:45 -
    -Rule	sol89	1989	only	-	Jul	2	12:04:00s -0:04:00 -
    -Rule	sol89	1989	only	-	Jul	3	12:04:10s -0:04:10 -
    -Rule	sol89	1989	only	-	Jul	4	12:04:20s -0:04:20 -
    -Rule	sol89	1989	only	-	Jul	5	12:04:30s -0:04:30 -
    -Rule	sol89	1989	only	-	Jul	6	12:04:40s -0:04:40 -
    -Rule	sol89	1989	only	-	Jul	7	12:04:50s -0:04:50 -
    -Rule	sol89	1989	only	-	Jul	8	12:05:00s -0:05:00 -
    -Rule	sol89	1989	only	-	Jul	9	12:05:10s -0:05:10 -
    -Rule	sol89	1989	only	-	Jul	10	12:05:20s -0:05:20 -
    -Rule	sol89	1989	only	-	Jul	11	12:05:25s -0:05:25 -
    -Rule	sol89	1989	only	-	Jul	12	12:05:35s -0:05:35 -
    -Rule	sol89	1989	only	-	Jul	13	12:05:40s -0:05:40 -
    -Rule	sol89	1989	only	-	Jul	14	12:05:50s -0:05:50 -
    -Rule	sol89	1989	only	-	Jul	15	12:05:55s -0:05:55 -
    -Rule	sol89	1989	only	-	Jul	16	12:06:00s -0:06:00 -
    -Rule	sol89	1989	only	-	Jul	17	12:06:05s -0:06:05 -
    -Rule	sol89	1989	only	-	Jul	18	12:06:10s -0:06:10 -
    -Rule	sol89	1989	only	-	Jul	19	12:06:15s -0:06:15 -
    -Rule	sol89	1989	only	-	Jul	20	12:06:20s -0:06:20 -
    -Rule	sol89	1989	only	-	Jul	21	12:06:20s -0:06:20 -
    -Rule	sol89	1989	only	-	Jul	22	12:06:25s -0:06:25 -
    -Rule	sol89	1989	only	-	Jul	23	12:06:25s -0:06:25 -
    -Rule	sol89	1989	only	-	Jul	24	12:06:30s -0:06:30 -
    -Rule	sol89	1989	only	-	Jul	25	12:06:30s -0:06:30 -
    -Rule	sol89	1989	only	-	Jul	26	12:06:30s -0:06:30 -
    -Rule	sol89	1989	only	-	Jul	27	12:06:30s -0:06:30 -
    -Rule	sol89	1989	only	-	Jul	28	12:06:30s -0:06:30 -
    -Rule	sol89	1989	only	-	Jul	29	12:06:25s -0:06:25 -
    -Rule	sol89	1989	only	-	Jul	30	12:06:25s -0:06:25 -
    -Rule	sol89	1989	only	-	Jul	31	12:06:20s -0:06:20 -
    -Rule	sol89	1989	only	-	Aug	1	12:06:20s -0:06:20 -
    -Rule	sol89	1989	only	-	Aug	2	12:06:15s -0:06:15 -
    -Rule	sol89	1989	only	-	Aug	3	12:06:10s -0:06:10 -
    -Rule	sol89	1989	only	-	Aug	4	12:06:05s -0:06:05 -
    -Rule	sol89	1989	only	-	Aug	5	12:06:00s -0:06:00 -
    -Rule	sol89	1989	only	-	Aug	6	12:05:50s -0:05:50 -
    -Rule	sol89	1989	only	-	Aug	7	12:05:45s -0:05:45 -
    -Rule	sol89	1989	only	-	Aug	8	12:05:35s -0:05:35 -
    -Rule	sol89	1989	only	-	Aug	9	12:05:30s -0:05:30 -
    -Rule	sol89	1989	only	-	Aug	10	12:05:20s -0:05:20 -
    -Rule	sol89	1989	only	-	Aug	11	12:05:10s -0:05:10 -
    -Rule	sol89	1989	only	-	Aug	12	12:05:00s -0:05:00 -
    -Rule	sol89	1989	only	-	Aug	13	12:04:50s -0:04:50 -
    -Rule	sol89	1989	only	-	Aug	14	12:04:40s -0:04:40 -
    -Rule	sol89	1989	only	-	Aug	15	12:04:30s -0:04:30 -
    -Rule	sol89	1989	only	-	Aug	16	12:04:15s -0:04:15 -
    -Rule	sol89	1989	only	-	Aug	17	12:04:05s -0:04:05 -
    -Rule	sol89	1989	only	-	Aug	18	12:03:50s -0:03:50 -
    -Rule	sol89	1989	only	-	Aug	19	12:03:35s -0:03:35 -
    -Rule	sol89	1989	only	-	Aug	20	12:03:25s -0:03:25 -
    -Rule	sol89	1989	only	-	Aug	21	12:03:10s -0:03:10 -
    -Rule	sol89	1989	only	-	Aug	22	12:02:55s -0:02:55 -
    -Rule	sol89	1989	only	-	Aug	23	12:02:40s -0:02:40 -
    -Rule	sol89	1989	only	-	Aug	24	12:02:20s -0:02:20 -
    -Rule	sol89	1989	only	-	Aug	25	12:02:05s -0:02:05 -
    -Rule	sol89	1989	only	-	Aug	26	12:01:50s -0:01:50 -
    -Rule	sol89	1989	only	-	Aug	27	12:01:30s -0:01:30 -
    -Rule	sol89	1989	only	-	Aug	28	12:01:15s -0:01:15 -
    -Rule	sol89	1989	only	-	Aug	29	12:00:55s -0:00:55 -
    -Rule	sol89	1989	only	-	Aug	30	12:00:40s -0:00:40 -
    -Rule	sol89	1989	only	-	Aug	31	12:00:20s -0:00:20 -
    -Rule	sol89	1989	only	-	Sep	1	12:00:00s 0:00:00 -
    -Rule	sol89	1989	only	-	Sep	2	11:59:45s 0:00:15 -
    -Rule	sol89	1989	only	-	Sep	3	11:59:25s 0:00:35 -
    -Rule	sol89	1989	only	-	Sep	4	11:59:05s 0:00:55 -
    -Rule	sol89	1989	only	-	Sep	5	11:58:45s 0:01:15 -
    -Rule	sol89	1989	only	-	Sep	6	11:58:25s 0:01:35 -
    -Rule	sol89	1989	only	-	Sep	7	11:58:05s 0:01:55 -
    -Rule	sol89	1989	only	-	Sep	8	11:57:45s 0:02:15 -
    -Rule	sol89	1989	only	-	Sep	9	11:57:20s 0:02:40 -
    -Rule	sol89	1989	only	-	Sep	10	11:57:00s 0:03:00 -
    -Rule	sol89	1989	only	-	Sep	11	11:56:40s 0:03:20 -
    -Rule	sol89	1989	only	-	Sep	12	11:56:20s 0:03:40 -
    -Rule	sol89	1989	only	-	Sep	13	11:56:00s 0:04:00 -
    -Rule	sol89	1989	only	-	Sep	14	11:55:35s 0:04:25 -
    -Rule	sol89	1989	only	-	Sep	15	11:55:15s 0:04:45 -
    -Rule	sol89	1989	only	-	Sep	16	11:54:55s 0:05:05 -
    -Rule	sol89	1989	only	-	Sep	17	11:54:35s 0:05:25 -
    -Rule	sol89	1989	only	-	Sep	18	11:54:10s 0:05:50 -
    -Rule	sol89	1989	only	-	Sep	19	11:53:50s 0:06:10 -
    -Rule	sol89	1989	only	-	Sep	20	11:53:30s 0:06:30 -
    -Rule	sol89	1989	only	-	Sep	21	11:53:10s 0:06:50 -
    -Rule	sol89	1989	only	-	Sep	22	11:52:45s 0:07:15 -
    -Rule	sol89	1989	only	-	Sep	23	11:52:25s 0:07:35 -
    -Rule	sol89	1989	only	-	Sep	24	11:52:05s 0:07:55 -
    -Rule	sol89	1989	only	-	Sep	25	11:51:45s 0:08:15 -
    -Rule	sol89	1989	only	-	Sep	26	11:51:25s 0:08:35 -
    -Rule	sol89	1989	only	-	Sep	27	11:51:05s 0:08:55 -
    -Rule	sol89	1989	only	-	Sep	28	11:50:40s 0:09:20 -
    -Rule	sol89	1989	only	-	Sep	29	11:50:20s 0:09:40 -
    -Rule	sol89	1989	only	-	Sep	30	11:50:00s 0:10:00 -
    -Rule	sol89	1989	only	-	Oct	1	11:49:45s 0:10:15 -
    -Rule	sol89	1989	only	-	Oct	2	11:49:25s 0:10:35 -
    -Rule	sol89	1989	only	-	Oct	3	11:49:05s 0:10:55 -
    -Rule	sol89	1989	only	-	Oct	4	11:48:45s 0:11:15 -
    -Rule	sol89	1989	only	-	Oct	5	11:48:30s 0:11:30 -
    -Rule	sol89	1989	only	-	Oct	6	11:48:10s 0:11:50 -
    -Rule	sol89	1989	only	-	Oct	7	11:47:50s 0:12:10 -
    -Rule	sol89	1989	only	-	Oct	8	11:47:35s 0:12:25 -
    -Rule	sol89	1989	only	-	Oct	9	11:47:20s 0:12:40 -
    -Rule	sol89	1989	only	-	Oct	10	11:47:00s 0:13:00 -
    -Rule	sol89	1989	only	-	Oct	11	11:46:45s 0:13:15 -
    -Rule	sol89	1989	only	-	Oct	12	11:46:30s 0:13:30 -
    -Rule	sol89	1989	only	-	Oct	13	11:46:15s 0:13:45 -
    -Rule	sol89	1989	only	-	Oct	14	11:46:00s 0:14:00 -
    -Rule	sol89	1989	only	-	Oct	15	11:45:50s 0:14:10 -
    -Rule	sol89	1989	only	-	Oct	16	11:45:35s 0:14:25 -
    -Rule	sol89	1989	only	-	Oct	17	11:45:20s 0:14:40 -
    -Rule	sol89	1989	only	-	Oct	18	11:45:10s 0:14:50 -
    -Rule	sol89	1989	only	-	Oct	19	11:45:00s 0:15:00 -
    -Rule	sol89	1989	only	-	Oct	20	11:44:50s 0:15:10 -
    -Rule	sol89	1989	only	-	Oct	21	11:44:40s 0:15:20 -
    -Rule	sol89	1989	only	-	Oct	22	11:44:30s 0:15:30 -
    -Rule	sol89	1989	only	-	Oct	23	11:44:20s 0:15:40 -
    -Rule	sol89	1989	only	-	Oct	24	11:44:10s 0:15:50 -
    -Rule	sol89	1989	only	-	Oct	25	11:44:05s 0:15:55 -
    -Rule	sol89	1989	only	-	Oct	26	11:44:00s 0:16:00 -
    -Rule	sol89	1989	only	-	Oct	27	11:43:50s 0:16:10 -
    -Rule	sol89	1989	only	-	Oct	28	11:43:45s 0:16:15 -
    -Rule	sol89	1989	only	-	Oct	29	11:43:40s 0:16:20 -
    -Rule	sol89	1989	only	-	Oct	30	11:43:40s 0:16:20 -
    -Rule	sol89	1989	only	-	Oct	31	11:43:35s 0:16:25 -
    -Rule	sol89	1989	only	-	Nov	1	11:43:35s 0:16:25 -
    -Rule	sol89	1989	only	-	Nov	2	11:43:35s 0:16:25 -
    -Rule	sol89	1989	only	-	Nov	3	11:43:30s 0:16:30 -
    -Rule	sol89	1989	only	-	Nov	4	11:43:35s 0:16:25 -
    -Rule	sol89	1989	only	-	Nov	5	11:43:35s 0:16:25 -
    -Rule	sol89	1989	only	-	Nov	6	11:43:35s 0:16:25 -
    -Rule	sol89	1989	only	-	Nov	7	11:43:40s 0:16:20 -
    -Rule	sol89	1989	only	-	Nov	8	11:43:45s 0:16:15 -
    -Rule	sol89	1989	only	-	Nov	9	11:43:50s 0:16:10 -
    -Rule	sol89	1989	only	-	Nov	10	11:43:55s 0:16:05 -
    -Rule	sol89	1989	only	-	Nov	11	11:44:00s 0:16:00 -
    -Rule	sol89	1989	only	-	Nov	12	11:44:05s 0:15:55 -
    -Rule	sol89	1989	only	-	Nov	13	11:44:15s 0:15:45 -
    -Rule	sol89	1989	only	-	Nov	14	11:44:25s 0:15:35 -
    -Rule	sol89	1989	only	-	Nov	15	11:44:35s 0:15:25 -
    -Rule	sol89	1989	only	-	Nov	16	11:44:45s 0:15:15 -
    -Rule	sol89	1989	only	-	Nov	17	11:44:55s 0:15:05 -
    -Rule	sol89	1989	only	-	Nov	18	11:45:10s 0:14:50 -
    -Rule	sol89	1989	only	-	Nov	19	11:45:20s 0:14:40 -
    -Rule	sol89	1989	only	-	Nov	20	11:45:35s 0:14:25 -
    -Rule	sol89	1989	only	-	Nov	21	11:45:50s 0:14:10 -
    -Rule	sol89	1989	only	-	Nov	22	11:46:05s 0:13:55 -
    -Rule	sol89	1989	only	-	Nov	23	11:46:25s 0:13:35 -
    -Rule	sol89	1989	only	-	Nov	24	11:46:40s 0:13:20 -
    -Rule	sol89	1989	only	-	Nov	25	11:47:00s 0:13:00 -
    -Rule	sol89	1989	only	-	Nov	26	11:47:20s 0:12:40 -
    -Rule	sol89	1989	only	-	Nov	27	11:47:35s 0:12:25 -
    -Rule	sol89	1989	only	-	Nov	28	11:47:55s 0:12:05 -
    -Rule	sol89	1989	only	-	Nov	29	11:48:20s 0:11:40 -
    -Rule	sol89	1989	only	-	Nov	30	11:48:40s 0:11:20 -
    -Rule	sol89	1989	only	-	Dec	1	11:49:00s 0:11:00 -
    -Rule	sol89	1989	only	-	Dec	2	11:49:25s 0:10:35 -
    -Rule	sol89	1989	only	-	Dec	3	11:49:50s 0:10:10 -
    -Rule	sol89	1989	only	-	Dec	4	11:50:15s 0:09:45 -
    -Rule	sol89	1989	only	-	Dec	5	11:50:35s 0:09:25 -
    -Rule	sol89	1989	only	-	Dec	6	11:51:00s 0:09:00 -
    -Rule	sol89	1989	only	-	Dec	7	11:51:30s 0:08:30 -
    -Rule	sol89	1989	only	-	Dec	8	11:51:55s 0:08:05 -
    -Rule	sol89	1989	only	-	Dec	9	11:52:20s 0:07:40 -
    -Rule	sol89	1989	only	-	Dec	10	11:52:50s 0:07:10 -
    -Rule	sol89	1989	only	-	Dec	11	11:53:15s 0:06:45 -
    -Rule	sol89	1989	only	-	Dec	12	11:53:45s 0:06:15 -
    -Rule	sol89	1989	only	-	Dec	13	11:54:10s 0:05:50 -
    -Rule	sol89	1989	only	-	Dec	14	11:54:40s 0:05:20 -
    -Rule	sol89	1989	only	-	Dec	15	11:55:10s 0:04:50 -
    -Rule	sol89	1989	only	-	Dec	16	11:55:40s 0:04:20 -
    -Rule	sol89	1989	only	-	Dec	17	11:56:05s 0:03:55 -
    -Rule	sol89	1989	only	-	Dec	18	11:56:35s 0:03:25 -
    -Rule	sol89	1989	only	-	Dec	19	11:57:05s 0:02:55 -
    -Rule	sol89	1989	only	-	Dec	20	11:57:35s 0:02:25 -
    -Rule	sol89	1989	only	-	Dec	21	11:58:05s 0:01:55 -
    -Rule	sol89	1989	only	-	Dec	22	11:58:35s 0:01:25 -
    -Rule	sol89	1989	only	-	Dec	23	11:59:05s 0:00:55 -
    -Rule	sol89	1989	only	-	Dec	24	11:59:35s 0:00:25 -
    -Rule	sol89	1989	only	-	Dec	25	12:00:05s -0:00:05 -
    -Rule	sol89	1989	only	-	Dec	26	12:00:35s -0:00:35 -
    -Rule	sol89	1989	only	-	Dec	27	12:01:05s -0:01:05 -
    -Rule	sol89	1989	only	-	Dec	28	12:01:35s -0:01:35 -
    -Rule	sol89	1989	only	-	Dec	29	12:02:00s -0:02:00 -
    -Rule	sol89	1989	only	-	Dec	30	12:02:30s -0:02:30 -
    -Rule	sol89	1989	only	-	Dec	31	12:03:00s -0:03:00 -
    -
    -# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
    -# Before and after 1989, we'll operate on local mean solar time.
    -
    -# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
    -Zone	Asia/Riyadh89	3:07:04	-		zzz	1989
    -			3:07:04	sol89		zzz	1990
    -			3:07:04	-		zzz
    -# For backward compatibility...
    -Link	Asia/Riyadh89	Mideast/Riyadh89
    diff --git a/src/java.base/share/data/tzdata/zone.tab b/src/java.base/share/data/tzdata/zone.tab
    deleted file mode 100644
    index b90ab4e4b25fb..0000000000000
    --- a/src/java.base/share/data/tzdata/zone.tab
    +++ /dev/null
    @@ -1,470 +0,0 @@
    -#
    -# 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.
    -#
    -# tzdb timezone descriptions (deprecated version)
    -#
    -# This file is in the public domain, so clarified as of
    -# 2009-05-17 by Arthur David Olson.
    -#
    -# From Paul Eggert (2021-09-20):
    -# This file is intended as a backward-compatibility aid for older programs.
    -# New programs should use zone1970.tab.  This file is like zone1970.tab (see
    -# zone1970.tab's comments), but with the following additional restrictions:
    -#
    -# 1.  This file contains only ASCII characters.
    -# 2.  The first data column contains exactly one country code.
    -#
    -# Because of (2), each row stands for an area that is the intersection
    -# of a region identified by a country code and of a timezone where civil
    -# clocks have agreed since 1970; this is a narrower definition than
    -# that of zone1970.tab.
    -#
    -# Unlike zone1970.tab, a row's third column can be a Link from
    -# 'backward' instead of a Zone.
    -#
    -# This table is intended as an aid for users, to help them select timezones
    -# appropriate for their practical needs.  It is not intended to take or
    -# endorse any position on legal or territorial claims.
    -#
    -#country-
    -#code	coordinates	TZ			comments
    -AD	+4230+00131	Europe/Andorra
    -AE	+2518+05518	Asia/Dubai
    -AF	+3431+06912	Asia/Kabul
    -AG	+1703-06148	America/Antigua
    -AI	+1812-06304	America/Anguilla
    -AL	+4120+01950	Europe/Tirane
    -AM	+4011+04430	Asia/Yerevan
    -AO	-0848+01314	Africa/Luanda
    -AQ	-7750+16636	Antarctica/McMurdo	New Zealand time - McMurdo, South Pole
    -AQ	-6617+11031	Antarctica/Casey	Casey
    -AQ	-6835+07758	Antarctica/Davis	Davis
    -AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville
    -AQ	-6736+06253	Antarctica/Mawson	Mawson
    -AQ	-6448-06406	Antarctica/Palmer	Palmer
    -AQ	-6734-06808	Antarctica/Rothera	Rothera
    -AQ	-690022+0393524	Antarctica/Syowa	Syowa
    -AQ	-720041+0023206	Antarctica/Troll	Troll
    -AQ	-7824+10654	Antarctica/Vostok	Vostok
    -AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
    -AR	-3124-06411	America/Argentina/Cordoba	Argentina (most areas: CB, CC, CN, ER, FM, MN, SE, SF)
    -AR	-2447-06525	America/Argentina/Salta	Salta (SA, LP, NQ, RN)
    -AR	-2411-06518	America/Argentina/Jujuy	Jujuy (JY)
    -AR	-2649-06513	America/Argentina/Tucuman	Tucuman (TM)
    -AR	-2828-06547	America/Argentina/Catamarca	Catamarca (CT), Chubut (CH)
    -AR	-2926-06651	America/Argentina/La_Rioja	La Rioja (LR)
    -AR	-3132-06831	America/Argentina/San_Juan	San Juan (SJ)
    -AR	-3253-06849	America/Argentina/Mendoza	Mendoza (MZ)
    -AR	-3319-06621	America/Argentina/San_Luis	San Luis (SL)
    -AR	-5138-06913	America/Argentina/Rio_Gallegos	Santa Cruz (SC)
    -AR	-5448-06818	America/Argentina/Ushuaia	Tierra del Fuego (TF)
    -AS	-1416-17042	Pacific/Pago_Pago
    -AT	+4813+01620	Europe/Vienna
    -AU	-3133+15905	Australia/Lord_Howe	Lord Howe Island
    -AU	-5430+15857	Antarctica/Macquarie	Macquarie Island
    -AU	-4253+14719	Australia/Hobart	Tasmania
    -AU	-3749+14458	Australia/Melbourne	Victoria
    -AU	-3352+15113	Australia/Sydney	New South Wales (most areas)
    -AU	-3157+14127	Australia/Broken_Hill	New South Wales (Yancowinna)
    -AU	-2728+15302	Australia/Brisbane	Queensland (most areas)
    -AU	-2016+14900	Australia/Lindeman	Queensland (Whitsunday Islands)
    -AU	-3455+13835	Australia/Adelaide	South Australia
    -AU	-1228+13050	Australia/Darwin	Northern Territory
    -AU	-3157+11551	Australia/Perth	Western Australia (most areas)
    -AU	-3143+12852	Australia/Eucla	Western Australia (Eucla)
    -AW	+1230-06958	America/Aruba
    -AX	+6006+01957	Europe/Mariehamn
    -AZ	+4023+04951	Asia/Baku
    -BA	+4352+01825	Europe/Sarajevo
    -BB	+1306-05937	America/Barbados
    -BD	+2343+09025	Asia/Dhaka
    -BE	+5050+00420	Europe/Brussels
    -BF	+1222-00131	Africa/Ouagadougou
    -BG	+4241+02319	Europe/Sofia
    -BH	+2623+05035	Asia/Bahrain
    -BI	-0323+02922	Africa/Bujumbura
    -BJ	+0629+00237	Africa/Porto-Novo
    -BL	+1753-06251	America/St_Barthelemy
    -BM	+3217-06446	Atlantic/Bermuda
    -BN	+0456+11455	Asia/Brunei
    -BO	-1630-06809	America/La_Paz
    -BQ	+120903-0681636	America/Kralendijk
    -BR	-0351-03225	America/Noronha	Atlantic islands
    -BR	-0127-04829	America/Belem	Para (east), Amapa
    -BR	-0343-03830	America/Fortaleza	Brazil (northeast: MA, PI, CE, RN, PB)
    -BR	-0803-03454	America/Recife	Pernambuco
    -BR	-0712-04812	America/Araguaina	Tocantins
    -BR	-0940-03543	America/Maceio	Alagoas, Sergipe
    -BR	-1259-03831	America/Bahia	Bahia
    -BR	-2332-04637	America/Sao_Paulo	Brazil (southeast: GO, DF, MG, ES, RJ, SP, PR, SC, RS)
    -BR	-2027-05437	America/Campo_Grande	Mato Grosso do Sul
    -BR	-1535-05605	America/Cuiaba	Mato Grosso
    -BR	-0226-05452	America/Santarem	Para (west)
    -BR	-0846-06354	America/Porto_Velho	Rondonia
    -BR	+0249-06040	America/Boa_Vista	Roraima
    -BR	-0308-06001	America/Manaus	Amazonas (east)
    -BR	-0640-06952	America/Eirunepe	Amazonas (west)
    -BR	-0958-06748	America/Rio_Branco	Acre
    -BS	+2505-07721	America/Nassau
    -BT	+2728+08939	Asia/Thimphu
    -BW	-2439+02555	Africa/Gaborone
    -BY	+5354+02734	Europe/Minsk
    -BZ	+1730-08812	America/Belize
    -CA	+4734-05243	America/St_Johns	Newfoundland, Labrador (SE)
    -CA	+4439-06336	America/Halifax	Atlantic - NS (most areas), PE
    -CA	+4612-05957	America/Glace_Bay	Atlantic - NS (Cape Breton)
    -CA	+4606-06447	America/Moncton	Atlantic - New Brunswick
    -CA	+5320-06025	America/Goose_Bay	Atlantic - Labrador (most areas)
    -CA	+5125-05707	America/Blanc-Sablon	AST - QC (Lower North Shore)
    -CA	+4339-07923	America/Toronto	Eastern - ON & QC (most areas)
    -CA	+6344-06828	America/Iqaluit	Eastern - NU (most areas)
    -CA	+484531-0913718	America/Atikokan	EST - ON (Atikokan), NU (Coral H)
    -CA	+4953-09709	America/Winnipeg	Central - ON (west), Manitoba
    -CA	+744144-0944945	America/Resolute	Central - NU (Resolute)
    -CA	+624900-0920459	America/Rankin_Inlet	Central - NU (central)
    -CA	+5024-10439	America/Regina	CST - SK (most areas)
    -CA	+5017-10750	America/Swift_Current	CST - SK (midwest)
    -CA	+5333-11328	America/Edmonton	Mountain - AB, BC(E), NT(E), SK(W)
    -CA	+690650-1050310	America/Cambridge_Bay	Mountain - NU (west)
    -CA	+682059-1334300	America/Inuvik	Mountain - NT (west)
    -CA	+4906-11631	America/Creston	MST - BC (Creston)
    -CA	+5546-12014	America/Dawson_Creek	MST - BC (Dawson Cr, Ft St John)
    -CA	+5848-12242	America/Fort_Nelson	MST - BC (Ft Nelson)
    -CA	+6043-13503	America/Whitehorse	MST - Yukon (east)
    -CA	+6404-13925	America/Dawson	MST - Yukon (west)
    -CA	+4916-12307	America/Vancouver	Pacific - BC (most areas)
    -CC	-1210+09655	Indian/Cocos
    -CD	-0418+01518	Africa/Kinshasa	Dem. Rep. of Congo (west)
    -CD	-1140+02728	Africa/Lubumbashi	Dem. Rep. of Congo (east)
    -CF	+0422+01835	Africa/Bangui
    -CG	-0416+01517	Africa/Brazzaville
    -CH	+4723+00832	Europe/Zurich
    -CI	+0519-00402	Africa/Abidjan
    -CK	-2114-15946	Pacific/Rarotonga
    -CL	-3327-07040	America/Santiago	most of Chile
    -CL	-5309-07055	America/Punta_Arenas	Region of Magallanes
    -CL	-2709-10926	Pacific/Easter	Easter Island
    -CM	+0403+00942	Africa/Douala
    -CN	+3114+12128	Asia/Shanghai	Beijing Time
    -CN	+4348+08735	Asia/Urumqi	Xinjiang Time
    -CO	+0436-07405	America/Bogota
    -CR	+0956-08405	America/Costa_Rica
    -CU	+2308-08222	America/Havana
    -CV	+1455-02331	Atlantic/Cape_Verde
    -CW	+1211-06900	America/Curacao
    -CX	-1025+10543	Indian/Christmas
    -CY	+3510+03322	Asia/Nicosia	most of Cyprus
    -CY	+3507+03357	Asia/Famagusta	Northern Cyprus
    -CZ	+5005+01426	Europe/Prague
    -DE	+5230+01322	Europe/Berlin	most of Germany
    -DE	+4742+00841	Europe/Busingen	Busingen
    -DJ	+1136+04309	Africa/Djibouti
    -DK	+5540+01235	Europe/Copenhagen
    -DM	+1518-06124	America/Dominica
    -DO	+1828-06954	America/Santo_Domingo
    -DZ	+3647+00303	Africa/Algiers
    -EC	-0210-07950	America/Guayaquil	Ecuador (mainland)
    -EC	-0054-08936	Pacific/Galapagos	Galapagos Islands
    -EE	+5925+02445	Europe/Tallinn
    -EG	+3003+03115	Africa/Cairo
    -EH	+2709-01312	Africa/El_Aaiun
    -ER	+1520+03853	Africa/Asmara
    -ES	+4024-00341	Europe/Madrid	Spain (mainland)
    -ES	+3553-00519	Africa/Ceuta	Ceuta, Melilla
    -ES	+2806-01524	Atlantic/Canary	Canary Islands
    -ET	+0902+03842	Africa/Addis_Ababa
    -FI	+6010+02458	Europe/Helsinki
    -FJ	-1808+17825	Pacific/Fiji
    -FK	-5142-05751	Atlantic/Stanley
    -FM	+0725+15147	Pacific/Chuuk	Chuuk/Truk, Yap
    -FM	+0658+15813	Pacific/Pohnpei	Pohnpei/Ponape
    -FM	+0519+16259	Pacific/Kosrae	Kosrae
    -FO	+6201-00646	Atlantic/Faroe
    -FR	+4852+00220	Europe/Paris
    -GA	+0023+00927	Africa/Libreville
    -GB	+513030-0000731	Europe/London
    -GD	+1203-06145	America/Grenada
    -GE	+4143+04449	Asia/Tbilisi
    -GF	+0456-05220	America/Cayenne
    -GG	+492717-0023210	Europe/Guernsey
    -GH	+0533-00013	Africa/Accra
    -GI	+3608-00521	Europe/Gibraltar
    -GL	+6411-05144	America/Nuuk	most of Greenland
    -GL	+7646-01840	America/Danmarkshavn	National Park (east coast)
    -GL	+7029-02158	America/Scoresbysund	Scoresbysund/Ittoqqortoormiit
    -GL	+7634-06847	America/Thule	Thule/Pituffik
    -GM	+1328-01639	Africa/Banjul
    -GN	+0931-01343	Africa/Conakry
    -GP	+1614-06132	America/Guadeloupe
    -GQ	+0345+00847	Africa/Malabo
    -GR	+3758+02343	Europe/Athens
    -GS	-5416-03632	Atlantic/South_Georgia
    -GT	+1438-09031	America/Guatemala
    -GU	+1328+14445	Pacific/Guam
    -GW	+1151-01535	Africa/Bissau
    -GY	+0648-05810	America/Guyana
    -HK	+2217+11409	Asia/Hong_Kong
    -HN	+1406-08713	America/Tegucigalpa
    -HR	+4548+01558	Europe/Zagreb
    -HT	+1832-07220	America/Port-au-Prince
    -HU	+4730+01905	Europe/Budapest
    -ID	-0610+10648	Asia/Jakarta	Java, Sumatra
    -ID	-0002+10920	Asia/Pontianak	Borneo (west, central)
    -ID	-0507+11924	Asia/Makassar	Borneo (east, south), Sulawesi/Celebes, Bali, Nusa Tengarra, Timor (west)
    -ID	-0232+14042	Asia/Jayapura	New Guinea (West Papua / Irian Jaya), Malukus/Moluccas
    -IE	+5320-00615	Europe/Dublin
    -IL	+314650+0351326	Asia/Jerusalem
    -IM	+5409-00428	Europe/Isle_of_Man
    -IN	+2232+08822	Asia/Kolkata
    -IO	-0720+07225	Indian/Chagos
    -IQ	+3321+04425	Asia/Baghdad
    -IR	+3540+05126	Asia/Tehran
    -IS	+6409-02151	Atlantic/Reykjavik
    -IT	+4154+01229	Europe/Rome
    -JE	+491101-0020624	Europe/Jersey
    -JM	+175805-0764736	America/Jamaica
    -JO	+3157+03556	Asia/Amman
    -JP	+353916+1394441	Asia/Tokyo
    -KE	-0117+03649	Africa/Nairobi
    -KG	+4254+07436	Asia/Bishkek
    -KH	+1133+10455	Asia/Phnom_Penh
    -KI	+0125+17300	Pacific/Tarawa	Gilbert Islands
    -KI	-0247-17143	Pacific/Kanton	Phoenix Islands
    -KI	+0152-15720	Pacific/Kiritimati	Line Islands
    -KM	-1141+04316	Indian/Comoro
    -KN	+1718-06243	America/St_Kitts
    -KP	+3901+12545	Asia/Pyongyang
    -KR	+3733+12658	Asia/Seoul
    -KW	+2920+04759	Asia/Kuwait
    -KY	+1918-08123	America/Cayman
    -KZ	+4315+07657	Asia/Almaty	most of Kazakhstan
    -KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda/Kyzylorda/Kzyl-Orda
    -KZ	+5312+06337	Asia/Qostanay	Qostanay/Kostanay/Kustanay
    -KZ	+5017+05710	Asia/Aqtobe	Aqtobe/Aktobe
    -KZ	+4431+05016	Asia/Aqtau	Mangghystau/Mankistau
    -KZ	+4707+05156	Asia/Atyrau	Atyrau/Atirau/Gur'yev
    -KZ	+5113+05121	Asia/Oral	West Kazakhstan
    -LA	+1758+10236	Asia/Vientiane
    -LB	+3353+03530	Asia/Beirut
    -LC	+1401-06100	America/St_Lucia
    -LI	+4709+00931	Europe/Vaduz
    -LK	+0656+07951	Asia/Colombo
    -LR	+0618-01047	Africa/Monrovia
    -LS	-2928+02730	Africa/Maseru
    -LT	+5441+02519	Europe/Vilnius
    -LU	+4936+00609	Europe/Luxembourg
    -LV	+5657+02406	Europe/Riga
    -LY	+3254+01311	Africa/Tripoli
    -MA	+3339-00735	Africa/Casablanca
    -MC	+4342+00723	Europe/Monaco
    -MD	+4700+02850	Europe/Chisinau
    -ME	+4226+01916	Europe/Podgorica
    -MF	+1804-06305	America/Marigot
    -MG	-1855+04731	Indian/Antananarivo
    -MH	+0709+17112	Pacific/Majuro	most of Marshall Islands
    -MH	+0905+16720	Pacific/Kwajalein	Kwajalein
    -MK	+4159+02126	Europe/Skopje
    -ML	+1239-00800	Africa/Bamako
    -MM	+1647+09610	Asia/Yangon
    -MN	+4755+10653	Asia/Ulaanbaatar	most of Mongolia
    -MN	+4801+09139	Asia/Hovd	Bayan-Olgii, Hovd, Uvs
    -MO	+221150+1133230	Asia/Macau
    -MP	+1512+14545	Pacific/Saipan
    -MQ	+1436-06105	America/Martinique
    -MR	+1806-01557	Africa/Nouakchott
    -MS	+1643-06213	America/Montserrat
    -MT	+3554+01431	Europe/Malta
    -MU	-2010+05730	Indian/Mauritius
    -MV	+0410+07330	Indian/Maldives
    -MW	-1547+03500	Africa/Blantyre
    -MX	+1924-09909	America/Mexico_City	Central Mexico
    -MX	+2105-08646	America/Cancun	Quintana Roo
    -MX	+2058-08937	America/Merida	Campeche, Yucatan
    -MX	+2540-10019	America/Monterrey	Durango; Coahuila, Nuevo Leon, Tamaulipas (most areas)
    -MX	+2550-09730	America/Matamoros	Coahuila, Nuevo Leon, Tamaulipas (US border)
    -MX	+2838-10605	America/Chihuahua	Chihuahua (most areas)
    -MX	+3144-10629	America/Ciudad_Juarez	Chihuahua (US border - west)
    -MX	+2934-10425	America/Ojinaga	Chihuahua (US border - east)
    -MX	+2313-10625	America/Mazatlan	Baja California Sur, Nayarit (most areas), Sinaloa
    -MX	+2048-10515	America/Bahia_Banderas	Bahia de Banderas
    -MX	+2904-11058	America/Hermosillo	Sonora
    -MX	+3232-11701	America/Tijuana	Baja California
    -MY	+0310+10142	Asia/Kuala_Lumpur	Malaysia (peninsula)
    -MY	+0133+11020	Asia/Kuching	Sabah, Sarawak
    -MZ	-2558+03235	Africa/Maputo
    -NA	-2234+01706	Africa/Windhoek
    -NC	-2216+16627	Pacific/Noumea
    -NE	+1331+00207	Africa/Niamey
    -NF	-2903+16758	Pacific/Norfolk
    -NG	+0627+00324	Africa/Lagos
    -NI	+1209-08617	America/Managua
    -NL	+5222+00454	Europe/Amsterdam
    -NO	+5955+01045	Europe/Oslo
    -NP	+2743+08519	Asia/Kathmandu
    -NR	-0031+16655	Pacific/Nauru
    -NU	-1901-16955	Pacific/Niue
    -NZ	-3652+17446	Pacific/Auckland	most of New Zealand
    -NZ	-4357-17633	Pacific/Chatham	Chatham Islands
    -OM	+2336+05835	Asia/Muscat
    -PA	+0858-07932	America/Panama
    -PE	-1203-07703	America/Lima
    -PF	-1732-14934	Pacific/Tahiti	Society Islands
    -PF	-0900-13930	Pacific/Marquesas	Marquesas Islands
    -PF	-2308-13457	Pacific/Gambier	Gambier Islands
    -PG	-0930+14710	Pacific/Port_Moresby	most of Papua New Guinea
    -PG	-0613+15534	Pacific/Bougainville	Bougainville
    -PH	+1435+12100	Asia/Manila
    -PK	+2452+06703	Asia/Karachi
    -PL	+5215+02100	Europe/Warsaw
    -PM	+4703-05620	America/Miquelon
    -PN	-2504-13005	Pacific/Pitcairn
    -PR	+182806-0660622	America/Puerto_Rico
    -PS	+3130+03428	Asia/Gaza	Gaza Strip
    -PS	+313200+0350542	Asia/Hebron	West Bank
    -PT	+3843-00908	Europe/Lisbon	Portugal (mainland)
    -PT	+3238-01654	Atlantic/Madeira	Madeira Islands
    -PT	+3744-02540	Atlantic/Azores	Azores
    -PW	+0720+13429	Pacific/Palau
    -PY	-2516-05740	America/Asuncion
    -QA	+2517+05132	Asia/Qatar
    -RE	-2052+05528	Indian/Reunion
    -RO	+4426+02606	Europe/Bucharest
    -RS	+4450+02030	Europe/Belgrade
    -RU	+5443+02030	Europe/Kaliningrad	MSK-01 - Kaliningrad
    -RU	+554521+0373704	Europe/Moscow	MSK+00 - Moscow area
    -# The obsolescent zone.tab format cannot represent Europe/Simferopol well.
    -# Put it in RU section and list as UA.  See "territorial claims" above.
    -# Programs should use zone1970.tab instead; see above.
    -UA	+4457+03406	Europe/Simferopol	Crimea
    -RU	+5836+04939	Europe/Kirov	MSK+00 - Kirov
    -RU	+4844+04425	Europe/Volgograd	MSK+00 - Volgograd
    -RU	+4621+04803	Europe/Astrakhan	MSK+01 - Astrakhan
    -RU	+5134+04602	Europe/Saratov	MSK+01 - Saratov
    -RU	+5420+04824	Europe/Ulyanovsk	MSK+01 - Ulyanovsk
    -RU	+5312+05009	Europe/Samara	MSK+01 - Samara, Udmurtia
    -RU	+5651+06036	Asia/Yekaterinburg	MSK+02 - Urals
    -RU	+5500+07324	Asia/Omsk	MSK+03 - Omsk
    -RU	+5502+08255	Asia/Novosibirsk	MSK+04 - Novosibirsk
    -RU	+5322+08345	Asia/Barnaul	MSK+04 - Altai
    -RU	+5630+08458	Asia/Tomsk	MSK+04 - Tomsk
    -RU	+5345+08707	Asia/Novokuznetsk	MSK+04 - Kemerovo
    -RU	+5601+09250	Asia/Krasnoyarsk	MSK+04 - Krasnoyarsk area
    -RU	+5216+10420	Asia/Irkutsk	MSK+05 - Irkutsk, Buryatia
    -RU	+5203+11328	Asia/Chita	MSK+06 - Zabaykalsky
    -RU	+6200+12940	Asia/Yakutsk	MSK+06 - Lena River
    -RU	+623923+1353314	Asia/Khandyga	MSK+06 - Tomponsky, Ust-Maysky
    -RU	+4310+13156	Asia/Vladivostok	MSK+07 - Amur River
    -RU	+643337+1431336	Asia/Ust-Nera	MSK+07 - Oymyakonsky
    -RU	+5934+15048	Asia/Magadan	MSK+08 - Magadan
    -RU	+4658+14242	Asia/Sakhalin	MSK+08 - Sakhalin Island
    -RU	+6728+15343	Asia/Srednekolymsk	MSK+08 - Sakha (E), N Kuril Is
    -RU	+5301+15839	Asia/Kamchatka	MSK+09 - Kamchatka
    -RU	+6445+17729	Asia/Anadyr	MSK+09 - Bering Sea
    -RW	-0157+03004	Africa/Kigali
    -SA	+2438+04643	Asia/Riyadh
    -SB	-0932+16012	Pacific/Guadalcanal
    -SC	-0440+05528	Indian/Mahe
    -SD	+1536+03232	Africa/Khartoum
    -SE	+5920+01803	Europe/Stockholm
    -SG	+0117+10351	Asia/Singapore
    -SH	-1555-00542	Atlantic/St_Helena
    -SI	+4603+01431	Europe/Ljubljana
    -SJ	+7800+01600	Arctic/Longyearbyen
    -SK	+4809+01707	Europe/Bratislava
    -SL	+0830-01315	Africa/Freetown
    -SM	+4355+01228	Europe/San_Marino
    -SN	+1440-01726	Africa/Dakar
    -SO	+0204+04522	Africa/Mogadishu
    -SR	+0550-05510	America/Paramaribo
    -SS	+0451+03137	Africa/Juba
    -ST	+0020+00644	Africa/Sao_Tome
    -SV	+1342-08912	America/El_Salvador
    -SX	+180305-0630250	America/Lower_Princes
    -SY	+3330+03618	Asia/Damascus
    -SZ	-2618+03106	Africa/Mbabane
    -TC	+2128-07108	America/Grand_Turk
    -TD	+1207+01503	Africa/Ndjamena
    -TF	-492110+0701303	Indian/Kerguelen
    -TG	+0608+00113	Africa/Lome
    -TH	+1345+10031	Asia/Bangkok
    -TJ	+3835+06848	Asia/Dushanbe
    -TK	-0922-17114	Pacific/Fakaofo
    -TL	-0833+12535	Asia/Dili
    -TM	+3757+05823	Asia/Ashgabat
    -TN	+3648+01011	Africa/Tunis
    -TO	-210800-1751200	Pacific/Tongatapu
    -TR	+4101+02858	Europe/Istanbul
    -TT	+1039-06131	America/Port_of_Spain
    -TV	-0831+17913	Pacific/Funafuti
    -TW	+2503+12130	Asia/Taipei
    -TZ	-0648+03917	Africa/Dar_es_Salaam
    -UA	+5026+03031	Europe/Kyiv	most of Ukraine
    -UG	+0019+03225	Africa/Kampala
    -UM	+2813-17722	Pacific/Midway	Midway Islands
    -UM	+1917+16637	Pacific/Wake	Wake Island
    -US	+404251-0740023	America/New_York	Eastern (most areas)
    -US	+421953-0830245	America/Detroit	Eastern - MI (most areas)
    -US	+381515-0854534	America/Kentucky/Louisville	Eastern - KY (Louisville area)
    -US	+364947-0845057	America/Kentucky/Monticello	Eastern - KY (Wayne)
    -US	+394606-0860929	America/Indiana/Indianapolis	Eastern - IN (most areas)
    -US	+384038-0873143	America/Indiana/Vincennes	Eastern - IN (Da, Du, K, Mn)
    -US	+410305-0863611	America/Indiana/Winamac	Eastern - IN (Pulaski)
    -US	+382232-0862041	America/Indiana/Marengo	Eastern - IN (Crawford)
    -US	+382931-0871643	America/Indiana/Petersburg	Eastern - IN (Pike)
    -US	+384452-0850402	America/Indiana/Vevay	Eastern - IN (Switzerland)
    -US	+415100-0873900	America/Chicago	Central (most areas)
    -US	+375711-0864541	America/Indiana/Tell_City	Central - IN (Perry)
    -US	+411745-0863730	America/Indiana/Knox	Central - IN (Starke)
    -US	+450628-0873651	America/Menominee	Central - MI (Wisconsin border)
    -US	+470659-1011757	America/North_Dakota/Center	Central - ND (Oliver)
    -US	+465042-1012439	America/North_Dakota/New_Salem	Central - ND (Morton rural)
    -US	+471551-1014640	America/North_Dakota/Beulah	Central - ND (Mercer)
    -US	+394421-1045903	America/Denver	Mountain (most areas)
    -US	+433649-1161209	America/Boise	Mountain - ID (south), OR (east)
    -US	+332654-1120424	America/Phoenix	MST - AZ (except Navajo)
    -US	+340308-1181434	America/Los_Angeles	Pacific
    -US	+611305-1495401	America/Anchorage	Alaska (most areas)
    -US	+581807-1342511	America/Juneau	Alaska - Juneau area
    -US	+571035-1351807	America/Sitka	Alaska - Sitka area
    -US	+550737-1313435	America/Metlakatla	Alaska - Annette Island
    -US	+593249-1394338	America/Yakutat	Alaska - Yakutat
    -US	+643004-1652423	America/Nome	Alaska (west)
    -US	+515248-1763929	America/Adak	Alaska - western Aleutians
    -US	+211825-1575130	Pacific/Honolulu	Hawaii
    -UY	-345433-0561245	America/Montevideo
    -UZ	+3940+06648	Asia/Samarkand	Uzbekistan (west)
    -UZ	+4120+06918	Asia/Tashkent	Uzbekistan (east)
    -VA	+415408+0122711	Europe/Vatican
    -VC	+1309-06114	America/St_Vincent
    -VE	+1030-06656	America/Caracas
    -VG	+1827-06437	America/Tortola
    -VI	+1821-06456	America/St_Thomas
    -VN	+1045+10640	Asia/Ho_Chi_Minh
    -VU	-1740+16825	Pacific/Efate
    -WF	-1318-17610	Pacific/Wallis
    -WS	-1350-17144	Pacific/Apia
    -YE	+1245+04512	Asia/Aden
    -YT	-1247+04514	Indian/Mayotte
    -ZA	-2615+02800	Africa/Johannesburg
    -ZM	-1525+02817	Africa/Lusaka
    -ZW	-1750+03103	Africa/Harare
    diff --git a/test/jdk/java/util/TimeZone/tools/share/Makefile b/test/jdk/java/util/TimeZone/tools/share/Makefile
    index 69c4838efe0ed..47734b96c551e 100644
    --- a/test/jdk/java/util/TimeZone/tools/share/Makefile
    +++ b/test/jdk/java/util/TimeZone/tools/share/Makefile
    @@ -1,5 +1,5 @@
     #
    -# Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
    +# Copyright (c) 2008, 2025, 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
    @@ -33,8 +33,7 @@
     TZDATA = ../../../../../../../src/java.base/share/data/tzdata
     TZDATA_VER = `grep '^tzdata' $(TZDATA)/VERSION`
     TZNAME = africa antarctica asia australasia europe northamerica \
    -	solar87 solar88 solar89 southamerica \
    -	backward
    +	southamerica backward
     TZFILES = $(addprefix $(TZDATA)/, $(TZNAME))
     ALIASLIST = aliases.txt
     DISPLAYNAMES = displaynames.txt
    diff --git a/test/jdk/sun/util/calendar/zi/BackEnd.java b/test/jdk/sun/util/calendar/zi/BackEnd.java
    deleted file mode 100644
    index 10d71ff721043..0000000000000
    --- a/test/jdk/sun/util/calendar/zi/BackEnd.java
    +++ /dev/null
    @@ -1,66 +0,0 @@
    -/*
    - * Copyright (c) 2000, 2018, 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.
    - */
    -
    -/**
    - * BackEnd is an abstract base class for a back-end of compiling
    - * Olson's zoneinfo database and generating Java zoneinfo database.
    - *
    - * @since 1.4
    - */
    -abstract class BackEnd {
    -
    -    /**
    -     * Receives each zone's TimeZone information which was created by
    -     * {@link Zoneinfo#parse} in class Zoneinfo,
    -     * and processes it.
    -     *
    -     * @param tz Timezone object for each zone
    -     * @return 0 if no error occurred, otherwise 1.
    -     */
    -    abstract int processZoneinfo(Timezone tz);
    -
    -    /**
    -     * Receives whole information which is generated by JavaZic's front-end
    -     * in the form of Mapping object and generates all Java zone information
    -     * files.
    -     *
    -     * @param m Mappings object which is generated by
    -     *          {@link Main#compile() Main.compile()}.
    -     * @return 0 if no error occurred, otherwise 1.
    -     */
    -    abstract int generateSrc(Mappings m);
    -
    -    /**
    -     * Decides which backend class should be used and returns its instance.
    -     * @return an instance of backend class
    -     */
    -    static BackEnd getBackEnd() {
    -        if (Zoneinfo.isYearForTimeZoneDataSpecified) {
    -            return new Simple();
    -        } else if (Main.outputDoc) {
    -            return new GenDoc();
    -        } else {
    -            return new Gen();
    -        }
    -    }
    -}
    diff --git a/test/jdk/sun/util/calendar/zi/Beyond2037.java b/test/jdk/sun/util/calendar/zi/Beyond2037.java
    deleted file mode 100644
    index af6f16067a854..0000000000000
    --- a/test/jdk/sun/util/calendar/zi/Beyond2037.java
    +++ /dev/null
    @@ -1,73 +0,0 @@
    -/*
    - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -
    -/*
    - * @test
    - * @bug 8073446 8262110
    - * @summary Tests DST related beyond the year 2037
    - * @run testng Beyond2037
    - */
    -
    -import java.text.SimpleDateFormat;
    -import java.util.TimeZone;
    -
    -import org.testng.annotations.DataProvider;
    -import org.testng.annotations.Test;
    -import static org.testng.Assert.assertEquals;
    -
    -@Test
    -public class Beyond2037 {
    -
    -    @DataProvider
    -    Object[][] dstTransition() {
    -        return new Object[][] {
    -            {"2037/03/08 01:59:59:999", "2037/03/08 01:59:59:999"},
    -            {"2037/03/08 02:00:00:000", "2037/03/08 03:00:00:000"},
    -            {"2038/03/14 01:59:59:999", "2038/03/14 01:59:59:999"},
    -            {"2038/03/14 02:00:00:000", "2038/03/14 03:00:00:000"},
    -            {"2099/03/08 01:59:59:999", "2099/03/08 01:59:59:999"},
    -            {"2099/03/08 02:00:00:000", "2099/03/08 03:00:00:000"},
    -            {"2100/03/14 01:59:59:999", "2100/03/14 01:59:59:999"},
    -            {"2100/03/14 02:00:00:000", "2100/03/14 03:00:00:000"},
    -            {"8000/03/12 01:59:59:999", "8000/03/12 01:59:59:999"},
    -            {"8000/03/12 02:00:00:000", "8000/03/12 03:00:00:000"},
    -        };
    -    }
    -
    -    @Test(dataProvider="dstTransition")
    -    public void testDstTransition(String source, String expected) throws Exception {
    -        var timeZone = TimeZone.getTimeZone("America/New_York");
    -        var sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS" );
    -        sdf.setTimeZone(timeZone);
    -        assertEquals(sdf.format(sdf.parse(source)), expected);
    -    }
    -
    -    @Test
    -    public void testGetOffset() throws Exception {
    -        var timeZone = TimeZone.getTimeZone("PST8PDT");
    -        var df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    -        df.setTimeZone(timeZone);
    -        var tMilli = df.parse("7681-03-09 03:20:49").getTime();
    -        assertEquals(timeZone.getOffset(tMilli), -25200000);
    -    }
    -}
    diff --git a/test/jdk/sun/util/calendar/zi/Checksum.java b/test/jdk/sun/util/calendar/zi/Checksum.java
    deleted file mode 100644
    index 93a1c8279038e..0000000000000
    --- a/test/jdk/sun/util/calendar/zi/Checksum.java
    +++ /dev/null
    @@ -1,65 +0,0 @@
    -/*
    - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -
    -import java.util.zip.CRC32;
    -
    -/**
    - * Checksum provides methods for calculating a CRC32 value for a
    - * transitions table.
    - *
    - * @since 1.4
    - */
    -public class Checksum extends CRC32
    -{
    -    /**
    -     * Updates the CRC32 value from each byte of the given int
    -     * value. The bytes are used in the big endian order.
    -     * @param val the int value
    -     */
    -    public void update(int val) {
    -        byte[] b = new byte[4];
    -        b[0] = (byte)((val >>> 24) & 0xff);
    -        b[1] = (byte)((val >>> 16) & 0xff);
    -        b[2] = (byte)((val >>> 8) & 0xff);
    -        b[3] = (byte)(val & 0xff);
    -        update(b);
    -    }
    -
    -    /**
    -     * Updates the CRC32 value from each byte of the given long
    -     * value. The bytes are used in the big endian order.
    -     * @param val the long value
    -     */
    -    void update(long val) {
    -        byte[] b = new byte[8];
    -        b[0] = (byte)((val >>> 56) & 0xff);
    -        b[1] = (byte)((val >>> 48) & 0xff);
    -        b[2] = (byte)((val >>> 40) & 0xff);
    -        b[3] = (byte)((val >>> 32) & 0xff);
    -        b[4] = (byte)((val >>> 24) & 0xff);
    -        b[5] = (byte)((val >>> 16) & 0xff);
    -        b[6] = (byte)((val >>> 8) & 0xff);
    -        b[7] = (byte)(val & 0xff);
    -        update(b);
    -    }
    -}
    diff --git a/test/jdk/sun/util/calendar/zi/DayOfWeek.java b/test/jdk/sun/util/calendar/zi/DayOfWeek.java
    deleted file mode 100644
    index ed820a83c392e..0000000000000
    --- a/test/jdk/sun/util/calendar/zi/DayOfWeek.java
    +++ /dev/null
    @@ -1,52 +0,0 @@
    -/*
    - * Copyright (c) 2004, 2018, 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.
    - */
    -
    -/**
    - * Day of week enum.
    - *
    - * @since 1.6
    - */
    -
    -enum DayOfWeek {
    -    SUNDAY("Sun"),
    -    MONDAY("Mon"),
    -    TUESDAY("Tue"),
    -    WEDNESDAY("Wed"),
    -    THURSDAY("Thu"),
    -    FRIDAY("Fri"),
    -    SATURDAY("Sat");
    -
    -    private final String abbr;
    -
    -    private DayOfWeek(String abbr) {
    -        this.abbr = abbr;
    -    }
    -
    -    String getAbbr() {
    -        return abbr;
    -    }
    -
    -    int value() {
    -        return ordinal() + 1;
    -    }
    -}
    diff --git a/test/jdk/sun/util/calendar/zi/Gen.java b/test/jdk/sun/util/calendar/zi/Gen.java
    deleted file mode 100644
    index 4cdabc55321e7..0000000000000
    --- a/test/jdk/sun/util/calendar/zi/Gen.java
    +++ /dev/null
    @@ -1,342 +0,0 @@
    -/*
    - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -
    -import  java.io.IOException;
    -import  java.io.File;
    -import  java.io.FileOutputStream;
    -import  java.io.DataOutputStream;
    -import  java.io.RandomAccessFile;
    -import  java.util.List;
    -import  java.util.Map;
    -import  java.util.Set;
    -
    -/**
    - * Gen is one of back-end classes of javazic, and generates
    - * ZoneInfoMappings and zone-specific file for each zone.
    - */
    -class Gen extends BackEnd {
    -
    -    /**
    -     * Generates datafile in binary TLV format for each time zone.
    -     * Regarding contents of output files, see {@link ZoneInfoFile}.
    -     *
    -     * @param Timezone
    -     * @return 0 if no errors, or 1 if error occurred.
    -     */
    -    int processZoneinfo(Timezone tz) {
    -        try {
    -            int size;
    -            String outputDir = Main.getOutputDir();
    -            String zonefile = ZoneInfoFile.getFileName(tz.getName());
    -
    -            /* If outputDir doesn't end with file-separator, adds it. */
    -            if (!outputDir.endsWith(File.separator)) {
    -                outputDir += File.separatorChar;
    -            }
    -
    -            /* If zonefile includes file-separator, it's treated as part of
    -             * pathname. And make directory if necessary.
    -             */
    -            int index = zonefile.lastIndexOf(File.separatorChar);
    -            if (index != -1) {
    -                outputDir += zonefile.substring(0, index+1);
    -            }
    -            File outD = new File(outputDir);
    -            outD.mkdirs();
    -
    -            FileOutputStream fos =
    -                new FileOutputStream(outputDir + zonefile.substring(index+1));
    -            DataOutputStream dos = new DataOutputStream(fos);
    -
    -            /* Output Label */
    -            dos.write(ZoneInfoFile.JAVAZI_LABEL, 0,
    -                      ZoneInfoFile.JAVAZI_LABEL.length);
    -
    -            /* Output Version of ZoneInfoFile */
    -            dos.writeByte(ZoneInfoFile.JAVAZI_VERSION);
    -
    -            List transitions = tz.getTransitions();
    -            if (transitions != null) {
    -                List dstOffsets = tz.getDstOffsets();
    -                List offsets = tz.getOffsets();
    -
    -                if ((dstOffsets == null && offsets != null) ||
    -                    (dstOffsets != null && offsets == null)) {
    -                    Main.panic("Data not exist. (dstOffsets or offsets)");
    -                    return 1;
    -                }
    -
    -                /* Output Transition records */
    -                dos.writeByte(ZoneInfoFile.TAG_Transition);
    -                size = transitions.size();
    -                dos.writeShort((size * 8) & 0xFFFF);
    -                int dstoffset;
    -                for (int i = 0; i < size; i++) {
    -                    /* if DST offset is 0, this means DST isn't used.
    -                     * (NOT: offset's index is 0.)
    -                     */
    -                    if ((dstoffset = dstOffsets.get(i).intValue()) == -1) {
    -                        dstoffset = 0;
    -                    }
    -
    -                    dos.writeLong((transitions.get(i).longValue() << 12)
    -                                  | (dstoffset << 4)
    -                                  | offsets.get(i).intValue());
    -
    -                }
    -
    -                /* Output data for GMTOffset */
    -                List gmtoffset = tz.getGmtOffsets();
    -                dos.writeByte(ZoneInfoFile.TAG_Offset);
    -                size = gmtoffset.size();
    -                dos.writeShort((size * 4) & 0xFFFF);
    -                for (int i = 0; i < size; i++) {
    -                    dos.writeInt(gmtoffset.get(i));
    -                }
    -            }
    -
    -            /* Output data for SimpleTimeZone */
    -            List stz = tz.getLastRules();
    -            if (stz != null) {
    -                RuleRec[] rr = new RuleRec[2];
    -                boolean wall = true;
    -
    -                rr[0] = stz.get(0);
    -                rr[1] = stz.get(1);
    -
    -                dos.writeByte(ZoneInfoFile.TAG_SimpleTimeZone);
    -                wall = rr[0].getTime().isWall() && rr[1].getTime().isWall();
    -                if (wall) {
    -                    dos.writeShort(32);
    -                } else {
    -                    dos.writeShort(40);
    -                }
    -
    -                for (int i = 0; i < 2; i++) {
    -                    dos.writeInt(rr[i].getMonthNum() - 1); // 0-based month number
    -                    dos.writeInt(rr[i].getDay().getDayForSimpleTimeZone());
    -                    dos.writeInt(rr[i].getDay().getDayOfWeekForSimpleTimeZoneInt());
    -                    dos.writeInt((int)rr[i].getTime().getTime());
    -                    if (!wall) {
    -                        dos.writeInt((rr[i].getTime().getType() & 0xFF) - 1);
    -                    }
    -                }
    -            }
    -
    -            /* Output RawOffset */
    -            dos.writeByte(ZoneInfoFile.TAG_RawOffset);
    -            dos.writeShort(4);
    -            dos.writeInt(tz.getRawOffset());
    -
    -            /* Output willGMTOffsetChange flag */
    -            if (tz.willGMTOffsetChange()) {
    -                dos.writeByte(ZoneInfoFile.TAG_GMTOffsetWillChange);
    -                dos.writeShort(1);
    -                dos.writeByte(1);
    -            }
    -
    -            /* Output LastDSTSaving */
    -            dos.writeByte(ZoneInfoFile.TAG_LastDSTSaving);
    -            dos.writeShort(2);
    -            dos.writeShort(tz.getLastDSTSaving()/1000);
    -
    -            /* Output checksum */
    -            dos.writeByte(ZoneInfoFile.TAG_CRC32);
    -            dos.writeShort(4);
    -            dos.writeInt(tz.getCRC32());
    -
    -            fos.close();
    -            dos.close();
    -        } catch(IOException e) {
    -            Main.panic("IO error: "+e.getMessage());
    -            return 1;
    -        }
    -
    -        return 0;
    -    }
    -
    -    /**
    -     * Generates ZoneInfoMappings in binary TLV format for each zone.
    -     * Regarding contents of output files, see {@link ZoneInfoFile}.
    -     *
    -     * @param Mappings
    -     * @return 0 if no errors, or 1 if error occurred.
    -     */
    -    int generateSrc(Mappings map) {
    -        try {
    -            int index;
    -            int block_size;
    -            int roi_size;
    -            long fp;
    -            String outputDir = Main.getOutputDir();
    -
    -            /* If outputDir doesn't end with file-separator, adds it. */
    -            if (!outputDir.endsWith(File.separator)) {
    -                outputDir += File.separatorChar;
    -            }
    -
    -            File outD = new File(outputDir);
    -            outD.mkdirs();
    -
    -            /* Open ZoneInfoMapping file to write. */
    -            RandomAccessFile raf =
    -                new RandomAccessFile(outputDir + ZoneInfoFile.JAVAZM_FILE_NAME, "rw");
    -
    -            /* Whether rawOffsetIndex list exists or not. */
    -            List roi = map.getRawOffsetsIndex();
    -            if (roi == null) {
    -                Main.panic("Data not exist. (rawOffsetsIndex)");
    -                return 1;
    -            }
    -            roi_size = roi.size();
    -
    -            /* Whether rawOffsetIndexTable list exists or not. */
    -            List> roit = map.getRawOffsetsIndexTable();
    -            if (roit == null || roit.size() != roi_size) {
    -                Main.panic("Data not exist. (rawOffsetsIndexTable) Otherwise, Invalid size");
    -                return 1;
    -            }
    -
    -            /* Output Label */
    -            raf.write(ZoneInfoFile.JAVAZM_LABEL, 0,
    -                      ZoneInfoFile.JAVAZM_LABEL.length);
    -
    -            /* Output Version */
    -            raf.writeByte(ZoneInfoFile.JAVAZM_VERSION);
    -
    -            index = ZoneInfoFile.JAVAZM_LABEL.length + 2;
    -
    -            /* Output Version of Olson's tzdata */
    -            byte[] b = Main.getVersionName().getBytes("UTF-8");
    -            raf.writeByte(ZoneInfoFile.TAG_TZDataVersion);
    -            raf.writeShort((b.length+1) & 0xFFFF);
    -            raf.write(b);
    -            raf.writeByte(0x00);
    -            index += b.length + 4;
    -
    -            /* Output ID list. */
    -            raf.writeByte(ZoneInfoFile.TAG_ZoneIDs);
    -            block_size = 2;
    -            raf.writeShort(block_size & 0xFFFF);
    -            short nID = 0;
    -            raf.writeShort(nID & 0xFFFF);
    -            for (int i = 0; i < roi_size; i++) {
    -                for (String key : roit.get(i)) {
    -                    byte size = (byte)key.getBytes("UTF-8").length;
    -                    raf.writeByte(size & 0xFF);
    -                    raf.write(key.getBytes("UTF-8"), 0, size);
    -                    block_size += 1 + size;
    -                    nID++;
    -                }
    -            }
    -            fp = raf.getFilePointer();
    -            raf.seek(index);
    -            raf.writeShort((block_size) & 0xFFFF);
    -            raf.writeShort(nID & 0xFFFF);
    -            raf.seek(fp);
    -
    -            /* Output sorted rawOffset list. */
    -            raf.writeByte(ZoneInfoFile.TAG_RawOffsets);
    -            index += 3 + block_size;
    -            block_size = roi_size * 4;
    -            raf.writeShort(block_size & 0xFFFF);
    -            for (int i = 0; i < roi_size; i++) {
    -                raf.writeInt(Integer.parseInt(roi.get(i).toString()));
    -            }
    -
    -            /* Output sorted rawOffsetIndex list. */
    -            raf.writeByte(ZoneInfoFile.TAG_RawOffsetIndices);
    -            index += 3 + block_size;
    -            block_size = 0;
    -            raf.writeShort(block_size & 0xFFFF);
    -            int num;
    -            for (int i = 0; i < roi_size; i++) {
    -                num = roit.get(i).size();
    -                block_size += num;
    -                for (int j = 0; j < num; j++) {
    -                    raf.writeByte(i);
    -                }
    -            }
    -            fp = raf.getFilePointer();
    -            raf.seek(index);
    -            raf.writeShort((block_size) & 0xFFFF);
    -            raf.seek(fp);
    -
    -            /* Whether alias list exists or not. */
    -            Map a = map.getAliases();
    -            if (a == null) {
    -                Main.panic("Data not exist. (aliases)");
    -                return 0;
    -            }
    -
    -            /* Output ID list. */
    -            raf.writeByte(ZoneInfoFile.TAG_ZoneAliases);
    -            index += 3 + block_size;
    -            block_size = 2;
    -            raf.writeShort(block_size & 0xFFFF);
    -            raf.writeShort(a.size() & 0xFFFF);
    -            for (String key : a.keySet()) {
    -                String alias = a.get(key);
    -                byte key_size = (byte)key.length();
    -                byte alias_size = (byte)alias.length();
    -                raf.writeByte(key_size & 0xFF);
    -                raf.write(key.getBytes("UTF-8"), 0, key_size);
    -                raf.writeByte(alias_size & 0xFF);
    -                raf.write(alias.getBytes("UTF-8"), 0, alias_size);
    -                block_size += 2 + key_size + alias_size;
    -            }
    -            fp = raf.getFilePointer();
    -            raf.seek(index);
    -            raf.writeShort((block_size) & 0xFFFF);
    -            raf.seek(fp);
    -
    -            /* Output the exclude list if it exists. */
    -            List excludedZones = map.getExcludeList();
    -            if (excludedZones != null) {
    -                raf.writeByte(ZoneInfoFile.TAG_ExcludedZones);
    -                index += 3 + block_size;
    -                block_size = 2;
    -                raf.writeShort(block_size & 0xFFFF);  // place holder
    -                raf.writeShort(excludedZones.size()); // the number of excluded zones
    -                for (String name : excludedZones) {
    -                    byte size = (byte) name.length();
    -                    raf.writeByte(size);                 // byte length
    -                    raf.write(name.getBytes("UTF-8"), 0, size); // zone name
    -                    block_size += 1 + size;
    -                }
    -                fp = raf.getFilePointer();
    -                raf.seek(index);
    -                raf.writeShort(block_size & 0xFFFF);
    -                raf.seek(fp);
    -            }
    -
    -            /* Close ZoneInfoMapping file. */
    -            raf.close();
    -        } catch(IOException e) {
    -            Main.panic("IO error: "+e.getMessage());
    -            return 1;
    -        }
    -
    -        return 0;
    -    }
    -}
    diff --git a/test/jdk/sun/util/calendar/zi/GenDoc.java b/test/jdk/sun/util/calendar/zi/GenDoc.java
    deleted file mode 100644
    index e9e6ebc0cd8fa..0000000000000
    --- a/test/jdk/sun/util/calendar/zi/GenDoc.java
    +++ /dev/null
    @@ -1,776 +0,0 @@
    -/*
    - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -
    -import  java.io.BufferedReader;
    -import  java.io.BufferedWriter;
    -import  java.io.File;
    -import  java.io.FileReader;
    -import  java.io.FileWriter;
    -import  java.io.IOException;
    -import  java.util.Date;
    -import  java.util.HashMap;
    -import  java.util.List;
    -import  java.util.Map;
    -import  java.util.Set;
    -import  java.util.SortedMap;
    -import  java.util.StringTokenizer;
    -import  java.util.TreeMap;
    -import  java.util.TreeSet;
    -
    -/**
    - * GenDoc is one of back-end classes of javazic, and generates
    - * index.html and other html files which prints the detailed time zone
    - * information for each zone.
    - */
    -class GenDoc extends BackEnd {
    -
    -    private static final String docDir = "doc";
    -
    -    private static final String header1 =
    -        "\n" +
    -        "\n\n\n\n" +
    -        "Java Platform, Standard Edition - TimeZone information based on ";
    -    private static final String header3 =
    -        "-->\n<TITLE>\n" +
    -        "Java Platform, Standard Edition  TimeZone - ";
    -    private static final String header4 =
    -        "\n" +
    -        "\n\n";
    -
    -    private static final String body1 =
    -        "\n";
    -    private static final String body2 =
    -        "\n";
    -
    -    private static final String footer =
    -        "\n";
    -
    -
    -    // list of time zone name and zonefile name/real time zone name
    -    //   e.g.
    -    //      key (String)       : value (String)
    -    //      "America/Denver"   : "America/Denver.html" (real time zone)
    -    //      "America/Shiprock" : "America/Denver"      (alias)
    -    TreeMap timezoneList = new TreeMap();
    -
    -    // list of time zone's display name and time zone name
    -    //   e.g.
    -    //      key (String)                : value (String)
    -    //      "Tokyo, Asia"               : "Asia/Tokyo"
    -    //      "Marengo, Indiana, America" : "America/Indiana/Marengo"
    -    //          (aliases included)
    -    TreeMap displayNameList = new TreeMap();
    -
    -    // list of top level regions
    -    //   e.g.
    -    //      key (String) : value (String)
    -    //      "America"    : "America.html"
    -    //          (including entries in America/Indiana/, America/Kentucky/, ...)
    -    TreeMap regionList = new TreeMap();
    -
    -    // mapping list from zone name to latitude & longitude
    -    //   This list is generated from zone.tab.
    -    //   e.g.
    -    //      key (String) : value (LatitudeAndLongitude object)
    -    //      "Asia/Tokyo" : latitude=35.3916, longitude=13.9444
    -    //          (aliases not included)
    -    HashMap mapList = null;
    -
    -    // SortedMap of zone IDs sorted by their GMT offsets. If zone's GMT
    -    // offset will change in the future, its last known offset is
    -    // used.
    -    SortedMap> zonesByOffset = new TreeMap>();
    -
    -    /**
    -     * Generates HTML document for each zone.
    -     * @param Timezone
    -     * @return 0 if no errors, or 1 if error occurred.
    -     */
    -    int processZoneinfo(Timezone tz) {
    -        try {
    -            int size;
    -            int index;
    -            String outputDir = Main.getOutputDir();
    -            String zonename = tz.getName();
    -            String zonefile = ZoneInfoFile.getFileName(zonename) + ".html";
    -            List stz = tz.getLastRules();
    -            timezoneList.put(zonename, zonefile);
    -            displayNameList.put(transform(zonename), zonename);
    -
    -            // Populate zonesByOffset. (Zones that will change their
    -            // GMT offsets are also added to zonesByOffset here.)
    -            int lastKnownOffset = tz.getRawOffset();
    -            Set set = zonesByOffset.get(lastKnownOffset);
    -            if (set == null) {
    -                set = new TreeSet();
    -                zonesByOffset.put(lastKnownOffset, set);
    -            }
    -            set.add(zonename);
    -
    -            /* If outputDir doesn't end with file-separator, adds it. */
    -            if (!outputDir.endsWith(File.separator)) {
    -                outputDir += File.separatorChar;
    -            }
    -            outputDir += docDir + File.separatorChar;
    -
    -            index = zonename.indexOf('/');
    -            if (index != -1) {
    -                regionList.put(zonename.substring(0, index),
    -                               zonename.substring(0, index) + ".html");
    -            }
    -
    -            /* If zonefile includes file-separator, it's treated as part of
    -             * pathname. And make directory if necessary.
    -             */
    -            index = zonefile.lastIndexOf('/');
    -            if (index != -1) {
    -                zonefile.replace('/', File.separatorChar);
    -                outputDir += zonefile.substring(0, index+1);
    -            }
    -            File outD = new File(outputDir);
    -            outD.mkdirs();
    -
    -            /* If mapfile is available, add a link to the appropriate map */
    -            if (mapList == null && Main.getMapFile() != null) {
    -                mapList = new HashMap();
    -                FileReader fr = new FileReader(Main.getMapFile());
    -                BufferedReader in = new BufferedReader(fr);
    -                String line;
    -                while ((line = in.readLine()) != null) {
    -                    // skip blank and comment lines
    -                    if (line.length() == 0 || line.charAt(0) == '#') {
    -                        continue;
    -                    }
    -                    StringTokenizer tokens = new StringTokenizer(line);
    -                    String token = tokens.nextToken();  /* We don't use the first token. */
    -                    token = tokens.nextToken();
    -                    LatitudeAndLongitude location = new LatitudeAndLongitude(token);
    -                    token = tokens.nextToken();
    -                    mapList.put(token, location);
    -                }
    -                in.close();
    -            }
    -
    -            /* Open zoneinfo file to write. */
    -            FileWriter fw = new FileWriter(outputDir + zonefile.substring(index+1));
    -            BufferedWriter out = new BufferedWriter(fw);
    -
    -            out.write(header1 + new Date() + header3 + zonename + header4);
    -            out.write(body1 + "" + zonename + "");
    -            LatitudeAndLongitude location = (mapList != null ? mapList.get(zonename) : null);
    -            if (location != null) {
    -                int deg, min, sec;
    -
    -                deg = location.getLatDeg();
    -                min = location.getLatMin();
    -                sec = location.getLatSec();
    -                if (deg < 0) {
    -                    min = -min;
    -                    sec = -sec;
    -                } else if (min < 0) {
    -                    sec = -sec;
    -                }
    -                out.write("   " +
    -                          "[map]");
    -            }
    -            out.write("\n

    \n"); - - List zone = tz.getZones(); - List rule = tz.getRules(); - if (rule != null && zone != null) { - out.write("\n" + - "\n" + - "\n" + - "\n" + - "\n

    " + - "Rules
    " + - "
    Zone
    \n"); - } - - /* Output Rule records. */ - if (rule != null) { - size = rule.size(); - out.write("

    \n" + - "Rules\n" + - "\n" + - "\n" + - "" + - "" + - "\n\n"); - for (int i = 0; i < size; i++) { - out.write("\n"); - StringTokenizer st = new StringTokenizer(rule.get(i).getLine()); - String s; - if (st.hasMoreTokens()) { /* RULE - truncated */ - st.nextToken(); - } - if (st.hasMoreTokens()) { /* NAME */ - out.write(""); - } - if (st.hasMoreTokens()) { /* FROM */ - out.write(""); - } - if (st.hasMoreTokens()) { /* TO */ - s = st.nextToken(); - if (s.equals("min") || s.equals("max")) { - out.write(""); - } else { - out.write(""); - } - } - if (st.hasMoreTokens()) { /* TYPE */ - out.write(""); - } - if (st.hasMoreTokens()) { /* IN */ - out.write(""); - } - if (st.hasMoreTokens()) { /* ON */ - out.write(""); - } - if (st.hasMoreTokens()) { /* AT */ - out.write(""); - } - if (st.hasMoreTokens()) { /* SAVE */ - out.write(""); - } - if (st.hasMoreTokens()) { /* LETTER/S */ - out.write(""); - } - if (st.hasMoreTokens()) { /* NOTES */ - s = st.nextToken(); - while (st.hasMoreTokens()) { - s += " " + st.nextToken(); - } - index = s.indexOf('#'); - out.write("\n"); - } else { - out.write("\n"); - } - out.write("\n"); - } - out.write("
    NAMEFROMTOTYPEINONATSAVELETTER/SNOTES
    " + st.nextToken() + "" + st.nextToken() + "" + s + "" + s + "" + st.nextToken() + "" + st.nextToken() + "" + st.nextToken() + "" + st.nextToken() + "" + st.nextToken() + "" + st.nextToken() + "" + s.substring(index+1) + " 
    \n

     

    \n"); - } - - /* Output Zone records. */ - if (zone != null) { - size = zone.size(); - out.write("

    \n" + - "Zone\n" + - "\n" + - "\n" + - "" + - "\n\n"); - for (int i = 0; i < size; i++) { - out.write("\n"); - StringTokenizer st = new StringTokenizer(zone.get(i).getLine()); - String s = st.nextToken(); - if (s.equals("Zone")) { /* NAME */ - s = st.nextToken(); - s = st.nextToken(); - } - out.write(""); /* GMTOFFSET */ - if (st.hasMoreTokens()) { /* RULES */ - out.write(""); - } - if (st.hasMoreTokens()) { /* FORMAT */ - s = st.nextToken(); - index = s.indexOf('#'); - if (index != -1) { - if (index != 0) { - out.write(""); /* FORMAT */ - s = s.substring(index+1); - } else { - out.write(""); /* FORMAT */ - } - while (st.hasMoreTokens()) { - s += " " + st.nextToken(); - } - out.write(""); /* UNTIL */ - out.write("\n\n"); /* NOTES */ - continue; - } else { - out.write(""); /* FORMAT */ - } - } - - if (st.hasMoreTokens()) { /* UNTIL */ - s = st.nextToken(); - while (st.hasMoreTokens()) { - s += " " + st.nextToken(); - } - index = s.indexOf('#'); - if (index != -1) { - if (index != 0) { - out.write(""); /* UNTIL */ - } else { - out.write(""); /* UNTIL */ - } - out.write("\n"); /* NOTES */ - } else { - out.write(""); /* UNTIL */ - out.write("\n"); /* NOTES */ - } - } else { - out.write(""); /* UNTIL */ - out.write("\n"); /* NOTES */ - } - out.write("\n"); - } - out.write("
    GMTOFFRULESFORMATUNTILNOTES
    " + s + "" + st.nextToken() + "" + s.substring(0, index-1) + - "  " + s + "
    " + s + "" + s.substring(0, index-1) + - " " + s.substring(index+1) + - "" + s + "   
    \n"); - } - out.write(body2 + footer); - - out.close(); - fw.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } - - /** - * Generates index.html and other top-level frame files. - * @param Mappings - * @return 0 if no errors, or 1 if error occurred. - */ - int generateSrc(Mappings map) { - try { - int len; - Object o[]; - String outputDir = Main.getOutputDir(); - FileWriter fw1, fw2; - BufferedWriter out1, out2; - - /* Whether alias list exists or not. */ - Map a = map.getAliases(); - if (a == null) { - Main.panic("Data not exist. (aliases)"); - return 1; - } - - timezoneList.putAll(a); - - /* If outputDir doesn't end with file-separator, adds it. */ - if (!outputDir.endsWith(File.separator)) { - outputDir += File.separatorChar; - } - outputDir += docDir + File.separatorChar; - - File outD = new File(outputDir); - outD.mkdirs(); - - /* Creates index.html */ - fw1 = new FileWriter(outputDir + "index.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + - "\n" + - "\n" + - "\n" + - "\n" + - "" + - "\n" + - "\n" + - "\n" + - "<H2>\nFrame Alert\n</H2>\n\n" + - "<P>\n\n" + - "This document is designed to be viewed using the frames feature. If you see this\n" + - "message, you are using a non-frame-capable web client.\n" + - "<BR>\n" + - "Link to<A HREF=\"overview-summary.html\">Non-frame version.</A>\n" + - "\n" + footer); - - out1.close(); - fw1.close(); - - - /* Creates overview-frame.html */ - fw1 = new FileWriter(outputDir + "overview-frame.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "\n\n" + - "\n" + - "\n
    \n" + - "JavaTM Platform
    Standard Ed.
    \n\n" + - "\n\n\n
    " + - "

    \n\nAll Time Zones Sorted By:\n
    \n" + - "  GMT offsets\n
    \n" + - "  Zone names\n
    " + - "  City names\n" + - "

    \n\nContinents and Oceans\n
    \n"); - - for (String regionKey : regionList.keySet()) { - out1.write("  " + regionKey + - "
    \n"); - - fw2 = new FileWriter(outputDir + regionList.get(regionKey), - false); - out2 = new BufferedWriter(fw2); - - out2.write(header1 + new Date() + header3 + regionKey + - header4 + body1 + "" + - regionKey + "\n
    \n\n\n\n\n
    "); - - boolean found = false; - for (String timezoneKey : timezoneList.keySet()) { - int regionIndex = timezoneKey.indexOf('/'); - if (regionIndex == -1 || - !regionKey.equals(timezoneKey.substring(0, regionIndex))) { - if (found) { - break; - } else { - continue; - } - } - - found = true; - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out2.write(timezoneKey + - " (alias for " + "" + - realName + ")"); - } else { - out2.write("" + timezoneKey + - ""); - } - out2.write("
    \n"); - } - out2.write("
    \n" + body2 + footer); - - out2.close(); - fw2.close(); - } - out1.write("

    \n" + body2 + footer); - - out1.close(); - fw1.close(); - - - /* Creates allTimeZone-frame1.html (Sorted by GMT offsets) */ - fw1 = new FileWriter(outputDir + "allTimeZone-frame1.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "Sorted by GMT offsets\n" + - "
    \n\n" + "\n" + - "\n\n\n\n\n"); - } - } - out1.write("\n\n
    \n"); - - List roi = map.getRawOffsetsIndex(); - List> roit = map.getRawOffsetsIndexTable(); - - int index = 0; - for (Integer offset : zonesByOffset.keySet()) { - int off = roi.get(index); - Set perRO = zonesByOffset.get(offset); - if (offset == off) { - // Merge aliases into zonesByOffset - perRO.addAll(roit.get(index)); - } - index++; - - for (String timezoneKey : perRO) { - out1.write("
    (" + - Time.toGMTFormat(offset.toString()) + - ")"); - - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out1.write(timezoneKey + - " (alias for " + "" + realName + - ")"); - } else { - out1.write("" + timezoneKey + - ""); - } - out1.write("
    \n" + body2 + footer); - - out1.close(); - fw1.close(); - - - /* Creates allTimeZone-frame2.html (Sorted by zone names) */ - fw1 = new FileWriter(outputDir + "allTimeZone-frame2.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "Sorted by zone names\n" + - "
    \n\n" + "\n" + - "\n\n\n
    \n"); - o = timezoneList.keySet().toArray(); - len = timezoneList.size(); - for (int i = 0; i < len; i++) { - Object timezoneKey = o[i]; - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out1.write(timezoneKey + - " (alias for " + - "" + realName + - ")"); - } else { - out1.write("" + timezoneKey + - ""); - } - out1.write("
    \n"); - } - out1.write("
    \n" + body2 + footer); - - out1.close(); - fw1.close(); - - /* Creates allTimeZone-frame3.html (Sorted by city names) */ - fw1 = new FileWriter(outputDir + "allTimeZone-frame3.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "Sorted by city names\n" + - "
    \n\n" + "\n" + - "\n\n\n
    \n"); - - Set aliasSet = a.keySet(); - len = aliasSet.size(); - String aliasNames[] = aliasSet.toArray(new String[0]); - for (int i = 0; i < len; i++) { - displayNameList.put(transform(aliasNames[i]), - aliasNames[i]); - } - - o = displayNameList.keySet().toArray(); - len = displayNameList.size(); - for (int i = 0; i < len; i++) { - Object displayName = o[i]; - Object timezoneKey = displayNameList.get(o[i]); - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out1.write(displayName + - " (alias for " + - "" + realName + - ")"); - } else { - out1.write("" + displayName + - ""); - } - out1.write("
    \n"); - } - - out1.write("
    \n" + body2 + footer); - - out1.close(); - fw1.close(); - - /* Creates overview-summary.html */ - fw1 = new FileWriter(outputDir + "overview-summary.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "

    This is the list of time zones generated from " + - Main.getVersionName() + " for Java Platform, " + - "Standard Edition. The source code can be obtained " + - "from ftp site " + - "ftp://elsie.nci.nih.gov/pub/. A total of " + - len + - " time zones and aliases are supported " + - "in this edition. For the " + - "format of rules and zones, refer to the zic " + - "(zoneinfo compiler) man page on " + - "Solaris or Linux.

    \n" + - "

    Note that the time zone data is not " + - "a public interface of the Java Platform. No " + - "applications should rely on the time zone data of " + - "this document. Time zone names and data " + - "may change without any prior notice.

    \n" + - body2 + footer); - - out1.close(); - fw1.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } - - String transform(String s) { - int index = s.lastIndexOf("/"); - - /* If the string doesn't include any delimiter, return */ - if (index == -1) { - return s; - } - - int lastIndex = index; - String str = s.substring(index+1); - do { - index = s.substring(0, lastIndex).lastIndexOf('/'); - str += ", " + s.substring(index+1, lastIndex); - lastIndex = index; - } while (index > -1); - - return str; - } - - static class LatitudeAndLongitude { - - private int latDeg, latMin, latSec, longDeg, longMin, longSec; - - LatitudeAndLongitude(String s) { - try { - // First of all, check the string has the correct format: - // either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS - - if (!s.startsWith("+") && !s.startsWith("-")) { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - int index; - if (((index = s.lastIndexOf("+")) <= 0) && - ((index = s.lastIndexOf("-")) <= 0)) { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - - if (index == 5) { - latDeg = Integer.parseInt(s.substring(1, 3)); - latMin = Integer.parseInt(s.substring(3, 5)); - latSec = 0; - } else if (index == 7) { - latDeg = Integer.parseInt(s.substring(1, 3)); - latMin = Integer.parseInt(s.substring(3, 5)); - latSec = Integer.parseInt(s.substring(5, 7)); - } else { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - if (s.startsWith("-")){ - latDeg = -latDeg; - latMin = -latMin; - latSec = -latSec; - } - - int len = s.length(); - if (index == 5 && len == 11) { - longDeg = Integer.parseInt(s.substring(index+1, index+4)); - longMin = Integer.parseInt(s.substring(index+4, index+6)); - longSec = 0; - } else if (index == 7 && len == 15) { - longDeg = Integer.parseInt(s.substring(index+1, index+4)); - longMin = Integer.parseInt(s.substring(index+4, index+6)); - longSec = Integer.parseInt(s.substring(index+6, index+8)); - } else { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - if (s.charAt(index) == '-'){ - longDeg = -longDeg; - longMin = -longMin; - longSec = -longSec; - } - } catch(Exception e) { - Main.warning("LatitudeAndLongitude() Parse error: " + s); - } - } - - int getLatDeg() { - return latDeg; - } - - int getLatMin() { - return latMin; - } - - int getLatSec() { - return latSec; - } - - int getLongDeg() { - return longDeg; - } - - int getLongMin() { - return longMin; - } - - int getLongSec() { - return longSec; - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/Main.java b/test/jdk/sun/util/calendar/zi/Main.java deleted file mode 100644 index 8078d7e2425d2..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Main.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.ArrayList; -import java.util.List; - -/** - * Main class for the javazic time zone data compiler. - * - * @since 1.4 - */ -public class Main { - - private static boolean verbose = false; - static boolean outputDoc = false; - - private List ziFiles = new ArrayList(); - private static String zoneNamesFile = null; - private static String versionName = "unknown"; - private static String outputDir = "zoneinfo"; - private static String mapFile = null; - - /** - * Parses the specified arguments and sets up the variables. - * @param argv the arguments - */ - void processArgs(String[] argv) { - for (int i = 0; i < argv.length; i++) { - String arg = argv[i]; - if (arg.startsWith("-h")) { - usage(); - System.exit(0); - } else if (arg.equals("-d")) { - outputDir = argv[++i]; - } else if (arg.equals("-v")) { - verbose = true; - } else if (arg.equals("-V")) { - versionName = argv[++i]; - } else if (arg.equals("-doc")) { - outputDoc = true; - } else if (arg.equals("-map")) { - outputDoc = true; - mapFile = argv[++i]; - } else if (arg.equals("-f")) { - zoneNamesFile = argv[++i]; - } else if (arg.equals("-S")) { - try { - Zoneinfo.setYear(Integer.parseInt(argv[++i])); - } catch (Exception e) { - error("invalid year: " + argv[i]); - usage(); - System.exit(1); - } - } else { - boolean isStartYear = arg.equals("-s"); - if (isStartYear || arg.equals("-e")) { - try { - int year = Integer.parseInt(argv[++i]); - if (isStartYear) { - Zoneinfo.setStartYear(year); - } else { - Zoneinfo.setEndYear(year); - } - } catch (Exception e) { - error("invalid year: " + argv[i]); - usage(); - System.exit(1); - } - } else { - // the rest of args are zoneinfo source files - while (i < argv.length) { - ziFiles.add(argv[i++]); - } - } - } - } - } - - /** - * Parses zoneinfo source files - */ - int compile() { - int nFiles = ziFiles.size(); - int status = 0; - Mappings maps = new Mappings(); - BackEnd backend = BackEnd.getBackEnd(); - - for (int i = 0; i < nFiles; i++) { - Zoneinfo frontend = Zoneinfo.parse(ziFiles.get(i)); - - for (String key : frontend.getZones().keySet()) { - info(key); - - Timezone tz = frontend.phase2(key); - status |= backend.processZoneinfo(tz); - } - - maps.add(frontend); - } - - // special code for dealing with the conflicting name "MET" - Zone.addMET(); - - maps.resolve(); - - status |= backend.generateSrc(maps); - - return status; - } - - public static void main(String[] argv) { - Main zic = new Main(); - - /* - * Parse args - */ - zic.processArgs(argv); - - /* - * Read target zone names - */ - if (zoneNamesFile != null) { - Zone.readZoneNames(zoneNamesFile); - } - - zic.compile(); - } - - void usage() { - System.err.println("Usage: javazic [options] file...\n"+ - " -f namefile file containing zone names\n"+ - " to be generated (ie, generating subset)\n"+ - " -d dir output directory\n"+ - " -v verbose\n"+ - " -V datavers specifies the tzdata version string\n"+ - " (eg, \"tzdata2000g\")"+ - " -S year output only SimleTimeZone data of that year\n"+ - " -s year start year (default: 1900)\n"+ - " -e year end year (default: 2037)\n"+ - " -doc generates HTML documents\n"+ - " -map mapfile generates HTML documents with map information\n"+ - " file... zoneinfo source file(s)"); - } - - /** - * @return the output directory path name - */ - static String getOutputDir() { - return outputDir; - } - - /** - * @return the map file's path and name - */ - static String getMapFile() { - return mapFile; - } - - /** - * Returns the time zone data version string specified by the -V - * option. If it is not specified, "unknown" is returned. - * @return the time zone data version string - */ - static String getVersionName() { - return versionName; - } - - /** - * Prints out the specified fatal error message and calls {@link - * java.lang.System#exit System.exit(1)}. - * @param msg the fatal error message - */ - static void panic(String msg) { - printMessage("fatal error", msg); - System.exit(1); - } - - /** - * Prints out the specified error message. - * @param msg the error message - */ - static void error(String msg) { - printMessage("error", msg); - } - - /** - * Prints out the specified warning message. - * @param msg the warning message - */ - static void warning(String msg) { - printMessage("warning", msg); - } - - /** - * Prints out the informative message. - * @param msg the informative message - */ - static void info(String msg) { - if (verbose) { - printMessage(null, msg); - } - } - - private static void printMessage(String type, String msg) { - if (type != null) { - type += ": "; - } else { - type = ""; - } - System.err.println("javazic: " + type + msg); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Mappings.java b/test/jdk/sun/util/calendar/zi/Mappings.java deleted file mode 100644 index 582a9509a51c8..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Mappings.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - -/** - * Mappings generates two Maps and a List which are used by - * javazic BackEnd. - * - * @since 1.4 - */ -class Mappings { - // All aliases specified by Link statements. It's alias name to - // real name mappings. - private Map aliases; - - private List rawOffsetsIndex; - - private List> rawOffsetsIndexTable; - - // Zone names to be excluded from rawOffset table. Those have GMT - // offsets to change some future time. - private List excludeList; - - /** - * Constructor creates some necessary instances. - */ - Mappings() { - aliases = new TreeMap(); - rawOffsetsIndex = new LinkedList(); - rawOffsetsIndexTable = new LinkedList>(); - } - - /** - * Generates aliases and rawOffsets tables. - * @param zi a Zoneinfo containing Zones - */ - void add(Zoneinfo zi) { - Map zones = zi.getZones(); - - for (String zoneName : zones.keySet()) { - Zone zone = zones.get(zoneName); - String zonename = zone.getName(); - int rawOffset = zone.get(zone.size()-1).getGmtOffset(); - - // If the GMT offset of this Zone will change in some - // future time, this Zone is added to the exclude list. - boolean isExcluded = false; - for (int i = 0; i < zone.size(); i++) { - ZoneRec zrec = zone.get(i); - if ((zrec.getGmtOffset() != rawOffset) - && (zrec.getUntilTime(0) > Time.getCurrentTime())) { - if (excludeList == null) { - excludeList = new ArrayList(); - } - excludeList.add(zone.getName()); - isExcluded = true; - break; - } - } - - if (!rawOffsetsIndex.contains(new Integer(rawOffset))) { - // Find the index to insert this raw offset zones - int n = rawOffsetsIndex.size(); - int i; - for (i = 0; i < n; i++) { - if (rawOffsetsIndex.get(i) > rawOffset) { - break; - } - } - rawOffsetsIndex.add(i, rawOffset); - - Set perRawOffset = new TreeSet(); - if (!isExcluded) { - perRawOffset.add(zonename); - } - rawOffsetsIndexTable.add(i, perRawOffset); - } else if (!isExcluded) { - int i = rawOffsetsIndex.indexOf(new Integer(rawOffset)); - Set perRawOffset = rawOffsetsIndexTable.get(i); - perRawOffset.add(zonename); - } - } - - Map a = zi.getAliases(); - // If there are time zone names which refer to any of the - // excluded zones, add those names to the excluded list. - if (excludeList != null) { - for (String zoneName : a.keySet()) { - String realname = a.get(zoneName); - if (excludeList.contains(realname)) { - excludeList.add(zoneName); - } - } - } - aliases.putAll(a); - } - - /** - * Adds valid aliases to one of per-RawOffset table and removes - * invalid aliases from aliases List. Aliases referring to - * excluded zones are not added to a per-RawOffset table. - */ - void resolve() { - int index = rawOffsetsIndexTable.size(); - List toBeRemoved = new ArrayList(); - for (String key : aliases.keySet()) { - boolean validname = false; - for (int j = 0; j < index; j++) { - Set perRO = rawOffsetsIndexTable.get(j); - boolean isExcluded = (excludeList == null) ? - false : excludeList.contains(key); - - if ((perRO.contains(aliases.get(key)) || isExcluded) - && Zone.isTargetZone(key)) { - validname = true; - if (!isExcluded) { - perRO.add(key); - Main.info("Alias <"+key+"> added to the list."); - } - break; - } - } - - if (!validname) { - Main.info("Alias <"+key+"> removed from the list."); - toBeRemoved.add(key); - } - } - - // Remove zones, if any, from the list. - for (String key : toBeRemoved) { - aliases.remove(key); - } - // Eliminate any alias-to-alias mappings. For example, if - // there are A->B and B->C, A->B is changed to A->C. - Map newMap = new HashMap(); - for (String key : aliases.keySet()) { - String realid = aliases.get(key); - String leaf = realid; - while (aliases.get(leaf) != null) { - leaf = aliases.get(leaf); - } - if (!realid.equals(leaf)) { - newMap.put(key, leaf); - } - } - aliases.putAll(newMap); - } - - Map getAliases() { - return(aliases); - } - - List getRawOffsetsIndex() { - return(rawOffsetsIndex); - } - - List> getRawOffsetsIndexTable() { - return(rawOffsetsIndexTable); - } - - List getExcludeList() { - return excludeList; - } -} diff --git a/test/jdk/sun/util/calendar/zi/Month.java b/test/jdk/sun/util/calendar/zi/Month.java deleted file mode 100644 index bab909f763787..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Month.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -/** - * Month enum handles month related manipulation. - * - * @since 1.4 - */ -enum Month { - JANUARY("Jan"), - FEBRUARY("Feb"), - MARCH("Mar"), - APRIL("Apr"), - MAY("May"), - JUNE("Jun"), - JULY("Jul"), - AUGUST("Aug"), - SEPTEMBER("Sep"), - OCTOBER("Oct"), - NOVEMBER("Nov"), - DECEMBER("Dec"); - - private final String abbr; - - private Month(String abbr) { - this.abbr = abbr; - } - - int value() { - return ordinal() + 1; - } - - /** - * Parses the specified string as a month abbreviation. - * @param name the month abbreviation - * @return the Month value - */ - static Month parse(String name) { - int len = name.length(); - - if (name.regionMatches(true, 0, "January", 0, len)) return Month.JANUARY; - if (name.regionMatches(true, 0, "February", 0, len)) return Month.FEBRUARY; - if (name.regionMatches(true, 0, "March", 0, len)) return Month.MARCH; - if (name.regionMatches(true, 0, "April", 0, len)) return Month.APRIL; - if (name.regionMatches(true, 0, "May", 0, len)) return Month.MAY; - if (name.regionMatches(true, 0, "June", 0, len)) return Month.JUNE; - if (name.regionMatches(true, 0, "July", 0, len)) return Month.JULY; - if (name.regionMatches(true, 0, "August", 0, len)) return Month.AUGUST; - if (name.regionMatches(true, 0, "September", 0, len)) return Month.SEPTEMBER; - if (name.regionMatches(true, 0, "October", 0, len)) return Month.OCTOBER; - if (name.regionMatches(true, 0, "November", 0, len)) return Month.NOVEMBER; - if (name.regionMatches(true, 0, "December", 0, len)) return Month.DECEMBER; - - throw new IllegalArgumentException("Unknown month: " + name); - } - - /** - * @param month the nunmth number (1-based) - * @return the month name in uppercase of the specified month - */ - static String toString(int month) { - if (month >= JANUARY.value() && month <= DECEMBER.value()) { - return "Calendar." + Month.values()[month - 1]; - } - throw new IllegalArgumentException("wrong month number: " + month); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Rule.java b/test/jdk/sun/util/calendar/zi/Rule.java deleted file mode 100644 index 3098dc7e76651..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Rule.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.StringTokenizer; - -/** - * Rule manipulates Rule records. - * - * @since 1.4 - */ -class Rule { - - private List list; - private String name; - - /** - * Constructs a Rule which consists of a Rule record list. The - * specified name is given to this Rule. - * @param name the Rule name - */ - Rule(String name) { - this.name = name; - list = new ArrayList(); - } - - /** - * Added a RuleRec to the Rule record list. - */ - void add(RuleRec rec) { - list.add(rec); - } - - /** - * @return the Rule name - */ - String getName() { - return name; - } - - /** - * Gets all rule records that cover the given year. - * - * @param year the year number for which the rule is applicable. - * @return rules in List that are collated in time. If no rule is found, an empty - * List is returned. - */ - List getRules(int year) { - List rules = new ArrayList(3); - for (RuleRec rec : list) { - if (year >= rec.getFromYear() && year <= rec.getToYear()) { - if ((rec.isOdd() && year % 2 == 0) || (rec.isEven() && year % 2 == 1)) - continue; - rules.add(rec); - } - } - int n = rules.size(); - if (n <= 1) { - return rules; - } - if (n == 2) { - RuleRec rec1 = rules.get(0); - RuleRec rec2 = rules.get(1); - if (rec1.getMonthNum() > rec2.getMonthNum()) { - rules.set(0, rec2); - rules.set(1, rec1); - } else if (rec1.getMonthNum() == rec2.getMonthNum()) { - // TODO: it's not accurate to ignore time types (STD, WALL, UTC) - long t1 = Time.getLocalTime(year, rec1.getMonth(), - rec1.getDay(), rec1.getTime().getTime()); - long t2 = Time.getLocalTime(year, rec2.getMonth(), - rec2.getDay(), rec2.getTime().getTime()); - if (t1 > t2) { - rules.set(0, rec2); - rules.set(1, rec1); - } - } - return rules; - } - - final int y = year; - RuleRec[] recs = new RuleRec[rules.size()]; - rules.toArray(recs); - - Arrays.sort(recs, new Comparator() { - public int compare(RuleRec r1, RuleRec r2) { - int n = r1.getMonthNum() - r2.getMonthNum(); - if (n != 0) { - return n; - } - // TODO: it's not accurate to ignore time types (STD, WALL, UTC) - long t1 = Time.getLocalTime(y, r1.getMonth(), - r1.getDay(), r1.getTime().getTime()); - long t2 = Time.getLocalTime(y, r2.getMonth(), - r2.getDay(), r2.getTime().getTime()); - return Long.compare(t1, t2); - } - public boolean equals(Object o) { - return this == o; - } - }); - rules.clear(); - for (int i = 0; i < n; i++) { - if (i != 0 && recs[i -1].getSave() == recs[i].getSave()) { - // we have two recs back to back with same saving for the same year. - if (recs[i].isLastRule()) { - continue; - } else if (recs[i - 1].isLastRule()) { - rules.remove(rules.size() - 1); - } - } - rules.add(recs[i]); - } - return rules; - } - - /** - * Gets rule records that have either "max" or cover the endYear - * value in its DST schedule. - * - * @return rules that contain last DST schedule. An empty - * ArrayList is returned if no last rules are found. - */ - List getLastRules() { - RuleRec start = null; - RuleRec end = null; - - for (int i = 0; i < list.size(); i++) { - RuleRec rec = list.get(i); - if (rec.isLastRule()) { - if (rec.getSave() > 0) { - start = rec; - } else { - end = rec; - } - } - } - if (start == null || end == null) { - int endYear = Zoneinfo.getEndYear(); - for (int i = 0; i < list.size(); i++) { - RuleRec rec = list.get(i); - if (endYear >= rec.getFromYear() && endYear <= rec.getToYear()) { - if (start == null && rec.getSave() > 0) { - start = rec; - } else { - if (end == null && rec.getSave() == 0) { - end = rec; - } - } - } - } - } - - List r = new ArrayList(2); - if (start == null || end == null) { - if (start != null || end != null) { - Main.warning("found last rules for "+name+" inconsistent."); - } - return r; - } - - r.add(start); - r.add(end); - return r; - } -} diff --git a/test/jdk/sun/util/calendar/zi/RuleDay.java b/test/jdk/sun/util/calendar/zi/RuleDay.java deleted file mode 100644 index 9cd81c1e5246f..0000000000000 --- a/test/jdk/sun/util/calendar/zi/RuleDay.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -/** - * RuleDay class represents the value of the "ON" field. The day of - * week values start from 1 following the {@link java.util.Calendar} - * convention. - * - * @since 1.4 - */ -class RuleDay { - private String dayName = null; - private DayOfWeek dow; - private boolean lastOne = false; - private int soonerOrLater = 0; - private int thanDayOfMonth; // day of month (e.g., 8 for "Sun>=8") - - RuleDay() { - } - - RuleDay(int day) { - thanDayOfMonth = day; - } - - int getDay() { - return thanDayOfMonth; - } - - /** - * @return the day of week value (1-based) - */ - int getDayOfWeekNum() { - return dow.value(); - } - - /** - * @return true if this rule day represents the last day of - * week. (e.g., lastSun). - */ - boolean isLast() { - return lastOne; - } - - /** - * @return true if this rule day represents the day of week on or - * later than (after) the {@link #getDay}. (e.g., Sun>=1) - */ - boolean isLater() { - return soonerOrLater > 0; - } - - /** - * @return true if this rule day represents the day of week on or - * earlier than (before) the {@link #getDay}. (e.g., Sun<=15) - */ - boolean isEarlier() { - return soonerOrLater < 0; - } - - /** - * @return true if this rule day represents an exact day. - */ - boolean isExact() { - return soonerOrLater == 0; - } - - /** - * Parses the "ON" field and constructs a RuleDay. - * @param day an "ON" field string (e.g., "Sun>=1") - * @return a RuleDay representing the given "ON" field - */ - static RuleDay parse(String day) { - RuleDay d = new RuleDay(); - if (day.startsWith("last")) { - d.lastOne = true; - d.dayName = day.substring(4); - d.dow = getDOW(d.dayName); - } else { - int index; - if ((index = day.indexOf(">=")) != -1) { - d.dayName = day.substring(0, index); - d.dow = getDOW(d.dayName); - d.soonerOrLater = 1; // greater or equal - d.thanDayOfMonth = Integer.parseInt(day.substring(index+2)); - } else if ((index = day.indexOf("<=")) != -1) { - d.dayName = day.substring(0, index); - d.dow = getDOW(d.dayName); - d.soonerOrLater = -1; // less or equal - d.thanDayOfMonth = Integer.parseInt(day.substring(index+2)); - } else { - // it should be an integer value. - d.thanDayOfMonth = Integer.parseInt(day); - } - } - return d; - } - - /** - * Converts this RuleDay to the SimpleTimeZone day rule. - * @return the converted SimpleTimeZone day rule - */ - int getDayForSimpleTimeZone() { - if (isLast()) { - return -1; - } - return isEarlier() ? -getDay() : getDay(); - } - - /** - * Converts this RuleDay to the SimpleTimeZone day-of-week rule. - * @return the SimpleTimeZone day-of-week rule value - */ - int getDayOfWeekForSimpleTimeZoneInt() { - if (isEarlier() || isLater()) { - return -getDayOfWeekNum(); - } - return isLast() ? getDayOfWeekNum() : 0; - } - - /** - * @return the string representation of the {@link - * #getDayOfWeekForSimpleTimeZoneInt} value - */ - String getDayOfWeekForSimpleTimeZone() { - int d = getDayOfWeekForSimpleTimeZoneInt(); - if (d == 0) { - return "0"; - } - String sign = ""; - if (d < 0) { - sign = "-"; - d = -d; - } - return sign + toString(d); - } - - private static DayOfWeek getDOW(String name) { - int len = name.length(); - - if (name.regionMatches(true, 0, "Monday", 0, len)) return DayOfWeek.MONDAY; - if (name.regionMatches(true, 0, "Tuesday", 0, len)) return DayOfWeek.TUESDAY; - if (name.regionMatches(true, 0, "Wednesday", 0, len)) return DayOfWeek.WEDNESDAY; - if (name.regionMatches(true, 0, "Thursday", 0, len)) return DayOfWeek.THURSDAY; - if (name.regionMatches(true, 0, "Friday", 0, len)) return DayOfWeek.FRIDAY; - if (name.regionMatches(true, 0, "Saturday", 0, len)) return DayOfWeek.SATURDAY; - if (name.regionMatches(true, 0, "Sunday", 0, len)) return DayOfWeek.SUNDAY; - - throw new IllegalArgumentException("Unknown day-of-week: " + name); - } - - /** - * Converts the specified day of week value to the day-of-week - * name defined in {@link java.util.Calendar}. - * @param dow 1-based day of week value - * @return the Calendar day of week name with "Calendar." prefix. - * @throws IllegalArgumentException if the specified dow value is out of range. - */ - static String toString(int dow) { - if (dow >= DayOfWeek.SUNDAY.value() && dow <= DayOfWeek.SATURDAY.value()) { - return "Calendar." + DayOfWeek.values()[dow - 1]; - } - throw new IllegalArgumentException("wrong Day_of_Week number: " + dow); - } -} diff --git a/test/jdk/sun/util/calendar/zi/RuleRec.java b/test/jdk/sun/util/calendar/zi/RuleRec.java deleted file mode 100644 index e6e18773d1606..0000000000000 --- a/test/jdk/sun/util/calendar/zi/RuleRec.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.util.StringTokenizer; - -/** - * RuleRec class represents one record of the Rule set. - * - * @since 1.4 - */ -class RuleRec { - private int fromYear; - private int toYear; - private String type; - private Month inMonth; - private RuleDay onDay; - private Time atTime; - private int save; - private String letters; - private String line; - private boolean isLastRule; - - int getFromYear() { - return fromYear; - } - - int getToYear() { - return toYear; - } - - Month getMonth() { - return inMonth; - } - - int getMonthNum() { - return inMonth.value(); - } - - RuleDay getDay() { - return onDay; - } - - Time getTime() { - return atTime; - } - - int getSave() { - return save; - } - - String getLine() { - return line; - } - - /** - * Sets the line from the text file. - * @param line the text of the line - */ - void setLine(String line) { - this.line = line; - } - - /** - * @return true if the rule type is "odd". - */ - boolean isOdd() { - return "odd".equals(type); - } - - /** - * @return true if the rule type is "even". - */ - boolean isEven() { - return "even".equals(type); - } - - /** - * Determines if this rule record is the last DST schedule rule. - * - * @return true if this rule record has "max" as TO (year). - */ - boolean isLastRule() { - return isLastRule; - } - - /** - * Determines if the unadjusted until time of the specified ZoneRec - * is the same as the transition time of this rule in the same - * year as the ZoneRec until year. - * - * @param zrec ZoneRec to compare to - * @param save the amount of daylight saving in milliseconds - * @param gmtOffset the GMT offset value in milliseconds - * @return true if the unadjusted until time is the same as rule's - * transition time. - */ - boolean isSameTransition(ZoneRec zrec, int save, int gmtOffset) { - long until, transition; - - if (zrec.getUntilTime().getType() != atTime.getType()) { - until = zrec.getLocalUntilTime(save, gmtOffset); - transition = Time.getLocalTime(zrec.getUntilYear(), - getMonth(), - getDay(), - save, - gmtOffset, - atTime); - } else { - until = zrec.getLocalUntilTime(); - transition = Time.getLocalTime(zrec.getUntilYear(), - getMonth(), - getDay(), - atTime.getTime()); - } - - return until == transition; - } - - /** - * Parses a Rule line and returns a RuleRec object. - * - * @param tokens a StringTokenizer object that should contain a - * token for the "FROM" field and the rest. - * @return a RuleRec object. - */ - static RuleRec parse(StringTokenizer tokens) { - RuleRec rec = new RuleRec(); - try { - // FROM - String token = tokens.nextToken(); - try { - rec.fromYear = Integer.parseInt(token); - } catch (NumberFormatException e) { - // it's not integer - if ("min".equals(token) || "minimum".equals(token)) { - rec.fromYear = Zoneinfo.getMinYear(); - } else if ("max".equals(token) || "maximum".equals(token)) { - rec.fromYear = Zoneinfo.getMaxYear(); - } else { - Main.panic("invalid year value: "+token); - } - } - - // TO - token = tokens.nextToken(); - rec.isLastRule = false; - try { - rec.toYear = Integer.parseInt(token); - } catch (NumberFormatException e) { - // it's not integer - int len = token.length(); - if (token.regionMatches(true, 0, "minimum", 0, len)) { - rec.fromYear = Zoneinfo.getMinYear(); - } else if (token.regionMatches(true, 0, "maximum", 0, len)) { - rec.toYear = Integer.MAX_VALUE; - rec.isLastRule = true; - } else if (token.regionMatches(true, 0, "only", 0, len)) { - rec.toYear = rec.fromYear; - } else { - Main.panic("invalid year value: "+token); - } - } - - // TYPE - rec.type = tokens.nextToken(); - - // IN - rec.inMonth = Month.parse(tokens.nextToken()); - - // ON - rec.onDay = RuleDay.parse(tokens.nextToken()); - - // AT - rec.atTime = Time.parse(tokens.nextToken()); - - // SAVE - rec.save = (int) Time.parse(tokens.nextToken()).getTime(); - - // LETTER/S - rec.letters = tokens.nextToken(); - } catch (Exception e) { - e.printStackTrace(); - } - return rec; - } - - /** - * Calculates the transition time of the given year under this rule. - * @param year the year value - * @param gmtOffset the GMT offset value in milliseconds - * @param save the amount of daylight save time - * @return the transition time in milliseconds of the given year in UTC. - */ - long getTransitionTime(int year, int gmtOffset, int save) { - long time = Time.getLocalTime(year, getMonth(), - getDay(), atTime.getTime()); - if (atTime.isSTD()) { - time -= gmtOffset; - } else if (atTime.isWall()) { - time -= gmtOffset + save; - } - return time; - } - - private static int getInt(StringTokenizer tokens) { - String token = tokens.nextToken(); - return Integer.parseInt(token); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Simple.java b/test/jdk/sun/util/calendar/zi/Simple.java deleted file mode 100644 index 0889155a99e97..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Simple.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.TreeSet; - -/** - * Simple generates TimeZoneData, which had been used as internal - * data of TimeZone before J2SDK1.3. - * Since J2SDK1.4 doesn't need TimeZoneData, this class is for maintenance - * of old JDK release. - */ -class Simple extends BackEnd { - - /** - * Zone records which are applied for given year. - */ - private static Map lastZoneRecs = new HashMap<>(); - - /** - * Rule records which are applied for given year. - */ - private static Map> lastRules = new TreeMap<>(); - - /** - * zone IDs sorted by their GMT offsets. If zone's GMT - * offset will change in the future, its last known offset is - * used. - */ - private SortedMap> zonesByOffset = new TreeMap<>(); - - /** - * Sets last Rule records and Zone records for given timezone to - * each Map. - * - * @param tz Timezone object for each zone - * @return always 0 - */ - int processZoneinfo(Timezone tz) { - String zonename = tz.getName(); - - lastRules.put(zonename, tz.getLastRules()); - lastZoneRecs.put(zonename, tz.getLastZoneRec()); - - // Populate zonesByOffset. (Zones that will change their - // GMT offsets are also added to zonesByOffset here.) - int lastKnownOffset = tz.getRawOffset(); - Set set = zonesByOffset.get(lastKnownOffset); - if (set == null) { - set = new TreeSet<>(); - zonesByOffset.put(lastKnownOffset, set); - } - set.add(zonename); - - return 0; - } - - /** - * Generates TimeZoneData to output SimpleTimeZone data. - * @param map Mappings object which is generated by {@link Main#compile}. - * @return 0 if no error occurred, otherwise 1. - */ - int generateSrc(Mappings map) { - try { - File outD = new File(Main.getOutputDir()); - outD.mkdirs(); - - FileWriter fw = - new FileWriter(new File(outD, "TimeZoneData.java"), false); - BufferedWriter out = new BufferedWriter(fw); - - out.write("import java.util.SimpleTimeZone;\n\n"); - out.write(" static SimpleTimeZone zones[] = {\n"); - - Map a = map.getAliases(); - List roi = map.getRawOffsetsIndex(); - List> roit = map.getRawOffsetsIndexTable(); - - int index = 0; - for (int offset : zonesByOffset.keySet()) { - int o = roi.get(index); - Set set = zonesByOffset.get(offset); - if (offset == o) { - // Merge aliases into zonesByOffset - set.addAll(roit.get(index)); - } - index++; - - for (String key : set) { - ZoneRec zrec; - String realname; - List stz; - if ((realname = a.get(key)) != null) { - // if this alias is not targeted, ignore it. - if (!Zone.isTargetZone(key)) { - continue; - } - stz = lastRules.get(realname); - zrec = lastZoneRecs.get(realname); - } else { - stz = lastRules.get(key); - zrec = lastZoneRecs.get(key); - } - - out.write("\t//--------------------------------------------------------------------\n"); - String s = Time.toFormedString(offset); - out.write("\tnew SimpleTimeZone(" + - Time.toFormedString(offset) + ", \"" + key + "\""); - if (realname != null) { - out.write(" /* " + realname + " */"); - } - - if (stz == null) { - out.write("),\n"); - } else { - RuleRec rr0 = stz.get(0); - RuleRec rr1 = stz.get(1); - - out.write(",\n\t " + Month.toString(rr0.getMonthNum()) + - ", " + rr0.getDay().getDayForSimpleTimeZone() + ", " + - rr0.getDay().getDayOfWeekForSimpleTimeZone() + ", " + - Time.toFormedString((int)rr0.getTime().getTime()) + ", " + - rr0.getTime().getTypeForSimpleTimeZone() + ",\n" + - - "\t " + Month.toString(rr1.getMonthNum()) + ", " + - rr1.getDay().getDayForSimpleTimeZone() + ", " + - rr1.getDay().getDayOfWeekForSimpleTimeZone() + ", " + - Time.toFormedString((int)rr1.getTime().getTime())+ ", " + - rr1.getTime().getTypeForSimpleTimeZone() + ",\n" + - - "\t " + Time.toFormedString(rr0.getSave()) + "),\n"); - - out.write("\t// " + rr0.getLine() + "\n"); - out.write("\t// " + rr1.getLine() + "\n"); - } - - String zline = zrec.getLine(); - if (zline.indexOf("Zone") == -1) { - zline = "Zone " + key + "\t" + zline.trim(); - } - out.write("\t// " + zline + "\n"); - } - } - out.write(" };\n"); - - out.close(); - fw.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } -} diff --git a/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java b/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java deleted file mode 100644 index 0b6570b74dc73..0000000000000 --- a/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2012, 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 8007572 8008161 8157792 8212970 8224560 8324065 - * @summary Test whether the TimeZone generated from JSR310 tzdb is the same - * as the one from the tz data from javazic - * @modules java.base/sun.util.calendar:+open - * @build BackEnd Checksum DayOfWeek Gen GenDoc Main Mappings Month - * Rule RuleDay RuleRec Simple TestZoneInfo310 Time Timezone - * TzIDOldMapping Zone ZoneInfoFile ZoneInfoOld ZoneRec Zoneinfo - * @run main TestZoneInfo310 - */ - -import java.io.File; -import java.lang.reflect.*; -import java.nio.file.*; -import java.util.*; -import java.util.regex.*; -import java.time.zone.*; -import java.time.ZoneId; - -public class TestZoneInfo310 { - - public static void main(String[] args) throws Throwable { - - String TESTDIR = System.getProperty("test.dir", "."); - Path tzdir = Paths.get(System.getProperty("test.root"), - "../../src/java.base/share/data/tzdata"); - String tzfiles = "africa antarctica asia australasia europe northamerica southamerica backward etcetera gmt"; - Path jdk_tzdir = Paths.get(System.getProperty("test.src"), "tzdata_jdk"); - String jdk_tzfiles = "jdk11_backward"; - String zidir = TESTDIR + File.separator + "zi"; - File fZidir = new File(zidir); - if (!fZidir.exists()) { - fZidir.mkdirs(); - } - Matcher m = Pattern.compile("tzdata(?[0-9]{4}[A-z])") - .matcher(new String(Files.readAllBytes(tzdir.resolve("VERSION")), "ascii")); - String ver = m.find() ? m.group("ver") : "NULL"; - - ArrayList alist = new ArrayList<>(); - alist.add("-V"); - alist.add(ver); - alist.add("-d"); - alist.add(zidir); - for (String f : tzfiles.split(" ")) { - alist.add(tzdir.resolve(f).toString()); - } - for (String f : jdk_tzfiles.split(" ")) { - alist.add(jdk_tzdir.resolve(f).toString()); - } - System.out.println("Compiling tz files!"); - Main.main(alist.toArray(new String[alist.size()])); - - ////////////////////////////////// - System.out.println("testing!"); - ZoneInfoFile.ziDir = zidir; - long t0, t1; - - t0 = System.nanoTime(); - ZoneInfoOld.getTimeZone("America/Los_Angeles"); - t1 = System.nanoTime(); - System.out.printf("OLD.getZoneInfoOld()[1]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - ZoneInfoOld.getTimeZone("America/New_York"); - t1 = System.nanoTime(); - System.out.printf("OLD.getZoneInfoOld()[2]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - ZoneInfoOld.getTimeZone("America/Denver"); - t1 = System.nanoTime(); - System.out.printf("OLD.getZoneInfoOld()[3]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - String[] zids_old = ZoneInfoOld.getAvailableIDs(); - t1 = System.nanoTime(); - System.out.printf("OLD.getAvailableIDs()=%d, total=%d%n", - (t1 - t0) / 1000, zids_old.length); - Arrays.sort(zids_old); - - t0 = System.nanoTime(); - String[] alias_old = ZoneInfoOld.getAliasTable() - .keySet().toArray(new String[0]); - t1 = System.nanoTime(); - System.out.printf("OLD.getAliasTable()=%d, total=%d%n", - (t1 - t0) / 1000, alias_old.length); - Arrays.sort(alias_old); - - t0 = System.currentTimeMillis(); - for (String zid : zids_old) { - ZoneInfoOld.getTimeZone(zid); - } - t1 = System.currentTimeMillis(); - System.out.printf("OLD.TotalTZ()=%d (ms)%n", t1 - t0); - -/* - t0 = System.nanoTime(); - ZoneId.of("America/Los_Angeles").getRules(); - t1 = System.nanoTime(); - System.out.printf("NEW.ZoneId.of()[1]=%d%n", (t1 - t0) / 1000); -*/ - t0 = System.nanoTime(); - TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); - t1 = System.nanoTime(); - System.out.printf("NEW.getTimeZone()[1]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - tz = TimeZone.getTimeZone("America/New_York"); - t1 = System.nanoTime(); - System.out.printf("NEW.getTimeZone()[2]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - tz = TimeZone.getTimeZone("America/Denver"); - t1 = System.nanoTime(); - System.out.printf("NEW.getTimeZone()[3]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - String[] zids_new = TimeZone.getAvailableIDs(); - t1 = System.nanoTime(); - System.out.printf("NEW.getAvailableIDs()=%d, total=%d%n", - (t1 - t0) / 1000, zids_new.length); - Arrays.sort(zids_new); - - t0 = System.nanoTime(); - String[] alias_new = sun.util.calendar.ZoneInfo.getAliasTable() - .keySet().toArray(new String[0]); - t1 = System.nanoTime(); - System.out.printf("NEW.getAliasTable()=%d, total=%d%n", - (t1 - t0) / 1000, alias_new.length); - Arrays.sort(alias_new); - - t0 = System.currentTimeMillis(); - for (String zid : zids_new) { - TimeZone.getTimeZone(zid); - } - t1 = System.currentTimeMillis(); - System.out.printf("NEW.TotalTZ()=%d (ms)%n", t1 - t0); - - if (!Arrays.equals(zids_old, zids_new)) { - throw new RuntimeException(" FAILED: availableIds don't match"); - } - - if (!Arrays.equals(alias_old, alias_new)) { - throw new RuntimeException(" FAILED: aliases don't match"); - } - - for (String zid : zids_new) { - ZoneInfoOld zi = toZoneInfoOld(TimeZone.getTimeZone(zid)); - ZoneInfoOld ziOLD = (ZoneInfoOld)ZoneInfoOld.getTimeZone(zid); - /* - * Ignoring the failing TimeZones which have negative DST - * save time in IANA tzdata, as javazic/ZoneInfoOld cannot - * handle the negative DST. - * - * These are the zones/rules that employ negative DST in vanguard - * format (as of 2019a), Palestine added in 2022d: - * - * - Rule "Eire" - * - Rule "Morocco" - * - Rule "Namibia" - * - Rule "Palestine" - * - Zone "Europe/Prague" - */ - if (zid.equals("Africa/Casablanca") || // uses "Morocco" rule - zid.equals("Africa/El_Aaiun") || // uses "Morocco" rule - zid.equals("Africa/Windhoek") || // uses "Namibia" rule - zid.equals("Eire") || - zid.equals("Europe/Bratislava") || // link to "Europe/Prague" - zid.equals("Europe/Dublin") || // uses "Eire" rule - zid.equals("Europe/Prague") || - zid.equals("Asia/Gaza") || // uses "Palestine" rule - zid.equals("Asia/Hebron")) { // uses "Palestine" rule - continue; - } - if (! zi.equalsTo(ziOLD)) { - System.out.println(zi.diffsTo(ziOLD)); - throw new RuntimeException(" FAILED: " + zid); - } - } - delete(fZidir); - - // test tzdb version - if (!ver.equals(sun.util.calendar.ZoneInfoFile.getVersion())) { - System.out.printf(" FAILED: ver=%s, expected=%s%n", - sun.util.calendar.ZoneInfoFile.getVersion(), ver); - throw new RuntimeException("Version test failed"); - } - - // test getAvailableIDs(raw); - zids_new = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000); - Arrays.sort(zids_new); - zids_old = ZoneInfoOld.getAvailableIDs(-8 * 60 * 60 * 1000); - Arrays.sort(zids_old); - if (!Arrays.equals(zids_new, zids_old)) { - System.out.println("------------------------"); - System.out.println("NEW.getAvailableIDs(-8:00)"); - for (String zid : zids_new) { - System.out.println(zid); - } - System.out.println("------------------------"); - System.out.println("OLD.getAvailableIDs(-8:00)"); - for (String zid : zids_old) { - System.out.println(zid); - } - throw new RuntimeException(" FAILED: availableIds(offset) don't match"); - } - } - - private static void delete(File f) { - if (f.isDirectory()) { - for (File f0 : f.listFiles()) { - delete(f0); - } - } - f.delete(); - } - - // to access sun.util.calendar.ZoneInfo's private fields - static Class ziClz; - static Field rawOffset; - static Field checksum; - static Field dstSavings; - static Field transitions; - static Field offsets; - static Field simpleTimeZoneParams; - static Field willGMTOffsetChange; - static { - try { - ziClz = Class.forName("sun.util.calendar.ZoneInfo"); - rawOffset = ziClz.getDeclaredField("rawOffset"); - checksum = ziClz.getDeclaredField("checksum"); - dstSavings = ziClz.getDeclaredField("dstSavings"); - transitions = ziClz.getDeclaredField("transitions"); - offsets = ziClz.getDeclaredField("offsets"); - simpleTimeZoneParams = ziClz.getDeclaredField("simpleTimeZoneParams"); - willGMTOffsetChange = ziClz.getDeclaredField("willGMTOffsetChange"); - rawOffset.setAccessible(true); - checksum.setAccessible(true); - dstSavings.setAccessible(true); - transitions.setAccessible(true); - offsets.setAccessible(true); - simpleTimeZoneParams.setAccessible(true); - willGMTOffsetChange.setAccessible(true); - } catch (Exception x) { - throw new RuntimeException(x); - } - } - - private static ZoneInfoOld toZoneInfoOld(TimeZone tz) throws Exception { - return new ZoneInfoOld(tz.getID(), - rawOffset.getInt(tz), - dstSavings.getInt(tz), - checksum.getInt(tz), - (long[])transitions.get(tz), - (int[])offsets.get(tz), - (int[])simpleTimeZoneParams.get(tz), - willGMTOffsetChange.getBoolean(tz)); - } - -} diff --git a/test/jdk/sun/util/calendar/zi/Time.java b/test/jdk/sun/util/calendar/zi/Time.java deleted file mode 100644 index 66379d29d28ee..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Time.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.Locale; -import sun.util.calendar.CalendarDate; -import sun.util.calendar.CalendarSystem; -import sun.util.calendar.Gregorian; - -/** - * Time class represents the "AT" field and other time related information. - * - * @since 1.4 - */ -class Time { - - static final Gregorian gcal = CalendarSystem.getGregorianCalendar(); - - // type is wall clock time - private static final int WALL = 1; - - // type is standard time - private static final int STD = 2; - - // type is UTC - private static final int UTC = 3; - - // type of representing time - private int type; - - /** - * Time from the EPOCH in milliseconds - */ - private long time; - - /** - * Current time in milliseconds - */ - private static final long currentTime = System.currentTimeMillis(); - - Time() { - time = 0L; - } - - Time(long time) { - this.time = time; - } - - void setType(int type) { - this.type = type; - } - - long getTime() { - return time; - } - - int getType() { - return type; - } - - static long getCurrentTime() { - return currentTime; - } - - /** - * @return true if the time is represented in wall-clock time. - */ - boolean isWall() { - return type == WALL; - } - - /** - * @return true if the time is represented in standard time. - */ - boolean isSTD() { - return type == STD; - } - - /** - * @return true if the time is represented in UTC time. - */ - boolean isUTC() { - return type == UTC; - } - - /** - * Converts the type to a string that represents the type in the - * SimpleTimeZone time mode. (e.g., "SimpleTimeZone.WALL_TIME"). - * @return the converted string or null if the type is undefined. - */ - String getTypeForSimpleTimeZone() { - String stz = "SimpleTimeZone."; - if (isWall()) { - return stz+"WALL_TIME"; - } - else if (isSTD()) { - return stz+"STANDARD_TIME"; - } - else if (isUTC()) { - return stz+"UTC_TIME"; - } - else { - return null; - } - } - - /** - * Converts the given Gregorian calendar field values to local time. - * Local time is represented by the amount of milliseconds from - * January 1, 1970 0:00 GMT. - * @param year the year value - * @param month the Month value - * @param day the day represented by {@link RuleDay} - * @param save the amount of daylight time in milliseconds - * @param gmtOffset the GMT offset in milliseconds - * @param time the time of the day represented by {@link Time} - * @return local time - */ - static long getLocalTime(int year, Month month, RuleDay day, int save, - int gmtOffset, Time time) { - long t = time.getTime(); - - if (time.isSTD()) - t = time.getTime() + save; - else if (time.isUTC()) - t = time.getTime() + save + gmtOffset; - - return getLocalTime(year, month, day, t); - } - - /** - * Converts the given Gregorian calendar field values to local time. - * Local time is represented by the amount of milliseconds from - * January 1, 1970 0:00 GMT. - * @param year the year value - * @param month the Month value - * @param day the day value - * @param time the time of the day in milliseconds - * @return local time - */ - static long getLocalTime(int year, Month month, int day, long time) { - CalendarDate date = gcal.newCalendarDate(null); - date.setDate(year, month.value(), day); - long millis = gcal.getTime(date); - return millis + time; - } - - /** - * Equivalent to getLocalTime(year, month, day, (long)time). - * @param year the year value - * @param month the Month value - * @param day the day value - * @param time the time of the day in milliseconds - * @return local time - */ - static long getLocalTime(int year, Month month, int day, int time) { - return getLocalTime(year, month, day, (long)time); - } - - /** - * Equivalent to {@link #getLocalTime(int, Month, RuleDay, int) - * getLocalTime(year, month, day, (int) time)}. - * @param year the year value - * @param month the Month value - * @param day the day represented by {@link RuleDay} - * @param time the time of the day represented by {@link Time} - * @return local time - */ - static long getLocalTime(int year, Month month, RuleDay day, long time) { - return getLocalTime(year, month, day, (int) time); - } - - /** - * Converts the given Gregorian calendar field values to local time. - * Local time is represented by the amount of milliseconds from - * January 1, 1970 0:00 GMT. - * @param year the year value - * @param month the Month value - * @param day the day represented by {@link RuleDay} - * @param time the time of the day represented by {@link Time} - * @return local time - */ - static long getLocalTime(int year, Month month, RuleDay day, int time) { - CalendarDate cdate = gcal.newCalendarDate(null); - int monthValue = month.value(); - - if (day.isLast()) { // e.g., "lastSun" - cdate.setDate(year, monthValue, 1); - cdate.setDayOfMonth(gcal.getMonthLength(cdate)); - cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate); - } else if (day.isLater()) { // e.g., "Sun>=1" - cdate.setDate(year, monthValue, day.getDay()); - cdate = gcal.getNthDayOfWeek(1, day.getDayOfWeekNum(), cdate); - } else if (day.isExact()) { - cdate.setDate(year, monthValue, day.getDay()); - } else if (day.isEarlier()) { // e.g., "Sun<=15" - cdate.setDate(year, monthValue, day.getDay()); - cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate); - } else { - Main.panic("invalid day type: " + day); - } - return gcal.getTime(cdate) + time; - } - - /** - * Parses the given "AT" field and constructs a Time object. - * @param the "AT" field string - * @return the Time object - */ - static Time parse(String time) { - int sign; - int index = 0; - Time tm; - - if (time.charAt(0) == '-') { - sign = -1; - index++; - } else { - sign = 1; - } - int val = 0; - int num = 0; - int countDelim = 0; - while (index < time.length()) { - char c = time.charAt(index++); - if (c == ':') { - val = val * 60 + num; - countDelim++; - num = 0; - continue; - } - int d = Character.digit(c, 10); - if (d == -1) { - --index; - break; - } - num = num * 10 + d; - } - val = val * 60 + num; - // convert val to second - for (; countDelim < 2; countDelim++) { - val *= 60; - } - tm = new Time((long)val * 1000 * sign); - if (index < time.length()) { - char c = time.charAt(index++); - if (c == 's') { - tm.setType(Time.STD); - } else if (c == 'u' || c == 'g' || c == 'z') { - tm.setType(Time.UTC); - } else if (c == 'w') { - tm.setType(Time.WALL); - } else { - Main.panic("unknown time mode: "+c); - } - } else { - tm.setType(Time.WALL); - } - return tm; - } - - /** - * Converts the given milliseconds string to a "[+-]hh:mm" string. - * @param ms the milliseconds string - */ - static String toGMTFormat(String ms) { - long sec = Long.parseLong(ms) / 1000; - char sign; - if (sec < 0) { - sign = '-'; - sec = -sec; - } else { - sign = '+'; - } - return String.format((Locale)null, "%c%02d:%02d", - sign, sec/3600, (sec%3600)/60); - } - - /** - * Converts the given millisecond value to a string for a - * SimpleTimeZone parameter. - * @param ms the millisecond value - * @return the string in a human readable form - */ - static String toFormedString(int ms) { - StringBuilder s = new StringBuilder(); - boolean minus = false; - - if (ms < 0) { - s.append("-"); - minus = true; - ms = -ms; - } else if (ms == 0) { - return "0"; - } - - int hour = ms / (60 * 60 * 1000); - ms %= (60 * 60 * 1000); - int minute = ms / (60 * 1000); - - if (hour != 0) { - if (minus && minute != 0) { - s.append("("); - } - s.append(Integer.toString(hour) + "*ONE_HOUR"); - } - - if (minute != 0) { - if (hour != 0) { - s.append("+"); - } - s.append(Integer.toString(minute) + "*ONE_MINUTE"); - if (minus && hour != 0) { - s.append(")"); - } - } - - return s.toString(); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Timezone.java b/test/jdk/sun/util/calendar/zi/Timezone.java deleted file mode 100644 index d4890e8f58b55..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Timezone.java +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.ArrayList; -import java.util.List; - -/** - * Timezone represents all information of a single point of time to - * generate its time zone database. - * - * @since 1.4 - */ -class Timezone { - /** - * zone name of this time zone - */ - private String name; - - /** - * transition time values in UTC (millisecond) - */ - private List transitions; - - /** - * All offset values in millisecond - * @see sun.util.calendar.ZoneInfo - */ - private List offsets; - - /** - * Indices of GMT offset values (both raw and raw+saving) - * at transitions - */ - private List gmtOffsets; - - /** - * Indices of regular or "direct" saving time values - * at transitions - */ - private List dstOffsets; - - /** - * Zone records of this time zone - */ - private List usedZoneRecs; - - /** - * Rule records referred to by this time zone - */ - private List usedRuleRecs; - - /** - * Type of DST rules in this time zone - */ - private int dstType; - static final int UNDEF_DST = 0; // DST type not set yet - static final int NO_DST = 1; // never observed DST - static final int LAST_DST = 2; // last rule ends in DST (all year round DST-only) - static final int X_DST = 3; // used to observe DST - static final int DST = 4; // observing DST regularly - - /** - * Raw GMT offset of this time zone in the last rule - */ - private int rawOffset; - - /** - * The CRC32 value of the transitions data - */ - private int crc32; - - /** - * The last ZoneRec - */ - private ZoneRec lastZoneRec; - - /** - * The last DST rules. lastRules[0] is the DST start - * rule. lastRules[1] is the DST end rules. - */ - private List lastRules; - - /** - * The amount of DST saving value (millisecond) in the last DST - * rule. - */ - private int lastSaving; - - /** - * true if the raw offset will change in the future time. - */ - private boolean willRawOffsetChange = false; - - - /** - * Constracts a Timezone object with the given zone name. - * @param name the zone name - */ - Timezone(String name) { - this.name = name; - } - - /** - * @return the number of transitions - */ - int getNTransitions() { - if (transitions == null) { - return 0; - } - return transitions.size(); - } - - /** - * @return the zone name - */ - String getName() { - return name; - } - - /** - * Returns the list of all rule records that have been referred to - * by this time zone. - * @return the rule records list - */ - List getRules() { - return usedRuleRecs; - } - - /** - * Returns the list of all zone records that have been referred to - * by this time zone. - * @return the zone records list - */ - List getZones() { - return usedZoneRecs; - } - - /** - * @return the transition table (list) - */ - List getTransitions() { - return transitions; - } - - /** - * @return the offsets list - */ - List getOffsets() { - return offsets; - } - - /** - * @return the DST saving offsets list - */ - List getDstOffsets() { - return dstOffsets; - } - - /** - * @return the GMT offsets list - */ - List getGmtOffsets() { - return gmtOffsets; - } - - /** - * @return the checksum (crc32) value of the trasition table - */ - int getCRC32() { - return crc32; - } - - /** - * @return true if the GMT offset of this time zone would change - * after the time zone database has been generated, false, otherwise. - */ - boolean willGMTOffsetChange() { - return willRawOffsetChange; - } - - /** - * @return the last known GMT offset value in milliseconds - */ - int getRawOffset() { - return rawOffset; - } - - /** - * Sets time zone's GMT offset to offset. - * @param offset the GMT offset value in milliseconds - */ - void setRawOffset(int offset) { - rawOffset = offset; - } - - /** - * Sets time zone's GMT offset value to offset. If - * startTime is future time, then the {@link - * #willRawOffsetChange} value is set to true. - * @param offset the GMT offset value in milliseconds - * @param startTime the UTC time at which the GMT offset is in effective - */ - void setRawOffset(int offset, long startTime) { - // if this rawOffset is for the future time, let the run-time - // look for the current GMT offset. - if (startTime > Time.getCurrentTime()) { - willRawOffsetChange = true; - } - setRawOffset(offset); - } - - /** - * Adds the specified transition information to the end of the transition table. - * @param time the UTC time at which this transition happens - * @param offset the total amount of the offset from GMT in milliseconds - * @param dstOffset the amount of time in milliseconds saved at this transition - */ - void addTransition(long time, int offset, int dstOffset) { - if (transitions == null) { - transitions = new ArrayList(); - offsets = new ArrayList(); - dstOffsets = new ArrayList(); - } - transitions.add(time); - offsets.add(offset); - dstOffsets.add(dstOffset); - } - - /** - * Sets the type of historical daylight saving time - * observation. For example, China used to observed daylight - * saving time, but it no longer does. Then, X_DST is set to the - * China time zone. - * @param type the type of daylight saving time - */ - void setDSTType(int type) { - dstType = type; - } - - /** - * @return the type of historical daylight saving time - * observation. - */ - int getDSTType() { - return dstType; - } - - /** - * Adds the specified zone record to the zone records list. - * @param rec the zone record - */ - void addUsedRec(ZoneRec rec) { - if (usedZoneRecs == null) { - usedZoneRecs = new ArrayList(); - } - usedZoneRecs.add(rec); - } - - /** - * Adds the specified rule record to the rule records list. - * @param rec the rule record - */ - void addUsedRec(RuleRec rec) { - if (usedRuleRecs == null) { - usedRuleRecs = new ArrayList(); - } - // if the last used rec is the same as the given rec, avoid - // putting the same rule. - int n = usedRuleRecs.size(); - for (int i = 0; i < n; i++) { - if (usedRuleRecs.get(i).equals(rec)) { - return; - } - } - usedRuleRecs.add(rec); - } - - /** - * Sets the last zone record for this time zone. - * @param the last zone record - */ - void setLastZoneRec(ZoneRec zrec) { - lastZoneRec = zrec; - } - - /** - * @return the last zone record for this time zone. - */ - ZoneRec getLastZoneRec() { - return lastZoneRec; - } - - /** - * Sets the last rule records for this time zone. Those are used - * for generating SimpleTimeZone parameters. - * @param rules the last rule records - */ - void setLastRules(List rules) { - int n = rules.size(); - if (n > 0) { - lastRules = rules; - RuleRec rec = rules.get(0); - int offset = rec.getSave(); - if (offset > 0) { - setLastDSTSaving(offset); - } else { - System.err.println("\t No DST starting rule in the last rules."); - } - } - } - - /** - * @return the last rule records for this time zone. - */ - List getLastRules() { - return lastRules; - } - - /** - * Sets the last daylight saving amount. - * @param the daylight saving amount - */ - void setLastDSTSaving(int offset) { - lastSaving = offset; - } - - /** - * @return the last daylight saving amount. - */ - int getLastDSTSaving() { - return lastSaving; - } - - /** - * Calculates the CRC32 value from the transition table and sets - * the value to crc32. - */ - void checksum() { - if (transitions == null) { - crc32 = 0; - return; - } - Checksum sum = new Checksum(); - for (int i = 0; i < transitions.size(); i++) { - int offset = offsets.get(i); - // adjust back to make the transition in local time - sum.update(transitions.get(i) + offset); - sum.update(offset); - sum.update(dstOffsets.get(i)); - } - crc32 = (int)sum.getValue(); - } - - /** - * Removes unnecessary transitions for Java time zone support. - */ - void optimize() { - // if there is only one offset, delete all transitions. This - // could happen if only time zone abbreviations changed. - if (gmtOffsets.size() == 1) { - transitions = null; - usedRuleRecs = null; - setDSTType(NO_DST); - return; - } - for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one - if (transitions.get(i) == transitions.get(i+1)) { - transitions.remove(i); - offsets.remove(i); - dstOffsets.remove(i); - i--; - } - } - - for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one - if (offsets.get(i) == offsets.get(i+1) - && dstOffsets.get(i) == dstOffsets.get(i+1)) { - transitions.remove(i+1); - offsets.remove(i+1); - dstOffsets.remove(i+1); - i--; - } - } - } - - /** - * Stores the specified offset value from GMT in the GMT offsets - * table and returns its index. The offset value includes the base - * GMT offset and any additional daylight saving if applicable. If - * the same value as the specified offset is already in the table, - * its index is returned. - * @param offset the offset value in milliseconds - * @return the index to the offset value in the GMT offsets table. - */ - int getOffsetIndex(int offset) { - return getOffsetIndex(offset, 0); - } - - /** - * Stores the specified daylight saving value in the GMT offsets - * table and returns its index. If the same value as the specified - * offset is already in the table, its index is returned. If 0 is - * specified, it's not stored in the table and -1 is returned. - * @param offset the offset value in milliseconds - * @return the index to the specified offset value in the GMT - * offsets table, or -1 if 0 is specified. - */ - int getDstOffsetIndex(int offset) { - if (offset == 0) { - return -1; - } - return getOffsetIndex(offset, 1); - } - - private int getOffsetIndex(int offset, int index) { - if (gmtOffsets == null) { - gmtOffsets = new ArrayList(); - } - for (int i = index; i < gmtOffsets.size(); i++) { - if (offset == gmtOffsets.get(i)) { - return i; - } - } - if (gmtOffsets.size() < index) { - gmtOffsets.add(0); - } - gmtOffsets.add(offset); - return gmtOffsets.size() - 1; - } -} diff --git a/test/jdk/sun/util/calendar/zi/TzIDOldMapping.java b/test/jdk/sun/util/calendar/zi/TzIDOldMapping.java deleted file mode 100644 index 7e8ce63644991..0000000000000 --- a/test/jdk/sun/util/calendar/zi/TzIDOldMapping.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.Map; -import java.util.HashMap; - -class TzIDOldMapping { - static final Map MAP = new HashMap(); - static { - String[][] oldmap = { - { "ACT", "Australia/Darwin" }, - { "AET", "Australia/Sydney" }, - { "AGT", "America/Argentina/Buenos_Aires" }, - { "ART", "Africa/Cairo" }, - { "AST", "America/Anchorage" }, - { "BET", "America/Sao_Paulo" }, - { "BST", "Asia/Dhaka" }, - { "CAT", "Africa/Harare" }, - { "CNT", "America/St_Johns" }, - { "CST", "America/Chicago" }, - { "CTT", "Asia/Shanghai" }, - { "EAT", "Africa/Addis_Ababa" }, - { "ECT", "Europe/Paris" }, - { "EST", "America/New_York" }, - { "HST", "Pacific/Honolulu" }, - { "IET", "America/Indianapolis" }, - { "IST", "Asia/Calcutta" }, - { "JST", "Asia/Tokyo" }, - { "MIT", "Pacific/Apia" }, - { "MST", "America/Denver" }, - { "NET", "Asia/Yerevan" }, - { "NST", "Pacific/Auckland" }, - { "PLT", "Asia/Karachi" }, - { "PNT", "America/Phoenix" }, - { "PRT", "America/Puerto_Rico" }, - { "PST", "America/Los_Angeles" }, - { "SST", "Pacific/Guadalcanal" }, - { "VST", "Asia/Saigon" }, - }; - for (String[] pair : oldmap) { - MAP.put(pair[0], pair[1]); - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/Zone.java b/test/jdk/sun/util/calendar/zi/Zone.java deleted file mode 100644 index f1adbf6f938dd..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Zone.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -/** - * Zone holds information corresponding to a "Zone" part of a time - * zone definition file. - * - * @since 1.4 - */ -class Zone { - // zone name (e.g., "America/Los_Angeles") - private String name; - - // zone records - private List list; - - // target zone names for this compilation - private static Set targetZones; - - /** - * Constructs a Zone with the specified zone name. - * @param name the zone name - */ - Zone(String name) { - this.name = name; - list = new ArrayList(); - } - - /** - * Reads time zone names to be generated, called "target zone - * name", from the specified text file and creats an internal hash - * table to keep those names. It's assumed that one text line - * contains a zone name or comments if it starts with - * '#'. Comments can't follow a zone name in a single line. - * @param fileName the text file name - */ - static void readZoneNames(String fileName) { - if (fileName == null) { - return; - } - BufferedReader in = null; - try { - FileReader fr = new FileReader(fileName); - in = new BufferedReader(fr); - } catch (FileNotFoundException e) { - Main.panic("can't open file: " + fileName); - } - targetZones = new HashSet(); - String line; - - try { - while ((line = in.readLine()) != null) { - line = line.trim(); - if (line.length() == 0 || line.charAt(0) == '#') { - continue; - } - if (!targetZones.add(line)) { - Main.warning("duplicated target zone name: " + line); - } - } - in.close(); - } catch (IOException e) { - Main.panic("IO error: "+e.getMessage()); - } - } - - /** - * Determines whether the specified zone is one of the target zones. - * If no target zones are specified, this method always returns - * true for any zone name. - * @param zoneName the zone name - * @return true if the specified name is a target zone. - */ - static boolean isTargetZone(String zoneName) { - if (targetZones == null) { - return true; - } - return targetZones.contains(zoneName); - } - - /** - * Forces to add "MET" to the target zone table. This is because - * there is a conflict between Java zone name "WET" and Olson zone - * name. - */ - static void addMET() { - if (targetZones != null) { - targetZones.add("MET"); - } - } - - /** - * @return the zone name - */ - String getName() { - return name; - } - - /** - * Adds the specified zone record to the zone record list. - */ - void add(ZoneRec rec) { - list.add(rec); - } - - /** - * @param index the index at which the zone record in the list is returned. - * @return the zone record specified by the index. - */ - ZoneRec get(int index) { - return list.get(index); - } - - /** - * @return the size of the zone record list - */ - int size() { - return list.size(); - } - - /** - * Resolves the reference to a rule in each zone record. - * @param zi the Zoneinfo object with which the rule reference is - * resolved. - */ - void resolve(Zoneinfo zi) { - for (int i = 0; i < list.size(); i++) { - ZoneRec rec = list.get(i); - rec.resolve(zi); - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/ZoneInfoFile.java b/test/jdk/sun/util/calendar/zi/ZoneInfoFile.java deleted file mode 100644 index 3134a517979bc..0000000000000 --- a/test/jdk/sun/util/calendar/zi/ZoneInfoFile.java +++ /dev/null @@ -1,1049 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.ref.SoftReference; -import java.nio.file.FileSystems; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import sun.util.calendar.*; - -/** - * ZoneInfoFile reads Zone information files in the - * <java.home>/lib/zi directory and provides time zone - * information in the form of a {@link ZoneInfo} object. Also, it - * reads the ZoneInfoMappings file to obtain time zone IDs information - * that is used by the {@link ZoneInfo} class. The directory layout - * and data file formats are as follows. - * - *

    Directory layout

    - * - * All zone data files and ZoneInfoMappings are put under the - * <java.home>/lib/zi directory. A path name for a given time - * zone ID is a concatenation of <java.home>/lib/zi/ and the - * time zone ID. (The file separator is replaced with the platform - * dependent value. e.g., '\' for Win32.) An example layout will look - * like as follows. - *

    - *
    - * <java.home>/lib/zi/Africa/Addis_Ababa
    - *                   /Africa/Dakar
    - *                   /America/Los_Angeles
    - *                   /Asia/Singapore
    - *                   /EET
    - *                   /Europe/Oslo
    - *                   /GMT
    - *                   /Pacific/Galapagos
    - *                       ...
    - *                   /ZoneInfoMappings
    - * 
    - *
    - * - * A zone data file has specific information of each zone. - * ZoneInfoMappings has global information of zone IDs so - * that the information can be obtained without instantiating all time - * zones. - * - *

    File format

    - * - * Two binary-file formats based on a simple Tag-Length-Value format are used - * to describe TimeZone information. The generic format of a data file is: - *

    - *
    - *    DataFile {
    - *      u1              magic[7];
    - *      u1              version;
    - *      data_item       data[];
    - *    }
    - * 
    - *
    - * where magic is a magic number identifying a file - * format, version is the format version number, and - * data is one or more data_items. The - * data_item structure is: - *
    - *
    - *    data_item {
    - *      u1              tag;
    - *      u2              length;
    - *      u1              value[length];
    - *    }
    - * 
    - *
    - * where tag indicates the data type of the item, - * length is a byte count of the following - * value that is the content of item data. - *

    - * All data is stored in the big-endian order. There is no boundary - * alignment between date items. - * - *

    1. ZoneInfo data file

    - * - * Each ZoneInfo data file consists of the following members. - *
    - *

    - *
    - *    ZoneInfoDataFile {
    - *      u1              magic[7];
    - *      u1              version;
    - *      SET OF1 {
    - *        transition            transitions2;
    - *        offset_table          offsets2;
    - *        simpletimezone        stzparams2;
    - *        raw_offset            rawoffset;
    - *        dstsaving             dst;
    - *        checksum              crc32;
    - *        gmtoffsetwillchange   gmtflag2;
    - *      }
    - *   }
    - *   1: an unordered collection of zero or one occurrences of each item
    - *   2: optional item
    - * 
    - *
    - * magic is a byte-string constant identifying the - * ZoneInfo data file. This field must be "javazi\0" - * defined as {@link #JAVAZI_LABEL}. - *

    - * version is the version number of the file format. This - * will be used for compatibility check. This field must be - * 0x01 in this version. - *

    - * transition, offset_table and - * simpletimezone have information of time transition - * from the past to the future. Therefore, these structures don't - * exist if the zone didn't change zone names and haven't applied DST in - * the past, and haven't planned to apply it. (e.g. Asia/Tokyo zone) - *

    - * raw_offset, dstsaving and checksum - * exist in every zoneinfo file. They are used by TimeZone.class indirectly. - * - *

    1.1 transition structure

    - *

    - *
    - *    transition {
    - *      u1      tag;              // 0x04 : constant
    - *      u2      length;           // byte length of whole values
    - *      s8      value[length/8];  // transitions in `long'
    - *    }
    - * 
    - *
    - * See {@link ZoneInfo#transitions ZoneInfo.transitions} about the value. - * - *

    1.2 offset_table structure

    - *

    - *
    - *    offset_table {
    - *      u1      tag;              // 0x05 : constant
    - *      u2      length;           // byte length of whole values
    - *      s4      value[length/4];  // offset values in `int'
    - *    }
    - * 
    - *
    - * - *

    1.3 simpletimezone structure

    - * See {@link ZoneInfo#simpleTimeZoneParams ZoneInfo.simpleTimeZoneParams} - * about the value. - *

    - *
    - *    simpletimezone {
    - *      u1      tag;              // 0x06 : constant
    - *      u2      length;           // byte length of whole values
    - *      s4      value[length/4];  // SimpleTimeZone parameters
    - *    }
    - * 
    - *
    - * See {@link ZoneInfo#offsets ZoneInfo.offsets} about the value. - * - *

    1.4 raw_offset structure

    - *

    - *
    - *    raw_offset {
    - *      u1      tag;              // 0x01 : constant
    - *      u2      length;           // must be 4.
    - *      s4      value;            // raw GMT offset [millisecond]
    - *    }
    - * 
    - *
    - * See {@link ZoneInfo#rawOffset ZoneInfo.rawOffset} about the value. - * - *

    1.5 dstsaving structure

    - * Value has dstSaving in seconds. - *

    - *
    - *    dstsaving {
    - *      u1      tag;              // 0x02 : constant
    - *      u2      length;           // must be 2.
    - *      s2      value;            // DST save value [second]
    - *    }
    - * 
    - *
    - * See {@link ZoneInfo#dstSavings ZoneInfo.dstSavings} about value. - * - *

    1.6 checksum structure

    - *

    - *
    - *    checksum {
    - *      u1      tag;              // 0x03 : constant
    - *      u2      length;           // must be 4.
    - *      s4      value;            // CRC32 value of transitions
    - *    }
    - * 
    - *
    - * See {@link ZoneInfo#checksum ZoneInfo.checksum}. - * - *

    1.7 gmtoffsetwillchange structure

    - * This record has a flag value for {@link ZoneInfo#rawOffsetWillChange}. - * If this record is not present in a zoneinfo file, 0 is assumed for - * the value. - *

    - *
    - *    gmtoffsetwillchange {
    - *      u1      tag;             // 0x07 : constant
    - *      u2      length;          // must be 1.
    - *      u1      value;           // 1: if the GMT raw offset will change
    - *                               // in the future, 0, otherwise.
    - *     }
    - * 
    - *
    - * - * - *

    2. ZoneInfoMappings file

    - * - * The ZoneInfoMappings file consists of the following members. - *
    - *

    - *
    - *    ZoneInfoMappings {
    - *      u1      magic[7];
    - *      u1      version;
    - *      SET OF {
    - *        versionName                   version;
    - *        zone_id_table                 zoneIDs;
    - *        raw_offset_table              rawoffsets;
    - *        raw_offset_index_table        rawoffsetindices;
    - *        alias_table                   aliases;
    - *        excluded_list                 excludedList;
    - *      }
    - *   }
    - * 
    - *
    - * - * magic is a byte-string constant which has the file type. - * This field must be "javazm\0" defined as {@link #JAVAZM_LABEL}. - *

    - * version is the version number of this file - * format. This will be used for compatibility check. This field must - * be 0x01 in this version. - *

    - * versionName shows which version of Olson's data has been used - * to generate this ZoneInfoMappings. (e.g. tzdata2000g)
    - * This field is for trouble-shooting and isn't usually used in runtime. - *

    - * zone_id_table, raw_offset_index_table and - * alias_table are general information of supported - * zones. - * - *

    2.1 zone_id_table structure

    - * The list of zone IDs included in the zi database. The list does - * not include zone IDs, if any, listed in excludedList. - *
    - *

    - *
    - *    zone_id_table {
    - *      u1      tag;              // 0x40 : constant
    - *      u2      length;           // byte length of whole values
    - *      u2      zone_id_count;
    - *      zone_id value[zone_id_count];
    - *    }
    - *
    - *    zone_id {
    - *      u1      byte_length;      // byte length of id
    - *      u1      id[byte_length];  // zone name string
    - *    }
    - * 
    - *
    - * - *

    2.2 raw_offset_table structure

    - *
    - *

    - *
    - *    raw_offset_table {
    - *      u1      tag;              // 0x41 : constant
    - *      u2      length;           // byte length of whole values
    - *      s4      value[length/4];  // raw GMT offset in milliseconds
    - *   }
    - * 
    - *
    - * - *

    2.3 raw_offset_index_table structure

    - *
    - *

    - *
    - *    raw_offset_index_table {
    - *      u1      tag;              // 0x42 : constant
    - *      u2      length;           // byte length of whole values
    - *      u1      value[length];
    - *    }
    - * 
    - *
    - * - *

    2.4 alias_table structure

    - *
    - *

    - *
    - *   alias_table {
    - *      u1      tag;              // 0x43 : constant
    - *      u2      length;           // byte length of whole values
    - *      u2      nentries;         // number of id-pairs
    - *      id_pair value[nentries];
    - *   }
    - *
    - *   id_pair {
    - *      zone_id aliasname;
    - *      zone_id ID;
    - *   }
    - * 
    - *
    - * - *

    2.5 versionName structure

    - *
    - *

    - *
    - *   versionName {
    - *      u1      tag;              // 0x44 : constant
    - *      u2      length;           // byte length of whole values
    - *      u1      value[length];
    - *   }
    - * 
    - *
    - * - *

    2.6 excludeList structure

    - * The list of zone IDs whose zones will change their GMT offsets - * (a.k.a. raw offsets) some time in the future. Those IDs must be - * added to the list of zone IDs for getAvailableIDs(). Also they must - * be examined for getAvailableIDs(int) to determine the - * current GMT offsets. - *
    - *

    - *
    - *   excluded_list {
    - *      u1      tag;              // 0x45 : constant
    - *      u2      length;           // byte length of whole values
    - *      u2      nentries;         // number of zone_ids
    - *      zone_id value[nentries];  // excluded zone IDs
    - *   }
    - * 
    - *
    - * - * @since 1.4 - */ - -public class ZoneInfoFile { - - /** - * The magic number for the ZoneInfo data file format. - */ - public static final byte[] JAVAZI_LABEL = { - (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'z', (byte)'i', (byte)'\0' - }; - private static final int JAVAZI_LABEL_LENGTH = JAVAZI_LABEL.length; - - /** - * The ZoneInfo data file format version number. Must increase - * one when any incompatible change has been made. - */ - public static final byte JAVAZI_VERSION = 0x01; - - /** - * Raw offset data item tag. - */ - public static final byte TAG_RawOffset = 1; - - /** - * Known last Daylight Saving Time save value data item tag. - */ - public static final byte TAG_LastDSTSaving = 2; - - /** - * Checksum data item tag. - */ - public static final byte TAG_CRC32 = 3; - - /** - * Transition data item tag. - */ - public static final byte TAG_Transition = 4; - - /** - * Offset table data item tag. - */ - public static final byte TAG_Offset = 5; - - /** - * SimpleTimeZone parameters data item tag. - */ - public static final byte TAG_SimpleTimeZone = 6; - - /** - * Raw GMT offset will change in the future. - */ - public static final byte TAG_GMTOffsetWillChange = 7; - - - /** - * The ZoneInfoMappings file name. - */ - public static final String JAVAZM_FILE_NAME = "ZoneInfoMappings"; - - /** - * The magic number for the ZoneInfoMappings file format. - */ - public static final byte[] JAVAZM_LABEL = { - (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'z', (byte)'m', (byte)'\0' - }; - private static final int JAVAZM_LABEL_LENGTH = JAVAZM_LABEL.length; - - /** - * The ZoneInfoMappings file format version number. Must increase - * one when any incompatible change has been made. - */ - public static final byte JAVAZM_VERSION = 0x01; - - /** - * Time zone IDs data item tag. - */ - public static final byte TAG_ZoneIDs = 64; - - /** - * Raw GMT offsets table data item tag. - */ - public static final byte TAG_RawOffsets = 65; - - /** - * Indices to the raw GMT offset table data item tag. - */ - public static final byte TAG_RawOffsetIndices = 66; - - /** - * Time zone aliases table data item tag. - */ - public static final byte TAG_ZoneAliases = 67; - - /** - * Olson's public zone information version tag. - */ - public static final byte TAG_TZDataVersion = 68; - - /** - * Excluded zones item tag. (Added in Mustang) - */ - public static final byte TAG_ExcludedZones = 69; - - private static Map zoneInfoObjects = null; - - private static final ZoneInfoOld GMT = new ZoneInfoOld("GMT", 0); - - static String ziDir; - - /** - * Converts the given time zone ID to a platform dependent path - * name. For example, "America/Los_Angeles" is converted to - * "America\Los_Angeles" on Win32. - * @return a modified ID replacing '/' with {@link - * java.io.File#separatorChar File.separatorChar} if needed. - */ - public static String getFileName(String ID) { - if (File.separatorChar == '/') { - return ID; - } - return ID.replace('/', File.separatorChar); - } - - /** - * Gets a ZoneInfo with the given GMT offset. The object - * has its ID in the format of GMT{+|-}hh:mm. - * - * @param originalId the given custom id (before normalized such as "GMT+9") - * @param gmtOffset GMT offset in milliseconds - * @return a ZoneInfo constructed with the given GMT offset - */ - public static ZoneInfoOld getCustomTimeZone(String originalId, int gmtOffset) { - String id = toCustomID(gmtOffset); - - ZoneInfoOld zi = getFromCache(id); - if (zi == null) { - zi = new ZoneInfoOld(id, gmtOffset); - zi = addToCache(id, zi); - if (!id.equals(originalId)) { - zi = addToCache(originalId, zi); - } - } - return (ZoneInfoOld) zi.clone(); - } - - public static String toCustomID(int gmtOffset) { - char sign; - int offset = gmtOffset / 60000; - - if (offset >= 0) { - sign = '+'; - } else { - sign = '-'; - offset = -offset; - } - int hh = offset / 60; - int mm = offset % 60; - - char[] buf = new char[] { 'G', 'M', 'T', sign, '0', '0', ':', '0', '0' }; - if (hh >= 10) { - buf[4] += hh / 10; - } - buf[5] += hh % 10; - if (mm != 0) { - buf[7] += mm / 10; - buf[8] += mm % 10; - } - return new String(buf); - } - - /** - * @return a ZoneInfo instance created for the specified id, or - * null if there is no time zone data file found for the specified - * id. - */ - public static ZoneInfoOld getZoneInfoOld(String id) { - //treat GMT zone as special - if ("GMT".equals(id)) - return (ZoneInfoOld) GMT.clone(); - ZoneInfoOld zi = getFromCache(id); - if (zi == null) { - Map aliases = ZoneInfoOld.getCachedAliasTable(); - if (aliases != null && aliases.get(id) != null) { - return null; - } - zi = createZoneInfoOld(id); - if (zi == null) { - return null; - } - zi = addToCache(id, zi); - } - return (ZoneInfoOld) zi.clone(); - } - - synchronized static ZoneInfoOld getFromCache(String id) { - if (zoneInfoObjects == null) { - return null; - } - return zoneInfoObjects.get(id); - } - - synchronized static ZoneInfoOld addToCache(String id, ZoneInfoOld zi) { - if (zoneInfoObjects == null) { - zoneInfoObjects = new HashMap<>(); - } else { - ZoneInfoOld zone = zoneInfoObjects.get(id); - if (zone != null) { - return zone; - } - } - zoneInfoObjects.put(id, zi); - return zi; - } - - private static ZoneInfoOld createZoneInfoOld(String id) { - byte[] buf = readZoneInfoFile(getFileName(id)); - if (buf == null) { - return null; - } - - int index = 0; - int filesize = buf.length; - int rawOffset = 0; - int dstSavings = 0; - int checksum = 0; - boolean willGMTOffsetChange = false; - long[] transitions = null; - int[] offsets = null; - int[] simpleTimeZoneParams = null; - - try { - for (index = 0; index < JAVAZI_LABEL.length; index++) { - if (buf[index] != JAVAZI_LABEL[index]) { - System.err.println("ZoneInfoOld: wrong magic number: " + id); - return null; - } - } - if (buf[index++] > JAVAZI_VERSION) { - System.err.println("ZoneInfo: incompatible version (" - + buf[index - 1] + "): " + id); - return null; - } - - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - if (filesize < index+len) { - break; - } - - switch (tag) { - case TAG_CRC32: - { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - checksum = val; - } - break; - - case TAG_LastDSTSaving: - { - short val = (short)(buf[index++] & 0xff); - val = (short)((val << 8) + (buf[index++] & 0xff)); - dstSavings = val * 1000; - } - break; - - case TAG_RawOffset: - { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - rawOffset = val; - } - break; - - case TAG_Transition: - { - int n = len / 8; - transitions = new long[n]; - for (int i = 0; i < n; i ++) { - long val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - transitions[i] = val; - } - } - break; - - case TAG_Offset: - { - int n = len / 4; - offsets = new int[n]; - for (int i = 0; i < n; i ++) { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - offsets[i] = val; - } - } - break; - - case TAG_SimpleTimeZone: - { - if (len != 32 && len != 40) { - System.err.println("ZoneInfo: wrong SimpleTimeZone parameter size"); - return null; - } - int n = len / 4; - simpleTimeZoneParams = new int[n]; - for (int i = 0; i < n; i++) { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - simpleTimeZoneParams[i] = val; - } - } - break; - - case TAG_GMTOffsetWillChange: - { - if (len != 1) { - System.err.println("ZoneInfo: wrong byte length for TAG_GMTOffsetWillChange"); - } - willGMTOffsetChange = buf[index++] == 1; - } - break; - - default: - System.err.println("ZoneInfo: unknown tag < " + tag + ">. ignored."); - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfo: corrupted zoneinfo file: " + id); - return null; - } - - if (index != filesize) { - System.err.println("ZoneInfo: wrong file size: " + id); - return null; - } - - return new ZoneInfoOld(id, rawOffset, dstSavings, checksum, - transitions, offsets, simpleTimeZoneParams, - willGMTOffsetChange); - } - - private volatile static SoftReference> zoneIDs = null; - - static List getZoneIDs() { - List ids = null; - SoftReference> cache = zoneIDs; - if (cache != null) { - ids = cache.get(); - if (ids != null) { - return ids; - } - } - byte[] buf = null; - buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_ZoneIDs: - { - int n = (buf[index++] << 8) + (buf[index++] & 0xFF); - ids = new ArrayList<>(n); - - for (int i = 0; i < n; i++) { - byte m = buf[index++]; - ids.add(new String(buf, index, m, "UTF-8")); - index += m; - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - } - - zoneIDs = new SoftReference<>(ids); - return ids; - } - - /** - * @return an alias table in HashMap where a key is an alias ID - * (e.g., "PST") and its value is a real time zone ID (e.g., - * "America/Los_Angeles"). - */ - static Map getZoneAliases() { - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - Map aliases = null; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_ZoneAliases: - { - int n = (buf[index++] << 8) + (buf[index++] & 0xFF); - aliases = new HashMap<>(n); - for (int i = 0; i < n; i++) { - byte m = buf[index++]; - String name = new String(buf, index, m, "UTF-8"); - index += m; - m = buf[index++]; - String realName = new String(buf, index, m, "UTF-8"); - index += m; - aliases.put(name, realName); - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - return null; - } - return aliases; - } - - private volatile static SoftReference> excludedIDs = null; - private volatile static boolean hasNoExcludeList = false; - - /** - * @return a List of zone IDs for zones that will change their GMT - * offsets in some future time. - * - * @since 1.6 - */ - static List getExcludedZones() { - if (hasNoExcludeList) { - return null; - } - - List excludeList = null; - - SoftReference> cache = excludedIDs; - if (cache != null) { - excludeList = cache.get(); - if (excludeList != null) { - return excludeList; - } - } - - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_ExcludedZones: - { - int n = (buf[index++] << 8) + (buf[index++] & 0xFF); - excludeList = new ArrayList<>(); - for (int i = 0; i < n; i++) { - byte m = buf[index++]; - String name = new String(buf, index, m, "UTF-8"); - index += m; - excludeList.add(name); - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - return null; - } - - if (excludeList != null) { - excludedIDs = new SoftReference<>(excludeList); - } else { - hasNoExcludeList = true; - } - return excludeList; - } - - private volatile static SoftReference rawOffsetIndices = null; - - static byte[] getRawOffsetIndices() { - byte[] indices = null; - - SoftReference cache = rawOffsetIndices; - if (cache != null) { - indices = cache.get(); - if (indices != null) { - return indices; - } - } - - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_RawOffsetIndices: - { - indices = new byte[len]; - for (int i = 0; i < len; i++) { - indices[i] = buf[index++]; - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (ArrayIndexOutOfBoundsException e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - } - - rawOffsetIndices = new SoftReference<>(indices); - return indices; - } - - private volatile static SoftReference rawOffsets = null; - - static int[] getRawOffsets() { - int[] offsets = null; - - SoftReference cache = rawOffsets; - if (cache != null) { - offsets = cache.get(); - if (offsets != null) { - return offsets; - } - } - - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_RawOffsets: - { - int n = len/4; - offsets = new int[n]; - for (int i = 0; i < n; i++) { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - offsets[i] = val; - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (ArrayIndexOutOfBoundsException e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - } - - rawOffsets = new SoftReference<>(offsets); - return offsets; - } - - private volatile static SoftReference zoneInfoMappings = null; - - private static byte[] getZoneInfoOldMappings() { - byte[] data; - SoftReference cache = zoneInfoMappings; - if (cache != null) { - data = cache.get(); - if (data != null) { - return data; - } - } - data = readZoneInfoFile(JAVAZM_FILE_NAME); - if (data == null) { - throw new RuntimeException("ZoneInfoOldMapping " + - JAVAZM_FILE_NAME + " either doesn't exist or doesn't have data"); - } - - int index; - for (index = 0; index < JAVAZM_LABEL.length; index++) { - if (data[index] != JAVAZM_LABEL[index]) { - System.err.println("ZoneInfoOld: wrong magic number: " + JAVAZM_FILE_NAME); - return null; - } - } - if (data[index++] > JAVAZM_VERSION) { - System.err.println("ZoneInfoOld: incompatible version (" - + data[index - 1] + "): " + JAVAZM_FILE_NAME); - return null; - } - - zoneInfoMappings = new SoftReference<>(data); - return data; - } - - /** - * Reads the specified file under <java.home>/lib/zi into a buffer. - * @return the buffer, or null if any I/O error occurred. - */ - private static byte[] readZoneInfoFile(final String fileName) { - if (fileName.indexOf("..") >= 0) { - return null; - } - byte[] buffer = null; - File file = new File(ziDir, fileName); - try { - int filesize = (int)file.length(); - if (filesize > 0) { - FileInputStream fis = new FileInputStream(file); - buffer = new byte[filesize]; - try { - if (fis.read(buffer) != filesize) { - throw new IOException("read error on " + fileName); - } - } finally { - fis.close(); - } - } - } catch (Exception ex) { - if (!(ex instanceof FileNotFoundException) || JAVAZM_FILE_NAME.equals(fileName)) { - System.err.println("ZoneInfoOld: " + ex.getMessage()); - } - } - return buffer; - } - - private ZoneInfoFile() { - } -} diff --git a/test/jdk/sun/util/calendar/zi/ZoneInfoOld.java b/test/jdk/sun/util/calendar/zi/ZoneInfoOld.java deleted file mode 100644 index 300b7f13dddd7..0000000000000 --- a/test/jdk/sun/util/calendar/zi/ZoneInfoOld.java +++ /dev/null @@ -1,1022 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.lang.ref.SoftReference; -import java.time.ZoneOffset; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.SimpleTimeZone; -import java.util.TimeZone; - -import sun.util.calendar.CalendarSystem; -import sun.util.calendar.CalendarDate; - -/** - * ZoneInfoOld is an implementation subclass of {@link - * java.util.TimeZone TimeZone} that represents GMT offsets and - * daylight saving time transitions of a time zone. - *

    - * The daylight saving time transitions are described in the {@link - * #transitions transitions} table consisting of a chronological - * sequence of transitions of GMT offset and/or daylight saving time - * changes. Since all transitions are represented in UTC, in theory, - * ZoneInfoOld can be used with any calendar systems except - * for the {@link #getOffset(int,int,int,int,int,int) getOffset} - * method that takes Gregorian calendar date fields. - *

    - * This table covers transitions from 1900 until 2100 (as of version - * 23), Before 1900, it assumes that there was no daylight saving - * time and the getOffset methods always return the - * {@link #getRawOffset} value. No Local Mean Time is supported. If a - * specified date is beyond the transition table and this time zone is - * supposed to observe daylight saving time in 2100, it delegates - * operations to a {@link java.util.SimpleTimeZone SimpleTimeZone} - * object created using the daylight saving time schedule as of 2100. - *

    - * The date items, transitions, GMT offset(s), etc. are read from a database - * file. See {@link ZoneInfoFile} for details. - * @see java.util.SimpleTimeZone - * @since 1.4 - */ - -public class ZoneInfoOld extends TimeZone { - - // The constants assume no leap seconds support. - static final int SECOND_IN_MILLIS = 1000; - static final int MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60; - static final int HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60; - static final int DAY_IN_MILLIS = HOUR_IN_MILLIS * 24; - - private static final int UTC_TIME = 0; - private static final int STANDARD_TIME = 1; - private static final int WALL_TIME = 2; - - private static final long OFFSET_MASK = 0x0fL; - private static final long DST_MASK = 0xf0L; - private static final int DST_NSHIFT = 4; - // this bit field is reserved for abbreviation support - private static final long ABBR_MASK = 0xf00L; - private static final int TRANSITION_NSHIFT = 12; - - // IDs having conflicting data between Olson and JDK 1.1 - static final Map conflictingIDs = Map.of( - "EST", "America/Panama", - "MST", "America/Phoenix"); - - private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar(); - - /** - * The raw GMT offset in milliseconds between this zone and GMT. - * Negative offsets are to the west of Greenwich. To obtain local - * standard time, add the offset to GMT time. - * @serial - */ - int rawOffset; - - /** - * Difference in milliseconds from the original GMT offset in case - * the raw offset value has been modified by calling {@link - * #setRawOffset}. The initial value is 0. - * @serial - */ - int rawOffsetDiff = 0; - - /** - * A CRC32 value of all pairs of transition time (in milliseconds - * in long) in local time and its GMT offset (in - * seconds in int) in the chronological order. Byte - * values of each long and int are taken - * in the big endian order (i.e., MSB to LSB). - * @serial - */ - int checksum; - - /** - * The amount of time in milliseconds saved during daylight saving - * time. If useDaylight is false, this value is 0. - * @serial - */ - int dstSavings; - - /** - * This array describes transitions of GMT offsets of this time - * zone, including both raw offset changes and daylight saving - * time changes. - * A long integer consists of four bit fields. - *

      - *
    • The most significant 52-bit field represents transition - * time in milliseconds from Gregorian January 1 1970, 00:00:00 - * GMT.
    • - *
    • The next 4-bit field is reserved and must be 0.
    • - *
    • The next 4-bit field is an index value to {@link #offsets - * offsets[]} for the amount of daylight saving at the - * transition. If this value is zero, it means that no daylight - * saving, not the index value zero.
    • - *
    • The least significant 4-bit field is an index value to - * {@link #offsets offsets[]} for total GMT offset at the - * transition.
    • - *
    - * If this time zone doesn't observe daylight saving time and has - * never changed any GMT offsets in the past, this value is null. - * @serial - */ - long[] transitions; - - /** - * This array holds all unique offset values in - * milliseconds. Index values to this array are stored in the - * transitions array elements. - * @serial - */ - int[] offsets; - - /** - * SimpleTimeZone parameter values. It has to have either 8 for - * {@link java.util.SimpleTimeZone#SimpleTimeZone(int, String, - * int, int , int , int , int , int , int , int , int) the - * 11-argument SimpleTimeZone constructor} or 10 for {@link - * java.util.SimpleTimeZone#SimpleTimeZone(int, String, int, int, - * int , int , int , int , int , int , int, int, int) the - * 13-argument SimpleTimeZone constructor} parameters. - * @serial - */ - int[] simpleTimeZoneParams; - - /** - * True if the raw GMT offset value would change after the time - * zone data has been generated; false, otherwise. The default - * value is false. - * @serial - */ - boolean willGMTOffsetChange = false; - - /** - * True if the object has been modified after its instantiation. - */ - transient private boolean dirty = false; - - private static final long serialVersionUID = 2653134537216586139L; - - /** - * A constructor. - */ - public ZoneInfoOld() { - } - - /** - * A Constructor for CustomID. - */ - public ZoneInfoOld(String ID, int rawOffset) { - this(ID, rawOffset, 0, 0, null, null, null, false); - } - - /** - * Constructs a ZoneInfoOld instance. - * - * @param ID time zone name - * @param rawOffset GMT offset in milliseconds - * @param dstSavings daylight saving value in milliseconds or 0 - * (zero) if this time zone doesn't observe Daylight Saving Time. - * @param checksum CRC32 value with all transitions table entry - * values - * @param transitions transition table - * @param offsets offset value table - * @param simpleTimeZoneParams parameter values for constructing - * SimpleTimeZone - * @param willGMTOffsetChange the value of willGMTOffsetChange - */ - ZoneInfoOld(String ID, - int rawOffset, - int dstSavings, - int checksum, - long[] transitions, - int[] offsets, - int[] simpleTimeZoneParams, - boolean willGMTOffsetChange) { - setID(ID); - this.rawOffset = rawOffset; - this.dstSavings = dstSavings; - this.checksum = checksum; - this.transitions = transitions; - this.offsets = offsets; - this.simpleTimeZoneParams = simpleTimeZoneParams; - this.willGMTOffsetChange = willGMTOffsetChange; - } - - /** - * Returns the difference in milliseconds between local time and UTC - * of given time, taking into account both the raw offset and the - * effect of daylight savings. - * - * @param date the milliseconds in UTC - * @return the milliseconds to add to UTC to get local wall time - */ - public int getOffset(long date) { - return getOffsets(date, null, UTC_TIME); - } - - public int getOffsets(long utc, int[] offsets) { - return getOffsets(utc, offsets, UTC_TIME); - } - - public int getOffsetsByStandard(long standard, int[] offsets) { - return getOffsets(standard, offsets, STANDARD_TIME); - } - - public int getOffsetsByWall(long wall, int[] offsets) { - return getOffsets(wall, offsets, WALL_TIME); - } - - private int getOffsets(long date, int[] offsets, int type) { - // if dst is never observed, there is no transition. - if (transitions == null) { - int offset = getLastRawOffset(); - if (offsets != null) { - offsets[0] = offset; - offsets[1] = 0; - } - return offset; - } - - date -= rawOffsetDiff; - int index = getTransitionIndex(date, type); - - // prior to the transition table, returns the raw offset. - // FIXME: should support LMT. - if (index < 0) { - int offset = getLastRawOffset(); - if (offsets != null) { - offsets[0] = offset; - offsets[1] = 0; - } - return offset; - } - - if (index < transitions.length) { - long val = transitions[index]; - int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff; - if (offsets != null) { - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : this.offsets[dst]; - offsets[0] = offset - save; - offsets[1] = save; - } - return offset; - } - - // beyond the transitions, delegate to SimpleTimeZone if there - // is a rule; otherwise, return rawOffset. - SimpleTimeZone tz = getLastRule(); - if (tz != null) { - int rawoffset = tz.getRawOffset(); - long msec = date; - if (type != UTC_TIME) { - msec -= rawOffset; - } - int dstoffset = tz.getOffset(msec) - rawOffset; - - // Check if it's in a standard-to-daylight transition. - if (dstoffset > 0 && tz.getOffset(msec - dstoffset) == rawoffset) { - dstoffset = 0; - } - - if (offsets != null) { - offsets[0] = rawoffset; - offsets[1] = dstoffset; - } - return rawoffset + dstoffset; - } - int offset = getLastRawOffset(); - if (offsets != null) { - offsets[0] = offset; - offsets[1] = 0; - } - return offset; - } - - private int getTransitionIndex(long date, int type) { - int low = 0; - int high = transitions.length - 1; - - while (low <= high) { - int mid = (low + high) / 2; - long val = transitions[mid]; - long midVal = val >> TRANSITION_NSHIFT; // sign extended - if (type != UTC_TIME) { - midVal += offsets[(int)(val & OFFSET_MASK)]; // wall time - } - if (type == STANDARD_TIME) { - int dstIndex = (int)((val >>> DST_NSHIFT) & 0xfL); - if (dstIndex != 0) { - midVal -= offsets[dstIndex]; // make it standard time - } - } - - if (midVal < date) { - low = mid + 1; - } else if (midVal > date) { - high = mid - 1; - } else { - return mid; - } - } - - // if beyond the transitions, returns that index. - if (low >= transitions.length) { - return low; - } - return low - 1; - } - - /** - * Returns the difference in milliseconds between local time and - * UTC, taking into account both the raw offset and the effect of - * daylight savings, for the specified date and time. This method - * assumes that the start and end month are distinct. This method - * assumes a Gregorian calendar for calculations. - *

    - * Note: In general, clients should use - * {@link Calendar#ZONE_OFFSET Calendar.get(ZONE_OFFSET)} + - * {@link Calendar#DST_OFFSET Calendar.get(DST_OFFSET)} - * instead of calling this method. - * - * @param era The era of the given date. The value must be either - * GregorianCalendar.AD or GregorianCalendar.BC. - * @param year The year in the given date. - * @param month The month in the given date. Month is 0-based. e.g., - * 0 for January. - * @param day The day-in-month of the given date. - * @param dayOfWeek The day-of-week of the given date. - * @param millis The milliseconds in day in standard local time. - * @return The milliseconds to add to UTC to get local time. - */ - public int getOffset(int era, int year, int month, int day, - int dayOfWeek, int milliseconds) { - if (milliseconds < 0 || milliseconds >= DAY_IN_MILLIS) { - throw new IllegalArgumentException(); - } - - if (era == java.util.GregorianCalendar.BC) { // BC - year = 1 - year; - } else if (era != java.util.GregorianCalendar.AD) { - throw new IllegalArgumentException(); - } - - CalendarDate date = gcal.newCalendarDate(null); - date.setDate(year, month + 1, day); - if (gcal.validate(date) == false) { - throw new IllegalArgumentException(); - } - - // bug-for-bug compatible argument checking - if (dayOfWeek < java.util.GregorianCalendar.SUNDAY - || dayOfWeek > java.util.GregorianCalendar.SATURDAY) { - throw new IllegalArgumentException(); - } - - if (transitions == null) { - return getLastRawOffset(); - } - - long dateInMillis = gcal.getTime(date) + milliseconds; - dateInMillis -= (long) rawOffset; // make it UTC - return getOffsets(dateInMillis, null, UTC_TIME); - } - - /** - * Sets the base time zone offset from GMT. This operation - * modifies all the transitions of this ZoneInfoOld object, including - * historical ones, if applicable. - * - * @param offsetMillis the base time zone offset to GMT. - * @see getRawOffset - */ - public synchronized void setRawOffset(int offsetMillis) { - if (offsetMillis == rawOffset + rawOffsetDiff) { - return; - } - rawOffsetDiff = offsetMillis - rawOffset; - if (lastRule != null) { - lastRule.setRawOffset(offsetMillis); - } - dirty = true; - } - - /** - * Returns the GMT offset of the current date. This GMT offset - * value is not modified during Daylight Saving Time. - * - * @return the GMT offset value in milliseconds to add to UTC time - * to get local standard time - */ - public int getRawOffset() { - if (!willGMTOffsetChange) { - return rawOffset + rawOffsetDiff; - } - - int[] offsets = new int[2]; - getOffsets(System.currentTimeMillis(), offsets, UTC_TIME); - return offsets[0]; - } - - public boolean isDirty() { - return dirty; - } - - int getLastRawOffset() { - return rawOffset + rawOffsetDiff; - } - - /** - * Queries if this time zone uses Daylight Saving Time in the last known rule. - */ - public boolean useDaylightTime() { - return (simpleTimeZoneParams != null); - } - - @Override - public boolean observesDaylightTime() { - if (simpleTimeZoneParams != null) { - return true; - } - if (transitions == null) { - return false; - } - - // Look up the transition table to see if it's in DST right - // now or if there's any standard-to-daylight transition at - // any future. - long utc = System.currentTimeMillis() - rawOffsetDiff; - int index = getTransitionIndex(utc, UTC_TIME); - - // before transitions in the transition table - if (index < 0) { - return false; - } - - // the time is in the table range. - for (int i = index; i < transitions.length; i++) { - if ((transitions[i] & DST_MASK) != 0) { - return true; - } - } - // No further DST is observed. - return false; - } - - /** - * Queries if the specified date is in Daylight Saving Time. - */ - public boolean inDaylightTime(Date date) { - if (date == null) { - throw new NullPointerException(); - } - - if (transitions == null) { - return false; - } - - long utc = date.getTime() - rawOffsetDiff; - int index = getTransitionIndex(utc, UTC_TIME); - - // before transitions in the transition table - if (index < 0) { - return false; - } - - // the time is in the table range. - if (index < transitions.length) { - return (transitions[index] & DST_MASK) != 0; - } - - // beyond the transition table - SimpleTimeZone tz = getLastRule(); - if (tz != null) { - return tz.inDaylightTime(date); - } - return false; - } - - /** - * Returns the amount of time in milliseconds that the clock is advanced - * during daylight saving time is in effect in its last daylight saving time rule. - * - * @return the number of milliseconds the time is advanced with respect to - * standard time when daylight saving time is in effect. - */ - public int getDSTSavings() { - return dstSavings; - } - -// /** -// * @return the last year in the transition table or -1 if this -// * time zone doesn't observe any daylight saving time. -// */ -// public int getMaxTransitionYear() { -// if (transitions == null) { -// return -1; -// } -// long val = transitions[transitions.length - 1]; -// int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff; -// val = (val >> TRANSITION_NSHIFT) + offset; -// CalendarDate lastDate = Gregorian.getCalendarDate(val); -// return lastDate.getYear(); -// } - - /** - * Returns a string representation of this time zone. - * @return the string - */ - public String toString() { - return getClass().getName() + - "[id=\"" + getID() + "\"" + - ",offset=" + getLastRawOffset() + - ",dstSavings=" + dstSavings + - ",useDaylight=" + useDaylightTime() + - ",transitions=" + ((transitions != null) ? transitions.length : 0) + - ",lastRule=" + (lastRule == null ? getLastRuleInstance() : lastRule) + - "]"; - } - - /** - * Gets all available IDs supported in the Java run-time. - * - * @return an array of time zone IDs. - */ - public static String[] getAvailableIDs() { - List idList = ZoneInfoFile.getZoneIDs(); - List excluded = ZoneInfoFile.getExcludedZones(); - if (excluded != null) { - // List all zones from the idList and excluded lists - List list = new ArrayList<>(idList.size() + excluded.size()); - list.addAll(idList); - list.addAll(excluded); - idList = list; - } - String[] ids = new String[idList.size()]; - return idList.toArray(ids); - } - - /** - * Gets all available IDs that have the same value as the - * specified raw GMT offset. - * - * @param rawOffset the GMT offset in milliseconds. This - * value should not include any daylight saving time. - * - * @return an array of time zone IDs. - */ - public static String[] getAvailableIDs(int rawOffset) { - String[] result; - List matched = new ArrayList<>(); - List IDs = ZoneInfoFile.getZoneIDs(); - int[] rawOffsets = ZoneInfoFile.getRawOffsets(); - - loop: - for (int index = 0; index < rawOffsets.length; index++) { - if (rawOffsets[index] == rawOffset) { - byte[] indices = ZoneInfoFile.getRawOffsetIndices(); - for (int i = 0; i < indices.length; i++) { - if (indices[i] == index) { - matched.add(IDs.get(i++)); - while (i < indices.length && indices[i] == index) { - matched.add(IDs.get(i++)); - } - break loop; - } - } - } - } - - // We need to add any zones from the excluded zone list that - // currently have the same GMT offset as the specified - // rawOffset. The zones returned by this method may not be - // correct as of return to the caller if any GMT offset - // transition is happening during this GMT offset checking... - List excluded = ZoneInfoFile.getExcludedZones(); - if (excluded != null) { - for (String id : excluded) { - TimeZone zi = getTimeZone(id); - if (zi != null && zi.getRawOffset() == rawOffset) { - matched.add(id); - } - } - } - - result = new String[matched.size()]; - matched.toArray(result); - return result; - } - - /** - * Gets the ZoneInfoOld for the given ID. - * - * @param ID the ID for a ZoneInfoOld. See TimeZone for detail. - * - * @return the specified ZoneInfoOld object, or null if there is no - * time zone of the ID. - */ - public static TimeZone getTimeZone(String ID) { - String givenID = null; - - ZoneInfoOld zi = ZoneInfoFile.getZoneInfoOld(ID); - if (zi == null) { - // if we can't create an object for the ID, try aliases. - try { - Map map = getAliasTable(); - String alias = ID; - while ((alias = map.get(alias)) != null) { - zi = ZoneInfoFile.getZoneInfoOld(alias); - if (zi != null) { - zi.setID(ID); - zi = ZoneInfoFile.addToCache(ID, zi); - zi = (ZoneInfoOld) zi.clone(); - break; - } - } - } catch (Exception e) { - // ignore exceptions - } - } - - if (givenID != null && zi != null) { - zi.setID(givenID); - } - return zi; - } - - private transient SimpleTimeZone lastRule; - - /** - * Returns a SimpleTimeZone object representing the last GMT - * offset and DST schedule or null if this time zone doesn't - * observe DST. - */ - synchronized SimpleTimeZone getLastRule() { - if (lastRule == null) { - lastRule = getLastRuleInstance(); - } - return lastRule; - } - - /** - * Returns a SimpleTimeZone object that represents the last - * known daylight saving time rules. - * - * @return a SimpleTimeZone object or null if this time zone - * doesn't observe DST. - */ - public SimpleTimeZone getLastRuleInstance() { - if (simpleTimeZoneParams == null) { - return null; - } - if (simpleTimeZoneParams.length == 10) { - return new SimpleTimeZone(getLastRawOffset(), getID(), - simpleTimeZoneParams[0], - simpleTimeZoneParams[1], - simpleTimeZoneParams[2], - simpleTimeZoneParams[3], - simpleTimeZoneParams[4], - simpleTimeZoneParams[5], - simpleTimeZoneParams[6], - simpleTimeZoneParams[7], - simpleTimeZoneParams[8], - simpleTimeZoneParams[9], - dstSavings); - } - return new SimpleTimeZone(getLastRawOffset(), getID(), - simpleTimeZoneParams[0], - simpleTimeZoneParams[1], - simpleTimeZoneParams[2], - simpleTimeZoneParams[3], - simpleTimeZoneParams[4], - simpleTimeZoneParams[5], - simpleTimeZoneParams[6], - simpleTimeZoneParams[7], - dstSavings); - } - - /** - * Returns a copy of this ZoneInfoOld. - */ - public Object clone() { - ZoneInfoOld zi = (ZoneInfoOld) super.clone(); - zi.lastRule = null; - return zi; - } - - /** - * Returns a hash code value calculated from the GMT offset and - * transitions. - * @return a hash code of this time zone - */ - public int hashCode() { - return getLastRawOffset() ^ checksum; - } - - /** - * Compares the equity of two ZoneInfoOld objects. - * - * @param obj the object to be compared with - * @return true if given object is same as this ZoneInfoOld object, - * false otherwise. - */ - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof ZoneInfoOld)) { - return false; - } - ZoneInfoOld that = (ZoneInfoOld) obj; - return (getID().equals(that.getID()) - && (getLastRawOffset() == that.getLastRawOffset()) - && (checksum == that.checksum)); - } - - /** - * Returns true if this zone has the same raw GMT offset value and - * transition table as another zone info. If the specified - * TimeZone object is not a ZoneInfoOld instance, this method returns - * true if the specified TimeZone object has the same raw GMT - * offset value with no daylight saving time. - * - * @param other the ZoneInfoOld object to be compared with - * @return true if the given TimeZone has the same - * GMT offset and transition information; false, otherwise. - */ - public boolean hasSameRules(TimeZone other) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - if (!(other instanceof ZoneInfoOld)) { - if (getRawOffset() != other.getRawOffset()) { - return false; - } - // if both have the same raw offset and neither observes - // DST, they have the same rule. - if ((transitions == null) - && (useDaylightTime() == false) - && (other.useDaylightTime() == false)) { - return true; - } - return false; - } - if (getLastRawOffset() != ((ZoneInfoOld)other).getLastRawOffset()) { - return false; - } - return (checksum == ((ZoneInfoOld)other).checksum); - } - - private static SoftReference> aliasTable; - - static Map getCachedAliasTable() { - Map aliases = null; - - SoftReference> cache = aliasTable; - if (cache != null) { - aliases = cache.get(); - } - return aliases; - } - - /** - * Returns a Map from alias time zone IDs to their standard - * time zone IDs. - * - * @return the Map that holds the mappings from alias time zone IDs - * to their standard time zone IDs, or null if - * ZoneInfoOldMappings file is not available. - */ - public synchronized static Map getAliasTable() { - Map aliases = getCachedAliasTable(); - if (aliases == null) { - aliases = ZoneInfoFile.getZoneAliases(); - if (aliases != null) { - // Replace old mappings from `jdk11_backward` - aliases.putAll(conflictingIDs); - aliasTable = new SoftReference>(aliases); - } - } - return aliases; - } - - private void readObject(ObjectInputStream stream) - throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - // We don't know how this object from 1.4.x or earlier has - // been mutated. So it should always be marked as `dirty'. - dirty = true; - } - - ////////////////////////////////////////////////////////////// - public boolean equalsTo(ZoneInfoOld other) { - return (getID().equals(other.getID()) - && (getLastRawOffset() == other.getLastRawOffset()) - && (dstSavings == other.dstSavings) - && (willGMTOffsetChange == other.willGMTOffsetChange) - && (checksum == other.checksum) - && equalsTransOffsets(other) - && (Arrays.equals(simpleTimeZoneParams, other.simpleTimeZoneParams) || - getLastRule().equals(other.getLastRule()))); - } - - private boolean equalsTransOffsets(ZoneInfoOld other) { - if (transitions == null) { - return (other.transitions == null && - Arrays.equals(offsets, other.offsets)); - } - if (other.transitions == null || - transitions.length != other.transitions.length) { - return false; - } - // if offsets and other.offsets have different order - // the last 4-bit in trans are different. - for (int i = 0; i < transitions.length; i++) { - long val = transitions[i]; - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : offsets[dst] / 1000; - int off = offsets[(int)(val & OFFSET_MASK)]/1000; - long second = (val >> TRANSITION_NSHIFT)/1000; - - val = other.transitions[i]; - int dstO = (int)((val >>> DST_NSHIFT) & 0xfL); - int saveO = (dstO == 0) ? 0 : other.offsets[dstO] / 1000; - int offO = other.offsets[(int)(val & OFFSET_MASK)]/1000; - long secondO = (val >> TRANSITION_NSHIFT)/1000; - if ((dst == 0) != (dstO == 0) || save != saveO || off != offO || second != secondO) - return false; - } - return true; - } - - private int transToString(long val, int off_old, int[] offsets, StringBuilder sb) { - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : offsets[dst] / 1000; - int off = offsets[(int)(val & OFFSET_MASK)]/1000; - long second = (val >> TRANSITION_NSHIFT)/1000; - ZoneOffset offset_old = ZoneOffset.ofTotalSeconds(off_old); - ZoneOffset offset = ZoneOffset.ofTotalSeconds(off); - sb.append(" " + LocalDateTime.ofEpochSecond(second, 0, offset_old)); - - sb.append(" [utc=" + second + - " raw=" + Long.toHexString(val >> TRANSITION_NSHIFT) + - ", offset=" + off + "/" + offset + ", saving=" + save + "]"); - return off; - } - - public String diffsTo(ZoneInfoOld other) { - - int rawOffset0 = other.rawOffset; - int checksum0 = other.checksum; - int dstSavings0 = other.dstSavings; - long[] transitions0 = other.transitions; - int[] offsets0 = other.offsets; - int[] simpleTimeZoneParams0 = other.simpleTimeZoneParams; - boolean willGMTOffsetChange0 = other.willGMTOffsetChange; - - - //return getClass().getName() + - StringBuilder sb = new StringBuilder(); - sb.append("******************************\n" + - getID() + " : " + other.getID()); - // ROC is excluded by ZoneInfoOld - if ("ROC".equals(getID())) { - return sb.toString(); - } - if (rawOffset != rawOffset0 || - dstSavings != dstSavings0 || - checksum != checksum0 || - willGMTOffsetChange != willGMTOffsetChange0 || - (simpleTimeZoneParams != null ) != (simpleTimeZoneParams0 != null) || - (transitions != null && transitions0 != null && - transitions.length != transitions0.length)) - { - sb.append("\n offset=" + getLastRawOffset() + - ",dstSavings=" + dstSavings + - ",useDaylight=" + useDaylightTime() + - ",transitions=" + ((transitions != null) ? transitions.length : 0) + - ",offsets=" + ((offsets != null) ? offsets.length : 0) + - ",checksum=" + checksum + - ",gmtChanged=" + willGMTOffsetChange) - .append("\n[NG]offset=" + rawOffset0 + - ",dstSavings=" + dstSavings0 + - ",useDaylight=" + (simpleTimeZoneParams != null) + - ",transitions=" + ((transitions0 != null) ? transitions0.length : 0) + - ",offsets=" + ((offsets0 != null) ? offsets0.length : 0) + - ",checksum=" + checksum0 + - ",gmtChanged=" + willGMTOffsetChange0 + - ""); - } - // offsets - if (!Arrays.equals(offsets, offsets0)) { - sb.append("\n offset.len=" + ((offsets != null)? offsets.length : "null") + - " " + ((offsets0 != null)? offsets0.length : "null")); - if (offsets != null && offsets0.length != 0) { - int len = Math.min(offsets.length, offsets0.length); - int i = 0; - for (i = 0; i < len; i++) { - sb.append("\n " + - ZoneOffset.ofTotalSeconds(offsets[i]/1000) + " " + - ZoneOffset.ofTotalSeconds(offsets0[i]/1000)); - } - for (; i < offsets0.length; i++) { - sb.append("\n " + ZoneOffset.ofTotalSeconds(offsets0[i]/1000)); - } - } - } - // trans - int offset = 0; - int offset0 = 0; - if (!equalsTransOffsets(other)) { - sb.append("\n -------------"); - if ((transitions == null) != (transitions0 == null)) { - sb.append("\n (NG) Different trans(null) :" + - transitions + ", " + transitions0); - if (transitions != null) { - for (int i = 0; i < transitions.length; i++) { - sb.append("\n (NG)"); - offset = transToString(transitions[i], offset, offsets, sb); - } - } - } else { - if (transitions.length != transitions0.length) { - sb.append("\n (NG) Different trans size :" + - transitions.length + ", " + transitions0.length); - } - int length = Math.min(transitions.length, transitions0.length); - for (int i = 0; i < length; i++) { - // sb.append("\n[" + i + "] "); - // offset = transToString(transitions[i], offset, offsets, sb); - long val = transitions[i]; - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : offsets[dst] / 1000; - int off = offsets[(int)(val & OFFSET_MASK)]/1000; - long second = (val >> TRANSITION_NSHIFT)/1000; - sb.append("\n "); - offset = transToString(transitions[i], offset, offsets, sb); - if (transitions0 == null || i >= transitions0.length) { - sb.append("\n "); - offset = transToString(transitions[i], offset, offsets, sb); - sb.append("\n (NG) trans0 is null or < trans.length"); - } else { - long val0 = transitions0[i]; - int dst0 = (int)((val0 >>> DST_NSHIFT) & 0xfL); - int save0 = (dst0 == 0) ? 0 : offsets0[dst0] / 1000; - int off0 = offsets0[(int)(val0 & OFFSET_MASK)]/1000; - long second0 = (val0 >> TRANSITION_NSHIFT)/1000; - if (save != save0 || off != off0 || second != second0) { - sb.append("\n (NG)"); - } else { - sb.append("\n (OK)"); - } - offset0 = transToString(transitions0[i], offset0, offsets0, sb); - sb.append("\n -----"); - } - } - } - } - SimpleTimeZone stz = getLastRuleInstance(); - if (stz != null) { - SimpleTimeZone stz0 = other.getLastRule(); - if (!stz.hasSameRules(stz0)) { - sb.append("\n -------------") - .append("\n SimpleTimeZone (NG)") - .append("\n stz=" + stz) - .append("\n stz0=" + stz0); - } - } - sb.append("\n -------------"); - return sb.toString(); - } -} diff --git a/test/jdk/sun/util/calendar/zi/ZoneRec.java b/test/jdk/sun/util/calendar/zi/ZoneRec.java deleted file mode 100644 index f6bbeb3a199db..0000000000000 --- a/test/jdk/sun/util/calendar/zi/ZoneRec.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -/** - * ZoneRec hold information of time zone corresponding to each text - * line of the "Zone" part. - * - * @since 1.4 - */ -class ZoneRec { - private int gmtOffset; - private String ruleName; - private int directSave; - private Rule ruleRef; - private String format; - private boolean hasUntil; - private int untilYear; - private Month untilMonth; - private RuleDay untilDay; - private Time untilTime; - private long untilInMillis; - private String line; - - /** - * @return the "UNTIL" value in milliseconds - */ - Time getUntilTime() { - return untilTime; - } - - /** - * @return the GMT offset value in milliseconds - */ - int getGmtOffset() { - return gmtOffset; - } - - /** - * @return the rule name to which this zone record refers - */ - String getRuleName() { - return ruleName; - } - - /** - * @return the amount of saving time directly defined in the - * "RULES/SAVE" field. - */ - int getDirectSave() { - return directSave; - } - - /** - * @return true if this zone record has a reference to a rule - */ - boolean hasRuleReference() { - return ruleRef != null; - } - - /** - * Returns the "FORMAT" field string of this zone record. This - * @return the "FORMAT" field - */ - String getFormat() { - return format; - } - - /** - * @return the year in the "UNTIL" field - */ - int getUntilYear() { - return untilYear; - } - - /** - * Returns the "UNTIL" field value in milliseconds from Janurary - * 1, 1970 0:00 GMT. - * @param currentSave the amount of daylight saving in - * milliseconds that is used to adjust wall-clock time. - * @return the milliseconds value of the "UNTIL" field - */ - long getUntilTime(int currentSave) { - if (untilTime.isWall()) { - return untilInMillis - currentSave; - } - return untilInMillis; - } - - /** - * Returns the "UNTIL" time in milliseconds without adjusting GMT - * offsets or daylight saving. - * @return local "UNTIL" time in milliseconds - */ - long getLocalUntilTime() { - return Time.getLocalTime(untilYear, - untilMonth, - untilDay, - untilTime.getTime()); - } - - /** - * Returns the "UNTIL" time in milliseconds with adjusting GMT offsets and daylight saving. - * @return the "UNTIL" time after the adjustment - */ - long getLocalUntilTime(int save, int gmtOffset) { - return Time.getLocalTime(untilYear, - untilMonth, - untilDay, - save, - gmtOffset, - untilTime); - } - - /** - * @return the text line of this zone record - */ - String getLine() { - return line; - } - - /** - * Sets the specified text line to this zone record - */ - void setLine(String line) { - this.line = line; - } - - /** - * @return true if this zone record has the "UNTIL" field - */ - boolean hasUntil() { - return this.hasUntil; - } - - /** - * Adjusts the "UNTIL" time to GMT offset if this zone record has - * it. untilTime is not adjusted to daylight saving - * in this method. - */ - void adjustTime() { - if (!hasUntil()) { - return; - } - if (untilTime.isSTD() || untilTime.isWall()) { - // adjust to gmt offset only here. adjust to real - // wall-clock time when tracking rules - untilInMillis -= gmtOffset; - } - } - - /** - * @return the reference to the Rule object - */ - Rule getRuleRef() { - return ruleRef; - } - - /** - * Resolves the reference to a Rule and adjusts its "UNTIL" time - * to GMT offset. - */ - void resolve(Zoneinfo zi) { - if (ruleName != null && (!"-".equals(ruleName))) { - ruleRef = zi.getRule(ruleName); - } - adjustTime(); - } - - /** - * Parses a Zone text line that is described by a StringTokenizer. - * @param tokens represents tokens of a Zone text line - * @return the zone record produced by parsing the text - */ - static ZoneRec parse(StringTokenizer tokens) { - ZoneRec rec = new ZoneRec(); - try { - rec.gmtOffset = (int) Time.parse(tokens.nextToken()).getTime(); - String token = tokens.nextToken(); - char c = token.charAt(0); - if (c >= '0' && c <= '9') { - rec.directSave = (int) Time.parse(token).getTime(); - } else { - rec.ruleName = token; - } - rec.format = tokens.nextToken(); - if (tokens.hasMoreTokens()) { - rec.hasUntil = true; - rec.untilYear = Integer.parseInt(tokens.nextToken()); - if (tokens.hasMoreTokens()) { - rec.untilMonth = Month.parse(tokens.nextToken()); - } else { - rec.untilMonth = Month.JANUARY; - } - if (tokens.hasMoreTokens()) { - rec.untilDay = RuleDay.parse(tokens.nextToken()); - } else { - rec.untilDay = new RuleDay(1); - } - if (tokens.hasMoreTokens()) { - rec.untilTime = Time.parse(tokens.nextToken()); - } else { - rec.untilTime = Time.parse("0:00"); - } - rec.untilInMillis = rec.getLocalUntilTime(); - } - } catch (Exception e) { - // TODO: error reporting - e.printStackTrace(); - } - return rec; - } - - private static void panic(String msg) { - Main.panic(msg); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Zoneinfo.java b/test/jdk/sun/util/calendar/zi/Zoneinfo.java deleted file mode 100644 index e125ad2cb87d1..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Zoneinfo.java +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - -/** - * Zoneinfo provides javazic compiler front-end functionality. - * @since 1.4 - */ -class Zoneinfo { - - private static final int minYear = 1900; - private static final int maxYear = 2100; - private static final long minTime = Time.getLocalTime(minYear, Month.JANUARY, 1, 0); - private static int startYear = minYear; - private static int endYear = maxYear; - - /** - * True if javazic should generate a list of SimpleTimeZone - * instances for the SimpleTimeZone-based time zone support. - */ - static boolean isYearForTimeZoneDataSpecified = false; - - /** - * Zone name to Zone mappings - */ - private Map zones; - - /** - * Rule name to Rule mappings - */ - private Map rules; - - /** - * Alias name to real name mappings - */ - private Map aliases; - - /** - * Constracts a Zoneinfo. - */ - Zoneinfo() { - zones = new HashMap(); - rules = new HashMap(); - aliases = new HashMap(); - } - - /** - * Adds the given zone to the list of Zones. - * @param zone Zone to be added to the list. - */ - void add(Zone zone) { - String name = zone.getName(); - zones.put(name, zone); - } - - /** - * Adds the given rule to the list of Rules. - * @param rule Rule to be added to the list. - */ - void add(Rule rule) { - String name = rule.getName(); - rules.put(name, rule); - } - - /** - * Puts the specifid name pair to the alias table. - * @param name1 an alias time zone name - * @param name2 the real time zone of the alias name - */ - void putAlias(String name1, String name2) { - aliases.put(name1, name2); - } - - /** - * Sets the given year for SimpleTimeZone list output. - * This method is called when the -S option is specified. - * @param year the year for which SimpleTimeZone list should be generated - */ - static void setYear(int year) { - setStartYear(year); - setEndYear(year); - isYearForTimeZoneDataSpecified = true; - } - - /** - * Sets the start year. - * @param year the start year value - * @throws IllegalArgumentException if the specified year value is - * smaller than the minimum year or greater than the end year. - */ - static void setStartYear(int year) { - if (year < minYear || year > endYear) { - throw new IllegalArgumentException("invalid start year specified: " + year); - } - startYear = year; - } - - /** - * @return the start year value - */ - static int getStartYear() { - return startYear; - } - - /** - * Sets the end year. - * @param year the end year value - * @throws IllegalArgumentException if the specified year value is - * smaller than the start year or greater than the maximum year. - */ - static void setEndYear(int year) { - if (year < startYear || year > maxYear) { - throw new IllegalArgumentException(); - } - endYear = year; - } - - /** - * @return the end year value - */ - static int getEndYear() { - return endYear; - } - - /** - * @return the minimum year value - */ - static int getMinYear() { - return minYear; - } - - /** - * @return the maximum year value - */ - static int getMaxYear() { - return maxYear; - } - - /** - * @return the alias table - */ - Map getAliases() { - return aliases; - } - - /** - * @return the Zone list - */ - Map getZones() { - return zones; - } - - /** - * @return a Zone specified by name. - * @param name a zone name - */ - Zone getZone(String name) { - return zones.get(name); - } - - /** - * @return a Rule specified by name. - * @param name a rule name - */ - Rule getRule(String name) { - return rules.get(name); - } - - private static String line; - - private static int lineNum; - - /** - * Parses the specified time zone data file and creates a Zoneinfo - * that has all Rules, Zones and Links (aliases) information. - * @param fname the time zone data file name - * @return a Zoneinfo object - */ - static Zoneinfo parse(String fname) { - BufferedReader in = null; - try { - FileReader fr = new FileReader(fname); - in = new BufferedReader(fr); - } catch (FileNotFoundException e) { - panic("can't open file: "+fname); - } - Zoneinfo zi = new Zoneinfo(); - boolean continued = false; - Zone zone = null; - String l; - lineNum = 0; - - try { - while ((line = in.readLine()) != null) { - lineNum++; - // skip blank and comment lines - if (line.length() == 0 || line.charAt(0) == '#') { - continue; - } - - // trim trailing comments - int rindex = line.lastIndexOf('#'); - if (rindex != -1) { - // take the data part of the line - l = line.substring(0, rindex); - } else { - l = line; - } - - StringTokenizer tokens = new StringTokenizer(l); - if (!tokens.hasMoreTokens()) { - continue; - } - String token = tokens.nextToken(); - int len = token.length(); - - if (continued || token.regionMatches(true, 0, "Zone", 0, len)){ - if (zone == null) { - if (!tokens.hasMoreTokens()) { - panic("syntax error: zone no more token"); - } - token = tokens.nextToken(); - // if the zone name is in "GMT+hh" or "GMT-hh" - // format, ignore it due to spec conflict. - if (token.startsWith("GMT+") || token.startsWith("GMT-")) { - continue; - } - zone = new Zone(token); - } else { - // no way to push the current token back... - tokens = new StringTokenizer(l); - } - - ZoneRec zrec = ZoneRec.parse(tokens); - zrec.setLine(line); - zone.add(zrec); - if ((continued = zrec.hasUntil()) == false) { - if (Zone.isTargetZone(zone.getName())) { - // zone.resolve(zi); - zi.add(zone); - } - zone = null; - } - } else if (token.regionMatches(true, 0, "Rule", 0, len)) { - if (!tokens.hasMoreTokens()) { - panic("syntax error: rule no more token"); - } - token = tokens.nextToken(); - Rule rule = zi.getRule(token); - if (rule == null) { - rule = new Rule(token); - zi.add(rule); - } - RuleRec rrec = RuleRec.parse(tokens); - rrec.setLine(line); - rule.add(rrec); - } else if (token.regionMatches(true, 0, "Link", 0, len)) { - // Link - try { - String name1 = tokens.nextToken(); - String name2 = tokens.nextToken(); - - // if the zone name is in "GMT+hh" or "GMT-hh" - // format, ignore it due to spec conflict with - // custom time zones. Also, ignore "ROC" for - // PC-ness. - if (name2.startsWith("GMT+") || name2.startsWith("GMT-") - || "ROC".equals(name2)) { - continue; - } - zi.putAlias(name2, name1); - } catch (Exception e) { - panic("syntax error: no more token for Link"); - } - } - } - in.close(); - } catch (IOException ex) { - panic("IO error: " + ex.getMessage()); - } - - return zi; - } - - /** - * Interprets a zone and constructs a Timezone object that - * contains enough information on GMT offsets and DST schedules to - * generate a zone info database. - * - * @param zoneName the zone name for which a Timezone object is - * constructed. - * - * @return a Timezone object that contains all GMT offsets and DST - * rules information. - */ - Timezone phase2(String zoneName) { - Timezone tz = new Timezone(zoneName); - Zone zone = getZone(zoneName); - zone.resolve(this); - - // TODO: merge phase2's for the regular and SimpleTimeZone ones. - if (isYearForTimeZoneDataSpecified) { - ZoneRec zrec = zone.get(zone.size()-1); - tz.setLastZoneRec(zrec); - tz.setRawOffset(zrec.getGmtOffset()); - if (zrec.hasRuleReference()) { - /* - * This part assumes that the specified year is covered by - * the rules referred to by the last zone record. - */ - List rrecs = zrec.getRuleRef().getRules(startYear); - - if (rrecs.size() == 2) { - // make sure that one is a start rule and the other is - // an end rule. - RuleRec r0 = rrecs.get(0); - RuleRec r1 = rrecs.get(1); - if (r0.getSave() == 0 && r1.getSave() > 0) { - rrecs.set(0, r1); - rrecs.set(1, r0); - } else if (!(r0.getSave() > 0 && r1.getSave() == 0)) { - rrecs = null; - Main.error(zoneName + ": rules for " + startYear + " not found."); - } - } else { - rrecs = null; - } - if (rrecs != null) { - tz.setLastRules(rrecs); - } - } - return tz; - } - - int gmtOffset; - int year = minYear; - int fromYear = year; - long fromTime = Time.getLocalTime(startYear, - Month.JANUARY, - 1, 0); - - // take the index 0 for the GMT offset of the last zone record - ZoneRec zrec = zone.get(zone.size()-1); - tz.getOffsetIndex(zrec.getGmtOffset()); - - int lastGmtOffsetValue = -1; - ZoneRec prevzrec = null; - int currentSave = 0; - boolean usedZone; - for (int zindex = 0; zindex < zone.size(); zindex++) { - zrec = zone.get(zindex); - usedZone = false; - gmtOffset = zrec.getGmtOffset(); - int stdOffset = zrec.getDirectSave(); - - if (gmtOffset != lastGmtOffsetValue) { - tz.setRawOffset(gmtOffset, fromTime); - lastGmtOffsetValue = gmtOffset; - } - // If this is the last zone record, take the last rule info. - if (!zrec.hasUntil()) { - if (zrec.hasRuleReference()) { - tz.setLastRules(zrec.getRuleRef().getLastRules()); - } else if (stdOffset != 0) { - // in case the last rule is all year round DST-only - // (Asia/Amman once announced this rule.) - tz.setLastDSTSaving(stdOffset); - } - } - if (!zrec.hasRuleReference()) { - if (!zrec.hasUntil() || zrec.getUntilTime(stdOffset) >= fromTime) { - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+stdOffset), - tz.getDstOffsetIndex(stdOffset)); - usedZone = true; - } - currentSave = stdOffset; - // optimization in case the last rule is fixed. - if (!zrec.hasUntil()) { - if (tz.getNTransitions() > 0) { - if (stdOffset == 0) { - tz.setDSTType(Timezone.X_DST); - } else { - tz.setDSTType(Timezone.LAST_DST); - } - long time = Time.getLocalTime(maxYear, - Month.JANUARY, 1, 0); - time -= zrec.getGmtOffset(); - tz.addTransition(time, - tz.getOffsetIndex(gmtOffset+stdOffset), - tz.getDstOffsetIndex(stdOffset)); - tz.addUsedRec(zrec); - } else { - tz.setDSTType(Timezone.NO_DST); - } - break; - } - } else { - Rule rule = zrec.getRuleRef(); - boolean fromTimeUsed = false; - currentSave = 0; - year_loop: - for (year = getMinYear(); year <= endYear; year++) { - if (zrec.hasUntil() && year > zrec.getUntilYear()) { - break; - } - List rules = rule.getRules(year); - if (rules.size() > 0) { - for (int i = 0; i < rules.size(); i++) { - RuleRec rrec = rules.get(i); - long transition = rrec.getTransitionTime(year, - gmtOffset, - currentSave); - if (zrec.hasUntil()) { - if (transition >= zrec.getUntilTime(currentSave)) { - // If the GMT offset changed from the previous one, - // record fromTime as a transition. - if (!fromTimeUsed && prevzrec != null - && gmtOffset != prevzrec.getGmtOffset()) { - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - fromTimeUsed = true; // for consistency - } - break year_loop; - } - } - - if (fromTimeUsed == false) { - if (fromTime <= transition) { - fromTimeUsed = true; - - if (fromTime != minTime) { - int prevsave; - - // See if until time in the previous - // ZoneRec is the same thing as the - // local time in the next rule. - // (examples are Asia/Ashkhabad in 1991, - // Europe/Riga in 1989) - - if (i > 0) { - prevsave = rules.get(i-1).getSave(); - } else { - List prevrules = rule.getRules(year-1); - - if (prevrules.size() > 0) { - prevsave = prevrules.get(prevrules.size()-1).getSave(); - } else { - prevsave = 0; - } - } - - if (rrec.isSameTransition(prevzrec, prevsave, gmtOffset)) { - currentSave = rrec.getSave(); - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - tz.addUsedRec(rrec); - usedZone = true; - continue; - } - if (!prevzrec.hasRuleReference() - || rule != prevzrec.getRuleRef() - || (rule == prevzrec.getRuleRef() - && gmtOffset != prevzrec.getGmtOffset())) { - int save = (fromTime == transition) ? rrec.getSave() : currentSave; - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+save), - tz.getDstOffsetIndex(save)); - tz.addUsedRec(rrec); - usedZone = true; - } - } else { // fromTime == minTime - int save = rrec.getSave(); - tz.addTransition(minTime, - tz.getOffsetIndex(gmtOffset), - tz.getDstOffsetIndex(0)); - - tz.addTransition(transition, - tz.getOffsetIndex(gmtOffset+save), - tz.getDstOffsetIndex(save)); - - tz.addUsedRec(rrec); - usedZone = true; - } - } else if (year == fromYear && i == rules.size()-1) { - int save = rrec.getSave(); - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+save), - tz.getDstOffsetIndex(save)); - } - } - - currentSave = rrec.getSave(); - if (fromTime < transition) { - tz.addTransition(transition, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - tz.addUsedRec(rrec); - usedZone = true; - } - } - } else { - if (year == fromYear) { - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - fromTimeUsed = true; - } - if (year == endYear && !zrec.hasUntil()) { - if (tz.getNTransitions() > 0) { - // Assume that this Zone stopped DST - tz.setDSTType(Timezone.X_DST); - long time = Time.getLocalTime(maxYear, Month.JANUARY, - 1, 0); - time -= zrec.getGmtOffset(); - tz.addTransition(time, - tz.getOffsetIndex(gmtOffset), - tz.getDstOffsetIndex(0)); - usedZone = true; - } else { - tz.setDSTType(Timezone.NO_DST); - } - } - } - } - } - if (usedZone) { - tz.addUsedRec(zrec); - } - if (zrec.hasUntil() && zrec.getUntilTime(currentSave) > fromTime) { - fromTime = zrec.getUntilTime(currentSave); - fromYear = zrec.getUntilYear(); - year = zrec.getUntilYear(); - } - prevzrec = zrec; - } - - if (tz.getDSTType() == Timezone.UNDEF_DST) { - tz.setDSTType(Timezone.DST); - } - tz.optimize(); - tz.checksum(); - return tz; - } - - private static void panic(String msg) { - Main.panic(msg); - } -} diff --git a/test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward b/test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward deleted file mode 100644 index e480a0083bef6..0000000000000 --- a/test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward +++ /dev/null @@ -1,78 +0,0 @@ -# -# Copyright (c) 2000, 2018, 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. -# -# JDK 1.1.x compatible time zone IDs -# - -Link Australia/Darwin ACT -Link Australia/Sydney AET -Link America/Argentina/Buenos_Aires AGT -Link Africa/Cairo ART -Link America/Anchorage AST -Link America/Sao_Paulo BET -Link Asia/Dhaka BST -Link Africa/Harare CAT -Link America/St_Johns CNT -Link America/Chicago CST -Link Asia/Shanghai CTT -Link Africa/Addis_Ababa EAT -Link Europe/Paris ECT -Link America/New_York EST -Link Pacific/Honolulu HST -Link America/Indianapolis IET -Link Asia/Calcutta IST -Link Asia/Tokyo JST -Link Pacific/Apia MIT -Link America/Denver MST -Link Asia/Yerevan NET -Link Pacific/Auckland NST -Link Asia/Karachi PLT -Link America/Phoenix PNT -Link America/Puerto_Rico PRT -Link America/Los_Angeles PST -Link Pacific/Guadalcanal SST -Link Asia/Saigon VST - -# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule SystemV min 1973 - Apr lastSun 2:00 1:00 D -Rule SystemV min 1973 - Oct lastSun 2:00 0 S -Rule SystemV 1974 only - Jan 6 2:00 1:00 D -Rule SystemV 1974 only - Nov lastSun 2:00 0 S -Rule SystemV 1975 only - Feb 23 2:00 1:00 D -Rule SystemV 1975 only - Oct lastSun 2:00 0 S -Rule SystemV 1976 max - Apr lastSun 2:00 1:00 D -Rule SystemV 1976 max - Oct lastSun 2:00 0 S - -# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] -Zone SystemV/AST4ADT -4:00 SystemV A%sT -Zone SystemV/EST5EDT -5:00 SystemV E%sT -Zone SystemV/CST6CDT -6:00 SystemV C%sT -Zone SystemV/MST7MDT -7:00 SystemV M%sT -Zone SystemV/PST8PDT -8:00 SystemV P%sT -Zone SystemV/YST9YDT -9:00 SystemV Y%sT -Zone SystemV/AST4 -4:00 - AST -Zone SystemV/EST5 -5:00 - EST -Zone SystemV/CST6 -6:00 - CST -Zone SystemV/MST7 -7:00 - MST -Zone SystemV/PST8 -8:00 - PST -Zone SystemV/YST9 -9:00 - YST -Zone SystemV/HST10 -10:00 - HST From a641932427cbe8453130593355372837d70a098f Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Wed, 8 Jan 2025 17:07:54 +0000 Subject: [PATCH 051/286] 8346310: Duplicate !HAS_PENDING_EXCEPTION check in DynamicArchive::dump_at_exit Reviewed-by: dholmes --- src/hotspot/share/cds/dynamicArchive.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/cds/dynamicArchive.cpp b/src/hotspot/share/cds/dynamicArchive.cpp index f102282f68201..2133f85ae004c 100644 --- a/src/hotspot/share/cds/dynamicArchive.cpp +++ b/src/hotspot/share/cds/dynamicArchive.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -509,12 +509,9 @@ void DynamicArchive::dump_at_exit(JavaThread* current, const char* archive_name) JavaThread* THREAD = current; // For TRAPS processing related to link_shared_classes MetaspaceShared::link_shared_classes(false/*not from jcmd*/, THREAD); if (!HAS_PENDING_EXCEPTION) { - // copy shared path table to saved. - if (!HAS_PENDING_EXCEPTION) { - VM_PopulateDynamicDumpSharedSpace op(archive_name); - VMThread::execute(&op); - return; - } + VM_PopulateDynamicDumpSharedSpace op(archive_name); + VMThread::execute(&op); + return; } // One of the prepatory steps failed From 6ee2bd2f33e38c13f93fba9953b33850828d031b Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 8 Jan 2025 19:48:25 +0000 Subject: [PATCH 052/286] 8347147: [REDO] AccessFlags can be u2 in metadata Co-authored-by: Amit Kumar Reviewed-by: vlivanov, yzheng --- .../cpu/aarch64/interp_masm_aarch64.cpp | 4 +- .../cpu/aarch64/sharedRuntime_aarch64.cpp | 4 +- .../templateInterpreterGenerator_aarch64.cpp | 18 +++---- src/hotspot/cpu/arm/interp_masm_arm.cpp | 4 +- .../arm/templateInterpreterGenerator_arm.cpp | 16 +++--- src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp | 6 +-- src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp | 4 +- .../ppc/templateInterpreterGenerator_ppc.cpp | 16 +++--- src/hotspot/cpu/riscv/interp_masm_riscv.cpp | 4 +- src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp | 4 +- .../templateInterpreterGenerator_riscv.cpp | 18 +++---- src/hotspot/cpu/s390/interp_masm_s390.cpp | 4 +- src/hotspot/cpu/s390/macroAssembler_s390.cpp | 14 ++++- src/hotspot/cpu/s390/macroAssembler_s390.hpp | 3 +- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 4 +- .../templateInterpreterGenerator_s390.cpp | 24 +++++---- src/hotspot/cpu/x86/interp_masm_x86.cpp | 4 +- src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp | 4 +- .../x86/templateInterpreterGenerator_x86.cpp | 18 +++---- .../templateInterpreterGenerator_x86_64.cpp | 6 +-- src/hotspot/share/c1/c1_LIRGenerator.cpp | 4 +- src/hotspot/share/ci/ciFlags.cpp | 4 +- src/hotspot/share/ci/ciFlags.hpp | 39 +++++++------- src/hotspot/share/ci/ciKlass.cpp | 4 +- .../share/classfile/classFileParser.cpp | 12 ++--- src/hotspot/share/classfile/javaClasses.cpp | 6 +-- src/hotspot/share/classfile/vmIntrinsics.cpp | 14 ++--- src/hotspot/share/classfile/vmIntrinsics.hpp | 6 +-- .../share/interpreter/linkResolver.cpp | 4 +- .../jfr/leakprofiler/chains/edgeUtils.cpp | 4 +- .../recorder/checkpoint/types/jfrTypeSet.cpp | 8 +-- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 4 +- src/hotspot/share/jvmci/jvmciEnv.cpp | 6 +-- src/hotspot/share/jvmci/vmStructs_jvmci.cpp | 5 +- src/hotspot/share/oops/fieldInfo.cpp | 6 +-- src/hotspot/share/oops/fieldInfo.inline.hpp | 4 +- src/hotspot/share/oops/instanceKlass.cpp | 8 +-- src/hotspot/share/oops/instanceKlass.hpp | 8 ++- src/hotspot/share/oops/klass.hpp | 42 +++++++-------- src/hotspot/share/oops/method.cpp | 6 +-- src/hotspot/share/oops/method.hpp | 4 +- src/hotspot/share/oops/objArrayKlass.cpp | 6 +-- src/hotspot/share/oops/objArrayKlass.hpp | 4 +- src/hotspot/share/oops/typeArrayKlass.cpp | 4 +- src/hotspot/share/oops/typeArrayKlass.hpp | 4 +- src/hotspot/share/opto/library_call.cpp | 13 +++-- src/hotspot/share/opto/memnode.cpp | 10 ++-- src/hotspot/share/prims/jvm.cpp | 14 ++--- .../prims/jvmtiClassFileReconstituter.cpp | 8 +-- src/hotspot/share/prims/jvmtiEnv.cpp | 6 +-- .../share/prims/jvmtiRedefineClasses.cpp | 16 +++--- src/hotspot/share/prims/methodHandles.cpp | 12 ++--- src/hotspot/share/runtime/reflection.cpp | 8 +-- src/hotspot/share/runtime/vmStructs.cpp | 6 +-- src/hotspot/share/utilities/accessFlags.cpp | 4 +- src/hotspot/share/utilities/accessFlags.hpp | 51 +++++++++---------- .../sun/jvm/hotspot/oops/AccessFlags.java | 7 +-- .../jvm/hotspot/runtime/ClassConstants.java | 11 +--- 58 files changed, 278 insertions(+), 283 deletions(-) diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp index 836caa86cb0af..017e86a9dc30f 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -503,7 +503,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags ldr(r1, Address(rfp, frame::interpreter_frame_method_offset * wordSize)); - ldr(r2, Address(r1, Method::access_flags_offset())); + ldrh(r2, Address(r1, Method::access_flags_offset())); tbz(r2, exact_log2(JVM_ACC_SYNCHRONIZED), unlocked); // Don't unlock anything if the _do_not_unlock_if_synchronized flag diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index fa48092fd505a..6010ddd25fe33 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -760,7 +760,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ ldrw(rscratch1, Address(rmethod, Method::access_flags_offset())); + __ ldrh(rscratch1, Address(rmethod, Method::access_flags_offset())); __ andsw(zr, rscratch1, JVM_ACC_STATIC); __ br(Assembler::EQ, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index f70450b722223..0a3240fa56efc 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -809,7 +809,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::NE, L); __ stop("method doesn't need synchronization"); @@ -820,7 +820,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ ldr(r0, Address(rlocals, Interpreter::local_offset_in_bytes(0))); @@ -1225,7 +1225,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); { Label L; __ tst(r0, JVM_ACC_NATIVE); @@ -1277,7 +1277,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::EQ, L); __ stop("method needs synchronization"); @@ -1354,7 +1354,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ ldrw(t, Address(rmethod, Method::access_flags_offset())); + __ ldrh(t, Address(rmethod, Method::access_flags_offset())); __ tbz(t, exact_log2(JVM_ACC_STATIC), L); // get mirror __ load_mirror(t, rmethod, r10, rscratch2); @@ -1564,7 +1564,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ ldrw(t, Address(rmethod, Method::access_flags_offset())); + __ ldrh(t, Address(rmethod, Method::access_flags_offset())); __ tbz(t, exact_log2(JVM_ACC_SYNCHRONIZED), L); // the code below should be shared with interpreter macro // assembler implementation @@ -1695,7 +1695,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); { Label L; __ tst(r0, JVM_ACC_NATIVE); @@ -1751,7 +1751,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::EQ, L); __ stop("method needs synchronization"); diff --git a/src/hotspot/cpu/arm/interp_masm_arm.cpp b/src/hotspot/cpu/arm/interp_masm_arm.cpp index 3a81fdddb3c32..b70a4b495b2cc 100644 --- a/src/hotspot/cpu/arm/interp_masm_arm.cpp +++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, 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 @@ -736,7 +736,7 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a ldrb(Rflag, do_not_unlock_if_synchronized); // get method access flags - ldr_u32(Raccess_flags, Address(Rmethod, Method::access_flags_offset())); + ldrh(Raccess_flags, Address(Rmethod, Method::access_flags_offset())); strb(zero_register(Rtemp), do_not_unlock_if_synchronized); // reset the flag diff --git a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp index 9df7a455eeb84..d84ae9d14d67a 100644 --- a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, 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 @@ -579,7 +579,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbnz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method doesn't need synchronization"); __ bind(L); @@ -588,7 +588,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tst(Rtemp, JVM_ACC_STATIC); __ ldr(R0, Address(Rlocals, Interpreter::local_offset_in_bytes(0)), eq); // get receiver (assume this is frequent case) __ b(done, eq); @@ -851,7 +851,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); { Label L; __ tbnz(Rtemp, JVM_ACC_NATIVE_BIT, L); @@ -893,7 +893,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // no synchronization necessary #ifdef ASSERT { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method needs synchronization"); __ bind(L); @@ -975,7 +975,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Pass JNIEnv and mirror for static methods { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ add(R0, Rthread, in_bytes(JavaThread::jni_environment_offset())); __ tbz(Rtemp, JVM_ACC_STATIC_BIT, L); __ load_mirror(Rtemp, Rmethod, Rtemp); @@ -1204,7 +1204,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); { Label L; __ tbz(Rtemp, JVM_ACC_NATIVE_BIT, L); @@ -1249,7 +1249,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // no synchronization necessary #ifdef ASSERT { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method needs synchronization"); __ bind(L); diff --git a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp index 67b9bdc04142f..e097adb1dbfc6 100644 --- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -681,14 +681,14 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, // Check if synchronized method or unlocking prevented by // JavaThread::do_not_unlock_if_synchronized flag. lbz(Rdo_not_unlock_flag, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); - lwz(Raccess_flags, in_bytes(Method::access_flags_offset()), R19_method); + lhz(Raccess_flags, in_bytes(Method::access_flags_offset()), R19_method); li(R0, 0); stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); // reset flag push(state); // Skip if we don't have to unlock. - rldicl_(R0, Raccess_flags, 64-JVM_ACC_SYNCHRONIZED_BIT, 63); // Extract bit and compare to 0. + testbitdi(CCR0, R0, Raccess_flags, JVM_ACC_SYNCHRONIZED_BIT); beq(CCR0, Lunlocked); cmpwi(CCR0, Rdo_not_unlock_flag, 0); diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index c2e4c2e9b55c9..bad1a037b9a20 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1202,7 +1202,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ lwz(R0, in_bytes(Method::access_flags_offset()), R19_method); + __ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method); __ andi_(R0, R0, JVM_ACC_STATIC); __ beq(CCR0, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp index 9147dfc1677ab..ec372bfb07d9d 100644 --- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -144,9 +144,9 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // TODO PPC port: requires change in shared code. //assert(in_bytes(AccessFlags::flags_offset()) == 0, // "MethodDesc._access_flags == MethodDesc._access_flags._flags"); - // _access_flags must be a 32 bit value. - assert(sizeof(AccessFlags) == 4, "wrong size"); - __ lwa(R11_scratch1/*access_flags*/, method_(access_flags)); + // _access_flags must be a 16 bit value. + assert(sizeof(AccessFlags) == 2, "wrong size"); + __ lhz(R11_scratch1/*access_flags*/, method_(access_flags)); // testbit with condition register. __ testbitdi(CCR0, R0, R11_scratch1/*access_flags*/, JVM_ACC_STATIC_BIT); __ btrue(CCR0, L); @@ -823,7 +823,7 @@ void TemplateInterpreterGenerator::lock_method(Register Rflags, Register Rscratc { if (!flags_preloaded) { - __ lwz(Rflags, method_(access_flags)); + __ lhz(Rflags, method_(access_flags)); } #ifdef ASSERT @@ -1301,8 +1301,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { assert(__ nonvolatile_accross_vthread_preemtion(access_flags), "access_flags not preserved"); // Type check. - assert(4 == sizeof(AccessFlags), "unexpected field size"); - __ lwz(access_flags, method_(access_flags)); + assert(2 == sizeof(AccessFlags), "unexpected field size"); + __ lhz(access_flags, method_(access_flags)); // We don't want to reload R19_method and access_flags after calls // to some helper functions. @@ -1769,7 +1769,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT else { Label Lok; - __ lwz(R0, in_bytes(Method::access_flags_offset()), R19_method); + __ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method); __ andi_(R0, R0, JVM_ACC_SYNCHRONIZED); __ asm_assert_eq("method needs synchronization"); __ bind(Lok); diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index e17a3765b50ec..70fec29d4f7e7 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -544,7 +544,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags ld(x11, Address(fp, frame::interpreter_frame_method_offset * wordSize)); - ld(x12, Address(x11, Method::access_flags_offset())); + load_unsigned_short(x12, Address(x11, Method::access_flags_offset())); test_bit(t0, x12, exact_log2(JVM_ACC_SYNCHRONIZED)); beqz(t0, unlocked); diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 9af1b6a9bb128..12e38d97b1342 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -641,7 +641,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ lwu(t0, Address(xmethod, Method::access_flags_offset())); + __ load_unsigned_short(t0, Address(xmethod, Method::access_flags_offset())); __ test_bit(t1, t0, exact_log2(JVM_ACC_STATIC)); __ beqz(t1, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index 5ea9077a2b72a..a2187b35bd5b1 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -714,14 +714,14 @@ void TemplateInterpreterGenerator::lock_method() { const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method doesn't need synchronization", false); #endif // ASSERT // get synchronization object { Label done; - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ andi(t0, x10, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ ld(x10, Address(xlocals, Interpreter::local_offset_in_bytes(0))); @@ -1028,7 +1028,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_NATIVE, "tried to execute non-native method as native", false); __ verify_access_flags(x10, JVM_ACC_ABSTRACT, "tried to execute abstract method in interpreter"); #endif @@ -1066,7 +1066,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { } else { // no synchronization necessary #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method needs synchronization"); #endif } @@ -1130,7 +1130,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ lwu(t, Address(xmethod, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(xmethod, Method::access_flags_offset())); __ test_bit(t0, t, exact_log2(JVM_ACC_STATIC)); __ beqz(t0, L); // get mirror @@ -1346,7 +1346,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ lwu(t, Address(xmethod, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(xmethod, Method::access_flags_offset())); __ test_bit(t0, t, exact_log2(JVM_ACC_SYNCHRONIZED)); __ beqz(t0, L); // the code below should be shared with interpreter macro @@ -1472,7 +1472,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_NATIVE, "tried to execute native method as non-native"); __ verify_access_flags(x10, JVM_ACC_ABSTRACT, "tried to execute abstract method in interpreter"); #endif @@ -1519,7 +1519,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { } else { // no synchronization necessary #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method needs synchronization"); #endif } diff --git a/src/hotspot/cpu/s390/interp_masm_s390.cpp b/src/hotspot/cpu/s390/interp_masm_s390.cpp index 5e80817aaba7b..0e31dbd33e198 100644 --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -780,7 +780,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, get_method(R_method); verify_oop(Z_tos, state); push(state); // Save tos/result. - testbit(method2_(R_method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + testbit_ushort(method2_(R_method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); z_bfalse(unlocked); // Don't unlock anything if the _do_not_unlock_if_synchronized flag diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index a069d6ceafbf0..3647aca0008b8 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * Copyright 2024 IBM Corporation. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -1015,6 +1015,18 @@ void MacroAssembler::load_and_test_long(Register dst, const Address &a) { z_ltg(dst, a); } +// Test a bit in memory for 2 byte datatype. +void MacroAssembler::testbit_ushort(const Address &a, unsigned int bit) { + assert(a.index() == noreg, "no index reg allowed in testbit"); + if (bit <= 7) { + z_tm(a.disp() + 1, a.base(), 1 << bit); + } else if (bit <= 15) { + z_tm(a.disp() + 0, a.base(), 1 << (bit - 8)); + } else { + ShouldNotReachHere(); + } +} + // Test a bit in memory. void MacroAssembler::testbit(const Address &a, unsigned int bit) { assert(a.index() == noreg, "no index reg allowed in testbit"); diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.hpp b/src/hotspot/cpu/s390/macroAssembler_s390.hpp index 159688128189a..d45f1321e0f28 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * Copyright (c) 2024 IBM Corporation. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -199,6 +199,7 @@ class MacroAssembler: public Assembler { // Test a bit in memory. Result is reflected in CC. void testbit(const Address &a, unsigned int bit); + void testbit_ushort(const Address &a, unsigned int bit); // Test a bit in a register. Result is reflected in CC. void testbit(Register r, unsigned int bitPos); diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index 2396a2a71059f..62f5c8fa524b4 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -2395,7 +2395,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ testbit(Address(Z_method, Method::access_flags_offset()), JVM_ACC_STATIC_BIT); + __ testbit_ushort(Address(Z_method, Method::access_flags_offset()), JVM_ACC_STATIC_BIT); __ z_bfalse(L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp index 1c4089d5beb07..99179bcad0611 100644 --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -164,7 +164,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // Therefore add 3 to address that byte within "_flags". // Reload method. VM call above may have destroyed register contents __ get_method(method); - __ testbit(method2_(method, access_flags), JVM_ACC_STATIC_BIT); + __ testbit_ushort(method2_(method, access_flags), JVM_ACC_STATIC_BIT); method = noreg; // end of life __ z_btrue(isStatic); @@ -883,7 +883,7 @@ void TemplateInterpreterGenerator::lock_method(void) { address reentry = nullptr; { Label L; - __ testbit(method2_(method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit_ushort(method2_(method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_btrue(L); reentry = __ stop_chain_static(reentry, "method doesn't need synchronization"); __ bind(L); @@ -897,7 +897,7 @@ void TemplateInterpreterGenerator::lock_method(void) { Label done; Label static_method; - __ testbit(method2_(method, access_flags), JVM_ACC_STATIC_BIT); + __ testbit_ushort(method2_(method, access_flags), JVM_ACC_STATIC_BIT); __ z_btrue(static_method); // non-static method: Load receiver obj from stack. @@ -1349,15 +1349,17 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Make sure method is native and not abstract. #ifdef ASSERT + // _access_flags must be a 16 bit value. + assert(sizeof(AccessFlags) == 2, "testbit_ushort will fail"); address reentry = nullptr; { Label L; - __ testbit(method_(access_flags), JVM_ACC_NATIVE_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_NATIVE_BIT); __ z_btrue(L); reentry = __ stop_chain_static(reentry, "tried to execute non-native method as native"); __ bind(L); } { Label L; - __ testbit(method_(access_flags), JVM_ACC_ABSTRACT_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_ABSTRACT_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute abstract method as non-abstract"); __ bind(L); @@ -1403,7 +1405,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; __ get_method(Z_R1_scratch); - __ testbit(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit_ushort(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "method needs synchronization"); __ bind(L); @@ -1461,7 +1463,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Pass mirror handle if static call. { Label method_is_not_static; - __ testbit(method2_(Rmethod, access_flags), JVM_ACC_STATIC_BIT); + __ testbit_ushort(method2_(Rmethod, access_flags), JVM_ACC_STATIC_BIT); __ z_bfalse(method_is_not_static); // Load mirror from interpreter frame. __ z_lg(Z_R1, _z_ijava_state_neg(mirror), Z_fp); @@ -1719,13 +1721,13 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT address reentry = nullptr; { Label L; - __ testbit(method_(access_flags), JVM_ACC_NATIVE_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_NATIVE_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute native method as non-native"); __ bind(L); } { Label L; - __ testbit(method_(access_flags), JVM_ACC_ABSTRACT_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_ABSTRACT_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute abstract method as non-abstract"); __ bind(L); @@ -1775,7 +1777,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; __ get_method(Z_R1_scratch); - __ testbit(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit_ushort(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "method needs synchronization"); __ bind(L); diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp index 3a3f01a640983..ff5b1c1454dfc 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -1030,7 +1030,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); - movl(rcx, Address(rcx, Method::access_flags_offset())); + load_unsigned_short(rcx, Address(rcx, Method::access_flags_offset())); testl(rcx, JVM_ACC_SYNCHRONIZED); jcc(Assembler::zero, unlocked); diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index ab7cbb9437453..b9901a1e95bf7 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -1099,7 +1099,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm { // Bypass the barrier for non-static methods Register flags = rscratch1; - __ movl(flags, Address(method, Method::access_flags_offset())); + __ load_unsigned_short(flags, Address(method, Method::access_flags_offset())); __ testl(flags, JVM_ACC_STATIC); __ jcc(Assembler::zero, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp index 823b965a09b51..b4e005faff3b9 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -596,7 +596,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::notZero, L); __ stop("method doesn't need synchronization"); @@ -607,7 +607,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ movptr(rax, Address(rlocals, Interpreter::local_offset_in_bytes(0))); @@ -855,7 +855,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); { Label L; __ testl(rax, JVM_ACC_NATIVE); @@ -909,7 +909,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); __ stop("method needs synchronization"); @@ -999,7 +999,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ movl(t, Address(method, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(method, Method::access_flags_offset())); __ testl(t, JVM_ACC_STATIC); __ jcc(Assembler::zero, L); // get mirror @@ -1280,7 +1280,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ movl(t, Address(method, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(method, Method::access_flags_offset())); __ testl(t, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); // the code below should be shared with interpreter macro @@ -1432,7 +1432,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); { Label L; __ testl(rax, JVM_ACC_NATIVE); @@ -1489,7 +1489,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); __ stop("method needs synchronization"); diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp index 5ea2d8eba259b..b2124c6b157f4 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -74,7 +74,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // Do Int register here switch ( i ) { case 0: - __ movl(rscratch1, Address(rbx, Method::access_flags_offset())); + __ load_unsigned_short(rscratch1, Address(rbx, Method::access_flags_offset())); __ testl(rscratch1, JVM_ACC_STATIC); __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); break; @@ -159,7 +159,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { } // Now handle integrals. Only do c_rarg1 if not static. - __ movl(c_rarg3, Address(rbx, Method::access_flags_offset())); + __ load_unsigned_short(c_rarg3, Address(rbx, Method::access_flags_offset())); __ testl(c_rarg3, JVM_ACC_STATIC); __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index 74fdf7a5b76a3..2df2fbf8adca9 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -1337,7 +1337,7 @@ void LIRGenerator::do_getModifiers(Intrinsic* x) { __ cmove(lir_cond_equal, prim_klass, recv_klass, klass, T_ADDRESS); // Get the answer. - __ move(new LIR_Address(klass, in_bytes(Klass::modifier_flags_offset()), T_INT), result); + __ move(new LIR_Address(klass, in_bytes(Klass::modifier_flags_offset()), T_CHAR), result); } void LIRGenerator::do_getObjectSize(Intrinsic* x) { diff --git a/src/hotspot/share/ci/ciFlags.cpp b/src/hotspot/share/ci/ciFlags.cpp index 1401a432a9e18..043470a32a227 100644 --- a/src/hotspot/share/ci/ciFlags.cpp +++ b/src/hotspot/share/ci/ciFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -92,5 +92,5 @@ void ciFlags::print_member_flags(outputStream* st) { // ------------------------------------------------------------------ // ciFlags::print void ciFlags::print(outputStream* st) { - st->print(" flags=%x", _flags); + st->print(" flags=%x", _flags.as_unsigned_short()); } diff --git a/src/hotspot/share/ci/ciFlags.hpp b/src/hotspot/share/ci/ciFlags.hpp index dd1df622487f3..426f953611fee 100644 --- a/src/hotspot/share/ci/ciFlags.hpp +++ b/src/hotspot/share/ci/ciFlags.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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,7 +26,6 @@ #define SHARE_CI_CIFLAGS_HPP #include "ci/ciClassList.hpp" -#include "jvm_constants.h" #include "utilities/accessFlags.hpp" #include "utilities/ostream.hpp" @@ -39,37 +38,37 @@ class ciFlags { friend class ciField; friend class ciMethod; - jint _flags; + AccessFlags _flags; bool _stable; - bool _intialized_final_update; + bool _initialized_final_update; - ciFlags() :_flags(0), _stable(false), _intialized_final_update(false) { } + ciFlags() :_flags(0), _stable(false), _initialized_final_update(false) { } ciFlags(AccessFlags flags, bool is_stable = false, bool is_initialized_final_update = false) : - _flags(flags.as_int()), _stable(is_stable), _intialized_final_update(is_initialized_final_update) { } + _flags(flags), _stable(is_stable), _initialized_final_update(is_initialized_final_update) { } public: // Java access flags - bool is_public () const { return (_flags & JVM_ACC_PUBLIC ) != 0; } - bool is_private () const { return (_flags & JVM_ACC_PRIVATE ) != 0; } - bool is_protected () const { return (_flags & JVM_ACC_PROTECTED ) != 0; } - bool is_static () const { return (_flags & JVM_ACC_STATIC ) != 0; } - bool is_final () const { return (_flags & JVM_ACC_FINAL ) != 0; } - bool is_synchronized () const { return (_flags & JVM_ACC_SYNCHRONIZED ) != 0; } - bool is_super () const { return (_flags & JVM_ACC_SUPER ) != 0; } - bool is_volatile () const { return (_flags & JVM_ACC_VOLATILE ) != 0; } - bool is_transient () const { return (_flags & JVM_ACC_TRANSIENT ) != 0; } - bool is_native () const { return (_flags & JVM_ACC_NATIVE ) != 0; } - bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; } - bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; } + bool is_public () const { return _flags.is_public(); } + bool is_private () const { return _flags.is_private(); } + bool is_protected () const { return _flags.is_protected(); } + bool is_static () const { return _flags.is_static(); } + bool is_final () const { return _flags.is_final(); } + bool is_synchronized () const { return _flags.is_synchronized(); } + bool is_super () const { return _flags.is_super(); } + bool is_volatile () const { return _flags.is_volatile(); } + bool is_transient () const { return _flags.is_transient(); } + bool is_native () const { return _flags.is_native(); } + bool is_interface () const { return _flags.is_interface(); } + bool is_abstract () const { return _flags.is_abstract(); } bool is_stable () const { return _stable; } // In case the current object represents a field, return true if // the field is modified outside of instance initializer methods // (or class/initializer methods if the field is static) and false // otherwise. - bool has_initialized_final_update() const { return _intialized_final_update; }; + bool has_initialized_final_update() const { return _initialized_final_update; }; // Conversion - jint as_int() { return _flags; } + jint as_int() { return _flags.as_unsigned_short(); } void print_klass_flags(outputStream* st = tty); void print_member_flags(outputStream* st = tty); diff --git a/src/hotspot/share/ci/ciKlass.cpp b/src/hotspot/share/ci/ciKlass.cpp index f65d4a0311c82..e14e237167d8c 100644 --- a/src/hotspot/share/ci/ciKlass.cpp +++ b/src/hotspot/share/ci/ciKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -222,7 +222,7 @@ jint ciKlass::modifier_flags() { jint ciKlass::access_flags() { assert(is_loaded(), "not loaded"); GUARDED_VM_ENTRY( - return get_Klass()->access_flags().as_int(); + return get_Klass()->access_flags().as_unsigned_short(); ) } diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index 5c58f20000616..c552e48c8b8e9 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -2981,7 +2981,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea "Class is both outer and inner class in class file %s", CHECK_0); } // Access flags - jint flags; + u2 flags; // JVM_ACC_MODULE is defined in JDK-9 and later. if (_major_version >= JAVA_9_VERSION) { flags = cfs->get_u2_fast() & (RECOGNIZED_INNER_CLASS_MODIFIERS | JVM_ACC_MODULE); @@ -2998,7 +2998,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea inner_classes->at_put(index++, inner_class_info_index); inner_classes->at_put(index++, outer_class_info_index); inner_classes->at_put(index++, inner_name_index); - inner_classes->at_put(index++, inner_access_flags.as_short()); + inner_classes->at_put(index++, inner_access_flags.as_unsigned_short()); } // Check for circular and duplicate entries. @@ -3750,7 +3750,7 @@ void ClassFileParser::apply_parsed_class_metadata( // Initialize cached modifier_flags to support Class.getModifiers(). // This must follow setting inner_class attributes. - int computed_modifiers = this_klass->compute_modifier_flags(); + u2 computed_modifiers = this_klass->compute_modifier_flags(); this_klass->set_modifier_flags(computed_modifiers); // Delay the setting of _local_interfaces and _transitive_interfaces until after @@ -5336,7 +5336,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream, assert(_stream != nullptr, "invariant"); assert(_stream->buffer() == _stream->current(), "invariant"); assert(_class_name != nullptr, "invariant"); - assert(0 == _access_flags.as_int(), "invariant"); + assert(0 == _access_flags.as_unsigned_short(), "invariant"); // Figure out whether we can skip format checking (matching classic VM behavior) _need_verify = Verifier::should_verify_for(_loader_data->class_loader()); @@ -5488,7 +5488,7 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream, stream->guarantee_more(8, CHECK); // flags, this_class, super_class, infs_len // Access flags - jint flags; + u2 flags; // JVM_ACC_MODULE is defined in JDK-9 and later. if (_major_version >= JAVA_9_VERSION) { flags = stream->get_u2_fast() & (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_MODULE); diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 1aedb43973c57..650d0a9fa744d 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -3169,7 +3169,7 @@ void java_lang_ClassFrameInfo::serialize_offsets(SerializeClosure* f) { #endif static int get_flags(const methodHandle& m) { - int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); + int flags = m->access_flags().as_method_flags(); if (m->is_object_initializer()) { flags |= java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR; } else { @@ -5537,7 +5537,7 @@ int InjectedField::compute_offset() { ik->print(); tty->print_cr("all fields:"); for (AllFieldStream fs(ik); !fs.done(); fs.next()) { - tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int()); + tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_field_flags()); } #endif //PRODUCT vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class"); diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp index 407cdafaf2017..38226d232ef66 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.cpp +++ b/src/hotspot/share/classfile/vmIntrinsics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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 @@ -36,31 +36,31 @@ #include "utilities/tribool.hpp" // These are flag-matching functions: -inline bool match_F_R(jshort flags) { +inline bool match_F_R(u2 flags) { const int req = 0; const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_Y(jshort flags) { +inline bool match_F_Y(u2 flags) { const int req = JVM_ACC_SYNCHRONIZED; const int neg = JVM_ACC_STATIC | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_RN(jshort flags) { +inline bool match_F_RN(u2 flags) { const int req = JVM_ACC_NATIVE; const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED; return (flags & (req | neg)) == req; } -inline bool match_F_S(jshort flags) { +inline bool match_F_S(u2 flags) { const int req = JVM_ACC_STATIC; const int neg = JVM_ACC_SYNCHRONIZED | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_SN(jshort flags) { +inline bool match_F_SN(u2 flags) { const int req = JVM_ACC_STATIC | JVM_ACC_NATIVE; const int neg = JVM_ACC_SYNCHRONIZED; return (flags & (req | neg)) == req; @@ -711,7 +711,7 @@ bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) { vmIntrinsics::ID vmIntrinsics::find_id_impl(vmSymbolID holder, vmSymbolID name, vmSymbolID sig, - jshort flags) { + u2 flags) { assert((int)vmSymbolID::SID_LIMIT <= (1<is_array_klass()) { // We need to change "protected" to "public". assert(flags.is_protected(), "clone not protected?"); - jint new_flags = flags.as_int(); + u2 new_flags = flags.as_method_flags(); new_flags = new_flags & (~JVM_ACC_PROTECTED); new_flags = new_flags | JVM_ACC_PUBLIC; flags.set_flags(new_flags); diff --git a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp index edb87c7fc8e41..27b01e99e5567 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, 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 @@ -72,7 +72,7 @@ const Symbol* EdgeUtils::field_name(const Edge& edge, jshort* modifiers) { JavaFieldStream jfs(ik); while (!jfs.done()) { if (offset == jfs.offset()) { - *modifiers = jfs.access_flags().as_short(); + *modifiers = jfs.access_flags().as_field_flags(); return jfs.name(); } jfs.next(); diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp index a53eaa474f3f0..bc5f97c719af9 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -227,9 +227,9 @@ static traceid method_id(KlassPtr klass, MethodPtr method) { } template -static s4 get_flags(const T* ptr) { +static u2 get_flags(const T* ptr) { assert(ptr != nullptr, "invariant"); - return ptr->access_flags().get_flags(); + return ptr->access_flags().as_unsigned_short(); } // Same as JVM_GetClassModifiers @@ -968,7 +968,7 @@ static int write_method(JfrCheckpointWriter* writer, MethodPtr method, bool leak writer->write(artifact_id(klass)); writer->write(mark_symbol(method->name(), leakp)); writer->write(mark_symbol(method->signature(), leakp)); - writer->write(static_cast(get_flags(method))); + writer->write(get_flags(method)); writer->write(get_visibility(method)); return 1; } diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 9052e6228945b..1fa3f23173ce3 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 @@ -1000,7 +1000,7 @@ C2V_VMENTRY_NULL(jobject, resolveFieldInPool, (JNIEnv* env, jobject, ARGUMENT_PA if (info.is_null() || JVMCIENV->get_length(info) != 4) { JVMCI_ERROR_NULL("info must not be null and have a length of 4"); } - JVMCIENV->put_int_at(info, 0, fd.access_flags().as_int()); + JVMCIENV->put_int_at(info, 0, fd.access_flags().as_field_flags()); JVMCIENV->put_int_at(info, 1, fd.offset()); JVMCIENV->put_int_at(info, 2, fd.index()); JVMCIENV->put_int_at(info, 3, fd.field_flags().as_uint()); diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 712745e2a021c..1a53f6b6d2cc1 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -1592,7 +1592,7 @@ JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) { HotSpotJVMCI::FieldInfo::set_nameIndex(JVMCIENV, obj_h(), (jint)fieldinfo->name_index()); HotSpotJVMCI::FieldInfo::set_signatureIndex(JVMCIENV, obj_h(), (jint)fieldinfo->signature_index()); HotSpotJVMCI::FieldInfo::set_offset(JVMCIENV, obj_h(), (jint)fieldinfo->offset()); - HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_int()); + HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_field_flags()); HotSpotJVMCI::FieldInfo::set_internalFlags(JVMCIENV, obj_h(), (jint)fieldinfo->field_flags().as_uint()); HotSpotJVMCI::FieldInfo::set_initializerIndex(JVMCIENV, obj_h(), (jint)fieldinfo->initializer_index()); return wrap(obj_h()); @@ -1603,7 +1603,7 @@ JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) { (jint)fieldinfo->name_index(), (jint)fieldinfo->signature_index(), (jint)fieldinfo->offset(), - (jint)fieldinfo->access_flags().as_int(), + (jint)fieldinfo->access_flags().as_field_flags(), (jint)fieldinfo->field_flags().as_uint(), (jint)fieldinfo->initializer_index()); diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index ba47e5599578f..97447c43b6e5a 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -273,7 +273,7 @@ nonstatic_field(Klass, _name, Symbol*) \ volatile_nonstatic_field(Klass, _next_sibling, Klass*) \ nonstatic_field(Klass, _java_mirror, OopHandle) \ - nonstatic_field(Klass, _modifier_flags, jint) \ + nonstatic_field(Klass, _modifier_flags, u2) \ nonstatic_field(Klass, _access_flags, AccessFlags) \ nonstatic_field(Klass, _class_loader_data, ClassLoaderData*) \ nonstatic_field(Klass, _secondary_supers_bitmap, uintx) \ @@ -488,7 +488,6 @@ declare_constant(InvocationEntryBci) \ declare_constant(JVMCINMethodData::SPECULATION_LENGTH_BITS) \ \ - declare_constant(JVM_ACC_WRITTEN_FLAGS) \ declare_constant(FieldInfo::FieldFlags::_ff_injected) \ declare_constant(FieldInfo::FieldFlags::_ff_stable) \ declare_preprocessor_constant("JVM_ACC_VARARGS", JVM_ACC_VARARGS) \ diff --git a/src/hotspot/share/oops/fieldInfo.cpp b/src/hotspot/share/oops/fieldInfo.cpp index 50a3b427d178e..3ae91a03b6797 100644 --- a/src/hotspot/share/oops/fieldInfo.cpp +++ b/src/hotspot/share/oops/fieldInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -34,7 +34,7 @@ void FieldInfo::print(outputStream* os, ConstantPool* cp) { name_index(), name(cp)->as_utf8(), signature_index(), signature(cp)->as_utf8(), offset(), - access_flags().as_int(), + access_flags().as_field_flags(), field_flags().as_uint(), initializer_index(), generic_signature_index(), @@ -97,7 +97,7 @@ Array* FieldInfoStream::create_FieldInfoStream(GrowableArray* fie assert(fi_ref->name_index() == fi.name_index(), "Must be"); assert(fi_ref->signature_index() == fi.signature_index(), "Must be"); assert(fi_ref->offset() == fi.offset(), "Must be"); - assert(fi_ref->access_flags().as_int() == fi.access_flags().as_int(), "Must be"); + assert(fi_ref->access_flags().as_field_flags() == fi.access_flags().as_field_flags(), "Must be"); assert(fi_ref->field_flags().as_uint() == fi.field_flags().as_uint(), " Must be"); if(fi_ref->field_flags().is_initialized()) { assert(fi_ref->initializer_index() == fi.initializer_index(), "Must be"); diff --git a/src/hotspot/share/oops/fieldInfo.inline.hpp b/src/hotspot/share/oops/fieldInfo.inline.hpp index 2e6727f1fb9f1..bf37d280510f7 100644 --- a/src/hotspot/share/oops/fieldInfo.inline.hpp +++ b/src/hotspot/share/oops/fieldInfo.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -73,7 +73,7 @@ inline void Mapper::map_field_info(const FieldInfo& fi) { _consumer->accept_uint(fi.name_index()); _consumer->accept_uint(fi.signature_index()); _consumer->accept_uint(fi.offset()); - _consumer->accept_uint(fi.access_flags().as_int()); + _consumer->accept_uint(fi.access_flags().as_field_flags()); _consumer->accept_uint(fi.field_flags().as_uint()); if(fi.field_flags().has_any_optionals()) { if (fi.field_flags().is_initialized()) { diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index ce46da55f986b..43b078a8af233 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -3339,8 +3339,8 @@ InstanceKlass* InstanceKlass::compute_enclosing_class(bool* inner_is_member, TRA return outer_klass; } -jint InstanceKlass::compute_modifier_flags() const { - jint access = access_flags().as_int(); +u2 InstanceKlass::compute_modifier_flags() const { + u2 access = access_flags().as_unsigned_short(); // But check if it happens to be member class. InnerClassesIterator iter(this); @@ -3360,7 +3360,7 @@ jint InstanceKlass::compute_modifier_flags() const { } } // Remember to strip ACC_SUPER bit - return (access & (~JVM_ACC_SUPER)) & JVM_ACC_WRITTEN_FLAGS; + return (access & (~JVM_ACC_SUPER)); } jint InstanceKlass::jvmti_class_status() const { diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 8209a692a8242..cedc17e9bafde 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -391,7 +391,7 @@ class InstanceKlass: public Klass { public: int field_offset (int index) const { return field(index).offset(); } - int field_access_flags(int index) const { return field(index).access_flags().as_int(); } + int field_access_flags(int index) const { return field(index).access_flags().as_field_flags(); } FieldInfo::FieldFlags field_flags(int index) const { return field(index).field_flags(); } FieldStatus field_status(int index) const { return fields_status()->at(index); } inline Symbol* field_name (int index) const; @@ -682,8 +682,6 @@ class InstanceKlass: public Klass { #if INCLUDE_JVMTI // Redefinition locking. Class can only be redefined by one thread at a time. - // The flag is in access_flags so that it can be set and reset using atomic - // operations, and not be reset by other misc_flag settings. bool is_being_redefined() const { return _misc_flags.is_being_redefined(); } void set_is_being_redefined(bool value) { _misc_flags.set_is_being_redefined(value); } @@ -1127,7 +1125,7 @@ class InstanceKlass: public Klass { void compute_has_loops_flag_for_methods(); #endif - jint compute_modifier_flags() const; + u2 compute_modifier_flags() const; public: // JVMTI support diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 2c75d6da3b8cb..d27665bbcc121 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -66,7 +66,7 @@ class Klass : public Metadata { friend class JVMCIVMStructs; public: // Klass Kinds for all subclasses of Klass - enum KlassKind { + enum KlassKind : u2 { InstanceKlassKind, InstanceRefKlassKind, InstanceMirrorKlassKind, @@ -113,15 +113,20 @@ class Klass : public Metadata { // // Final note: This comes first, immediately after C++ vtable, // because it is frequently queried. - jint _layout_helper; + jint _layout_helper; // Klass kind used to resolve the runtime type of the instance. // - Used to implement devirtualized oop closure dispatching. // - Various type checking in the JVM const KlassKind _kind; + AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. + // Some flags created by the JVM, not in the class file itself, + // are in _misc_flags below. // Processed access flags, for use by Class.getModifiers. - jint _modifier_flags; + u2 _modifier_flags; + + KlassFlags _misc_flags; // The fields _super_check_offset, _secondary_super_cache, _secondary_supers // and _primary_supers all help make fast subtype checks. See big discussion @@ -157,22 +162,12 @@ class Klass : public Metadata { // Provide access the corresponding instance java.lang.ClassLoader. ClassLoaderData* _class_loader_data; + markWord _prototype_header; // Used to initialize objects' header + // Bitmap and hash code used by hashed secondary supers. uintx _secondary_supers_bitmap; uint8_t _hash_slot; - markWord _prototype_header; // Used to initialize objects' header - - int _vtable_len; // vtable length. This field may be read very often when we - // have lots of itable dispatches (e.g., lambdas and streams). - // Keep it away from the beginning of a Klass to avoid cacheline - // contention that may happen when a nearby object is modified. - AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. - // Some flags created by the JVM, not in the class file itself, - // are in _misc_flags below. - - JFR_ONLY(DEFINE_TRACE_ID_FIELD;) - private: // This is an index into FileMapHeader::_shared_path_table[], to // associate this class with the JAR file where it's loaded from during @@ -200,10 +195,17 @@ class Klass : public Metadata { }; #endif - KlassFlags _misc_flags; + int _vtable_len; // vtable length. This field may be read very often when we + // have lots of itable dispatches (e.g., lambdas and streams). + // Keep it away from the beginning of a Klass to avoid cacheline + // contention that may happen when a nearby object is modified. CDS_JAVA_HEAP_ONLY(int _archived_mirror_index;) +public: + + JFR_ONLY(DEFINE_TRACE_ID_FIELD;) + protected: Klass(KlassKind kind); @@ -292,8 +294,8 @@ class Klass : public Metadata { void clear_java_mirror_handle() { _java_mirror = OopHandle(); } // modifier flags - jint modifier_flags() const { return _modifier_flags; } - void set_modifier_flags(jint flags) { _modifier_flags = flags; } + u2 modifier_flags() const { return _modifier_flags; } + void set_modifier_flags(u2 flags) { _modifier_flags = flags; } // size helper int layout_helper() const { return _layout_helper; } @@ -756,7 +758,7 @@ class Klass : public Metadata { virtual void release_C_heap_structures(bool release_constant_pool = true); public: - virtual jint compute_modifier_flags() const = 0; + virtual u2 compute_modifier_flags() const = 0; // JVMTI support virtual jint jvmti_class_status() const; diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index d0b29a4a30992..ab15379409f76 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -1652,8 +1652,8 @@ void Method::init_intrinsic_id(vmSymbolID klass_id) { && sig_id == vmSymbolID::NO_SID) { return; } - jshort flags = access_flags().as_short(); + u2 flags = access_flags().as_method_flags(); vmIntrinsics::ID id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags); if (id != vmIntrinsics::_none) { set_intrinsic_id(id); @@ -2300,7 +2300,7 @@ void Method::print_on(outputStream* st) const { st->print (" - method holder: "); method_holder()->print_value_on(st); st->cr(); st->print (" - constants: " PTR_FORMAT " ", p2i(constants())); constants()->print_value_on(st); st->cr(); - st->print (" - access: 0x%x ", access_flags().as_int()); access_flags().print_on(st); st->cr(); + st->print (" - access: 0x%x ", access_flags().as_method_flags()); access_flags().print_on(st); st->cr(); st->print (" - flags: 0x%x ", _flags.as_int()); _flags.print_on(st); st->cr(); st->print (" - name: "); name()->print_value_on(st); st->cr(); st->print (" - signature: "); signature()->print_value_on(st); st->cr(); diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index 271d8b3986378..7b13337ecafcf 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -75,8 +75,8 @@ class Method : public Metadata { MethodData* _method_data; MethodCounters* _method_counters; AdapterHandlerEntry* _adapter; - AccessFlags _access_flags; // Access flags int _vtable_index; // vtable index of this method (see VtableIndexFlag) + AccessFlags _access_flags; // Access flags MethodFlags _flags; u2 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none) diff --git a/src/hotspot/share/oops/objArrayKlass.cpp b/src/hotspot/share/oops/objArrayKlass.cpp index 04bc374e5226c..903c5660d5311 100644 --- a/src/hotspot/share/oops/objArrayKlass.cpp +++ b/src/hotspot/share/oops/objArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -341,12 +341,12 @@ void ObjArrayKlass::metaspace_pointers_do(MetaspaceClosure* it) { it->push(&_bottom_klass); } -jint ObjArrayKlass::compute_modifier_flags() const { +u2 ObjArrayKlass::compute_modifier_flags() const { // The modifier for an objectArray is the same as its element assert (element_klass() != nullptr, "should be initialized"); // Return the flags of the bottom element type. - jint element_flags = bottom_klass()->compute_modifier_flags(); + u2 element_flags = bottom_klass()->compute_modifier_flags(); return (element_flags & (JVM_ACC_PUBLIC | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED)) | (JVM_ACC_ABSTRACT | JVM_ACC_FINAL); diff --git a/src/hotspot/share/oops/objArrayKlass.hpp b/src/hotspot/share/oops/objArrayKlass.hpp index e16f1f2eb0fcd..c44c8d28f6247 100644 --- a/src/hotspot/share/oops/objArrayKlass.hpp +++ b/src/hotspot/share/oops/objArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -143,7 +143,7 @@ class ObjArrayKlass : public ArrayKlass { inline void oop_oop_iterate_elements_bounded(objArrayOop a, OopClosureType* closure, void* low, void* high); public: - jint compute_modifier_flags() const; + u2 compute_modifier_flags() const; public: // Printing diff --git a/src/hotspot/share/oops/typeArrayKlass.cpp b/src/hotspot/share/oops/typeArrayKlass.cpp index 8ca6a49fc46a4..86c4f9d7138c4 100644 --- a/src/hotspot/share/oops/typeArrayKlass.cpp +++ b/src/hotspot/share/oops/typeArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -75,7 +75,7 @@ TypeArrayKlass* TypeArrayKlass::allocate(ClassLoaderData* loader_data, BasicType return new (loader_data, size, THREAD) TypeArrayKlass(type, name); } -jint TypeArrayKlass::compute_modifier_flags() const { +u2 TypeArrayKlass::compute_modifier_flags() const { return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; } diff --git a/src/hotspot/share/oops/typeArrayKlass.hpp b/src/hotspot/share/oops/typeArrayKlass.hpp index 9dc3ed607fe3a..6ec72ae49c0c8 100644 --- a/src/hotspot/share/oops/typeArrayKlass.hpp +++ b/src/hotspot/share/oops/typeArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -73,7 +73,7 @@ class TypeArrayKlass : public ArrayKlass { // Copying void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS); - jint compute_modifier_flags() const; + u2 compute_modifier_flags() const; // Oop iterators. Since there are no oops in TypeArrayKlasses, // these functions only return the size of the object. diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 40b19eecd9f65..56cfb9fe16e7b 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -3871,7 +3871,7 @@ Node* LibraryCallKit::generate_klass_flags_guard(Node* kls, int modifier_mask, i } Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { return generate_klass_flags_guard(kls, JVM_ACC_INTERFACE, 0, region, - Klass::access_flags_offset(), TypeInt::INT, T_INT); + Klass::access_flags_offset(), TypeInt::CHAR, T_CHAR); } // Use this for testing if Klass is_hidden, has_finalizer, and is_cloneable_fast. @@ -3904,8 +3904,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { break; case vmIntrinsics::_getModifiers: prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); - assert(is_power_of_2((int)JVM_ACC_WRITTEN_FLAGS+1), "change next line"); - return_type = TypeInt::make(0, JVM_ACC_WRITTEN_FLAGS, Type::WidenMin); + return_type = TypeInt::CHAR; break; case vmIntrinsics::_isInterface: prim_return_value = intcon(0); @@ -3927,7 +3926,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { break; case vmIntrinsics::_getClassAccessFlags: prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); - return_type = TypeInt::INT; // not bool! 6297094 + return_type = TypeInt::CHAR; break; default: fatal_unexpected_iid(id); @@ -3988,7 +3987,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { case vmIntrinsics::_getModifiers: p = basic_plus_adr(kls, in_bytes(Klass::modifier_flags_offset())); - query_value = make_load(nullptr, p, TypeInt::INT, T_INT, MemNode::unordered); + query_value = make_load(nullptr, p, TypeInt::CHAR, T_CHAR, MemNode::unordered); break; case vmIntrinsics::_isInterface: @@ -4053,7 +4052,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { case vmIntrinsics::_getClassAccessFlags: p = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset())); - query_value = make_load(nullptr, p, TypeInt::INT, T_INT, MemNode::unordered); + query_value = make_load(nullptr, p, TypeInt::CHAR, T_CHAR, MemNode::unordered); break; default: diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index ad351fb81add7..78ffbe05ae492 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Alibaba Group Holding Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1976,24 +1976,24 @@ LoadNode::load_array_final_field(const TypeKlassPtr *tkls, if (tkls->offset() == in_bytes(Klass::modifier_flags_offset())) { // The field is Klass::_modifier_flags. Return its (constant) value. // (Folds up the 2nd indirection in aClassConstant.getModifiers().) - assert(this->Opcode() == Op_LoadI, "must load an int from _modifier_flags"); + assert(Opcode() == Op_LoadUS, "must load an unsigned short from _modifier_flags"); return TypeInt::make(klass->modifier_flags()); } if (tkls->offset() == in_bytes(Klass::access_flags_offset())) { // The field is Klass::_access_flags. Return its (constant) value. // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) - assert(this->Opcode() == Op_LoadI, "must load an int from _access_flags"); + assert(Opcode() == Op_LoadUS, "must load an unsigned short from _access_flags"); return TypeInt::make(klass->access_flags()); } if (tkls->offset() == in_bytes(Klass::misc_flags_offset())) { // The field is Klass::_misc_flags. Return its (constant) value. // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) - assert(this->Opcode() == Op_LoadUB, "must load an unsigned byte from _misc_flags"); + assert(Opcode() == Op_LoadUB, "must load an unsigned byte from _misc_flags"); return TypeInt::make(klass->misc_flags()); } if (tkls->offset() == in_bytes(Klass::layout_helper_offset())) { // The field is Klass::_layout_helper. Return its constant value if known. - assert(this->Opcode() == Op_LoadI, "must load an int from _layout_helper"); + assert(Opcode() == Op_LoadI, "must load an int from _layout_helper"); return TypeInt::make(klass->layout_helper()); } diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 12c7898f4cf19..198165cdd1ed9 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -1306,7 +1306,7 @@ JVM_ENTRY(jint, JVM_GetClassModifiers(JNIEnv *env, jclass cls)) } Klass* k = java_lang_Class::as_Klass(mirror); - debug_only(int computed_modifiers = k->compute_modifier_flags()); + debug_only(u2 computed_modifiers = k->compute_modifier_flags()); assert(k->modifier_flags() == computed_modifiers, "modifiers cache is OK"); return k->modifier_flags(); JVM_END @@ -1817,7 +1817,7 @@ JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)) } Klass* k = java_lang_Class::as_Klass(mirror); - return k->access_flags().as_int() & JVM_ACC_WRITTEN_FLAGS; + return k->access_flags().as_class_flags(); } JVM_END @@ -2460,14 +2460,14 @@ JVM_ENTRY(jint, JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_ind Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); Method* method = InstanceKlass::cast(k)->methods()->at(method_index); - return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + return method->access_flags().as_method_flags(); JVM_END JVM_ENTRY(jint, JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)) Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); - return InstanceKlass::cast(k)->field_access_flags(field_index) & JVM_RECOGNIZED_FIELD_MODIFIERS; + return InstanceKlass::cast(k)->field_access_flags(field_index); JVM_END @@ -2657,7 +2657,7 @@ JVM_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, j InstanceKlass* ik = InstanceKlass::cast(k_called); for (JavaFieldStream fs(ik); !fs.done(); fs.next()) { if (fs.name() == name && fs.signature() == signature) { - return fs.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS; + return fs.access_flags().as_field_flags(); } } return -1; @@ -2686,7 +2686,7 @@ JVM_ENTRY(jint, JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, for (int i = 0; i < methods_count; i++) { Method* method = methods->at(i); if (method->name() == name && method->signature() == signature) { - return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + return method->access_flags().as_method_flags(); } } return -1; diff --git a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp index ceed1d8ad952a..10fb4121472e4 100644 --- a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp +++ b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -85,7 +85,7 @@ void JvmtiClassFileReconstituter::write_field_infos() { // JVMSpec| attribute_info attributes[attributes_count]; // JVMSpec| } - write_u2(access_flags.get_flags() & JVM_RECOGNIZED_FIELD_MODIFIERS); + write_u2(access_flags.as_field_flags()); write_u2(name_index); write_u2(signature_index); u2 attr_count = 0; @@ -704,7 +704,7 @@ void JvmtiClassFileReconstituter::write_method_info(const methodHandle& method) return; } - write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS); + write_u2(access_flags.as_method_flags()); write_u2(const_method->name_index()); write_u2(const_method->signature_index()); @@ -919,7 +919,7 @@ void JvmtiClassFileReconstituter::write_class_file_format() { copy_cpool_bytes(writeable_address(cpool_size())); // JVMSpec| u2 access_flags; - write_u2(ik()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS); + write_u2(ik()->access_flags().as_class_flags()); // JVMSpec| u2 this_class; // JVMSpec| u2 super_class; diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index 554b4baf7b2a3..e97bfc300422e 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -3149,7 +3149,7 @@ jvmtiError JvmtiEnv::GetFieldModifiers(fieldDescriptor* fdesc_ptr, jint* modifiers_ptr) { AccessFlags resultFlags = fdesc_ptr->access_flags(); - jint result = resultFlags.as_int(); + jint result = resultFlags.as_field_flags(); *modifiers_ptr = result; return JVMTI_ERROR_NONE; @@ -3228,7 +3228,7 @@ JvmtiEnv::GetMethodDeclaringClass(Method* method, jclass* declaring_class_ptr) { jvmtiError JvmtiEnv::GetMethodModifiers(Method* method, jint* modifiers_ptr) { NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID); - (*modifiers_ptr) = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + (*modifiers_ptr) = method->access_flags().as_method_flags(); return JVMTI_ERROR_NONE; } /* end GetMethodModifiers */ diff --git a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp index a982ac97c4786..0a53eadbbd88b 100644 --- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -1005,8 +1005,8 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( } // Check whether class modifiers are the same. - jushort old_flags = (jushort) the_class->access_flags().get_flags(); - jushort new_flags = (jushort) scratch_class->access_flags().get_flags(); + u2 old_flags = the_class->access_flags().as_class_flags(); + u2 new_flags = scratch_class->access_flags().as_class_flags(); if (old_flags != new_flags) { log_info(redefine, class, normalize) ("redefined class %s modifiers change error: modifiers changed from %d to %d.", @@ -1040,9 +1040,9 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED; } // access - old_flags = old_fs.access_flags().as_short(); - new_flags = new_fs.access_flags().as_short(); - if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) { + old_flags = old_fs.access_flags().as_field_flags(); + new_flags = new_fs.access_flags().as_field_flags(); + if (old_flags != new_flags) { log_info(redefine, class, normalize) ("redefined class %s field %s change error: modifiers changed from %d to %d.", the_class->external_name(), name_sym2->as_C_string(), old_flags, new_flags); @@ -1147,8 +1147,8 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( switch (method_was) { case matched: // methods match, be sure modifiers do too - old_flags = (jushort) k_old_method->access_flags().get_flags(); - new_flags = (jushort) k_new_method->access_flags().get_flags(); + old_flags = k_old_method->access_flags().as_method_flags(); + new_flags = k_new_method->access_flags().as_method_flags(); if ((old_flags ^ new_flags) & ~(JVM_ACC_NATIVE)) { log_info(redefine, class, normalize) ("redefined class %s method %s modifiers error: modifiers changed from %d to %d", diff --git a/src/hotspot/share/prims/methodHandles.cpp b/src/hotspot/share/prims/methodHandles.cpp index 1e44ea957311e..5b40682851042 100644 --- a/src/hotspot/share/prims/methodHandles.cpp +++ b/src/hotspot/share/prims/methodHandles.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, 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 @@ -239,7 +239,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { assert(m.not_null(), "null method handle"); InstanceKlass* m_klass = m->method_holder(); assert(m_klass != nullptr, "null holder for method handle"); - int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); + int flags = (m->access_flags().as_method_flags()); int vmindex = Method::invalid_vtable_index; LogTarget(Debug, methodhandles, indy) lt_indy; @@ -352,7 +352,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { InstanceKlass* ik = fd.field_holder(); - int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); + int flags = fd.access_flags().as_field_flags(); flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); if (fd.is_trusted_final()) flags |= TRUSTED_FINAL; if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); @@ -404,7 +404,7 @@ bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) { Method* m = iklass->find_method(name, poly_sig); if (m != nullptr) { int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; - int flags = m->access_flags().as_int(); + int flags = m->access_flags().as_method_flags(); if ((flags & required) == required) { return true; } @@ -417,7 +417,7 @@ bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) { for (; ms < me; ms++) { Method* m = iklass->methods()->at(ms); int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; - int flags = m->access_flags().as_int(); + int flags = m->access_flags().as_method_flags(); if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) { return true; } @@ -522,7 +522,7 @@ bool MethodHandles::is_signature_polymorphic_public_name(Klass* klass, Symbol* n for (; ms < me; ms++) { Method* m = iklass->methods()->at(ms); int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS | JVM_ACC_PUBLIC; - int flags = m->access_flags().as_int(); + int flags = m->access_flags().as_method_flags(); if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) { return true; } diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp index 7739cff03bf23..3aef7028a7970 100644 --- a/src/hotspot/share/runtime/reflection.cpp +++ b/src/hotspot/share/runtime/reflection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -778,7 +778,7 @@ oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_ac Handle name = Handle(THREAD, name_oop); if (name == nullptr) return nullptr; - const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + const int modifiers = method->access_flags().as_method_flags(); Handle mh = java_lang_reflect_Method::create(CHECK_NULL); @@ -819,7 +819,7 @@ oop Reflection::new_constructor(const methodHandle& method, TRAPS) { objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); assert(!exception_types.is_null(), "cannot return null"); - const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + const int modifiers = method->access_flags().as_method_flags(); Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL); @@ -859,7 +859,7 @@ oop Reflection::new_field(fieldDescriptor* fd, TRAPS) { java_lang_reflect_Field::set_trusted_final(rh()); } // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here. - java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); + java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_field_flags()); java_lang_reflect_Field::set_override(rh(), false); if (fd->has_generic_signature()) { Symbol* gs = fd->generic_signature(); diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index f5cb2805c8ed9..b6e5457551929 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -263,7 +263,7 @@ nonstatic_field(Klass, _secondary_supers, Array*) \ nonstatic_field(Klass, _primary_supers[0], Klass*) \ nonstatic_field(Klass, _java_mirror, OopHandle) \ - nonstatic_field(Klass, _modifier_flags, jint) \ + nonstatic_field(Klass, _modifier_flags, u2) \ nonstatic_field(Klass, _super, Klass*) \ volatile_nonstatic_field(Klass, _subklass, Klass*) \ nonstatic_field(Klass, _layout_helper, jint) \ @@ -1017,7 +1017,7 @@ nonstatic_field(vframeArrayElement, _bci, int) \ nonstatic_field(vframeArrayElement, _method, Method*) \ \ - nonstatic_field(AccessFlags, _flags, jint) \ + nonstatic_field(AccessFlags, _flags, u2) \ nonstatic_field(elapsedTimer, _counter, jlong) \ nonstatic_field(elapsedTimer, _active, bool) \ nonstatic_field(InvocationCounter, _counter, unsigned int) \ diff --git a/src/hotspot/share/utilities/accessFlags.cpp b/src/hotspot/share/utilities/accessFlags.cpp index ec68d1244889c..fc11491174f71 100644 --- a/src/hotspot/share/utilities/accessFlags.cpp +++ b/src/hotspot/share/utilities/accessFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -47,5 +47,5 @@ void AccessFlags::print_on(outputStream* st) const { #endif // !PRODUCT || INCLUDE_JVMTI void accessFlags_init() { - assert(sizeof(AccessFlags) == sizeof(jint), "just checking size of flags"); + assert(sizeof(AccessFlags) == sizeof(u2), "just checking size of flags"); } diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index 74ccbd20ac142..a752c09cb4272 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -30,28 +30,19 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" -// AccessFlags is an abstraction over Java access flags. +// AccessFlags is an abstraction over Java ACC flags. +// See generated file classfile_constants.h for shared JVM_ACC_XXX access flags class outputStream; -enum { - // See jvm.h for shared JVM_ACC_XXX access flags - - // flags actually put in .class file - JVM_ACC_WRITTEN_FLAGS = 0x00007FFF, - - // Do not add new ACC flags here. -}; - - class AccessFlags { friend class VMStructs; private: - jint _flags; // TODO: move 4 access flags above to Klass and change to u2 + u2 _flags; public: AccessFlags() : _flags(0) {} - explicit AccessFlags(jint flags) : _flags(flags) {} + explicit AccessFlags(u2 flags) : _flags(flags) {} // Java access flags bool is_public () const { return (_flags & JVM_ACC_PUBLIC ) != 0; } @@ -70,15 +61,10 @@ class AccessFlags { // Attribute flags bool is_synthetic () const { return (_flags & JVM_ACC_SYNTHETIC ) != 0; } - // get .class file flags - jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); } + // get as integral value + u2 as_unsigned_short() const { return _flags; } - // Initialization - void set_field_flags(jint flags) { - assert((flags & JVM_RECOGNIZED_FIELD_MODIFIERS) == flags, "only recognized flags"); - _flags = (flags & JVM_RECOGNIZED_FIELD_MODIFIERS); - } - void set_flags(jint flags) { _flags = (flags & JVM_ACC_WRITTEN_FLAGS); } + void set_flags(u2 flags) { _flags = flags; } private: friend class Klass; @@ -90,11 +76,22 @@ class AccessFlags { void set_is_synthetic() { _flags |= JVM_ACC_SYNTHETIC; } public: - // Conversion - jshort as_short() const { return (jshort)_flags; } - jint as_int() const { return _flags; } + inline friend AccessFlags accessFlags_from(u2 flags); - inline friend AccessFlags accessFlags_from(jint flags); + u2 as_method_flags() const { + assert((_flags & JVM_RECOGNIZED_METHOD_MODIFIERS) == _flags, "only recognized flags"); + return _flags; + } + + u2 as_field_flags() const { + assert((_flags & JVM_RECOGNIZED_FIELD_MODIFIERS) == _flags, "only recognized flags"); + return _flags; + } + + u2 as_class_flags() const { + assert((_flags & JVM_RECOGNIZED_CLASS_MODIFIERS) == _flags, "only recognized flags"); + return _flags; + } // Printing/debugging #if INCLUDE_JVMTI @@ -104,7 +101,7 @@ class AccessFlags { #endif }; -inline AccessFlags accessFlags_from(jint flags) { +inline AccessFlags accessFlags_from(u2 flags) { AccessFlags af; af._flags = flags; return af; diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java index 2f310effc87f4..66ebd6551a4fd 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -75,9 +75,4 @@ public void printOn(PrintStream tty) { if (isStrict ()) tty.print("strict " ); if (isSynthetic ()) tty.print("synthetic " ); } - - // get flags written to .class files - public int getStandardFlags() { - return (int) (flags & JVM_ACC_WRITTEN_FLAGS); - } } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java index 25f40ec443f50..7f9a6b4b49d2a 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, 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 @@ -98,16 +98,7 @@ public interface ClassConstants public static final long JVM_ACC_ENUM = 0x4000; /* field is declared as element of enum */ - // from accessFlags.hpp - hotspot internal flags - - // flags actually put in .class file - public static final long JVM_ACC_WRITTEN_FLAGS = 0x00007FFF; - - // flags accepted by set_field_flags - public static final long JVM_ACC_FIELD_FLAGS = 0x00008000 | JVM_ACC_WRITTEN_FLAGS; - // from jvm.h - public static final long JVM_RECOGNIZED_CLASS_MODIFIERS = (JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_SUPER | From 88fa3b2fe9bccf9cd4a4041732e2f6d425c19244 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Wed, 8 Jan 2025 20:14:59 +0000 Subject: [PATCH 053/286] 8346998: Test nsk/jvmti/ResourceExhausted/resexhausted003 fails with java.lang.OutOfMemoryError when CDS is off Reviewed-by: dholmes, sspitsyn --- .../ResourceExhausted/resexhausted003/TestDescription.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java index b6ef5ab84870a..26cdf4473cf05 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -39,10 +39,7 @@ * /test/lib * @run main/othervm/native * -agentlib:resexhausted=-waittime=5 - * -Xms64m - * -Xmx64m - * -XX:MaxMetaspaceSize=9m - * -XX:-UseGCOverheadLimit + * -XX:MaxMetaspaceSize=20m * nsk.jvmti.ResourceExhausted.resexhausted003 */ From 2e00816ac30373df28a29dc938f7ce5489a3edfc Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Wed, 8 Jan 2025 20:46:57 +0000 Subject: [PATCH 054/286] 8346671: java/nio/file/Files/probeContentType/Basic.java fails on Windows 2025 Reviewed-by: jpai --- .../java/nio/file/Files/probeContentType/Basic.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/jdk/java/nio/file/Files/probeContentType/Basic.java b/test/jdk/java/nio/file/Files/probeContentType/Basic.java index 8add9e76104b0..aee1b19a01dbb 100644 --- a/test/jdk/java/nio/file/Files/probeContentType/Basic.java +++ b/test/jdk/java/nio/file/Files/probeContentType/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, 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 @@ -40,6 +40,7 @@ import jdk.internal.util.OperatingSystem; import jdk.internal.util.OSVersion; +import jdk.internal.util.StaticProperty; /** * Uses Files.probeContentType to probe html file, custom file type, and minimal @@ -83,7 +84,7 @@ private static int checkContentTypes(String expected, String actual) { if (!expected.equals(actual)) { if (!OperatingSystem.isWindows()) { Path userMimeTypes = - Path.of(System.getProperty("user.home"), ".mime.types"); + Path.of(StaticProperty.userHome(), ".mime.types"); checkMimeTypesFile(userMimeTypes); Path etcMimeTypes = Path.of("/etc/mime.types"); @@ -188,9 +189,10 @@ public static void main(String[] args) throws IOException { exTypes.add(new ExType("xlsx", List.of("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))); exTypes.add(new ExType("wasm", List.of("application/wasm"))); - // extensions with content type that differs on Windows 11+ + // extensions with content type that differs on Windows 11+ and + // Windows Server 2025 if (OperatingSystem.isWindows() && - (System.getProperty("os.name").endsWith("11") || + (StaticProperty.osName().matches("^.*[11|2025]$") || new OSVersion(10, 0).compareTo(OSVersion.current()) > 0)) { System.out.println("Windows 11+ detected: using different types"); exTypes.add(new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip", "application/x-compressed"))); From ea49537726db6530f0ddcc04d9938df3d6d18250 Mon Sep 17 00:00:00 2001 From: Patricio Chilano Mateo Date: Wed, 8 Jan 2025 21:51:02 +0000 Subject: [PATCH 055/286] 8310340: assert(_thread->is_interp_only_mode() || stub_caller) failed: expected a stub-caller Reviewed-by: dholmes, amenkov, sspitsyn --- src/hotspot/share/prims/jvmtiEventController.cpp | 2 +- src/hotspot/share/runtime/continuationFreezeThaw.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/prims/jvmtiEventController.cpp b/src/hotspot/share/prims/jvmtiEventController.cpp index df14047e70030..32d691a5793de 100644 --- a/src/hotspot/share/prims/jvmtiEventController.cpp +++ b/src/hotspot/share/prims/jvmtiEventController.cpp @@ -598,7 +598,7 @@ JvmtiEventControllerPrivate::recompute_thread_enabled(JvmtiThreadState *state) { } // compute interp_only mode bool should_be_interp = (any_env_enabled & INTERP_EVENT_BITS) != 0 || has_frame_pops; - bool is_now_interp = state->is_interp_only_mode(); + bool is_now_interp = state->is_interp_only_mode() || state->is_pending_interp_only_mode(); if (should_be_interp != is_now_interp) { if (should_be_interp) { diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp index a6c8e64e55e73..ccbcaf452afa8 100644 --- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp +++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp @@ -2603,6 +2603,7 @@ void ThawBase::recurse_thaw_compiled_frame(const frame& hf, frame& caller, int n || (stub_caller && f.cb()->as_nmethod()->is_marked_for_deoptimization())) { // The caller of the safepoint stub when the continuation is preempted is not at a call instruction, and so // cannot rely on nmethod patching for deopt. + assert(_thread->is_interp_only_mode() || stub_caller, "expected a stub-caller"); log_develop_trace(continuations)("Deoptimizing thawed frame"); DEBUG_ONLY(ContinuationHelper::Frame::patch_pc(f, nullptr)); From 0a5ef827b06ca9fc6a7cbc059e4331cfd3cd2e62 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Wed, 8 Jan 2025 22:52:13 +0000 Subject: [PATCH 056/286] 8347162: Update problemlist CR for vmTestbase/nsk/jdi/VMOutOfMemoryException Reviewed-by: kevinw, amenkov --- test/hotspot/jtreg/ProblemList-Virtual.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList-Virtual.txt b/test/hotspot/jtreg/ProblemList-Virtual.txt index b5bb2c72779a5..23d21cd033861 100644 --- a/test/hotspot/jtreg/ProblemList-Virtual.txt +++ b/test/hotspot/jtreg/ProblemList-Virtual.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2025, 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 @@ -85,7 +85,7 @@ vmTestbase/nsk/jdi/ExceptionEvent/catchLocation/location002/TestDescription.java # the debuggee, which can lead to I/O poller threads exiting. Because # of this no vthreads can complete their reads, and the test times out as a result. -vmTestbase/nsk/jdi/VMOutOfMemoryException/VMOutOfMemoryException001/VMOutOfMemoryException001.java 8285417 generic-all +vmTestbase/nsk/jdi/VMOutOfMemoryException/VMOutOfMemoryException001/VMOutOfMemoryException001.java 8347137 generic-all ### # Fails because resume of a virtual thread is not enough to allow the virtual thread From db7fa6a2c65d11e5bd790073d345f37b5ec356b6 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 9 Jan 2025 01:21:00 +0000 Subject: [PATCH 057/286] 8347289: HKDF delayed provider selection failed with non-extractable PRK Reviewed-by: valeriep --- .../crypto/provider/HKDFKeyDerivation.java | 8 +- .../crypto/provider/KDF/HKDFDelayedPRK.java | 104 ++++++++++++++++++ 2 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 test/jdk/com/sun/crypto/provider/KDF/HKDFDelayedPRK.java diff --git a/src/java.base/share/classes/com/sun/crypto/provider/HKDFKeyDerivation.java b/src/java.base/share/classes/com/sun/crypto/provider/HKDFKeyDerivation.java index a9988bbc115e0..9b4cf557598bb 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/HKDFKeyDerivation.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/HKDFKeyDerivation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, 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 @@ -180,8 +180,8 @@ protected byte[] engineDeriveData(AlgorithmParameterSpec derivationSpec) } else if (derivationSpec instanceof HKDFParameterSpec.Expand anExpand) { // set this value in the "if" if ((pseudoRandomKey = anExpand.prk().getEncoded()) == null) { - throw new AssertionError( - "PRK is required for HKDFParameterSpec.Expand"); + throw new InvalidAlgorithmParameterException( + "Cannot retrieve PRK for HKDFParameterSpec.Expand"); } // set this value in the "if" if ((info = anExpand.info()) == null) { @@ -411,4 +411,4 @@ public HKDFSHA512(KDFParameters kdfParameters) } } -} \ No newline at end of file +} diff --git a/test/jdk/com/sun/crypto/provider/KDF/HKDFDelayedPRK.java b/test/jdk/com/sun/crypto/provider/KDF/HKDFDelayedPRK.java new file mode 100644 index 0000000000000..50157723416dc --- /dev/null +++ b/test/jdk/com/sun/crypto/provider/KDF/HKDFDelayedPRK.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2025, 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 8347289 + * @summary make sure DPS works when non-extractable PRK is provided + * @library /test/lib /test/jdk/security/unsignedjce + * @build java.base/javax.crypto.ProviderVerifier + * @enablePreview + * @run main/othervm HKDFDelayedPRK + */ + +import jdk.test.lib.Asserts; + +import javax.crypto.KDF; +import javax.crypto.KDFParameters; +import javax.crypto.KDFSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.HKDFParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidAlgorithmParameterException; +import java.security.Provider; +import java.security.Security; +import java.security.spec.AlgorithmParameterSpec; + +public class HKDFDelayedPRK { + public static void main(String[] args) throws Exception { + // This is a fake non-extractable key + var prk = new SecretKey() { + @Override + public String getAlgorithm() { + return "PRK"; + } + + @Override + public String getFormat() { + return null; + } + + @Override + public byte[] getEncoded() { + return null; + } + }; + + Security.addProvider(new ProviderImpl()); + var kdf = KDF.getInstance("HKDF-SHA256"); + kdf.deriveData(HKDFParameterSpec.expandOnly(prk, null, 32)); + + // Confirms our own omnipotent impl is selected + Asserts.assertEquals("P", kdf.getProviderName()); + } + + public static class ProviderImpl extends Provider { + public ProviderImpl() { + super("P", "1", "info"); + put("KDF.HKDF-SHA256", KDFImpl.class.getName()); + } + } + + // This HKDF impl accepts everything + public static class KDFImpl extends KDFSpi { + + public KDFImpl(KDFParameters params) throws InvalidAlgorithmParameterException { + super(params); + } + + @Override + protected KDFParameters engineGetParameters() { + return null; + } + + @Override + protected SecretKey engineDeriveKey(String alg, AlgorithmParameterSpec dummy) { + return new SecretKeySpec(new byte[32], alg); + } + + @Override + protected byte[] engineDeriveData(AlgorithmParameterSpec dummy) { + return new byte[32]; + } + } +} From 1ade96b808e66cf1623c38e23772eaf9fc991db9 Mon Sep 17 00:00:00 2001 From: Qizheng Xing Date: Thu, 9 Jan 2025 02:24:25 +0000 Subject: [PATCH 058/286] 8347042: Remove an extra parenthesis in macro definition in `jfrTraceIdMacros.hpp` Reviewed-by: mgronlun, fyang --- .../jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp index f53eecad2cf9e..b487b5e667001 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp @@ -97,7 +97,7 @@ #define METHOD_USED_THIS_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (THIS_EPOCH_METHOD_BIT))) #define METHOD_NOT_USED_THIS_EPOCH(kls) (!(METHOD_USED_THIS_EPOCH(kls))) #define METHOD_USED_PREVIOUS_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (PREVIOUS_EPOCH_METHOD_BIT))) -#define METHOD_USED_ANY_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (EPOCH_1_METHOD_BIT) | EPOCH_0_METHOD_BIT))) +#define METHOD_USED_ANY_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (EPOCH_1_METHOD_BIT | EPOCH_0_METHOD_BIT))) #define METHOD_AND_CLASS_USED_THIS_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (THIS_EPOCH_METHOD_AND_CLASS_BITS))) #define METHOD_AND_CLASS_USED_PREVIOUS_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (PREVIOUS_EPOCH_METHOD_AND_CLASS_BITS))) #define METHOD_AND_CLASS_USED_ANY_EPOCH(kls) (METHOD_USED_ANY_EPOCH(kls) && USED_ANY_EPOCH(kls)) From b3e87360917fd56df8aa0a927723a561dcb840a2 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 9 Jan 2025 03:33:21 +0000 Subject: [PATCH 059/286] 8347296: WinInstallerUiTest fails in local test runs if the path to test work directory is longer that regular Reviewed-by: almatvee --- test/jdk/tools/jpackage/windows/WinInstallerUiTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java b/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java index c6489ab68cf4c..7dcf025a506ce 100644 --- a/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java +++ b/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, 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 @@ -122,13 +122,13 @@ private void setPackageName(JPackageCommand cmd) { StringBuilder sb = new StringBuilder(cmd.name()); sb.append("With"); if (withDirChooser) { - sb.append("DirChooser"); + sb.append("Dc"); // DirChooser } if (withShortcutPrompt) { - sb.append("ShortcutPrompt"); + sb.append("Sp"); // ShortcutPrompt } if (withLicense) { - sb.append("License"); + sb.append("L"); // License } cmd.setArgumentValue("--name", sb.toString()); } From 0a35ebfd5709c3069fd64bb736bbbc37d392759c Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 9 Jan 2025 03:35:31 +0000 Subject: [PATCH 060/286] 8347297: Skip the RuntimeImageSymbolicLinksTest test on Windows when it is executed outside of the jtreg Reviewed-by: almatvee --- .../tools/jpackage/share/RuntimeImageSymbolicLinksTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java index db74e3456c4ee..867ea57121303 100644 --- a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java +++ b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -23,6 +23,7 @@ import java.nio.file.Files; import java.nio.file.Path; +import static jdk.internal.util.OperatingSystem.WINDOWS; import jdk.jpackage.test.ApplicationLayout; import jdk.jpackage.test.TKit; import jdk.jpackage.test.Annotations.Test; @@ -49,7 +50,7 @@ public class RuntimeImageSymbolicLinksTest { - @Test + @Test(ifNotOS = WINDOWS) public static void test() throws Exception { final Path jmods = Path.of(System.getProperty("java.home"), "jmods"); final Path workDir = TKit.createTempDirectory("runtime").resolve("data"); From 97dd06ce0a5a2bbc28c3c97b201eca81196af698 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 9 Jan 2025 03:42:47 +0000 Subject: [PATCH 061/286] 8347299: Add annotations to test cases in LicenseTest Reviewed-by: almatvee --- .../jdk/tools/jpackage/share/LicenseTest.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/test/jdk/tools/jpackage/share/LicenseTest.java b/test/jdk/tools/jpackage/share/LicenseTest.java index b0eef94fa7c57..66cda39eec288 100644 --- a/test/jdk/tools/jpackage/share/LicenseTest.java +++ b/test/jdk/tools/jpackage/share/LicenseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -29,6 +29,8 @@ import java.util.Arrays; import java.util.function.Function; import java.util.stream.Collectors; +import static jdk.internal.util.OperatingSystem.LINUX; +import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.PackageTest; @@ -67,6 +69,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @compile LicenseTest.java + * @requires (jpackage.test.SQETest != null) * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=LicenseTest.testCommon */ @@ -78,18 +81,14 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @compile LicenseTest.java - * @requires (os.family == "linux") * @requires (jpackage.test.SQETest == null) * @run main/othervm/timeout=1440 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=LicenseTest.testCustomDebianCopyright - * --jpt-run=LicenseTest.testCustomDebianCopyrightSubst - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree2 - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree3 - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree4 + * --jpt-run=LicenseTest */ public class LicenseTest { + + @Test public static void testCommon() { PackageTest test = new PackageTest().configureHelloApp() .addInitializer(cmd -> { @@ -102,26 +101,32 @@ public static void testCommon() { test.run(); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree() { testLinuxLicenseInUsrTree("/usr"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree2() { testLinuxLicenseInUsrTree("/usr/local"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree3() { testLinuxLicenseInUsrTree("/usr/foo"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree4() { testLinuxLicenseInUsrTree("/usrbuz"); } + @Test(ifOS = LINUX) public static void testCustomDebianCopyright() { new CustomDebianCopyrightTest().run(); } + @Test(ifOS = LINUX) public static void testCustomDebianCopyrightSubst() { new CustomDebianCopyrightTest().withSubstitution(true).run(); } From a46ae7031e30eb4940e43012a42f1b7fa5d942ef Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 9 Jan 2025 04:11:54 +0000 Subject: [PATCH 062/286] 8339728: [Accessibility,Windows,JAWS] Bug in the getKeyChar method of the AccessBridge class Reviewed-by: aivanov, psadhukhan, kizune --- .../accessibility/internal/AccessBridge.java | 17 ++- .../include/bridge/AccessBridgePackages.h | 4 +- .../TestJMenuItemShortcutAccessibility.java | 112 ++++++++++++++++++ 3 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java diff --git a/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java b/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java index 1f5b5b215fa67..021a13fceacce 100644 --- a/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java +++ b/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -3904,6 +3904,8 @@ private int controlCode(KeyStroke keyStroke) { return 0; int code = keyStroke.getKeyCode(); switch (code) { + case KeyEvent.VK_TAB: + case KeyEvent.VK_SPACE: case KeyEvent.VK_BACK_SPACE: case KeyEvent.VK_DELETE: case KeyEvent.VK_DOWN: @@ -3946,15 +3948,10 @@ private char getKeyChar(KeyStroke keyStroke) { debugString("[INFO]: Shortcut is control character: " + Integer.toHexString(keyCode)); return (char)keyCode; } - String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode()); - debugString("[INFO]: Shortcut is: " + keyText); - if (keyText != null || keyText.length() > 0) { - CharSequence seq = keyText.subSequence(0, 1); - if (seq != null || seq.length() > 0) { - return seq.charAt(0); - } - } - return 0; + + keyCode = keyStroke.getKeyCode(); + debugString("[INFO]: Shortcut is: " + Integer.toHexString(keyCode)); + return (char)keyCode; } /* diff --git a/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h b/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h index 27c31be09a8a6..232cab4b21bf3 100644 --- a/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h +++ b/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -1108,6 +1108,8 @@ typedef long ABHWND64; #define ACCESSIBLE_CONTROLCODE_KEYSTROKE 512 // Control code key pressed, character contains control code. // The supported control code keys are: +#define ACCESSIBLE_VK_TAB 9 +#define ACCESSIBLE_VK_SPACE 32 #define ACCESSIBLE_VK_BACK_SPACE 8 #define ACCESSIBLE_VK_DELETE 127 #define ACCESSIBLE_VK_DOWN 40 diff --git a/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java b/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java new file mode 100644 index 0000000000000..acd7ec3c64a12 --- /dev/null +++ b/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; + +/* + * @test + * @bug 8339728 + * @summary Tests that JAWS announce the shortcuts for JMenuItems. + * @requires os.family == "windows" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestJMenuItemShortcutAccessibility + */ + +public class TestJMenuItemShortcutAccessibility { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Start the JAWS application + 2. Press Alt + M to open application Menu + 3. Navigate the Menu Items by using UP / DOWN arrow key + 4. Press Pass if you are able to hear correct JAWS announcements + (JAWS should read full shortcut text and not only the 1st + character of shortcut text for each menu item) else Fail + """; + + PassFailJFrame.builder() + .title("TestJMenuItemShortcutAccessibility Instruction") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(TestJMenuItemShortcutAccessibility::createUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createUI() { + JFrame frame = new JFrame("A Frame with Menu"); + + JMenuBar menuBar = new JMenuBar(); + JMenu menu = new JMenu("Menu with shortcuts"); + menu.setMnemonic(KeyEvent.VK_M); + menuBar.add(menu); + + KeyStroke keyStroke1 = KeyStroke.getKeyStroke(KeyEvent.VK_F, + InputEvent.CTRL_DOWN_MASK); + KeyStroke keyStroke2 = KeyStroke.getKeyStroke(KeyEvent.VK_2, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke3 = KeyStroke.getKeyStroke(KeyEvent.VK_F1, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke4 = KeyStroke.getKeyStroke(KeyEvent.VK_COMMA, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke5 = KeyStroke.getKeyStroke(KeyEvent.VK_PERIOD, + InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK); + KeyStroke keyStroke6 = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, + InputEvent.CTRL_DOWN_MASK); + KeyStroke keyStroke7 = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + + JMenuItem menuItem1 = new JMenuItem("First Menu Item"); + menuItem1.setAccelerator(keyStroke1); + JMenuItem menuItem2 = new JMenuItem("Second Menu Item"); + menuItem2.setAccelerator(keyStroke2); + JMenuItem menuItem3 = new JMenuItem("Third Menu Item"); + menuItem3.setAccelerator(keyStroke3); + JMenuItem menuItem4 = new JMenuItem("Fourth Menu Item"); + menuItem4.setAccelerator(keyStroke4); + JMenuItem menuItem5 = new JMenuItem("Fifth Menu Item"); + menuItem5.setAccelerator(keyStroke5); + JMenuItem menuItem6 = new JMenuItem("Sixth Menu Item"); + menuItem6.setAccelerator(keyStroke6); + JMenuItem menuItem7 = new JMenuItem("Seventh Menu Item"); + menuItem7.setAccelerator(keyStroke7); + + menu.add(menuItem1); + menu.add(menuItem2); + menu.add(menuItem3); + menu.add(menuItem4); + menu.add(menuItem5); + menu.add(menuItem6); + menu.add(menuItem7); + + frame.setJMenuBar(menuBar); + frame.setSize(300, 200); + return frame; + } +} From 8eddf67c82a2af4d704c4063ad802640770b3c26 Mon Sep 17 00:00:00 2001 From: Dmitry Markov Date: Thu, 9 Jan 2025 06:58:31 +0000 Subject: [PATCH 063/286] 8346887: DrawFocusRect() may cause an assertion failure Reviewed-by: aivanov, prr --- .../windows/native/libawt/windows/awt_Button.cpp | 4 ++-- .../windows/native/libawt/windows/awt_Checkbox.cpp | 6 +++--- .../windows/native/libawt/windows/awt_Component.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp index e1dd68a8b5070..e59644521ab79 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, 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 @@ -242,7 +242,7 @@ AwtButton::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo) RECT focusRect; VERIFY(::CopyRect(&focusRect, &rect)); VERIFY(::InflateRect(&focusRect,-inf,-inf)); - if(::DrawFocusRect(hDC, &focusRect) == 0) + if (!::IsRectEmpty(&focusRect) && (::DrawFocusRect(hDC, &focusRect) == 0)) VERIFY(::GetLastError() == 0); } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp index d038783d5f0e1..b37207fa2ebd9 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, 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 @@ -290,13 +290,13 @@ AwtCheckbox::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo) if ((drawInfo.itemState & ODS_FOCUS) && ((drawInfo.itemAction & ODA_FOCUS)|| (drawInfo.itemAction &ODA_DRAWENTIRE))) { - if(::DrawFocusRect(hDC, &focusRect) == 0) + if (!::IsRectEmpty(&focusRect) && (::DrawFocusRect(hDC, &focusRect) == 0)) VERIFY(::GetLastError() == 0); } /* erase focus rect */ else if (!(drawInfo.itemState & ODS_FOCUS) && (drawInfo.itemAction & ODA_FOCUS)) { - if(::DrawFocusRect(hDC, &focusRect) == 0) + if (!::IsRectEmpty(&focusRect) && (::DrawFocusRect(hDC, &focusRect) == 0)) VERIFY(::GetLastError() == 0); } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp index c49c2265ca332..b67c5dfcf8d11 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, 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 @@ -4465,7 +4465,7 @@ void AwtComponent::DrawListItem(JNIEnv *env, DRAWITEMSTRUCT &drawInfo) if ((drawInfo.itemState & ODS_FOCUS) && (drawInfo.itemAction & (ODA_FOCUS | ODA_DRAWENTIRE))) { if (!unfocusableChoice){ - if(::DrawFocusRect(hDC, &rect) == 0) + if (!::IsRectEmpty(&rect) && (::DrawFocusRect(hDC, &rect) == 0)) VERIFY(::GetLastError() == 0); } } From 33f9be8de730e664e335e36848732397393abd94 Mon Sep 17 00:00:00 2001 From: Ramkumar Sunderbabu Date: Thu, 9 Jan 2025 07:50:42 +0000 Subject: [PATCH 064/286] 8347083: Incomplete logging in nsk/jvmti/ResourceExhausted/resexhausted00* tests Reviewed-by: dholmes, sspitsyn, lmesnik --- .../nsk/jvmti/ResourceExhausted/resexhausted001.java | 4 ++-- .../nsk/jvmti/ResourceExhausted/resexhausted002.java | 4 ++-- .../nsk/jvmti/ResourceExhausted/resexhausted003.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java index b147757f9e0a1..1009f2d353800 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -62,7 +62,7 @@ public static int run(String args[], PrintStream out) { makeThread(); } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless." + System.out.println("Test resexhausted001: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless." + " threadCount=" + threadCount.get()); throw new SkippedException("Test did not get an OutOfMemory error"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java index 46832df7dc30c..c1a6e111c9f8d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -55,7 +55,7 @@ public static int run(String args[], PrintStream out) { ++count; } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); + System.out.println("Test resexhausted002: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); throw new SkippedException("Test did not get an OutOfMemory error"); } catch (OutOfMemoryError e) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java index f336c1bf3d57d..8cc997fa4ab75 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -115,7 +115,7 @@ public static int run(String args[], PrintStream out) { ++count; } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); + System.out.println("Test resexhausted003: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); throw new SkippedException("Test did not get an OutOfMemory error"); } catch (OutOfMemoryError e) { From 82e16ba248a97e3446d5b2d64c353b61dd6bdda6 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Thu, 9 Jan 2025 08:32:09 +0000 Subject: [PATCH 065/286] 8347268: [ubsan] logOutput.cpp:357:21: runtime error: applying non-zero offset 1 to null pointer Reviewed-by: dholmes --- src/hotspot/share/logging/logOutput.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/logging/logOutput.cpp b/src/hotspot/share/logging/logOutput.cpp index 17d0e8b555d60..6eba01d8aa6c6 100644 --- a/src/hotspot/share/logging/logOutput.cpp +++ b/src/hotspot/share/logging/logOutput.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -354,7 +354,9 @@ bool LogOutput::parse_options(const char* options, outputStream* errstream) { } break; } - pos = comma_pos + 1; + if (comma_pos != nullptr) { + pos = comma_pos + 1; + } } while (comma_pos != nullptr); os::free(opts); From dff5719e6f95f9ce50a5d49adf13541e22f7b5b1 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 9 Jan 2025 09:49:14 +0000 Subject: [PATCH 066/286] 8347126: gc/stress/TestStressG1Uncommit.java gets OOM-killed Reviewed-by: tschatzl, gli --- test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java b/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java index d04f1acf206b7..0006ad5ad1357 100644 --- a/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java +++ b/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java @@ -57,6 +57,7 @@ public static void main(String[] args) throws Exception { Collections.addAll(options, "-Xlog:gc,gc+heap+region=debug", "-XX:+UseG1GC", + "-Xmx1g", StressUncommit.class.getName() ); OutputAnalyzer output = ProcessTools.executeLimitedTestJava(options); @@ -79,9 +80,9 @@ public static void main(String args[]) throws InterruptedException { // Leave 20% head room to try to avoid Full GCs. long allocationSize = (long) (Runtime.getRuntime().maxMemory() * 0.8); - // Figure out suitable number of workers (~1 per gig). - int gigsOfAllocation = (int) Math.ceil((double) allocationSize / G); - int numWorkers = Math.min(gigsOfAllocation, Runtime.getRuntime().availableProcessors()); + // Figure out suitable number of workers (~1 per 100M). + int allocationChunks = (int) Math.ceil((double) allocationSize / (100 * M)); + int numWorkers = Math.min(allocationChunks, Runtime.getRuntime().availableProcessors()); long workerAllocation = allocationSize / numWorkers; log("Using " + numWorkers + " workers, each allocating: ~" + (workerAllocation / M) + "M"); From d66737ea1cfd92bcb208ded4e64822d12760205d Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 9 Jan 2025 10:18:08 +0000 Subject: [PATCH 067/286] 8341097: GHA: Demote Mac x86 jobs to build only Reviewed-by: kbarrett, prr, ihse --- .github/workflows/main.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 210d53be65819..3ea07501477f8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -325,17 +325,6 @@ jobs: bootjdk-platform: linux-x64 runs-on: ubuntu-22.04 - test-macos-x64: - name: macos-x64 - needs: - - build-macos-x64 - uses: ./.github/workflows/test.yml - with: - platform: macos-x64 - bootjdk-platform: macos-x64 - runs-on: macos-13 - xcode-toolset-version: '14.3.1' - test-macos-aarch64: name: macos-aarch64 needs: From 765b9e606b82539be136cb655c8fae33be52113b Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Thu, 9 Jan 2025 11:25:37 +0000 Subject: [PATCH 068/286] 8346706: RISC-V: Add available registers to hs_err Reviewed-by: mli, fyang, ihse --- make/autoconf/flags-cflags.m4 | 16 +++++ .../os_cpu/linux_riscv/os_linux_riscv.cpp | 69 ++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index d33f1885922d5..c1b873ed0ab42 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -830,6 +830,22 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], FLAGS_SETUP_BRANCH_PROTECTION + if test "x$FLAGS_CPU" = xriscv64; then + AC_MSG_CHECKING([if RVV/vector sigcontext supported]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], + [ + return (int)sizeof(struct __riscv_v_ext_state); + ])], + [ + AC_MSG_RESULT([yes]) + ], + [ + $1_DEFINES_CPU_JVM="${$1_DEFINES_CPU_JVM} -DNO_RVV_SIGCONTEXT" + AC_MSG_RESULT([no]) + ] + ) + fi + # EXPORT to API CFLAGS_JVM_COMMON="$ALWAYS_CFLAGS_JVM $ALWAYS_DEFINES_JVM \ $TOOLCHAIN_CFLAGS_JVM ${$1_TOOLCHAIN_CFLAGS_JVM} \ diff --git a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp index a00659f37cb42..0b6a1469d0647 100644 --- a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp +++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp @@ -56,8 +56,9 @@ // put OS-includes here # include -# include # include +# include +# include # include # include # include @@ -350,6 +351,72 @@ void os::print_context(outputStream *st, const void *context) { st->print_cr("%-*.*s=" INTPTR_FORMAT, 8, 8, reg_abi_names[r], (uintptr_t)uc->uc_mcontext.__gregs[r]); } st->cr(); + const struct __riscv_mc_d_ext_state * const f_ext_state = &(uc->uc_mcontext.__fpregs.__d); + st->print_cr("Floating point state:"); + st->print_cr("fcsr=" UINT32_FORMAT, f_ext_state->__fcsr); + st->print_cr("Floating point registers:"); + for (int r = 0; r < 32; r++) { + st->print_cr("f%d=" INTPTR_FORMAT, r, (intptr_t)f_ext_state->__f[r]); + } + st->cr(); + +#ifdef NO_RVV_SIGCONTEXT + st->print_cr("Vector state: JVM compiled without vector sigcontext support"); +#else // ifndef NO_RVV_SIGCONTEXT +// This magic number is not in any user-space header. +// No other choice but to define it (arch/riscv/include/uapi/asm/sigcontext.h). +#ifndef RISCV_V_MAGIC +#define RISCV_V_MAGIC 0x53465457 +#endif + + // Find the vector context + struct __riscv_extra_ext_header *ext = (struct __riscv_extra_ext_header *)(&uc->uc_mcontext.__fpregs); + if (ext->hdr.magic != RISCV_V_MAGIC) { + st->print_cr("Vector state: not found"); + return; + } + + // The size passed to user-space is calculated accordingly: + // size = sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state) + riscv_v_vsize; + uint32_t ext_size = ext->hdr.size; + + if (ext_size < (sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state))) { + st->print_cr("Vector state: not found, invalid size"); + return; + } + + struct __riscv_v_ext_state *v_ext_state = (struct __riscv_v_ext_state *)((char *)(ext) + sizeof(struct __riscv_extra_ext_header)); + + st->print_cr("Vector state:"); + st->print_cr("vstart=" INTPTR_FORMAT, v_ext_state->vstart); + st->print_cr("vl =" INTPTR_FORMAT, v_ext_state->vl); + st->print_cr("vtype =" INTPTR_FORMAT, v_ext_state->vtype); + st->print_cr("vcsr =" INTPTR_FORMAT, v_ext_state->vcsr); + st->print_cr("vlenb =" INTPTR_FORMAT, v_ext_state->vlenb); + st->print_cr("Vector registers:"); + + uint64_t vr_size = v_ext_state->vlenb; + + // Registers are after the v extensions header. + ext_size -= (sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state)); + + if (ext_size != (32 * vr_size)) { + st->print_cr("Vector registers: not found, invalid size"); + return; + } + + // datap format is undocumented, but is generated by kernel function riscv_v_vstate_save(). + uint8_t *regp = (uint8_t *)v_ext_state->datap; + for (int r = 0; r < 32; r++) { + st->print("v%d=0x", r); + for (int i = vr_size; i > 0; i--) { + st->print("%02" PRIx8, regp[i-1]); + } + st->print_cr(""); + regp += vr_size; + } + st->cr(); +#endif // #ifndef NO_RVV_SIGCONTEXT } void os::print_register_info(outputStream *st, const void *context, int& continuation) { From 8c87ea2bdf6e1aea5fdca4624d7b7fe590d33a37 Mon Sep 17 00:00:00 2001 From: Fei Yang Date: Thu, 9 Jan 2025 11:36:40 +0000 Subject: [PATCH 069/286] 8346478: RISC-V: Refactor add/sub assembler routines Reviewed-by: fjiang, rehn, gcao --- src/hotspot/cpu/riscv/assembler_riscv.hpp | 8 +- .../riscv/c1_LIRAssembler_arraycopy_riscv.cpp | 6 +- .../cpu/riscv/c1_LIRAssembler_riscv.cpp | 6 +- .../cpu/riscv/c1_MacroAssembler_riscv.cpp | 10 +- src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp | 8 +- .../cpu/riscv/c2_MacroAssembler_riscv.cpp | 98 +++++---- .../gc/g1/g1BarrierSetAssembler_riscv.cpp | 6 +- .../cardTableBarrierSetAssembler_riscv.cpp | 4 +- .../shenandoahBarrierSetAssembler_riscv.cpp | 8 +- .../riscv/gc/z/zBarrierSetAssembler_riscv.cpp | 8 +- src/hotspot/cpu/riscv/interp_masm_riscv.cpp | 34 +-- src/hotspot/cpu/riscv/interpreterRT_riscv.cpp | 6 +- .../cpu/riscv/macroAssembler_riscv.cpp | 180 ++++++++-------- .../cpu/riscv/macroAssembler_riscv.hpp | 26 ++- src/hotspot/cpu/riscv/riscv.ad | 24 +-- src/hotspot/cpu/riscv/riscv_b.ad | 8 +- src/hotspot/cpu/riscv/runtime_riscv.cpp | 16 +- src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp | 14 +- src/hotspot/cpu/riscv/stubGenerator_riscv.cpp | 204 +++++++++--------- .../templateInterpreterGenerator_riscv.cpp | 38 ++-- src/hotspot/cpu/riscv/templateTable_riscv.cpp | 106 ++++----- 21 files changed, 413 insertions(+), 405 deletions(-) diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 31713d7362a18..a9d601edbbef5 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -2015,10 +2015,10 @@ enum Nf { } INSN(add_uw, 0b0111011, 0b000, 0b0000100); - INSN(rol, 0b0110011, 0b001, 0b0110000); - INSN(rolw, 0b0111011, 0b001, 0b0110000); - INSN(ror, 0b0110011, 0b101, 0b0110000); - INSN(rorw, 0b0111011, 0b101, 0b0110000); + INSN(rolr, 0b0110011, 0b001, 0b0110000); + INSN(rolrw, 0b0111011, 0b001, 0b0110000); + INSN(rorr, 0b0110011, 0b101, 0b0110000); + INSN(rorrw, 0b0111011, 0b101, 0b0110000); INSN(sh1add, 0b0110011, 0b010, 0b0010000); INSN(sh2add, 0b0110011, 0b100, 0b0010000); INSN(sh3add, 0b0110011, 0b110, 0b0010000); diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp index 7d673383cad26..029c4069c0700 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp @@ -211,7 +211,7 @@ void LIR_Assembler::arraycopy_type_check(Register src, Register src_pos, Registe Label cont, slow; #define PUSH(r1, r2) \ - __ addi(sp, sp, -2 * wordSize); \ + __ subi(sp, sp, 2 * wordSize); \ __ sd(r1, Address(sp, 1 * wordSize)); \ __ sd(r2, Address(sp, 0)); @@ -337,10 +337,10 @@ void LIR_Assembler::arraycopy_prepare_params(Register src, Register src_pos, Reg Register dst, Register dst_pos, BasicType basic_type) { int scale = array_element_size(basic_type); __ shadd(c_rarg0, src_pos, src, t0, scale); - __ add(c_rarg0, c_rarg0, arrayOopDesc::base_offset_in_bytes(basic_type)); + __ addi(c_rarg0, c_rarg0, arrayOopDesc::base_offset_in_bytes(basic_type)); assert_different_registers(c_rarg0, dst, dst_pos, length); __ shadd(c_rarg1, dst_pos, dst, t0, scale); - __ add(c_rarg1, c_rarg1, arrayOopDesc::base_offset_in_bytes(basic_type)); + __ addi(c_rarg1, c_rarg1, arrayOopDesc::base_offset_in_bytes(basic_type)); assert_different_registers(c_rarg1, dst, length); __ mv(c_rarg2, length); assert_different_registers(c_rarg2, dst); diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp index d587a557a7312..6ac3ebe518497 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp @@ -1084,7 +1084,7 @@ void LIR_Assembler::typecheck_helper_slowcheck(ciKlass *k, Register obj, Registe // check for self __ beq(klass_RInfo, k_RInfo, *success_target); - __ addi(sp, sp, -2 * wordSize); // 2: store k_RInfo and klass_RInfo + __ subi(sp, sp, 2 * wordSize); // 2: store k_RInfo and klass_RInfo __ sd(k_RInfo, Address(sp, 0)); // sub klass __ sd(klass_RInfo, Address(sp, wordSize)); // super klass __ far_call(RuntimeAddress(Runtime1::entry_for(C1StubId::slow_subtype_check_id))); @@ -1099,7 +1099,7 @@ void LIR_Assembler::typecheck_helper_slowcheck(ciKlass *k, Register obj, Registe // perform the fast part of the checking logic __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, nullptr); // call out-of-line instance of __ check_klass_subtytpe_slow_path(...) - __ addi(sp, sp, -2 * wordSize); // 2: store k_RInfo and klass_RInfo + __ subi(sp, sp, 2 * wordSize); // 2: store k_RInfo and klass_RInfo __ sd(klass_RInfo, Address(sp, wordSize)); // sub klass __ sd(k_RInfo, Address(sp, 0)); // super klass __ far_call(RuntimeAddress(Runtime1::entry_for(C1StubId::slow_subtype_check_id))); @@ -2139,7 +2139,7 @@ void LIR_Assembler::lir_store_slowcheck(Register k_RInfo, Register klass_RInfo, // perform the fast part of the checking logic __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, nullptr); // call out-of-line instance of __ check_klass_subtype_slow_path(...) - __ addi(sp, sp, -2 * wordSize); // 2: store k_RInfo and klass_RInfo + __ subi(sp, sp, 2 * wordSize); // 2: store k_RInfo and klass_RInfo __ sd(klass_RInfo, Address(sp, wordSize)); // sub klass __ sd(k_RInfo, Address(sp, 0)); // super klass __ far_call(RuntimeAddress(Runtime1::entry_for(C1StubId::slow_subtype_check_id))); diff --git a/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp index ed932dddcd8d8..10aa5514fdf3e 100644 --- a/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp @@ -199,16 +199,16 @@ void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int Label done; // len_in_bytes is positive and ptr sized - sub(len_in_bytes, len_in_bytes, hdr_size_in_bytes); + subi(len_in_bytes, len_in_bytes, hdr_size_in_bytes); beqz(len_in_bytes, done); // Preserve obj if (hdr_size_in_bytes) { - add(obj, obj, hdr_size_in_bytes); + addi(obj, obj, hdr_size_in_bytes); } zero_memory(obj, len_in_bytes, tmp); if (hdr_size_in_bytes) { - sub(obj, obj, hdr_size_in_bytes); + subi(obj, obj, hdr_size_in_bytes); } bind(done); @@ -262,7 +262,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register j(entry_point); bind(loop); - sub(index, index, 1); + subi(index, index, 1); for (int i = -unroll; i < 0; i++) { if (-i == remainder) { bind(entry_point); @@ -272,7 +272,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register if (remainder == 0) { bind(entry_point); } - add(t0, t0, unroll * wordSize); + addi(t0, t0, unroll * wordSize); bnez(index, loop); } } diff --git a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp index 6f59f5c2b9559..717f10ca30d57 100644 --- a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp @@ -147,7 +147,7 @@ int StubAssembler::call_RT(Register oop_result, Register metadata_result, addres const int arg1_sp_offset = 0; const int arg2_sp_offset = 1; const int arg3_sp_offset = 2; - addi(sp, sp, -(arg_num + 1) * wordSize); + subi(sp, sp, (arg_num + 1) * wordSize); sd(arg1, Address(sp, arg1_sp_offset * wordSize)); sd(arg2, Address(sp, arg2_sp_offset * wordSize)); sd(arg3, Address(sp, arg3_sp_offset * wordSize)); @@ -301,14 +301,14 @@ static OopMap* save_live_registers(StubAssembler* sasm, if (save_fpu_registers) { // float registers - __ addi(sp, sp, -(FrameMap::nof_fpu_regs * wordSize)); + __ subi(sp, sp, FrameMap::nof_fpu_regs * wordSize); for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { __ fsd(as_FloatRegister(i), Address(sp, i * wordSize)); } } else { // we define reg_save_layout = 62 as the fixed frame size, // we should also sub 32 * wordSize to sp when save_fpu_registers == false - __ addi(sp, sp, -32 * wordSize); + __ subi(sp, sp, 32 * wordSize); } return generate_oop_map(sasm, save_fpu_registers); @@ -543,7 +543,7 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { // Save our return address because // exception_handler_for_return_address will destroy it. We also // save exception_oop - __ addi(sp, sp, -2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ sd(exception_oop, Address(sp, wordSize)); __ sd(ra, Address(sp)); diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 798804269d4ae..d04f48713eda7 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -211,16 +211,14 @@ void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, // Handle existing monitor. bind(object_has_monitor); - STATIC_ASSERT(markWord::monitor_value <= INT_MAX); - add(tmp, tmp, -(int)markWord::monitor_value); // monitor - + subi(tmp, tmp, (int)markWord::monitor_value); // monitor ld(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); Label notRecursive; beqz(disp_hdr, notRecursive); // Will be 0 if not recursive. // Recursive lock - addi(disp_hdr, disp_hdr, -1); + subi(disp_hdr, disp_hdr, 1); sd(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); j(unlocked); @@ -537,7 +535,7 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box, if (!UseObjectMonitorTable) { assert(tmp1_monitor == tmp1_mark, "should be the same here"); // Untag the monitor. - add(tmp1_monitor, tmp1_mark, -(int)markWord::monitor_value); + subi(tmp1_monitor, tmp1_mark, (int)markWord::monitor_value); } else { ld(tmp1_monitor, Address(box, BasicLock::object_monitor_cache_offset_in_bytes())); // No valid pointer below alignof(ObjectMonitor*). Take the slow path. @@ -553,7 +551,7 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box, beqz(tmp2_recursions, not_recursive); // Recursive unlock. - addi(tmp2_recursions, tmp2_recursions, -1); + subi(tmp2_recursions, tmp2_recursions, 1); sd(tmp2_recursions, Address(tmp1_monitor, ObjectMonitor::recursions_offset())); j(unlocked); @@ -732,7 +730,7 @@ void C2_MacroAssembler::string_indexof_char(Register str1, Register cnt1, BLOCK_COMMENT("string_indexof_char {"); beqz(cnt1, NOMATCH); - addi(t0, cnt1, isL ? -32 : -16); + subi(t0, cnt1, isL ? 32 : 16); bgtz(t0, DO_LONG); string_indexof_char_short(str1, cnt1, ch, result, isL); j(DONE); @@ -780,7 +778,7 @@ void C2_MacroAssembler::string_indexof_char(Register str1, Register cnt1, bind(CH1_LOOP); ld(ch1, Address(str1)); addi(str1, str1, 8); - addi(cnt1, cnt1, -8); + subi(cnt1, cnt1, 8); compute_match_mask(ch1, ch, match_mask, mask1, mask2); bnez(match_mask, HIT); bgtz(cnt1, CH1_LOOP); @@ -957,7 +955,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, const int ASIZE = 256; const int STORE_BYTES = 8; // 8 bytes stored per instruction(sd) - sub(sp, sp, ASIZE); + subi(sp, sp, ASIZE); // init BC offset table with default value: needle_len slli(t0, needle_len, 8); @@ -976,16 +974,16 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, for (int i = 0; i < 4; i++) { sd(tmp5, Address(ch1, i * wordSize)); } - add(ch1, ch1, 32); - sub(tmp6, tmp6, 4); + addi(ch1, ch1, 32); + subi(tmp6, tmp6, 4); bgtz(tmp6, BM_INIT_LOOP); - sub(nlen_tmp, needle_len, 1); // m - 1, index of the last element in pattern + subi(nlen_tmp, needle_len, 1); // m - 1, index of the last element in pattern Register orig_haystack = tmp5; mv(orig_haystack, haystack); // result_tmp = tmp4 shadd(haystack_end, result_tmp, haystack, haystack_end, haystack_chr_shift); - sub(ch2, needle_len, 1); // bc offset init value, ch2 is t1 + subi(ch2, needle_len, 1); // bc offset init value, ch2 is t1 mv(tmp3, needle); // for (i = 0; i < m - 1; ) { @@ -1000,7 +998,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, // } bind(BCLOOP); (this->*needle_load_1chr)(ch1, Address(tmp3), noreg); - add(tmp3, tmp3, needle_chr_size); + addi(tmp3, tmp3, needle_chr_size); if (!needle_isL) { // ae == StrIntrinsicNode::UU mv(tmp6, ASIZE); @@ -1010,7 +1008,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, sb(ch2, Address(tmp4)); // store skip offset to BC offset table bind(BCSKIP); - sub(ch2, ch2, 1); // for next pattern element, skip distance -1 + subi(ch2, ch2, 1); // for next pattern element, skip distance -1 bgtz(ch2, BCLOOP); // tmp6: pattern end, address after needle @@ -1047,7 +1045,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, // compare pattern to source string backward shadd(result, nlen_tmp, haystack, result, haystack_chr_shift); (this->*haystack_load_1chr)(skipch, Address(result), noreg); - sub(nlen_tmp, nlen_tmp, firstStep); // nlen_tmp is positive here, because needle_len >= 8 + subi(nlen_tmp, nlen_tmp, firstStep); // nlen_tmp is positive here, because needle_len >= 8 if (needle_isL == haystack_isL) { // re-init tmp3. It's for free because it's executed in parallel with // load above. Alternative is to initialize it before loop, but it'll @@ -1066,7 +1064,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, if (isLL) { j(BMLOOPSTR1_AFTER_LOAD); } else { - sub(nlen_tmp, nlen_tmp, 1); // no need to branch for UU/UL case. cnt1 >= 8 + subi(nlen_tmp, nlen_tmp, 1); // no need to branch for UU/UL case. cnt1 >= 8 j(BMLOOPSTR1_CMP); } @@ -1077,7 +1075,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, (this->*haystack_load_1chr)(ch2, Address(ch2), noreg); bind(BMLOOPSTR1_AFTER_LOAD); - sub(nlen_tmp, nlen_tmp, 1); + subi(nlen_tmp, nlen_tmp, 1); bltz(nlen_tmp, BMLOOPSTR1_LASTCMP); bind(BMLOOPSTR1_CMP); @@ -1099,11 +1097,11 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, lbu(result_tmp, Address(result_tmp)); // load skip offset bind(BMADV); - sub(nlen_tmp, needle_len, 1); + subi(nlen_tmp, needle_len, 1); // move haystack after bad char skip offset shadd(haystack, result_tmp, haystack, result, haystack_chr_shift); ble(haystack, haystack_end, BMLOOPSTR2); - add(sp, sp, ASIZE); + addi(sp, sp, ASIZE); j(NOMATCH); bind(BMLOOPSTR1_LASTCMP); @@ -1114,11 +1112,11 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, if (!haystack_isL) { srli(result, result, 1); } - add(sp, sp, ASIZE); + addi(sp, sp, ASIZE); j(DONE); bind(LINEARSTUB); - sub(t0, needle_len, 16); // small patterns still should be handled by simple algorithm + subi(t0, needle_len, 16); // small patterns still should be handled by simple algorithm bltz(t0, LINEARSEARCH); mv(result, zr); RuntimeAddress stub = nullptr; @@ -1197,7 +1195,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne if (needle_con_cnt == -1) { Label DOSHORT, FIRST_LOOP, STR2_NEXT, STR1_LOOP, STR1_NEXT; - sub(t0, needle_len, needle_isL == haystack_isL ? 4 : 2); + subi(t0, needle_len, needle_isL == haystack_isL ? 4 : 2); bltz(t0, DOSHORT); (this->*needle_load_1chr)(first, Address(needle), noreg); @@ -1214,13 +1212,13 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne beq(first, ch2, STR1_LOOP); bind(STR2_NEXT); - add(hlen_neg, hlen_neg, haystack_chr_size); + addi(hlen_neg, hlen_neg, haystack_chr_size); blez(hlen_neg, FIRST_LOOP); j(NOMATCH); bind(STR1_LOOP); - add(nlen_tmp, nlen_neg, needle_chr_size); - add(hlen_tmp, hlen_neg, haystack_chr_size); + addi(nlen_tmp, nlen_neg, needle_chr_size); + addi(hlen_tmp, hlen_neg, haystack_chr_size); bgez(nlen_tmp, MATCH); bind(STR1_NEXT); @@ -1229,14 +1227,14 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne add(ch2, haystack, hlen_tmp); (this->*haystack_load_1chr)(ch2, Address(ch2), noreg); bne(ch1, ch2, STR2_NEXT); - add(nlen_tmp, nlen_tmp, needle_chr_size); - add(hlen_tmp, hlen_tmp, haystack_chr_size); + addi(nlen_tmp, nlen_tmp, needle_chr_size); + addi(hlen_tmp, hlen_tmp, haystack_chr_size); bltz(nlen_tmp, STR1_NEXT); j(MATCH); bind(DOSHORT); if (needle_isL == haystack_isL) { - sub(t0, needle_len, 2); + subi(t0, needle_len, 2); bltz(t0, DO1); bgtz(t0, DO3); } @@ -1245,7 +1243,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne if (needle_con_cnt == 4) { Label CH1_LOOP; (this->*load_4chr)(ch1, Address(needle), noreg); - sub(result_tmp, haystack_len, 4); + subi(result_tmp, haystack_len, 4); slli(tmp3, result_tmp, haystack_chr_shift); // result as tmp add(haystack, haystack, tmp3); neg(hlen_neg, tmp3); @@ -1274,7 +1272,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne (this->*load_4chr)(ch2, Address(tmp3), noreg); } beq(ch1, ch2, MATCH); - add(hlen_neg, hlen_neg, haystack_chr_size); + addi(hlen_neg, hlen_neg, haystack_chr_size); blez(hlen_neg, CH1_LOOP); j(NOMATCH); } @@ -1285,7 +1283,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne bind(DO2); (this->*load_2chr)(ch1, Address(needle), noreg); if (needle_con_cnt == 2) { - sub(result_tmp, haystack_len, 2); + subi(result_tmp, haystack_len, 2); } slli(tmp3, result_tmp, haystack_chr_shift); add(haystack, haystack, tmp3); @@ -1308,7 +1306,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne (this->*load_2chr)(ch2, Address(tmp3), noreg); } beq(ch1, ch2, MATCH); - add(hlen_neg, hlen_neg, haystack_chr_size); + addi(hlen_neg, hlen_neg, haystack_chr_size); blez(hlen_neg, CH1_LOOP); j(NOMATCH); BLOCK_COMMENT("} string_indexof DO2"); @@ -1322,7 +1320,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne (this->*load_2chr)(first, Address(needle), noreg); (this->*needle_load_1chr)(ch1, Address(needle, 2 * needle_chr_size), noreg); if (needle_con_cnt == 3) { - sub(result_tmp, haystack_len, 3); + subi(result_tmp, haystack_len, 3); } slli(hlen_tmp, result_tmp, haystack_chr_shift); add(haystack, haystack, hlen_tmp); @@ -1341,12 +1339,12 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne beq(first, ch2, STR1_LOOP); bind(STR2_NEXT); - add(hlen_neg, hlen_neg, haystack_chr_size); + addi(hlen_neg, hlen_neg, haystack_chr_size); blez(hlen_neg, FIRST_LOOP); j(NOMATCH); bind(STR1_LOOP); - add(hlen_tmp, hlen_neg, 2 * haystack_chr_size); + addi(hlen_tmp, hlen_neg, 2 * haystack_chr_size); add(ch2, haystack, hlen_tmp); (this->*haystack_load_1chr)(ch2, Address(ch2), noreg); bne(ch1, ch2, STR2_NEXT); @@ -1360,7 +1358,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne BLOCK_COMMENT("string_indexof DO1 {"); bind(DO1); (this->*needle_load_1chr)(ch1, Address(needle), noreg); - sub(result_tmp, haystack_len, 1); + subi(result_tmp, haystack_len, 1); slli(tmp3, result_tmp, haystack_chr_shift); add(haystack, haystack, tmp3); neg(hlen_neg, tmp3); @@ -1369,7 +1367,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne add(tmp3, haystack, hlen_neg); (this->*haystack_load_1chr)(ch2, Address(tmp3), noreg); beq(ch1, ch2, MATCH); - add(hlen_neg, hlen_neg, haystack_chr_size); + addi(hlen_neg, hlen_neg, haystack_chr_size); blez(hlen_neg, DO1_LOOP); BLOCK_COMMENT("} string_indexof DO1"); } @@ -1444,7 +1442,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, ld(tmp2, Address(str2)); mv(t0, STUB_THRESHOLD); bge(cnt2, t0, STUB); - sub(cnt2, cnt2, minCharsInWord); + subi(cnt2, cnt2, minCharsInWord); beqz(cnt2, TAIL_CHECK); // convert cnt2 from characters to bytes if (!str1_isL) { @@ -1458,7 +1456,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, ld(tmp2, Address(str2)); mv(t0, STUB_THRESHOLD); bge(cnt2, t0, STUB); - addi(cnt2, cnt2, -4); + subi(cnt2, cnt2, 4); add(str1, str1, cnt2); sub(cnt1, zr, cnt2); slli(cnt2, cnt2, 1); @@ -1586,13 +1584,13 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, // while comparing previous (this->*str1_load_chr)(tmp1, Address(str1), t0); addi(str1, str1, str1_chr_size); - addi(cnt2, cnt2, -1); + subi(cnt2, cnt2, 1); beqz(cnt2, SHORT_LAST_INIT); (this->*str2_load_chr)(cnt1, Address(str2), t0); addi(str2, str2, str2_chr_size); j(SHORT_LOOP_START); bind(SHORT_LOOP); - addi(cnt2, cnt2, -1); + subi(cnt2, cnt2, 1); beqz(cnt2, SHORT_LAST); bind(SHORT_LOOP_START); (this->*str1_load_chr)(tmp2, Address(str1), t0); @@ -1600,7 +1598,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, (this->*str2_load_chr)(t0, Address(str2), t0); addi(str2, str2, str2_chr_size); bne(tmp1, cnt1, SHORT_LOOP_TAIL); - addi(cnt2, cnt2, -1); + subi(cnt2, cnt2, 1); beqz(cnt2, SHORT_LAST2); (this->*str1_load_chr)(tmp1, Address(str1), t0); addi(str1, str1, str1_chr_size); @@ -1635,7 +1633,7 @@ void C2_MacroAssembler::arrays_equals(Register a1, Register a2, assert(elem_size == 1 || elem_size == 2, "must be char or byte"); assert_different_registers(a1, a2, result, tmp1, tmp2, tmp3, t0); - int elem_per_word = wordSize/elem_size; + int elem_per_word = wordSize / elem_size; int log_elem_size = exact_log2(elem_size); int length_offset = arrayOopDesc::length_offset_in_bytes(); int base_offset = arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE); @@ -1664,14 +1662,14 @@ void C2_MacroAssembler::arrays_equals(Register a1, Register a2, la(a1, Address(a1, base_offset)); la(a2, Address(a2, base_offset)); // Check for short strings, i.e. smaller than wordSize. - addi(cnt1, cnt1, -elem_per_word); + subi(cnt1, cnt1, elem_per_word); bltz(cnt1, SHORT); // Main 8 byte comparison loop. bind(NEXT_WORD); { ld(tmp1, Address(a1)); ld(tmp2, Address(a2)); - addi(cnt1, cnt1, -elem_per_word); + subi(cnt1, cnt1, elem_per_word); addi(a1, a1, wordSize); addi(a2, a2, wordSize); bne(tmp1, tmp2, DONE); @@ -1743,14 +1741,14 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2, mv(result, false); // Check for short strings, i.e. smaller than wordSize. - addi(cnt1, cnt1, -wordSize); + subi(cnt1, cnt1, wordSize); bltz(cnt1, SHORT); // Main 8 byte comparison loop. bind(NEXT_WORD); { ld(tmp1, Address(a1)); ld(tmp2, Address(a2)); - addi(cnt1, cnt1, -wordSize); + subi(cnt1, cnt1, wordSize); addi(a1, a1, wordSize); addi(a2, a2, wordSize); bne(tmp1, tmp2, DONE); @@ -1838,7 +1836,7 @@ void C2_MacroAssembler::arrays_hashcode(Register ary, Register cnt, Register res beqz(cnt, DONE); - andi(chunks, cnt, ~(stride-1)); + andi(chunks, cnt, ~(stride - 1)); beqz(chunks, TAIL); mv(pow31_4, 923521); // [31^^4] @@ -1847,7 +1845,7 @@ void C2_MacroAssembler::arrays_hashcode(Register ary, Register cnt, Register res slli(chunks_end, chunks, chunks_end_shift); add(chunks_end, ary, chunks_end); - andi(cnt, cnt, stride-1); // don't forget about tail! + andi(cnt, cnt, stride - 1); // don't forget about tail! bind(WIDE_LOOP); mulw(result, result, pow31_4); // 31^^4 * h diff --git a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp index 6a3e4f95b9848..e5d4952e1728c 100644 --- a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp @@ -106,7 +106,7 @@ static void generate_queue_test_and_insertion(MacroAssembler* masm, ByteSize ind __ ld(tmp1, Address(thread, in_bytes(index_offset))); // tmp1 := *(index address) __ beqz(tmp1, runtime); // jump to runtime if index == 0 (full buffer) // The buffer is not full, store value into it. - __ sub(tmp1, tmp1, wordSize); // tmp1 := next index + __ subi(tmp1, tmp1, wordSize); // tmp1 := next index __ sd(tmp1, Address(thread, in_bytes(index_offset))); // *(index address) := next index __ ld(tmp2, Address(thread, in_bytes(buffer_offset))); // tmp2 := buffer address __ add(tmp2, tmp2, tmp1); @@ -490,7 +490,7 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* __ ld(tmp, queue_index); __ beqz(tmp, runtime); - __ sub(tmp, tmp, wordSize); + __ subi(tmp, tmp, wordSize); __ sd(tmp, queue_index); __ ld(t1, buffer); __ add(tmp, tmp, t1); @@ -557,7 +557,7 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* __ ld(t0, queue_index); __ beqz(t0, runtime); - __ sub(t0, t0, wordSize); + __ subi(t0, t0, wordSize); __ sd(t0, queue_index); // Reuse RA to hold buffer_addr diff --git a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp index 2ad44400687f2..316dae5ead1bf 100644 --- a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp @@ -69,7 +69,7 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl __ beqz(count, L_done); // zero count - nothing to do // end = start + count << LogBytesPerHeapOop __ shadd(end, count, start, count, LogBytesPerHeapOop); - __ sub(end, end, BytesPerHeapOop); // last element address to make inclusive + __ subi(end, end, BytesPerHeapOop); // last element address to make inclusive __ srli(start, start, CardTable::card_shift()); __ srli(end, end, CardTable::card_shift()); @@ -81,7 +81,7 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl __ bind(L_loop); __ add(tmp, start, count); __ sb(zr, Address(tmp)); - __ sub(count, count, 1); + __ subi(count, count, 1); __ bgez(count, L_loop); __ bind(L_done); } diff --git a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp index 257d445f01187..8ae97492affda 100644 --- a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp @@ -143,7 +143,7 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm, __ ld(tmp1, index); // tmp := *index_adr __ beqz(tmp1, runtime); // tmp == 0? If yes, goto runtime - __ sub(tmp1, tmp1, wordSize); // tmp := tmp - wordSize + __ subi(tmp1, tmp1, wordSize); // tmp := tmp - wordSize __ sd(tmp1, index); // *index_adr := tmp __ ld(tmp2, buffer); __ add(tmp1, tmp1, tmp2); // tmp := tmp + *buffer_adr @@ -562,7 +562,7 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb // end = start + count << LogBytesPerHeapOop // last element address to make inclusive __ shadd(end, count, start, tmp, LogBytesPerHeapOop); - __ sub(end, end, BytesPerHeapOop); + __ subi(end, end, BytesPerHeapOop); __ srli(start, start, CardTable::card_shift()); __ srli(end, end, CardTable::card_shift()); @@ -575,7 +575,7 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb __ bind(L_loop); __ add(tmp, start, count); __ sb(zr, Address(tmp)); - __ sub(count, count, 1); + __ subi(count, count, 1); __ bgez(count, L_loop); __ bind(L_done); } @@ -690,7 +690,7 @@ void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAss __ ld(tmp, queue_index); __ beqz(tmp, runtime); - __ sub(tmp, tmp, wordSize); + __ subi(tmp, tmp, wordSize); __ sd(tmp, queue_index); __ ld(t1, buffer); __ add(tmp, tmp, t1); diff --git a/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp index 0b093838b8b68..ad4f243e5e1e3 100644 --- a/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp @@ -241,7 +241,7 @@ static void store_barrier_buffer_add(MacroAssembler* masm, __ beqz(tmp2, slow_path); // Bump the pointer - __ sub(tmp2, tmp2, sizeof(ZStoreBarrierEntry)); + __ subi(tmp2, tmp2, sizeof(ZStoreBarrierEntry)); __ sd(tmp2, Address(tmp1, ZStoreBarrierBuffer::current_offset())); // Compute the buffer entry address @@ -848,10 +848,10 @@ void ZBarrierSetAssembler::generate_c1_load_barrier_stub(LIR_Assembler* ce, // Save x10 unless it is the result or tmp register // Set up SP to accommdate parameters and maybe x10. if (ref != x10 && tmp != x10) { - __ sub(sp, sp, 32); + __ subi(sp, sp, 32); __ sd(x10, Address(sp, 16)); } else { - __ sub(sp, sp, 16); + __ subi(sp, sp, 16); } // Setup arguments and call runtime stub @@ -963,7 +963,7 @@ void ZBarrierSetAssembler::generate_c1_store_barrier_stub(LIR_Assembler* ce, __ la(stub->new_zpointer()->as_register(), ce->as_Address(stub->ref_addr()->as_address_ptr())); - __ sub(sp, sp, 16); + __ subi(sp, sp, 16); //Setup arguments and call runtime stub assert(stub->new_zpointer()->is_valid(), "invariant"); ce->store_parameter(stub->new_zpointer()->as_register(), 0); diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index 70fec29d4f7e7..605a8124e6cd5 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -270,18 +270,18 @@ void InterpreterMacroAssembler::pop_l(Register r) { } void InterpreterMacroAssembler::push_ptr(Register r) { - addi(esp, esp, -wordSize); + subi(esp, esp, wordSize); sd(r, Address(esp, 0)); } void InterpreterMacroAssembler::push_i(Register r) { - addi(esp, esp, -wordSize); + subi(esp, esp, wordSize); sext(r, r, 32); sd(r, Address(esp, 0)); } void InterpreterMacroAssembler::push_l(Register r) { - addi(esp, esp, -2 * wordSize); + subi(esp, esp, 2 * wordSize); sd(zr, Address(esp, wordSize)); sd(r, Address(esp)); } @@ -297,12 +297,12 @@ void InterpreterMacroAssembler::pop_d(FloatRegister r) { } void InterpreterMacroAssembler::push_f(FloatRegister r) { - addi(esp, esp, -wordSize); + subi(esp, esp, wordSize); fsw(r, Address(esp, 0)); } void InterpreterMacroAssembler::push_d(FloatRegister r) { - addi(esp, esp, -2 * wordSize); + subi(esp, esp, 2 * wordSize); fsd(r, Address(esp, 0)); } @@ -895,7 +895,7 @@ void InterpreterMacroAssembler::verify_method_data_pointer() { assert(ProfileInterpreter, "must be profiling interpreter"); #ifdef ASSERT Label verify_continue; - add(sp, sp, -4 * wordSize); + subi(sp, sp, 4 * wordSize); sd(x10, Address(sp, 0)); sd(x11, Address(sp, wordSize)); sd(x12, Address(sp, 2 * wordSize)); @@ -920,7 +920,7 @@ void InterpreterMacroAssembler::verify_method_data_pointer() { ld(x11, Address(sp, wordSize)); ld(x12, Address(sp, 2 * wordSize)); ld(x13, Address(sp, 3 * wordSize)); - add(sp, sp, 4 * wordSize); + addi(sp, sp, 4 * wordSize); #endif // ASSERT } @@ -961,7 +961,7 @@ void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, if (decrement) { ld(t0, addr); - addi(t0, t0, -DataLayout::counter_increment); + subi(t0, t0, DataLayout::counter_increment); Label L; bltz(t0, L); // skip store if counter underflow sd(t0, addr); @@ -1028,7 +1028,7 @@ void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, int constant) { assert(ProfileInterpreter, "must be profiling interpreter"); - addi(mdp_in, mdp_in, (unsigned)constant); + add(mdp_in, mdp_in, (unsigned)constant); sd(mdp_in, Address(fp, frame::interpreter_frame_mdp_offset * wordSize)); } @@ -1037,7 +1037,7 @@ void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { assert(ProfileInterpreter, "must be profiling interpreter"); // save/restore across call_VM - addi(sp, sp, -2 * wordSize); + subi(sp, sp, 2 * wordSize); sd(zr, Address(sp, 0)); sd(return_bci, Address(sp, wordSize)); call_VM(noreg, @@ -1739,7 +1739,7 @@ void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register ca add(t0, mdp, t0); ld(t0, Address(t0)); sub(tmp, tmp, t0); - addi(tmp, tmp, -1); + subi(tmp, tmp, 1); Address arg_addr = argument_address(tmp); ld(tmp, arg_addr); @@ -1762,7 +1762,7 @@ void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register ca if (MethodData::profile_return()) { ld(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset()))); - addi(tmp, tmp, -TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count()); + sub(tmp, tmp, TypeProfileArgsLimit * TypeStackSlotEntries::per_arg_count()); } add(t0, mdp, off_to_args); @@ -1849,7 +1849,7 @@ void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register t // mdo start + parameters offset + array length - 1 add(mdp, mdp, tmp1); ld(tmp1, Address(mdp, ArrayData::array_len_offset())); - add(tmp1, tmp1, - TypeStackSlotEntries::per_arg_count()); + subi(tmp1, tmp1, TypeStackSlotEntries::per_arg_count()); Label loop; bind(loop); @@ -1875,7 +1875,7 @@ void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register t profile_obj_type(tmp2, arg_type, tmp3); // go to next parameter - add(tmp1, tmp1, - TypeStackSlotEntries::per_arg_count()); + subi(tmp1, tmp1, TypeStackSlotEntries::per_arg_count()); bgez(tmp1, loop); bind(profile_continue); @@ -1890,7 +1890,7 @@ void InterpreterMacroAssembler::load_resolved_indy_entry(Register cache, Registe ld(cache, Address(xcpool, in_bytes(ConstantPoolCache::invokedynamic_entries_offset()))); // Scale the index to be the entry index * sizeof(ResolvedIndyEntry) slli(index, index, log2i_exact(sizeof(ResolvedIndyEntry))); - add(cache, cache, Array::base_offset_in_bytes()); + addi(cache, cache, Array::base_offset_in_bytes()); add(cache, cache, index); } @@ -1906,7 +1906,7 @@ void InterpreterMacroAssembler::load_field_entry(Register cache, Register index, } // Get address of field entries array ld(cache, Address(xcpool, ConstantPoolCache::field_entries_offset())); - add(cache, cache, Array::base_offset_in_bytes()); + addi(cache, cache, Array::base_offset_in_bytes()); add(cache, cache, index); // Prevents stale data from being read after the bytecode is patched to the fast bytecode membar(MacroAssembler::LoadLoad); @@ -1932,7 +1932,7 @@ void InterpreterMacroAssembler::load_method_entry(Register cache, Register index // Get address of field entries array ld(cache, Address(xcpool, ConstantPoolCache::method_entries_offset())); - add(cache, cache, Array::base_offset_in_bytes()); + addi(cache, cache, Array::base_offset_in_bytes()); add(cache, cache, index); } diff --git a/src/hotspot/cpu/riscv/interpreterRT_riscv.cpp b/src/hotspot/cpu/riscv/interpreterRT_riscv.cpp index de34d84fecb00..602aacb99485c 100644 --- a/src/hotspot/cpu/riscv/interpreterRT_riscv.cpp +++ b/src/hotspot/cpu/riscv/interpreterRT_riscv.cpp @@ -138,10 +138,10 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { Register reg = next_gpr(); if (reg == c_rarg1) { assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); - __ addi(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset())); + __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset())); } else if (reg != noreg) { // c_rarg2-c_rarg7 - __ addi(x10, from(), Interpreter::local_offset_in_bytes(offset())); + __ add(x10, from(), Interpreter::local_offset_in_bytes(offset())); __ mv(reg, zr); //_num_reg_int_args:c_rarg -> 1:c_rarg2, 2:c_rarg3... __ ld(temp(), x10); Label L; @@ -150,7 +150,7 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { __ bind(L); } else { //to stack - __ addi(x10, from(), Interpreter::local_offset_in_bytes(offset())); + __ add(x10, from(), Interpreter::local_offset_in_bytes(offset())); __ ld(temp(), x10); Label L; __ bnez(temp(), L); diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 804407fd80e68..f0e5992b04b65 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -245,7 +245,7 @@ void MacroAssembler::inc_held_monitor_count(Register tmp) { void MacroAssembler::dec_held_monitor_count(Register tmp) { Address dst(xthread, JavaThread::held_monitor_count_offset()); ld(tmp, dst); - addi(tmp, tmp, -1); + subi(tmp, tmp, 1); sd(tmp, dst); #ifdef ASSERT Label ok; @@ -1430,7 +1430,7 @@ void MacroAssembler::restore_cpu_control_state_after_jni(Register tmp) { void MacroAssembler::push_reg(Register Rs) { - addi(esp, esp, 0 - wordSize); + subi(esp, esp, wordSize); sd(Rs, Address(esp, 0)); } @@ -1462,7 +1462,7 @@ int MacroAssembler::push_reg(unsigned int bitset, Register stack) { int offset = is_even(count) ? 0 : wordSize; if (count) { - addi(stack, stack, -count * wordSize - offset); + sub(stack, stack, count * wordSize + offset); } for (int i = count - 1; i >= 0; i--) { sd(as_Register(regs[i]), Address(stack, (count - 1 - i) * wordSize + offset)); @@ -1487,7 +1487,7 @@ int MacroAssembler::pop_reg(unsigned int bitset, Register stack) { } if (count) { - addi(stack, stack, count * wordSize + offset); + add(stack, stack, count * wordSize + offset); } assert(words_popped == count, "oops, popped != count"); @@ -1503,7 +1503,7 @@ int MacroAssembler::push_fp(unsigned int bitset, Register stack) { int push_slots = count + (count & 1); if (count) { - addi(stack, stack, -push_slots * wordSize); + subi(stack, stack, push_slots * wordSize); } for (int i = count - 1; i >= 0; i--) { @@ -1632,7 +1632,7 @@ void MacroAssembler::vector_update_crc32(Register crc, Register buf, Register le Label VectorLoop; Label LastBlock; - add(tableN16, table3, 1*single_table_size*sizeof(juint), tmp1); + add(tableN16, table3, 1 * single_table_size * sizeof(juint), tmp1); mv(tmp5, 0xff); if (MaxVectorSize == 16) { @@ -1651,7 +1651,7 @@ void MacroAssembler::vector_update_crc32(Register crc, Register buf, Register le srli(blks, len, 6); slli(t1, blks, 6); sub(len, len, t1); - sub(blks, blks, 1); + subi(blks, blks, 1); blez(blks, LastBlock); bind(VectorLoop); @@ -1683,7 +1683,7 @@ void MacroAssembler::vector_update_crc32(Register crc, Register buf, Register le addi(tmp1, tmp1, 1); } - sub(blks, blks, 1); + subi(blks, blks, 1); bgtz(blks, VectorLoop); } @@ -2046,7 +2046,7 @@ void MacroAssembler::kernel_crc32_vclmul_fold(Register crc, Register buf, Regist Register vclmul_table = tmp3; la(vclmul_table, table_addr); - add(vclmul_table, vclmul_table, table_num*single_table_size*sizeof(juint), tmp1); + add(vclmul_table, vclmul_table, table_num * single_table_size * sizeof(juint), tmp1); la(table0, table_addr); if (MaxVectorSize == 16) { @@ -2092,25 +2092,25 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, const ExternalAddress table_addr = StubRoutines::crc_table_addr(); la(table0, table_addr); - add(table1, table0, 1*single_table_size*sizeof(juint), tmp1); - add(table2, table0, 2*single_table_size*sizeof(juint), tmp1); - add(table3, table2, 1*single_table_size*sizeof(juint), tmp1); + add(table1, table0, 1 * single_table_size * sizeof(juint), tmp1); + add(table2, table0, 2 * single_table_size * sizeof(juint), tmp1); + add(table3, table2, 1 * single_table_size * sizeof(juint), tmp1); // Ensure basic 4-byte alignment of input byte buffer mv(tmp1, 4); blt(len, tmp1, L_by1_loop); test_bit(tmp1, buf, 0); beqz(tmp1, L_skip1); - subw(len, len, 1); + subiw(len, len, 1); lbu(tmp1, Address(buf)); - add(buf, buf, 1); + addi(buf, buf, 1); update_byte_crc32(crc, tmp1, table0); bind(L_skip1); test_bit(tmp1, buf, 1); beqz(tmp1, L_skip2); - subw(len, len, 2); + subiw(len, len, 2); lhu(tmp1, Address(buf)); - add(buf, buf, 2); + addi(buf, buf, 2); zext(tmp2, tmp1, 8); update_byte_crc32(crc, tmp2, table0); srli(tmp2, tmp1, 8); @@ -2134,8 +2134,8 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, align(CodeEntryAlignment); // Entry for L_unroll_loop - add(loop_buf_end, buf, len); // loop_buf_end will be used as endpoint for loop below - andi(len, len, unroll_words-1); // len = (len % unroll_words) + add(loop_buf_end, buf, len); // loop_buf_end will be used as endpoint for loop below + andi(len, len, unroll_words - 1); // len = (len % unroll_words) sub(loop_buf_end, loop_buf_end, len); bind(L_unroll_loop); for (int i = 0; i < unroll; i++) { @@ -2162,17 +2162,17 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, bind(L_by1_loop); beqz(len, L_exit); - subw(len, len, 1); + subiw(len, len, 1); lbu(tmp1, Address(buf)); update_byte_crc32(crc, tmp1, table0); beqz(len, L_exit); - subw(len, len, 1); + subiw(len, len, 1); lbu(tmp1, Address(buf, 1)); update_byte_crc32(crc, tmp1, table0); beqz(len, L_exit); - subw(len, len, 1); + subiw(len, len, 1); lbu(tmp1, Address(buf, 2)); update_byte_crc32(crc, tmp1, table0); @@ -2238,7 +2238,7 @@ void MacroAssembler::push_call_clobbered_registers_except(RegSet exclude) { push_reg(RegSet::of(x7) + RegSet::range(x10, x17) + RegSet::range(x28, x31) - exclude, sp); // Push float registers f0-f7, f10-f17, f28-f31. - addi(sp, sp, - wordSize * 20); + subi(sp, sp, wordSize * 20); int offset = 0; for (int i = 0; i < 32; i++) { if (i <= f7->encoding() || i >= f28->encoding() || (i >= f10->encoding() && i <= f17->encoding())) { @@ -2264,7 +2264,7 @@ void MacroAssembler::push_CPU_state(bool save_vectors, int vector_size_in_bytes) push_reg(RegSet::range(x5, x31), sp); // float registers - addi(sp, sp, - 32 * wordSize); + subi(sp, sp, 32 * wordSize); for (int i = 0; i < 32; i++) { fsd(as_FloatRegister(i), Address(sp, i * wordSize)); } @@ -2605,32 +2605,32 @@ void MacroAssembler::movptr2(Register Rd, uint64_t addr, int32_t &offset, Regist offset = lower12; } -void MacroAssembler::add(Register Rd, Register Rn, int64_t increment, Register temp) { +void MacroAssembler::add(Register Rd, Register Rn, int64_t increment, Register tmp) { if (is_simm12(increment)) { addi(Rd, Rn, increment); } else { - assert_different_registers(Rn, temp); - li(temp, increment); - add(Rd, Rn, temp); + assert_different_registers(Rn, tmp); + mv(tmp, increment); + add(Rd, Rn, tmp); } } -void MacroAssembler::addw(Register Rd, Register Rn, int32_t increment, Register temp) { +void MacroAssembler::sub(Register Rd, Register Rn, int64_t decrement, Register tmp) { + add(Rd, Rn, -decrement, tmp); +} + +void MacroAssembler::addw(Register Rd, Register Rn, int32_t increment, Register tmp) { if (is_simm12(increment)) { addiw(Rd, Rn, increment); } else { - assert_different_registers(Rn, temp); - li(temp, increment); - addw(Rd, Rn, temp); + assert_different_registers(Rn, tmp); + mv(tmp, increment); + addw(Rd, Rn, tmp); } } -void MacroAssembler::sub(Register Rd, Register Rn, int64_t decrement, Register temp) { - add(Rd, Rn, -decrement, temp); -} - -void MacroAssembler::subw(Register Rd, Register Rn, int32_t decrement, Register temp) { - addw(Rd, Rn, -decrement, temp); +void MacroAssembler::subw(Register Rd, Register Rn, int32_t decrement, Register tmp) { + addw(Rd, Rn, -decrement, tmp); } void MacroAssembler::andrw(Register Rd, Register Rs1, Register Rs2) { @@ -2870,7 +2870,7 @@ void MacroAssembler::revb(Register Rd, Register Rs, Register tmp1, Register tmp2 } // rotate right with shift bits -void MacroAssembler::ror_imm(Register dst, Register src, uint32_t shift, Register tmp) +void MacroAssembler::ror(Register dst, Register src, uint32_t shift, Register tmp) { if (UseZbb) { rori(dst, src, shift); @@ -2886,7 +2886,7 @@ void MacroAssembler::ror_imm(Register dst, Register src, uint32_t shift, Registe } // rotate left with shift bits, 32-bit version -void MacroAssembler::rolw_imm(Register dst, Register src, uint32_t shift, Register tmp) { +void MacroAssembler::rolw(Register dst, Register src, uint32_t shift, Register tmp) { if (UseZbb) { // no roliw available roriw(dst, src, 32 - shift); @@ -4153,8 +4153,8 @@ void MacroAssembler::repne_scan(Register addr, Register value, Register count, bind(Lloop); ld(tmp, addr); beq(value, tmp, Lexit); - add(addr, addr, wordSize); - sub(count, count, 1); + addi(addr, addr, wordSize); + subi(count, count, 1); bnez(count, Lloop); bind(Lexit); } @@ -4222,7 +4222,7 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, // Load the array length. lwu(x12, Address(x15, Array::length_offset_in_bytes())); // Skip to start of data. - add(x15, x15, Array::base_offset_in_bytes()); + addi(x15, x15, Array::base_offset_in_bytes()); // Set t0 to an obvious invalid value, falling through by default mv(t0, -1); @@ -4359,7 +4359,7 @@ bool MacroAssembler::lookup_secondary_supers_table(Register r_sub_klass, // Linear probe. if (bit != 0) { - ror_imm(r_bitmap, r_bitmap, bit); + ror(r_bitmap, r_bitmap, bit); } // The slot we just inspected is at secondary_supers[r_array_index - 1]. @@ -4440,7 +4440,7 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl test_bit(t0, r_bitmap, 2); // look-ahead check (Bit 2); result is non-zero beqz(t0, L_fallthrough); - ror_imm(r_bitmap, r_bitmap, 1); + ror(r_bitmap, r_bitmap, 1); addi(r_array_index, r_array_index, 1); j(L_loop); } @@ -4914,11 +4914,11 @@ void MacroAssembler::mul_add(Register out, Register in, Register offset, blt(len, tmp, L_tail_loop); bind(L_unroll); for (int i = 0; i < unroll; i++) { - sub(in, in, BytesPerInt); + subi(in, in, BytesPerInt); lwu(t0, Address(in, 0)); mul(t1, t0, k); add(t0, t1, out); - sub(offset, offset, BytesPerInt); + subi(offset, offset, BytesPerInt); lwu(t1, Address(offset, 0)); add(t0, t0, t1); sw(t0, Address(offset, 0)); @@ -4929,16 +4929,16 @@ void MacroAssembler::mul_add(Register out, Register in, Register offset, bind(L_tail_loop); blez(len, L_end); - sub(in, in, BytesPerInt); + subi(in, in, BytesPerInt); lwu(t0, Address(in, 0)); mul(t1, t0, k); add(t0, t1, out); - sub(offset, offset, BytesPerInt); + subi(offset, offset, BytesPerInt); lwu(t1, Address(offset, 0)); add(t0, t0, t1); sw(t0, Address(offset, 0)); srli(out, t0, 32); - subw(len, len, 1); + subiw(len, len, 1); j(L_tail_loop); bind(L_end); @@ -5015,13 +5015,13 @@ void MacroAssembler::multiply_32_x_32_loop(Register x, Register xstart, Register lwu(x_xstart, Address(t0, 0)); bind(L_first_loop); - subw(idx, idx, 1); + subiw(idx, idx, 1); shadd(t0, idx, y, t0, LogBytesPerInt); lwu(y_idx, Address(t0, 0)); mul(product, x_xstart, y_idx); add(product, product, carry); srli(carry, product, 32); - subw(kdx, kdx, 1); + subiw(kdx, kdx, 1); shadd(t0, kdx, z, t0, LogBytesPerInt); sw(product, Address(t0, 0)); bgtz(idx, L_first_loop); @@ -5049,22 +5049,22 @@ void MacroAssembler::multiply_64_x_64_loop(Register x, Register xstart, Register Label L_first_loop, L_first_loop_exit; Label L_one_x, L_one_y, L_multiply; - subw(xstart, xstart, 1); + subiw(xstart, xstart, 1); bltz(xstart, L_one_x); shadd(t0, xstart, x, t0, LogBytesPerInt); ld(x_xstart, Address(t0, 0)); - ror_imm(x_xstart, x_xstart, 32); // convert big-endian to little-endian + ror(x_xstart, x_xstart, 32); // convert big-endian to little-endian bind(L_first_loop); - subw(idx, idx, 1); + subiw(idx, idx, 1); bltz(idx, L_first_loop_exit); - subw(idx, idx, 1); + subiw(idx, idx, 1); bltz(idx, L_one_y); shadd(t0, idx, y, t0, LogBytesPerInt); ld(y_idx, Address(t0, 0)); - ror_imm(y_idx, y_idx, 32); // convert big-endian to little-endian + ror(y_idx, y_idx, 32); // convert big-endian to little-endian bind(L_multiply); mulhu(t0, x_xstart, y_idx); @@ -5072,8 +5072,8 @@ void MacroAssembler::multiply_64_x_64_loop(Register x, Register xstart, Register cad(product, product, carry, t1); adc(carry, t0, zr, t1); - subw(kdx, kdx, 2); - ror_imm(product, product, 32); // back to big-endian + subiw(kdx, kdx, 2); + ror(product, product, 32); // back to big-endian shadd(t0, kdx, z, t0, LogBytesPerInt); sd(product, Address(t0, 0)); @@ -5134,8 +5134,8 @@ void MacroAssembler::multiply_128_x_128_loop(Register y, Register z, shadd(tmp6, idx, z, t0, LogBytesPerInt); - ror_imm(yz_idx1, yz_idx1, 32); // convert big-endian to little-endian - ror_imm(yz_idx2, yz_idx2, 32); + ror(yz_idx1, yz_idx1, 32); // convert big-endian to little-endian + ror(yz_idx2, yz_idx2, 32); ld(t1, Address(tmp6, 0)); ld(t0, Address(tmp6, wordSize)); @@ -5143,8 +5143,8 @@ void MacroAssembler::multiply_128_x_128_loop(Register y, Register z, mul(tmp3, product_hi, yz_idx1); // yz_idx1 * product_hi -> tmp4:tmp3 mulhu(tmp4, product_hi, yz_idx1); - ror_imm(t0, t0, 32, tmp); // convert big-endian to little-endian - ror_imm(t1, t1, 32, tmp); + ror(t0, t0, 32, tmp); // convert big-endian to little-endian + ror(t1, t1, 32, tmp); mul(tmp, product_hi, yz_idx2); // yz_idx2 * product_hi -> carry2:tmp mulhu(carry2, product_hi, yz_idx2); @@ -5157,8 +5157,8 @@ void MacroAssembler::multiply_128_x_128_loop(Register y, Register z, cad(tmp4, tmp4, t1, carry2); adc(carry, carry, zr, carry2); - ror_imm(tmp3, tmp3, 32); // convert little-endian to big-endian - ror_imm(tmp4, tmp4, 32); + ror(tmp3, tmp3, 32); // convert little-endian to big-endian + ror(tmp4, tmp4, 32); sd(tmp4, Address(tmp6, 0)); sd(tmp3, Address(tmp6, wordSize)); @@ -5170,29 +5170,29 @@ void MacroAssembler::multiply_128_x_128_loop(Register y, Register z, beqz(idx, L_post_third_loop_done); Label L_check_1; - subw(idx, idx, 2); + subiw(idx, idx, 2); bltz(idx, L_check_1); shadd(t0, idx, y, t0, LogBytesPerInt); ld(yz_idx1, Address(t0, 0)); - ror_imm(yz_idx1, yz_idx1, 32); + ror(yz_idx1, yz_idx1, 32); mul(tmp3, product_hi, yz_idx1); // yz_idx1 * product_hi -> tmp4:tmp3 mulhu(tmp4, product_hi, yz_idx1); shadd(t0, idx, z, t0, LogBytesPerInt); ld(yz_idx2, Address(t0, 0)); - ror_imm(yz_idx2, yz_idx2, 32, tmp); + ror(yz_idx2, yz_idx2, 32, tmp); add2_with_carry(carry, tmp4, tmp3, carry, yz_idx2, tmp); - ror_imm(tmp3, tmp3, 32, tmp); + ror(tmp3, tmp3, 32, tmp); sd(tmp3, Address(t0, 0)); bind(L_check_1); andi(idx, idx, 0x1); - subw(idx, idx, 1); + subiw(idx, idx, 1); bltz(idx, L_post_third_loop_done); shadd(t0, idx, y, t0, LogBytesPerInt); lwu(tmp4, Address(t0, 0)); @@ -5252,7 +5252,7 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi Label L_multiply_64_x_64_loop, L_done; - subw(xstart, xlen, 1); + subiw(xstart, xlen, 1); bltz(xstart, L_done); const Register jdx = tmp1; @@ -5271,9 +5271,9 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi bind(L_second_loop_unaligned); mv(carry, zr); mv(jdx, ylen); - subw(xstart, xstart, 1); + subiw(xstart, xstart, 1); bltz(xstart, L_done); - sub(sp, sp, 2 * wordSize); + subi(sp, sp, 2 * wordSize); sd(z, Address(sp, 0)); sd(zr, Address(sp, wordSize)); shadd(t0, xstart, z, t0, LogBytesPerInt); @@ -5285,7 +5285,7 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi blez(jdx, L_third_loop_exit); bind(L_third_loop); - subw(jdx, jdx, 1); + subiw(jdx, jdx, 1); shadd(t0, jdx, y, t0, LogBytesPerInt); lwu(t0, Address(t0, 0)); mul(t1, t0, product); @@ -5313,13 +5313,13 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi beqz(kdx, L_second_loop_aligned); Label L_carry; - subw(kdx, kdx, 1); + subiw(kdx, kdx, 1); beqz(kdx, L_carry); shadd(t0, kdx, z, t0, LogBytesPerInt); sw(carry, Address(t0, 0)); srli(carry, carry, 32); - subw(kdx, kdx, 1); + subiw(kdx, kdx, 1); bind(L_carry); shadd(t0, kdx, z, t0, LogBytesPerInt); @@ -5344,21 +5344,21 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi mv(carry, zr); // carry = 0; mv(jdx, ylen); // j = ystart+1 - subw(xstart, xstart, 1); // i = xstart-1; + subiw(xstart, xstart, 1); // i = xstart-1; bltz(xstart, L_done); - sub(sp, sp, 4 * wordSize); + subi(sp, sp, 4 * wordSize); sd(z, Address(sp, 0)); Label L_last_x; shadd(t0, xstart, z, t0, LogBytesPerInt); addi(z, t0, 4); - subw(xstart, xstart, 1); // i = xstart-1; + subiw(xstart, xstart, 1); // i = xstart-1; bltz(xstart, L_last_x); shadd(t0, xstart, x, t0, LogBytesPerInt); ld(product_hi, Address(t0, 0)); - ror_imm(product_hi, product_hi, 32); // convert big-endian to little-endian + ror(product_hi, product_hi, 32); // convert big-endian to little-endian Label L_third_loop_prologue; bind(L_third_loop_prologue); @@ -5378,7 +5378,7 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi shadd(t0, tmp3, z, t0, LogBytesPerInt); sw(carry, Address(t0, 0)); - subw(tmp3, tmp3, 1); + subiw(tmp3, tmp3, 1); bltz(tmp3, L_done); srli(carry, carry, 32); @@ -5536,13 +5536,13 @@ void MacroAssembler::zero_words(Register base, uint64_t cnt) { Register loop_base = t1; cnt = cnt - remainder; mv(cnt_reg, cnt); - add(loop_base, base, remainder * wordSize); + addi(loop_base, base, remainder * wordSize); bind(loop); sub(cnt_reg, cnt_reg, unroll); for (int i = 0; i < unroll; i++) { sd(zr, Address(loop_base, i * wordSize)); } - add(loop_base, loop_base, unroll * wordSize); + addi(loop_base, loop_base, unroll * wordSize); bnez(cnt_reg, loop); } @@ -5593,12 +5593,12 @@ void MacroAssembler::fill_words(Register base, Register cnt, Register value) { jr(t1); bind(loop); - add(base, base, unroll * 8); + addi(base, base, unroll * wordSize); for (int i = -unroll; i < 0; i++) { sd(value, Address(base, i * 8)); } bind(entry); - sub(cnt, cnt, unroll); + subi(cnt, cnt, unroll); bgez(cnt, loop); bind(fini); @@ -5637,7 +5637,7 @@ void MacroAssembler::zero_dcache_blocks(Register base, Register cnt, Register tm bind(loop); cbo_zero(base); sub(cnt, cnt, tmp1); - add(base, base, CacheLineSize); + addi(base, base, CacheLineSize); bge(cnt, tmp1, loop); } @@ -5723,7 +5723,7 @@ void MacroAssembler::FLOATTYPE##_compare(Register result, FloatRegister Rs1, /* Rs1 > Rs2, install 1 */ \ bgtz(result, Ldone); \ feq_##FLOATSIG(result, Rs1, Rs2); \ - addi(result, result, -1); \ + subi(result, result, 1); \ /* Rs1 = Rs2, install 0 */ \ /* NaN or Rs1 < Rs2, install -1 */ \ bind(Ldone); \ @@ -5734,7 +5734,7 @@ void MacroAssembler::FLOATTYPE##_compare(Register result, FloatRegister Rs1, /* Rs1 < Rs2, install -1 */ \ bgtz(result, Ldone); \ feq_##FLOATSIG(result, Rs1, Rs2); \ - addi(result, result, -1); \ + subi(result, result, 1); \ /* Rs1 = Rs2, install 0 */ \ /* NaN or Rs1 > Rs2, install 1 */ \ bind(Ldone); \ @@ -6198,7 +6198,7 @@ void MacroAssembler::lightweight_lock(Register basic_lock, Register obj, Registe // After successful lock, push object on lock-stack. add(t, xthread, top); sd(obj, Address(t)); - addw(top, top, oopSize); + addiw(top, top, oopSize); sw(top, Address(xthread, JavaThread::lock_stack_top_offset())); } @@ -6230,7 +6230,7 @@ void MacroAssembler::lightweight_unlock(Register obj, Register tmp1, Register tm // Check if obj is top of lock-stack. lwu(top, Address(xthread, JavaThread::lock_stack_top_offset())); - subw(top, top, oopSize); + subiw(top, top, oopSize); add(t, xthread, top); ld(t, Address(t)); bne(obj, t, slow, /* is_far */ true); @@ -6270,7 +6270,7 @@ void MacroAssembler::lightweight_unlock(Register obj, Register tmp1, Register tm // Restore lock-stack and handle the unlock in runtime. DEBUG_ONLY(add(t, xthread, top);) DEBUG_ONLY(sd(obj, Address(t));) - addw(top, top, oopSize); + addiw(top, top, oopSize); sw(top, Address(xthread, JavaThread::lock_stack_top_offset())); j(slow); diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 4cfc1c5525480..b2e79edd96341 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -60,14 +60,14 @@ class MacroAssembler: public Assembler { // Note that SP must be updated to the right place before saving/restoring RA and FP // because signal based thread suspend/resume could happen asynchronously. void enter() { - addi(sp, sp, - 2 * wordSize); + subi(sp, sp, 2 * wordSize); sd(ra, Address(sp, wordSize)); sd(fp, Address(sp)); addi(fp, sp, 2 * wordSize); } void leave() { - addi(sp, fp, - 2 * wordSize); + subi(sp, fp, 2 * wordSize); ld(fp, Address(sp)); ld(ra, Address(sp, wordSize)); addi(sp, sp, 2 * wordSize); @@ -886,10 +886,20 @@ class MacroAssembler: public Assembler { public: // arith - void add (Register Rd, Register Rn, int64_t increment, Register temp = t0); - void addw(Register Rd, Register Rn, int32_t increment, Register temp = t0); - void sub (Register Rd, Register Rn, int64_t decrement, Register temp = t0); - void subw(Register Rd, Register Rn, int32_t decrement, Register temp = t0); + void add(Register Rd, Register Rn, int64_t increment, Register tmp = t0); + void sub(Register Rd, Register Rn, int64_t decrement, Register tmp = t0); + void addw(Register Rd, Register Rn, int32_t increment, Register tmp = t0); + void subw(Register Rd, Register Rn, int32_t decrement, Register tmp = t0); + + void subi(Register Rd, Register Rn, int32_t decrement) { + assert(is_simm12(-decrement), "Must be"); + addi(Rd, Rn, -decrement); + } + + void subiw(Register Rd, Register Rn, int32_t decrement) { + assert(is_simm12(-decrement), "Must be"); + addiw(Rd, Rn, -decrement); + } #define INSN(NAME) \ inline void NAME(Register Rd, Register Rs1, Register Rs2) { \ @@ -916,8 +926,8 @@ class MacroAssembler: public Assembler { void revbw(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2= t1); // reverse bytes in lower word, sign-extend void revb(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); // reverse bytes in doubleword - void ror_imm(Register dst, Register src, uint32_t shift, Register tmp = t0); - void rolw_imm(Register dst, Register src, uint32_t, Register tmp = t0); + void ror(Register dst, Register src, uint32_t shift, Register tmp = t0); + void rolw(Register dst, Register src, uint32_t shift, Register tmp = t0); void andi(Register Rd, Register Rn, int64_t imm, Register tmp = t0); void orptr(Address adr, RegisterOrConstant src, Register tmp1 = t0, Register tmp2 = t1); diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index 7cb42a6b30c3c..a9b48fd18c406 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -6482,9 +6482,9 @@ instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAdd src2) %{ ins_encode %{ // src2 is imm, so actually call the addi - __ add(as_Register($dst$$reg), - as_Register($src1$$reg), - $src2$$constant); + __ addi(as_Register($dst$$reg), + as_Register($src1$$reg), + $src2$$constant); %} ins_pipe(ialu_reg_imm); @@ -6513,9 +6513,9 @@ instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ ins_encode %{ // src2 is imm, so actually call the addi - __ add(as_Register($dst$$reg), - as_Register($src1$$reg), - $src2$$constant); + __ addi(as_Register($dst$$reg), + as_Register($src1$$reg), + $src2$$constant); %} ins_pipe(ialu_reg_imm); @@ -6546,9 +6546,9 @@ instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immISub src2) %{ ins_encode %{ // src2 is imm, so actually call the addiw - __ subw(as_Register($dst$$reg), - as_Register($src1$$reg), - $src2$$constant); + __ subiw(as_Register($dst$$reg), + as_Register($src1$$reg), + $src2$$constant); %} ins_pipe(ialu_reg_imm); @@ -6577,9 +6577,9 @@ instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLSub src2) %{ ins_encode %{ // src2 is imm, so actually call the addi - __ sub(as_Register($dst$$reg), - as_Register($src1$$reg), - $src2$$constant); + __ subi(as_Register($dst$$reg), + as_Register($src1$$reg), + $src2$$constant); %} ins_pipe(ialu_reg_imm); diff --git a/src/hotspot/cpu/riscv/riscv_b.ad b/src/hotspot/cpu/riscv/riscv_b.ad index 535c0fd534ddf..990d9eab87c7b 100644 --- a/src/hotspot/cpu/riscv/riscv_b.ad +++ b/src/hotspot/cpu/riscv/riscv_b.ad @@ -60,7 +60,7 @@ instruct rorI_reg_b(iRegINoSp dst, iRegI src, iRegI shift) %{ format %{ "rorw $dst, $src, $shift\t#@rorI_reg_b" %} ins_cost(ALU_COST); ins_encode %{ - __ rorw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); + __ rorrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); %} ins_pipe(ialu_reg_reg); %} @@ -72,7 +72,7 @@ instruct rorL_reg_b(iRegLNoSp dst, iRegL src, iRegI shift) %{ format %{ "ror $dst, $src, $shift\t#@rorL_reg_b" %} ins_cost(ALU_COST); ins_encode %{ - __ ror(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); + __ rorr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); %} ins_pipe(ialu_reg_reg); %} @@ -84,7 +84,7 @@ instruct rolI_reg_b(iRegINoSp dst, iRegI src, iRegI shift) %{ format %{ "rolw $dst, $src, $shift\t#@rolI_reg_b" %} ins_cost(ALU_COST); ins_encode %{ - __ rolw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); + __ rolrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); %} ins_pipe(ialu_reg_reg); %} @@ -96,7 +96,7 @@ instruct rolL_reg_b(iRegLNoSp dst, iRegL src, iRegI shift) %{ format %{ "rol $dst, $src, $shift\t#@rolL_reg_b" %} ins_cost(ALU_COST); ins_encode %{ - __ rol(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); + __ rolr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); %} ins_pipe(ialu_reg_reg); %} diff --git a/src/hotspot/cpu/riscv/runtime_riscv.cpp b/src/hotspot/cpu/riscv/runtime_riscv.cpp index 441bd1f241f28..33c1fb6e06bfd 100644 --- a/src/hotspot/cpu/riscv/runtime_riscv.cpp +++ b/src/hotspot/cpu/riscv/runtime_riscv.cpp @@ -73,7 +73,7 @@ void OptoRuntime::generate_uncommon_trap_blob() { // Push self-frame. We get here with a return address in RA // and sp should be 16 byte aligned // push fp and retaddr by hand - __ addi(sp, sp, -2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ sd(ra, Address(sp, wordSize)); __ sd(fp, Address(sp, 0)); // we don't expect an arg reg save area @@ -140,7 +140,7 @@ void OptoRuntime::generate_uncommon_trap_blob() { __ lwu(x12, Address(x14, Deoptimization::UnrollBlock:: size_of_deoptimized_frame_offset())); - __ sub(x12, x12, 2 * wordSize); + __ subi(x12, x12, 2 * wordSize); __ add(sp, sp, x12); __ ld(fp, Address(sp, 0)); __ ld(ra, Address(sp, wordSize)); @@ -188,7 +188,7 @@ void OptoRuntime::generate_uncommon_trap_blob() { Label loop; __ bind(loop); __ ld(x11, Address(x15, 0)); // Load frame size - __ sub(x11, x11, 2 * wordSize); // We'll push pc and fp by hand + __ subi(x11, x11, 2 * wordSize); // We'll push pc and fp by hand __ ld(ra, Address(x12, 0)); // Save return address __ enter(); // and old fp & set new fp __ sub(sp, sp, x11); // Prolog @@ -196,9 +196,9 @@ void OptoRuntime::generate_uncommon_trap_blob() { // This value is corrected by layout_activation_impl __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); __ mv(sender_sp, sp); // Pass sender_sp to next frame - __ add(x15, x15, wordSize); // Bump array pointer (sizes) - __ add(x12, x12, wordSize); // Bump array pointer (pcs) - __ subw(x13, x13, 1); // Decrement counter + __ addi(x15, x15, wordSize); // Bump array pointer (sizes) + __ addi(x12, x12, wordSize); // Bump array pointer (pcs) + __ subiw(x13, x13, 1); // Decrement counter __ bgtz(x13, loop); __ ld(ra, Address(x12, 0)); // save final return address // Re-push self-frame @@ -292,7 +292,7 @@ void OptoRuntime::generate_exception_blob() { // push fp and retaddr by hand // Exception pc is 'return address' for stack walker - __ addi(sp, sp, -2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ sd(ra, Address(sp, wordSize)); __ sd(fp, Address(sp)); // there are no callee save registers and we don't expect an @@ -346,7 +346,7 @@ void OptoRuntime::generate_exception_blob() { // and we dont' expect an arg reg save area __ ld(fp, Address(sp)); __ ld(x13, Address(sp, wordSize)); - __ addi(sp, sp , 2 * wordSize); + __ addi(sp, sp, 2 * wordSize); // x10: exception handler diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 12e38d97b1342..f919bd9c53075 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -802,7 +802,7 @@ static void save_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegP if (args[i].first()->is_Register()) { x = x + args[i].first()->as_Register(); } else if (args[i].first()->is_FloatRegister()) { - __ addi(sp, sp, -2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ fsd(args[i].first()->as_FloatRegister(), Address(sp, 0)); } } @@ -824,7 +824,7 @@ static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMR ; } else if (args[i].first()->is_FloatRegister()) { __ fld(args[i].first()->as_FloatRegister(), Address(sp, 0)); - __ add(sp, sp, 2 * wordSize); + __ addi(sp, sp, 2 * wordSize); } } } @@ -2336,7 +2336,7 @@ void SharedRuntime::generate_deopt_blob() { // Pop deoptimized frame __ lwu(x12, Address(x15, Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset())); - __ sub(x12, x12, 2 * wordSize); + __ subi(x12, x12, 2 * wordSize); __ add(sp, sp, x12); __ ld(fp, Address(sp, 0)); __ ld(ra, Address(sp, wordSize)); @@ -2379,7 +2379,7 @@ void SharedRuntime::generate_deopt_blob() { __ bind(loop); __ ld(x9, Address(x14, 0)); // Load frame size __ addi(x14, x14, wordSize); - __ sub(x9, x9, 2 * wordSize); // We'll push pc and fp by hand + __ subi(x9, x9, 2 * wordSize); // We'll push pc and fp by hand __ ld(ra, Address(x12, 0)); // Load pc __ addi(x12, x12, wordSize); __ enter(); // Save old & set new fp @@ -2388,7 +2388,7 @@ void SharedRuntime::generate_deopt_blob() { __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); __ sd(sender_sp, Address(fp, frame::interpreter_frame_sender_sp_offset * wordSize)); // Make it walkable __ mv(sender_sp, sp); // Pass sender_sp to next frame - __ addi(x13, x13, -1); // Decrement counter + __ subi(x13, x13, 1); // Decrement counter __ bnez(x13, loop); // Re-push self-frame @@ -2566,7 +2566,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal #endif // Adjust return pc forward to step over the safepoint poll instruction - __ add(x18, x18, NativeInstruction::instruction_size); + __ addi(x18, x18, NativeInstruction::instruction_size); __ sd(x18, Address(fp, frame::return_addr_offset * wordSize)); } @@ -2736,7 +2736,7 @@ RuntimeStub* SharedRuntime::generate_throw_exception(SharedStubId id, address ru assert(is_even(framesize / 2), "sp not 16-byte aligned"); // ra and fp are already in place - __ addi(sp, fp, 0 - ((unsigned)framesize << LogBytesPerInt)); // prolog + __ subi(sp, fp, (unsigned)framesize << LogBytesPerInt); // prolog int frame_complete = __ pc() - start; diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 0b619923b06b1..439162f01f105 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -341,7 +341,7 @@ class StubGenerator: public StubCodeGenerator { address loop = __ pc(); __ ld(t0, Address(c_rarg5, 0)); __ addi(c_rarg5, c_rarg5, wordSize); - __ addi(c_rarg6, c_rarg6, -1); + __ subi(c_rarg6, c_rarg6, 1); __ push_reg(t0); __ bgtz(c_rarg6, loop); @@ -623,7 +623,7 @@ class StubGenerator: public StubCodeGenerator { __ la(c_rarg2, ExternalAddress((address) StubRoutines::verify_oop_count_addr())); __ ld(c_rarg3, Address(c_rarg2)); - __ add(c_rarg3, c_rarg3, 1); + __ addi(c_rarg3, c_rarg3, 1); __ sd(c_rarg3, Address(c_rarg2)); // object is in x10 @@ -698,8 +698,8 @@ class StubGenerator: public StubCodeGenerator { for (int i = 0; i < MacroAssembler::zero_words_block_size; i++) { __ sd(zr, Address(base, i * wordSize)); } - __ add(base, base, MacroAssembler::zero_words_block_size * wordSize); - __ sub(cnt, cnt, MacroAssembler::zero_words_block_size); + __ addi(base, base, MacroAssembler::zero_words_block_size * wordSize); + __ subi(cnt, cnt, MacroAssembler::zero_words_block_size); __ bge(cnt, tmp1, loop); __ bind(done); } @@ -779,7 +779,7 @@ class StubGenerator: public StubCodeGenerator { __ ld(tmp_reg7, Address(s, 8 * unit)); __ addi(s, s, 8 * unit); - __ sub(count, count, 16); + __ subi(count, count, 16); __ bltz(count, drain); __ bind(again); @@ -805,7 +805,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(s, s, 8 * unit); __ addi(d, d, 8 * unit); - __ sub(count, count, 8); + __ subi(count, count, 8); __ bgez(count, again); // Drain @@ -959,9 +959,9 @@ class StubGenerator: public StubCodeGenerator { } if (is_aligned) { - __ addi(t0, cnt, -32); + __ subi(t0, cnt, 32); __ bgez(t0, copy32_loop); - __ addi(t0, cnt, -8); + __ subi(t0, cnt, 8); __ bgez(t0, copy8_loop, is_far); __ j(copy_small); } else { @@ -985,7 +985,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(src, src, step); __ addi(dst, dst, step); } - __ addi(cnt, cnt, -granularity); + __ subi(cnt, cnt, granularity); __ beqz(cnt, done, is_far); __ j(same_aligned); @@ -996,8 +996,8 @@ class StubGenerator: public StubCodeGenerator { __ bind(copy32_loop); if (is_backwards) { - __ addi(src, src, -wordSize * 4); - __ addi(dst, dst, -wordSize * 4); + __ subi(src, src, wordSize * 4); + __ subi(dst, dst, wordSize * 4); } // we first load 32 bytes, then write it, so the direction here doesn't matter bs_asm->copy_load_at(_masm, decorators, type, 8, tmp3, Address(src), gct1); @@ -1014,19 +1014,19 @@ class StubGenerator: public StubCodeGenerator { __ addi(src, src, wordSize * 4); __ addi(dst, dst, wordSize * 4); } - __ addi(t0, cnt, -(32 + wordSize * 4)); - __ addi(cnt, cnt, -wordSize * 4); + __ subi(t0, cnt, 32 + wordSize * 4); + __ subi(cnt, cnt, wordSize * 4); __ bgez(t0, copy32_loop); // cnt >= 32, do next loop __ beqz(cnt, done); // if that's all - done - __ addi(t0, cnt, -8); // if not - copy the reminder + __ subi(t0, cnt, 8); // if not - copy the reminder __ bltz(t0, copy_small); // cnt < 8, go to copy_small, else fall through to copy8_loop __ bind(copy8_loop); if (is_backwards) { - __ addi(src, src, -wordSize); - __ addi(dst, dst, -wordSize); + __ subi(src, src, wordSize); + __ subi(dst, dst, wordSize); } bs_asm->copy_load_at(_masm, decorators, type, 8, tmp3, Address(src), gct1); bs_asm->copy_store_at(_masm, decorators, type, 8, Address(dst), tmp3, gct1, gct2, gct3); @@ -1035,8 +1035,8 @@ class StubGenerator: public StubCodeGenerator { __ addi(src, src, wordSize); __ addi(dst, dst, wordSize); } - __ addi(t0, cnt, -(8 + wordSize)); - __ addi(cnt, cnt, -wordSize); + __ subi(t0, cnt, 8 + wordSize); + __ subi(cnt, cnt, wordSize); __ bgez(t0, copy8_loop); // cnt >= 8, do next loop __ beqz(cnt, done); // if that's all - done @@ -1054,7 +1054,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(src, src, step); __ addi(dst, dst, step); } - __ addi(cnt, cnt, -granularity); + __ subi(cnt, cnt, granularity); __ bgtz(cnt, copy_small); __ bind(done); @@ -1578,8 +1578,8 @@ class StubGenerator: public StubCodeGenerator { bs->copy_store_at(_masm, decorators, T_OBJECT, element_size, Address(to, 0), copied_oop, gct1, gct2, gct3); - __ add(to, to, UseCompressedOops ? 4 : 8); - __ sub(count, count, 1); + __ addi(to, to, UseCompressedOops ? 4 : 8); + __ subi(count, count, 1); __ beqz(count, L_do_card_marks); // ======== loop entry is here ======== @@ -1587,7 +1587,7 @@ class StubGenerator: public StubCodeGenerator { bs->copy_load_at(_masm, decorators, T_OBJECT, element_size, copied_oop, Address(from, 0), gct1); - __ add(from, from, UseCompressedOops ? 4 : 8); + __ addi(from, from, UseCompressedOops ? 4 : 8); __ beqz(copied_oop, L_store_element); __ load_klass(r9_klass, copied_oop);// query the object klass @@ -1929,9 +1929,9 @@ class StubGenerator: public StubCodeGenerator { t1, L_failed); __ shadd(from, src_pos, src, t0, LogBytesPerHeapOop); - __ add(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addi(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); __ shadd(to, dst_pos, dst, t0, LogBytesPerHeapOop); - __ add(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addi(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); __ sext(count, scratch_length, 32); // length __ BIND(L_plain_copy); __ j(RuntimeAddress(oop_copy_entry)); @@ -1952,9 +1952,9 @@ class StubGenerator: public StubCodeGenerator { // Marshal the base address arguments now, freeing registers. __ shadd(from, src_pos, src, t0, LogBytesPerHeapOop); - __ add(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addi(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); __ shadd(to, dst_pos, dst, t0, LogBytesPerHeapOop); - __ add(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addi(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); __ sext(count, length, 32); // length (reloaded) const Register sco_temp = c_rarg3; // this register is free now assert_different_registers(from, to, count, sco_temp, @@ -2068,7 +2068,7 @@ class StubGenerator: public StubCodeGenerator { __ beqz(t0, L_skip_align1); __ sb(value, Address(to, 0)); __ addi(to, to, 1); - __ addiw(count, count, -1); + __ subiw(count, count, 1); __ bind(L_skip_align1); // Fallthrough case T_SHORT: @@ -2077,7 +2077,7 @@ class StubGenerator: public StubCodeGenerator { __ beqz(t0, L_skip_align2); __ sh(value, Address(to, 0)); __ addi(to, to, 2); - __ addiw(count, count, -(2 >> shift)); + __ subiw(count, count, 2 >> shift); __ bind(L_skip_align2); // Fallthrough case T_INT: @@ -2086,7 +2086,7 @@ class StubGenerator: public StubCodeGenerator { __ beqz(t0, L_skip_align4); __ sw(value, Address(to, 0)); __ addi(to, to, 4); - __ addiw(count, count, -(4 >> shift)); + __ subiw(count, count, 4 >> shift); __ bind(L_skip_align4); break; default: ShouldNotReachHere(); @@ -2500,7 +2500,7 @@ class StubGenerator: public StubCodeGenerator { __ mv(isLU ? tmp1 : tmp2, tmp3); __ addi(str1, str1, isLU ? wordSize / 2 : wordSize); __ addi(str2, str2, isLU ? wordSize : wordSize / 2); - __ sub(cnt2, cnt2, wordSize / 2); // Already loaded 4 symbols + __ subi(cnt2, cnt2, wordSize / 2); // Already loaded 4 symbols __ xorr(tmp3, tmp1, tmp2); __ bnez(tmp3, CALCULATE_DIFFERENCE); @@ -2523,10 +2523,10 @@ class StubGenerator: public StubCodeGenerator { __ addi(cnt2, cnt2, -wordSize / 2); // we are now 8-bytes aligned on strL - __ sub(cnt2, cnt2, wordSize * 2); + __ subi(cnt2, cnt2, wordSize * 2); __ bltz(cnt2, TAIL); __ bind(SMALL_LOOP); // smaller loop - __ sub(cnt2, cnt2, wordSize * 2); + __ subi(cnt2, cnt2, wordSize * 2); compare_string_8_x_LU(tmpL, tmpU, strL, strU, CALCULATE_DIFFERENCE); compare_string_8_x_LU(tmpL, tmpU, strL, strU, CALCULATE_DIFFERENCE); __ bgez(cnt2, SMALL_LOOP); @@ -2540,11 +2540,11 @@ class StubGenerator: public StubCodeGenerator { __ bltz(t0, LOAD_LAST); // remaining characters are greater than or equals to 8, we can do one compare_string_8_x_LU compare_string_8_x_LU(tmpL, tmpU, strL, strU, CALCULATE_DIFFERENCE); - __ addi(cnt2, cnt2, -wordSize); + __ subi(cnt2, cnt2, wordSize); __ beqz(cnt2, DONE); // no character left __ bind(LOAD_LAST); // cnt2 = 1..7 characters left - __ addi(cnt2, cnt2, -wordSize); // cnt2 is now an offset in strL which points to last 8 bytes + __ subi(cnt2, cnt2, wordSize); // cnt2 is now an offset in strL which points to last 8 bytes __ slli(t0, cnt2, 1); // t0 is now an offset in strU which points to last 16 bytes __ add(strL, strL, cnt2); // Address of last 8 bytes in Latin1 string __ add(strU, strU, t0); // Address of last 16 bytes in UTF-16 string @@ -2610,9 +2610,9 @@ class StubGenerator: public StubCodeGenerator { __ set_last_Java_frame(sp, fp, ra); __ enter(); - __ add(t1, sp, wordSize); + __ addi(t1, sp, wordSize); - __ sub(sp, sp, 4 * wordSize); + __ subi(sp, sp, 4 * wordSize); __ push_call_clobbered_registers(); @@ -2665,22 +2665,22 @@ class StubGenerator: public StubCodeGenerator { // cnt1/cnt2 contains amount of characters to compare. cnt1 can be re-used // update cnt2 counter with already loaded 8 bytes - __ sub(cnt2, cnt2, wordSize / (isLL ? 1 : 2)); + __ subi(cnt2, cnt2, wordSize / (isLL ? 1 : 2)); // update pointers, because of previous read - __ add(str1, str1, wordSize); - __ add(str2, str2, wordSize); + __ addi(str1, str1, wordSize); + __ addi(str2, str2, wordSize); // less than 16 bytes left? - __ sub(cnt2, cnt2, isLL ? 16 : 8); + __ subi(cnt2, cnt2, isLL ? 16 : 8); __ push_reg(spilled_regs, sp); __ bltz(cnt2, TAIL); __ bind(SMALL_LOOP); compare_string_16_bytes_same(DIFF, DIFF2); - __ sub(cnt2, cnt2, isLL ? 16 : 8); + __ subi(cnt2, cnt2, isLL ? 16 : 8); __ bgez(cnt2, SMALL_LOOP); __ bind(TAIL); __ addi(cnt2, cnt2, isLL ? 16 : 8); __ beqz(cnt2, LAST_CHECK_AND_LENGTH_DIFF); - __ sub(cnt2, cnt2, isLL ? 8 : 4); + __ subi(cnt2, cnt2, isLL ? 8 : 4); __ blez(cnt2, CHECK_LAST); __ xorr(tmp4, tmp1, tmp2); __ bnez(tmp4, DIFF); @@ -2688,7 +2688,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(str1, str1, 8); __ ld(tmp2, Address(str2)); __ addi(str2, str2, 8); - __ sub(cnt2, cnt2, isLL ? 8 : 4); + __ subi(cnt2, cnt2, isLL ? 8 : 4); __ bind(CHECK_LAST); if (!isLL) { __ add(cnt2, cnt2, cnt2); // now in bytes @@ -2801,7 +2801,7 @@ class StubGenerator: public StubCodeGenerator { if (needle_isL != haystack_isL) { __ mv(tmp, ch1); } - __ sub(haystack_len, haystack_len, wordSize / haystack_chr_size - 1); + __ subi(haystack_len, haystack_len, wordSize / haystack_chr_size - 1); __ blez(haystack_len, L_SMALL); if (needle_isL != haystack_isL) { @@ -2817,9 +2817,9 @@ class StubGenerator: public StubCodeGenerator { // search first char of needle, if success, goto L_HAS_ZERO; __ bnez(match_mask, L_HAS_ZERO); - __ sub(haystack_len, haystack_len, wordSize / haystack_chr_size); - __ add(result, result, wordSize / haystack_chr_size); - __ add(haystack, haystack, wordSize); + __ subi(haystack_len, haystack_len, wordSize / haystack_chr_size); + __ addi(result, result, wordSize / haystack_chr_size); + __ addi(haystack, haystack, wordSize); __ bltz(haystack_len, L_POST_LOOP); __ bind(L_LOOP); @@ -2828,9 +2828,9 @@ class StubGenerator: public StubCodeGenerator { __ bnez(match_mask, L_HAS_ZERO); __ bind(L_LOOP_PROCEED); - __ sub(haystack_len, haystack_len, wordSize / haystack_chr_size); - __ add(haystack, haystack, wordSize); - __ add(result, result, wordSize / haystack_chr_size); + __ subi(haystack_len, haystack_len, wordSize / haystack_chr_size); + __ addi(haystack, haystack, wordSize); + __ addi(result, result, wordSize / haystack_chr_size); __ bgez(haystack_len, L_LOOP); __ bind(L_POST_LOOP); @@ -2879,7 +2879,7 @@ class StubGenerator: public StubCodeGenerator { __ shadd(ch2, trailing_zeros, haystack, ch2, haystack_chr_shift); needle_isL ? __ lbu(first, Address(first)) : __ lhu(first, Address(first)); haystack_isL ? __ lbu(ch2, Address(ch2)) : __ lhu(ch2, Address(ch2)); - __ add(trailing_zeros, trailing_zeros, 1); + __ addi(trailing_zeros, trailing_zeros, 1); __ bge(trailing_zeros, needle_len, L_SMALL_CMP_LOOP_LAST_CMP); __ beq(first, ch2, L_SMALL_CMP_LOOP); @@ -2888,8 +2888,8 @@ class StubGenerator: public StubCodeGenerator { // count bits of trailing zero chars __ ctzc_bits(trailing_zeros, match_mask, haystack_isL, tmp, ch2); __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); - __ add(result, result, 1); - __ add(haystack, haystack, haystack_chr_size); + __ addi(result, result, 1); + __ addi(haystack, haystack, haystack_chr_size); __ j(L_SMALL_HAS_ZERO_LOOP); __ align(OptoLoopAlignment); @@ -2910,7 +2910,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); __ slli(needle_len, needle_len, BitsPerByte * wordSize / 2); __ orr(haystack_len, haystack_len, needle_len); // restore needle_len(32bits) - __ sub(result, result, 1); // array index from 0, so result -= 1 + __ subi(result, result, 1); // array index from 0, so result -= 1 __ bind(L_HAS_ZERO_LOOP); __ mv(needle_len, wordSize / haystack_chr_size); @@ -2918,7 +2918,7 @@ class StubGenerator: public StubCodeGenerator { __ bge(needle_len, ch2, L_CMP_LOOP_LAST_CMP2); // load next 8 bytes from haystack, and increase result index __ compute_index(haystack, trailing_zeros, match_mask, result, ch2, tmp, haystack_isL); - __ add(result, result, 1); + __ addi(result, result, 1); __ mv(trailing_zeros, wordSize / haystack_chr_size); __ bne(ch1, ch2, L_CMP_LOOP_NOMATCH); @@ -2928,7 +2928,7 @@ class StubGenerator: public StubCodeGenerator { needle_isL ? __ lbu(needle_len, Address(needle_len)) : __ lhu(needle_len, Address(needle_len)); __ shadd(ch2, trailing_zeros, haystack, ch2, haystack_chr_shift); haystack_isL ? __ lbu(ch2, Address(ch2)) : __ lhu(ch2, Address(ch2)); - __ add(trailing_zeros, trailing_zeros, 1); // next char index + __ addi(trailing_zeros, trailing_zeros, 1); // next char index __ srli(tmp, haystack_len, BitsPerByte * wordSize / 2); __ bge(trailing_zeros, tmp, L_CMP_LOOP_LAST_CMP); __ beq(needle_len, ch2, L_CMP_LOOP); @@ -2938,7 +2938,7 @@ class StubGenerator: public StubCodeGenerator { // count bits of trailing zero chars __ ctzc_bits(trailing_zeros, match_mask, haystack_isL, needle_len, ch2); __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); - __ add(haystack, haystack, haystack_chr_size); + __ addi(haystack, haystack, haystack_chr_size); __ j(L_HAS_ZERO_LOOP); __ align(OptoLoopAlignment); @@ -2949,7 +2949,7 @@ class StubGenerator: public StubCodeGenerator { __ align(OptoLoopAlignment); __ bind(L_CMP_LOOP_LAST_CMP2); __ compute_index(haystack, trailing_zeros, match_mask, result, ch2, tmp, haystack_isL); - __ add(result, result, 1); + __ addi(result, result, 1); __ bne(ch1, ch2, L_CMP_LOOP_NOMATCH); __ j(DONE); @@ -3310,7 +3310,7 @@ class StubGenerator: public StubCodeGenerator { (this->*block)(); bind(odd); (this->*block)(); - addi(count, count, -2); + subi(count, count, 2); bgtz(count, loop); bind(end); } @@ -3326,7 +3326,7 @@ class StubGenerator: public StubCodeGenerator { (this->*block)(d, s, tmp); bind(odd); (this->*block)(d, s, tmp); - addi(count, count, -2); + subi(count, count, 2); bgtz(count, loop); bind(end); } @@ -3378,7 +3378,7 @@ class StubGenerator: public StubCodeGenerator { mul(Rlo_ab, Ra, Rb); addi(Pa, Pa, wordSize); ld(Ra, Address(Pa)); - addi(Pb, Pb, -wordSize); + subi(Pb, Pb, wordSize); ld(Rb, Address(Pb)); acc(Rhi_mn, Rlo_mn, tmp0, tmp1, tmp2); // The pending m*n from the // previous iteration. @@ -3389,7 +3389,7 @@ class StubGenerator: public StubCodeGenerator { mul(Rlo_mn, Rm, Rn); addi(Pm, Pm, wordSize); ld(Rm, Address(Pm)); - addi(Pn, Pn, -wordSize); + subi(Pn, Pn, wordSize); ld(Rn, Address(Pn)); acc(Rhi_ab, Rlo_ab, tmp0, tmp1, tmp2); } @@ -3433,7 +3433,7 @@ class StubGenerator: public StubCodeGenerator { // // mul(Rlo_mn, Rm, Rn); // cad(zr, tmp0, Rlo_mn); - addi(t0, tmp0, -1); + subi(t0, tmp0, 1); sltu(t0, t0, tmp0); // Set carry iff tmp0 is nonzero cadc(tmp0, tmp1, Rhi_mn, t0); adc(tmp1, tmp2, zr, t0); @@ -3462,13 +3462,13 @@ class StubGenerator: public StubCodeGenerator { // Rb = *--Pb; // Rm = *++Pm; // Rn = *--Pn; - add(Pa, Pa, wordSize); + addi(Pa, Pa, wordSize); ld(Ra, Address(Pa)); - add(Pb, Pb, -wordSize); + subi(Pb, Pb, wordSize); ld(Rb, Address(Pb)); - add(Pm, Pm, wordSize); + addi(Pm, Pm, wordSize); ld(Rm, Address(Pm)); - add(Pn, Pn, -wordSize); + subi(Pn, Pn, wordSize); ld(Rn, Address(Pn)); mv(Rhi_mn, zr); @@ -3523,15 +3523,15 @@ class StubGenerator: public StubCodeGenerator { slli(Rn, i, LogBytesPerWord); // Rn as temp register add(Rn, Pm_base, Rn); sd(Rm, Address(Rn)); - add(i, i, 1); + addi(i, i, 1); slli(Rn, i, LogBytesPerWord); add(Rm, Pm_base, Rn); ld(Rm, Address(Rm)); add(Rn, Pn_base, Rn); ld(Rn, Address(Rn)); - sub(cnt, cnt, 1); + subi(cnt, cnt, 1); } bnez(cnt, loop); - addi(tmp0, tmp0, -1); + subi(tmp0, tmp0, 1); add(tmp0, tmp0, t0); } bnez(tmp0, again); } bind(post); @@ -3554,9 +3554,9 @@ class StubGenerator: public StubCodeGenerator { } // [63...0] -> [31...0][63...32] void reverse1(Register d, Register s, Register tmp) { - addi(s, s, -wordSize); + subi(s, s, wordSize); ld(tmp, Address(s)); - ror_imm(tmp, tmp, 32, t0); + ror(tmp, tmp, 32, t0); sd(tmp, Address(d)); addi(d, d, wordSize); } @@ -3591,7 +3591,7 @@ class StubGenerator: public StubCodeGenerator { mul(Rlo_mn, Rm, Rn); addi(Pm, Pm, wordSize); ld(Rm, Address(Pm)); - addi(Pn, Pn, -wordSize); + subi(Pn, Pn, wordSize); ld(Rn, Address(Pn)); } @@ -3626,7 +3626,7 @@ class StubGenerator: public StubCodeGenerator { // // mul(Rlo_mn, Rm, Rn); // cad(zr, tmp, Rlo_mn); - addi(t0, tmp0, -1); + subi(t0, tmp0, 1); sltu(t0, t0, tmp0); // Set carry iff tmp0 is nonzero cadc(tmp0, tmp1, Rhi_mn, t0); adc(tmp1, tmp2, zr, t0); @@ -3732,7 +3732,7 @@ class StubGenerator: public StubCodeGenerator { } block_comment(" } // j"); post1(); - addw(Ri, Ri, 1); + addiw(Ri, Ri, 1); blt(Ri, Rlen, loop); bind(end); block_comment("} // i"); @@ -3750,12 +3750,12 @@ class StubGenerator: public StubCodeGenerator { block_comment(" for (j = len*2-i-1; j; j--) {"); { slliw(Rj, Rlen, 1); subw(Rj, Rj, Ri); - subw(Rj, Rj, 1); + subiw(Rj, Rj, 1); unroll_2(Rj, &MontgomeryMultiplyGenerator::step); } block_comment(" } // j"); post2(Ri, Rlen); - addw(Ri, Ri, 1); + addiw(Ri, Ri, 1); slli(t0, Rlen, 1); blt(Ri, t0, loop); bind(end); @@ -3866,7 +3866,7 @@ class StubGenerator: public StubCodeGenerator { block_comment(" for (j = (2*len-i-1)/2; j; j--) {"); { slli(Rj, Rlen, 1); sub(Rj, Rj, Ri); - sub(Rj, Rj, 1); + subi(Rj, Rj, 1); srliw(Rj, Rj, 1); unroll_2(Rj, &MontgomeryMultiplyGenerator::step_squaring); } block_comment(" } // j"); @@ -3928,7 +3928,7 @@ class StubGenerator: public StubCodeGenerator { if (return_barrier) { // preserve possible return value from a method returning to the return barrier - __ sub(sp, sp, 2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ fsd(f10, Address(sp, 0 * wordSize)); __ sd(x10, Address(sp, 1 * wordSize)); } @@ -3941,7 +3941,7 @@ class StubGenerator: public StubCodeGenerator { // restore return value (no safepoint in the call to thaw, so even an oop return value should be OK) __ ld(x10, Address(sp, 1 * wordSize)); __ fld(f10, Address(sp, 0 * wordSize)); - __ add(sp, sp, 2 * wordSize); + __ addi(sp, sp, 2 * wordSize); } #ifndef PRODUCT @@ -3966,7 +3966,7 @@ class StubGenerator: public StubCodeGenerator { if (return_barrier) { // save original return value -- again - __ sub(sp, sp, 2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ fsd(f10, Address(sp, 0 * wordSize)); __ sd(x10, Address(sp, 1 * wordSize)); } @@ -3981,14 +3981,14 @@ class StubGenerator: public StubCodeGenerator { // restore return value (no safepoint in the call to thaw, so even an oop return value should be OK) __ ld(x10, Address(sp, 1 * wordSize)); __ fld(f10, Address(sp, 0 * wordSize)); - __ add(sp, sp, 2 * wordSize); + __ addi(sp, sp, 2 * wordSize); } else { __ mv(x10, zr); // return 0 (success) from doYield } // we're now on the yield frame (which is in an address above us b/c sp has been pushed down) __ mv(fp, t1); - __ sub(sp, t1, 2 * wordSize); // now pointing to fp spill + __ subi(sp, t1, 2 * wordSize); // now pointing to fp spill if (return_barrier_exception) { __ ld(c_rarg1, Address(fp, -1 * wordSize)); // return address @@ -4445,7 +4445,7 @@ class StubGenerator: public StubCodeGenerator { if (multi_block) { int total_adds = vset_sew == Assembler::e32 ? 240 : 608; __ addi(consts, consts, -total_adds); - __ add(ofs, ofs, vset_sew == Assembler::e32 ? 64 : 128); + __ addi(ofs, ofs, vset_sew == Assembler::e32 ? 64 : 128); __ ble(ofs, limit, multi_block_loop); __ mv(c_rarg0, ofs); // return ofs } @@ -4523,7 +4523,7 @@ class StubGenerator: public StubCodeGenerator { __ addw(a, a, value); // a = Integer.rotateLeft(a, s) + b; - __ rolw_imm(a, a, s); + __ rolw(a, a, s); __ addw(a, a, b); } @@ -4939,7 +4939,7 @@ class StubGenerator: public StubCodeGenerator { chacha20_quarter_round(work_vrs[2], work_vrs[7], work_vrs[8], work_vrs[13], tmp_vr); chacha20_quarter_round(work_vrs[3], work_vrs[4], work_vrs[9], work_vrs[14], tmp_vr); - __ sub(loop, loop, 1); + __ subi(loop, loop, 1); __ bnez(loop, L_Rounds); } @@ -5028,7 +5028,7 @@ class StubGenerator: public StubCodeGenerator { __ xorr(cur_w, cur_w, t1); __ xorr(cur_w, cur_w, t0); - __ rolw_imm(cur_w, cur_w, 1, t0); + __ rolw(cur_w, cur_w, 1, t0); // copy the cur_w value to ws[8]. // now, valid w't values are at: @@ -5048,7 +5048,7 @@ class StubGenerator: public StubCodeGenerator { __ xorr(cur_w, ws[(idx-16)/2], ws[(idx-14)/2]); __ xorr(cur_w, cur_w, t0); - __ rolw_imm(cur_w, cur_w, 1, t0); + __ rolw(cur_w, cur_w, 1, t0); // copy the cur_w value to ws[8] __ zext(cur_w, cur_w, 32); @@ -5113,7 +5113,7 @@ class StubGenerator: public StubCodeGenerator { Register tmp3 = e; __ add(tmp2, cur_k, tmp2); __ add(tmp3, tmp3, tmp2); - __ rolw_imm(tmp2, a, 5, t0); + __ rolw(tmp2, a, 5, t0); sha1_f(tmp, b, c, d, round); @@ -5128,7 +5128,7 @@ class StubGenerator: public StubCodeGenerator { __ mv(e, d); __ mv(d, c); - __ rolw_imm(c, b, 30); + __ rolw(c, b, 30); __ mv(b, a); __ mv(a, tmp2); } @@ -5519,7 +5519,7 @@ class StubGenerator: public StubCodeGenerator { __ sb(byte2, Address(dst, 2)); __ sb(combined24Bits, Address(dst, 3)); - __ sub(length, length, 3); + __ subi(length, length, 3); __ addi(dst, dst, 4); // loop back __ bnez(length, ScalarLoop); @@ -5796,7 +5796,7 @@ class StubGenerator: public StubCodeGenerator { __ sb(byte1, Address(dst, 1)); __ sb(combined32Bits, Address(dst, 2)); - __ sub(length, length, 4); + __ subi(length, length, 4); __ addi(dst, dst, 3); // loop back __ bnez(length, ScalarLoop); @@ -5979,23 +5979,23 @@ class StubGenerator: public StubCodeGenerator { __ beqz(len, L_combine); // Jumping to L_by1_loop - __ sub(len, len, step_1); + __ subi(len, len, step_1); __ j(L_by1_loop); __ bind(L_nmax); __ sub(len, len, nmax); - __ sub(count, nmax, 16); + __ subi(count, nmax, 16); __ bltz(len, L_by16); // Align L_nmax loop by 64 __ bind(L_nmax_loop_entry); - __ sub(count, count, 32); + __ subi(count, count, 32); __ bind(L_nmax_loop); adler32_process_bytes(buff, s1, s2, vtable_64, vzero, vbytes, vs1acc, vs2acc, temp0, temp1, temp2, temp3, vtemp1, vtemp2, step_64, Assembler::m4); - __ sub(count, count, step_64); + __ subi(count, count, step_64); __ bgtz(count, L_nmax_loop); // There are three iterations left to do @@ -6012,7 +6012,7 @@ class StubGenerator: public StubCodeGenerator { __ remuw(s2, s2, base); __ sub(len, len, nmax); - __ sub(count, nmax, 16); + __ subi(count, nmax, 16); __ bgez(len, L_nmax_loop_entry); __ bind(L_by16); @@ -6026,7 +6026,7 @@ class StubGenerator: public StubCodeGenerator { adler32_process_bytes(buff, s1, s2, vtable_64, vzero, vbytes, vs1acc, vs2acc, temp0, temp1, temp2, temp3, vtemp1, vtemp2, step_64, Assembler::m4); - __ sub(len, len, step_64); + __ subi(len, len, step_64); // By now the temp3 should still be 64 __ bge(len, temp3, L_by16_loop_unroll); @@ -6034,11 +6034,11 @@ class StubGenerator: public StubCodeGenerator { adler32_process_bytes(buff, s1, s2, vtable_16, vzero, vbytes, vs1acc, vs2acc, temp0, temp1, temp2, temp3, vtemp1, vtemp2, step_16, Assembler::m1); - __ sub(len, len, step_16); + __ subi(len, len, step_16); __ bgez(len, L_by16_loop); __ bind(L_by1); - __ add(len, len, 15); + __ addi(len, len, 15); __ bltz(len, L_do_mod); __ bind(L_by1_loop); @@ -6046,7 +6046,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(buff, buff, step_1); __ add(s1, temp0, s1); __ add(s2, s2, s1); - __ sub(len, len, step_1); + __ subi(len, len, step_1); __ bgez(len, L_by1_loop); __ bind(L_do_mod); @@ -6228,7 +6228,7 @@ static const int64_t right_3_bits = right_n_bits(3); // U_2:U_1:U_0: += (U_2 >> 2) * 5 poly1305_reduce(U_2, U_1, U_0, t1, t2); - __ sub(length, length, BLOCK_LENGTH); + __ subi(length, length, BLOCK_LENGTH); __ addi(input_start, input_start, BLOCK_LENGTH); __ mv(t1, BLOCK_LENGTH); __ bge(length, t1, LOOP); diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index a2187b35bd5b1..48eaa8533775a 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -85,8 +85,8 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // c_rarg3: first stack arg - wordSize // adjust sp - __ addi(sp, c_rarg3, -18 * wordSize); - __ addi(sp, sp, -2 * wordSize); + __ subi(sp, c_rarg3, 18 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ sd(ra, Address(sp, 0)); __ call_VM(noreg, @@ -742,8 +742,8 @@ void TemplateInterpreterGenerator::lock_method() { // add space for monitor & lock __ check_extended_sp(); - __ add(sp, sp, - entry_size); // add space for a monitor entry - __ add(esp, esp, - entry_size); + __ sub(sp, sp, entry_size); // add space for a monitor entry + __ sub(esp, esp, entry_size); __ sub(t0, sp, fp); __ srai(t0, t0, Interpreter::logStackElementSize); __ sd(t0, Address(fp, frame::interpreter_frame_extended_sp_offset * wordSize)); @@ -768,17 +768,17 @@ void TemplateInterpreterGenerator::lock_method() { void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // initialize fixed part of activation frame if (native_call) { - __ add(esp, sp, - 14 * wordSize); + __ subi(esp, sp, 14 * wordSize); __ mv(xbcp, zr); - __ add(sp, sp, - 14 * wordSize); + __ subi(sp, sp, 14 * wordSize); // add 2 zero-initialized slots for native calls __ sd(zr, Address(sp, 13 * wordSize)); __ sd(zr, Address(sp, 12 * wordSize)); } else { - __ add(esp, sp, - 12 * wordSize); + __ subi(esp, sp, 12 * wordSize); __ ld(t0, Address(xmethod, Method::const_offset())); // get ConstMethod __ add(xbcp, t0, in_bytes(ConstMethod::codes_offset())); // get codebase - __ add(sp, sp, - 12 * wordSize); + __ subi(sp, sp, 12 * wordSize); } __ sd(xbcp, Address(sp, wordSize)); __ mv(t0, frame::interpreter_frame_initial_sp_offset); @@ -833,7 +833,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { } else { // Make sure there is room for the exception oop pushed in case method throws // an exception (see TemplateInterpreterGenerator::generate_throw_exception()) - __ sub(t0, sp, 2 * wordSize); + __ subi(t0, sp, 2 * wordSize); __ sub(t1, t0, fp); __ srai(t1, t1, Interpreter::logStackElementSize); __ sd(t1, Address(sp, 5 * wordSize)); @@ -1018,7 +1018,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // compute beginning of parameters (xlocals) __ shadd(xlocals, x12, esp, xlocals, 3); - __ addi(xlocals, xlocals, -wordSize); + __ subi(xlocals, xlocals, wordSize); // Pull SP back to minimum size: this avoids holes in the stack __ andi(sp, esp, -16); @@ -1175,7 +1175,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { { Label L; __ lwu(t, Address(xthread, JavaThread::thread_state_offset())); - __ addi(t0, zr, (u1)_thread_in_Java); + __ mv(t0, (u1)_thread_in_Java); __ beq(t, t0, L); __ stop("Wrong thread state in native stub"); __ bind(L); @@ -1202,7 +1202,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { __ restore_cpu_control_state_after_jni(t0); // make room for the pushes we're about to do - __ sub(t0, esp, 4 * wordSize); + __ subi(t0, esp, 4 * wordSize); __ andi(sp, t0, -16); // NOTE: The order of these pushes is known to frame::interpreter_frame_result @@ -1308,7 +1308,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { { Label no_reguard; __ lwu(t0, Address(xthread, in_bytes(JavaThread::stack_guard_state_offset()))); - __ addi(t1, zr, (u1)StackOverflow::stack_guard_yellow_reserved_disabled); + __ mv(t1, (u1)StackOverflow::stack_guard_yellow_reserved_disabled); __ bne(t0, t1, no_reguard); __ push_call_clobbered_registers(); @@ -1440,7 +1440,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // compute beginning of parameters (xlocals) __ shadd(xlocals, x12, esp, t1, 3); - __ add(xlocals, xlocals, -wordSize); + __ subi(xlocals, xlocals, wordSize); // Make room for additional locals __ slli(t1, x13, 3); @@ -1458,8 +1458,8 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { __ blez(x13, exit); // do nothing if x13 <= 0 __ bind(loop); __ sd(zr, Address(t0)); - __ add(t0, t0, wordSize); - __ add(x13, x13, -1); // until everything initialized + __ addi(t0, t0, wordSize); + __ subi(x13, x13, 1); // until everything initialized __ bnez(x13, loop); __ bind(exit); } @@ -1650,7 +1650,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ slli(x10, x10, Interpreter::logStackElementSize); __ restore_locals(); __ sub(xlocals, xlocals, x10); - __ add(xlocals, xlocals, wordSize); + __ addi(xlocals, xlocals, wordSize); // Save these arguments __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization:: @@ -1745,7 +1745,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // sp: expression stack of caller // fp: fp of caller // FIXME: There's no point saving ra here because VM calls don't trash it - __ sub(sp, sp, 2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ sd(x10, Address(sp, 0)); // save exception __ sd(ra, Address(sp, wordSize)); // save return address __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, @@ -1754,7 +1754,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ mv(x11, x10); // save exception handler __ ld(x10, Address(sp, 0)); // restore exception __ ld(ra, Address(sp, wordSize)); // restore return address - __ add(sp, sp, 2 * wordSize); + __ addi(sp, sp, 2 * wordSize); // We might be returning to a deopt handler that expects x13 to // contain the exception pc __ mv(x13, ra); diff --git a/src/hotspot/cpu/riscv/templateTable_riscv.cpp b/src/hotspot/cpu/riscv/templateTable_riscv.cpp index e51604569f688..59e9ab95d94b5 100644 --- a/src/hotspot/cpu/riscv/templateTable_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp @@ -197,7 +197,7 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg, Label L_fast_patch; // if a breakpoint is present we can't rewrite the stream directly __ load_unsigned_byte(temp_reg, at_bcp(0)); - __ addi(temp_reg, temp_reg, -Bytecodes::_breakpoint); // temp_reg is temporary register. + __ subi(temp_reg, temp_reg, Bytecodes::_breakpoint); // temp_reg is temporary register. __ bnez(temp_reg, L_fast_patch); // Let breakpoint table handling rewrite to quicker bytecode __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), xmethod, xbcp, bc_reg); @@ -209,7 +209,7 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg, Label L_okay; __ load_unsigned_byte(temp_reg, at_bcp(0)); __ beq(temp_reg, bc_reg, L_okay); - __ addi(temp_reg, temp_reg, -(int) Bytecodes::java_code(bc)); + __ subi(temp_reg, temp_reg, (int)Bytecodes::java_code(bc)); __ beqz(temp_reg, L_okay); __ stop("patching the wrong bytecode"); __ bind(L_okay); @@ -737,7 +737,7 @@ void TemplateTable::iaload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2); __ shadd(x10, x11, x10, t0, 2); __ access_load_at(T_INT, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); __ sext(x10, x10, 32); @@ -750,7 +750,7 @@ void TemplateTable::laload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3); __ shadd(x10, x11, x10, t0, 3); __ access_load_at(T_LONG, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -762,7 +762,7 @@ void TemplateTable::faload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2); __ shadd(x10, x11, x10, t0, 2); __ access_load_at(T_FLOAT, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -774,7 +774,7 @@ void TemplateTable::daload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3); __ shadd(x10, x11, x10, t0, 3); __ access_load_at(T_DOUBLE, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -786,7 +786,7 @@ void TemplateTable::aaload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); __ shadd(x10, x11, x10, t0, LogBytesPerHeapOop); do_oop_load(_masm, Address(x10), x10, IS_ARRAY); } @@ -798,7 +798,7 @@ void TemplateTable::baload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0); __ shadd(x10, x11, x10, t0, 0); __ access_load_at(T_BYTE, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -810,7 +810,7 @@ void TemplateTable::caload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); __ shadd(x10, x11, x10, t0, 1); __ access_load_at(T_CHAR, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -826,7 +826,7 @@ void TemplateTable::fast_icaload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11, kills t0 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); // addi, max imm is 2^11 + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); // addi, max imm is 2^11 __ shadd(x10, x11, x10, t0, 1); __ access_load_at(T_CHAR, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -838,7 +838,7 @@ void TemplateTable::saload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11, kills t0 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_SHORT) >> 1); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_SHORT) >> 1); __ shadd(x10, x11, x10, t0, 1); __ access_load_at(T_SHORT, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -1017,7 +1017,7 @@ void TemplateTable::iastore() { // x11: index // x13: array index_check(x13, x11); // prefer index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2); __ shadd(t0, x11, x13, t0, 2); __ access_store_at(T_INT, IN_HEAP | IS_ARRAY, Address(t0, 0), x10, noreg, noreg, noreg); } @@ -1030,7 +1030,7 @@ void TemplateTable::lastore() { // x11: index // x13: array index_check(x13, x11); // prefer index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3); __ shadd(t0, x11, x13, t0, 3); __ access_store_at(T_LONG, IN_HEAP | IS_ARRAY, Address(t0, 0), x10, noreg, noreg, noreg); } @@ -1043,7 +1043,7 @@ void TemplateTable::fastore() { // x11: index // x13: array index_check(x13, x11); // prefer index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2); __ shadd(t0, x11, x13, t0, 2); __ access_store_at(T_FLOAT, IN_HEAP | IS_ARRAY, Address(t0, 0), noreg /* ftos */, noreg, noreg, noreg); } @@ -1056,7 +1056,7 @@ void TemplateTable::dastore() { // x11: index // x13: array index_check(x13, x11); // prefer index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3); __ shadd(t0, x11, x13, t0, 3); __ access_store_at(T_DOUBLE, IN_HEAP | IS_ARRAY, Address(t0, 0), noreg /* dtos */, noreg, noreg, noreg); } @@ -1070,7 +1070,7 @@ void TemplateTable::aastore() { __ ld(x13, at_tos_p2()); // array index_check(x13, x12); // kills x11 - __ add(x14, x12, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); + __ addi(x14, x12, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); __ shadd(x14, x14, x13, x14, LogBytesPerHeapOop); Address element_address(x14, 0); @@ -1112,7 +1112,7 @@ void TemplateTable::aastore() { // Pop stack arguments __ bind(done); - __ add(esp, esp, 3 * Interpreter::stackElementSize); + __ addi(esp, esp, 3 * Interpreter::stackElementSize); } void TemplateTable::bastore() { @@ -1134,7 +1134,7 @@ void TemplateTable::bastore() { __ andi(x10, x10, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 __ bind(L_skip); - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0); __ add(x11, x13, x11); __ access_store_at(T_BYTE, IN_HEAP | IS_ARRAY, Address(x11, 0), x10, noreg, noreg, noreg); @@ -1148,7 +1148,7 @@ void TemplateTable::castore() { // x11: index // x13: array index_check(x13, x11); // prefer index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); __ shadd(t0, x11, x13, t0, 1); __ access_store_at(T_CHAR, IN_HEAP | IS_ARRAY, Address(t0, 0), x10, noreg, noreg, noreg); } @@ -1883,7 +1883,7 @@ void TemplateTable::ret() { __ profile_ret(x11, x12); __ ld(xbcp, Address(xmethod, Method::const_offset())); __ add(xbcp, xbcp, x11); - __ addi(xbcp, xbcp, in_bytes(ConstMethod::codes_offset())); + __ add(xbcp, xbcp, in_bytes(ConstMethod::codes_offset())); __ dispatch_next(vtos, 0, /*generate_poll*/true); } @@ -1958,7 +1958,7 @@ void TemplateTable::fast_linearswitch() { __ lw(t0, Address(t0, 2 * BytesPerInt)); __ beq(x10, t0, found); __ bind(loop_entry); - __ addi(x11, x11, -1); + __ subi(x11, x11, 1); __ bgez(x11, loop); // default case __ profile_switch_default(x10); @@ -2544,7 +2544,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notByte); - __ sub(t0, tos_state, (u1)ztos); + __ subi(t0, tos_state, (u1)ztos); __ bnez(t0, notBool); // ztos (same code as btos) @@ -2558,7 +2558,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notBool); - __ sub(t0, tos_state, (u1)atos); + __ subi(t0, tos_state, (u1)atos); __ bnez(t0, notObj); // atos do_oop_load(_masm, field, x10, IN_HEAP); @@ -2569,7 +2569,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notObj); - __ sub(t0, tos_state, (u1)itos); + __ subi(t0, tos_state, (u1)itos); __ bnez(t0, notInt); // itos __ access_load_at(T_INT, IN_HEAP, x10, field, noreg, noreg); @@ -2582,7 +2582,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notInt); - __ sub(t0, tos_state, (u1)ctos); + __ subi(t0, tos_state, (u1)ctos); __ bnez(t0, notChar); // ctos __ access_load_at(T_CHAR, IN_HEAP, x10, field, noreg, noreg); @@ -2594,7 +2594,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notChar); - __ sub(t0, tos_state, (u1)stos); + __ subi(t0, tos_state, (u1)stos); __ bnez(t0, notShort); // stos __ access_load_at(T_SHORT, IN_HEAP, x10, field, noreg, noreg); @@ -2606,7 +2606,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notShort); - __ sub(t0, tos_state, (u1)ltos); + __ subi(t0, tos_state, (u1)ltos); __ bnez(t0, notLong); // ltos __ access_load_at(T_LONG, IN_HEAP, x10, field, noreg, noreg); @@ -2618,7 +2618,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notLong); - __ sub(t0, tos_state, (u1)ftos); + __ subi(t0, tos_state, (u1)ftos); __ bnez(t0, notFloat); // ftos __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg); @@ -2631,7 +2631,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ bind(notFloat); #ifdef ASSERT - __ sub(t0, tos_state, (u1)dtos); + __ subi(t0, tos_state, (u1)dtos); __ bnez(t0, notDouble); #endif // dtos @@ -2696,9 +2696,9 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is __ load_unsigned_byte(c_rarg3, Address(c_rarg2, in_bytes(ResolvedFieldEntry::type_offset()))); Label nope2, done, ok; __ ld(c_rarg1, at_tos_p1()); // initially assume a one word jvalue - __ sub(t0, c_rarg3, ltos); + __ subi(t0, c_rarg3, (u1)ltos); __ beqz(t0, ok); - __ sub(t0, c_rarg3, dtos); + __ subi(t0, c_rarg3, (u1)dtos); __ bnez(t0, nope2); __ bind(ok); __ ld(c_rarg1, at_tos_p2()); // ltos (two word jvalue); @@ -2772,7 +2772,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notByte); - __ sub(t0, tos_state, (u1)ztos); + __ subi(t0, tos_state, (u1)ztos); __ bnez(t0, notBool); // ztos @@ -2792,7 +2792,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notBool); - __ sub(t0, tos_state, (u1)atos); + __ subi(t0, tos_state, (u1)atos); __ bnez(t0, notObj); // atos @@ -2813,7 +2813,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notObj); - __ sub(t0, tos_state, (u1)itos); + __ subi(t0, tos_state, (u1)itos); __ bnez(t0, notInt); // itos @@ -2833,7 +2833,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notInt); - __ sub(t0, tos_state, (u1)ctos); + __ subi(t0, tos_state, (u1)ctos); __ bnez(t0, notChar); // ctos @@ -2853,7 +2853,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notChar); - __ sub(t0, tos_state, (u1)stos); + __ subi(t0, tos_state, (u1)stos); __ bnez(t0, notShort); // stos @@ -2873,7 +2873,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notShort); - __ sub(t0, tos_state, (u1)ltos); + __ subi(t0, tos_state, (u1)ltos); __ bnez(t0, notLong); // ltos @@ -2893,7 +2893,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notLong); - __ sub(t0, tos_state, (u1)ftos); + __ subi(t0, tos_state, (u1)ftos); __ bnez(t0, notFloat); // ftos @@ -2914,7 +2914,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr __ bind(notFloat); #ifdef ASSERT - __ sub(t0, tos_state, (u1)dtos); + __ subi(t0, tos_state, (u1)dtos); __ bnez(t0, notDouble); #endif @@ -3207,7 +3207,7 @@ void TemplateTable::fast_xaccess(TosState state) { __ bind(notVolatile); } - __ sub(xbcp, xbcp, 1); + __ subi(xbcp, xbcp, 1); } //----------------------------------------------------------------------------- @@ -3521,7 +3521,7 @@ void TemplateTable::_new() { __ la(t0, Address(t0, tags_offset)); __ lbu(t0, t0); __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); - __ sub(t1, t0, (u1)JVM_CONSTANT_Class); + __ subi(t1, t0, (u1)JVM_CONSTANT_Class); __ bnez(t1, slow_case); // get InstanceKlass @@ -3558,9 +3558,9 @@ void TemplateTable::_new() { // zero, go directly to the header initialization. if (UseCompactObjectHeaders) { assert(is_aligned(oopDesc::base_offset_in_bytes(), BytesPerLong), "oop base offset must be 8-byte-aligned"); - __ sub(x13, x13, oopDesc::base_offset_in_bytes()); + __ subi(x13, x13, oopDesc::base_offset_in_bytes()); } else { - __ sub(x13, x13, sizeof(oopDesc)); + __ subi(x13, x13, sizeof(oopDesc)); } __ beqz(x13, initialize_header); @@ -3568,15 +3568,15 @@ void TemplateTable::_new() { { if (UseCompactObjectHeaders) { assert(is_aligned(oopDesc::base_offset_in_bytes(), BytesPerLong), "oop base offset must be 8-byte-aligned"); - __ add(x12, x10, oopDesc::base_offset_in_bytes()); + __ addi(x12, x10, oopDesc::base_offset_in_bytes()); } else { - __ add(x12, x10, sizeof(oopDesc)); + __ addi(x12, x10, sizeof(oopDesc)); } Label loop; __ bind(loop); __ sd(zr, Address(x12)); - __ add(x12, x12, BytesPerLong); - __ sub(x13, x13, BytesPerLong); + __ addi(x12, x12, BytesPerLong); + __ subi(x13, x13, BytesPerLong); __ bnez(x13, loop); } @@ -3649,11 +3649,11 @@ void TemplateTable::checkcast() { __ get_cpool_and_tags(x12, x13); // x12=cpool, x13=tags array __ get_unsigned_2_byte_index_at_bcp(x9, 1); // x9=index // See if bytecode has already been quicked - __ add(t0, x13, Array::base_offset_in_bytes()); + __ addi(t0, x13, Array::base_offset_in_bytes()); __ add(x11, t0, x9); __ lbu(x11, x11); __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); - __ sub(t0, x11, (u1)JVM_CONSTANT_Class); + __ subi(t0, x11, (u1)JVM_CONSTANT_Class); __ beqz(t0, quicked); __ push(atos); // save receiver for result, and for GC @@ -3704,11 +3704,11 @@ void TemplateTable::instanceof() { __ get_cpool_and_tags(x12, x13); // x12=cpool, x13=tags array __ get_unsigned_2_byte_index_at_bcp(x9, 1); // x9=index // See if bytecode has already been quicked - __ add(t0, x13, Array::base_offset_in_bytes()); + __ addi(t0, x13, Array::base_offset_in_bytes()); __ add(x11, t0, x9); __ lbu(x11, x11); __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); - __ sub(t0, x11, (u1)JVM_CONSTANT_Class); + __ subi(t0, x11, (u1)JVM_CONSTANT_Class); __ beqz(t0, quicked); __ push(atos); // save receiver for result, and for GC @@ -3884,7 +3884,7 @@ void TemplateTable::monitorenter() { __ ld(c_rarg2, Address(c_rarg3, entry_size)); // load expression stack // word from old location __ sd(c_rarg2, Address(c_rarg3, 0)); // and store it at new location - __ add(c_rarg3, c_rarg3, wordSize); // advance to next word + __ addi(c_rarg3, c_rarg3, wordSize); // advance to next word __ bind(entry); __ bne(c_rarg3, c_rarg1, loop); // check if bottom reached.if not at bottom // then copy next word @@ -3979,7 +3979,7 @@ void TemplateTable::multianewarray() { // last dim is on top of stack; we want address of first one: // first_addr = last_addr + (ndims - 1) * wordSize __ shadd(c_rarg1, x10, esp, c_rarg1, 3); - __ sub(c_rarg1, c_rarg1, wordSize); + __ subi(c_rarg1, c_rarg1, wordSize); call_VM(x10, CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), c_rarg1); From ceae2b977dac58a9b2c09e42cb256c94eff9222b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 9 Jan 2025 11:49:18 +0000 Subject: [PATCH 070/286] 8347121: Add missing @serial tags to module java.base Reviewed-by: alanb --- .../lang/EnumConstantNotPresentException.java | 6 +-- .../classes/java/lang/StackTraceElement.java | 18 ++++----- .../java/lang/TypeNotPresentException.java | 4 +- .../AnnotationTypeMismatchException.java | 4 +- .../IncompleteAnnotationException.java | 6 +-- .../java/lang/invoke/SerializedLambda.java | 22 +++++----- .../classes/java/net/HttpRetryException.java | 6 +-- .../classes/java/net/URISyntaxException.java | 6 +-- .../share/classes/java/net/URLPermission.java | 4 +- .../nio/charset/MalformedInputException.java | 4 +- .../charset/UnmappableCharacterException.java | 4 +- .../java/nio/file/FileSystemException.java | 6 +-- .../java/nio/file/InvalidPathException.java | 6 +-- .../UserPrincipalNotFoundException.java | 4 +- .../java/security/AccessControlException.java | 4 +- .../classes/java/security/AllPermission.java | 4 +- .../classes/java/security/GuardedObject.java | 6 +-- .../share/classes/java/security/KeyPair.java | 6 +-- .../classes/java/security/Permission.java | 4 +- .../java/security/PermissionCollection.java | 4 +- .../classes/java/security/Permissions.java | 3 +- .../classes/java/security/SignedObject.java | 8 ++-- .../classes/java/security/cert/CertPath.java | 6 +-- .../java/security/cert/Certificate.java | 6 +-- .../share/classes/java/text/DateFormat.java | 4 +- .../share/classes/java/time/Duration.java | 6 +-- .../share/classes/java/time/Instant.java | 6 +-- .../share/classes/java/time/LocalDate.java | 8 ++-- .../classes/java/time/LocalDateTime.java | 6 +-- .../share/classes/java/time/LocalTime.java | 10 ++--- .../share/classes/java/time/MonthDay.java | 6 +-- .../classes/java/time/OffsetDateTime.java | 6 +-- .../share/classes/java/time/OffsetTime.java | 6 +-- .../share/classes/java/time/Period.java | 8 ++-- .../share/classes/java/time/Year.java | 4 +- .../share/classes/java/time/YearMonth.java | 6 +-- .../share/classes/java/time/ZoneOffset.java | 4 +- .../classes/java/time/ZonedDateTime.java | 8 ++-- .../time/format/DateTimeParseException.java | 6 +-- .../java/time/temporal/ValueRange.java | 10 ++--- .../java/time/temporal/WeekFields.java | 6 +-- .../java/time/zone/ZoneOffsetTransition.java | 10 ++--- .../time/zone/ZoneOffsetTransitionRule.java | 20 +++++----- .../classes/java/time/zone/ZoneRules.java | 14 +++---- .../share/classes/java/util/AbstractMap.java | 6 ++- .../share/classes/java/util/Arrays.java | 3 +- .../share/classes/java/util/Collections.java | 40 +++++++++++++++++-- .../util/DuplicateFormatFlagsException.java | 3 +- ...ormatFlagsConversionMismatchException.java | 4 +- .../util/IllegalFormatCodePointException.java | 3 +- .../IllegalFormatConversionException.java | 4 +- .../util/IllegalFormatFlagsException.java | 3 +- .../util/IllegalFormatPrecisionException.java | 3 +- .../util/IllegalFormatWidthException.java | 3 +- .../java/util/IllformedLocaleException.java | 3 +- .../util/MissingFormatArgumentException.java | 3 +- .../util/MissingFormatWidthException.java | 3 +- .../classes/java/util/PriorityQueue.java | 6 +-- .../share/classes/java/util/TreeMap.java | 13 ++++-- .../share/classes/java/util/UUID.java | 14 +++---- .../UnknownFormatConversionException.java | 3 +- .../util/UnknownFormatFlagsException.java | 3 +- .../util/concurrent/ArrayBlockingQueue.java | 14 +++---- .../util/concurrent/ConcurrentHashMap.java | 1 + .../concurrent/ConcurrentSkipListMap.java | 12 +++--- .../concurrent/ConcurrentSkipListSet.java | 2 +- .../util/concurrent/CopyOnWriteArraySet.java | 1 + .../util/concurrent/CountedCompleter.java | 4 +- .../java/util/concurrent/ForkJoinTask.java | 1 + .../util/concurrent/LinkedBlockingDeque.java | 8 ++-- .../util/concurrent/LinkedBlockingQueue.java | 12 +++--- .../concurrent/PriorityBlockingQueue.java | 6 +-- .../java/util/concurrent/RecursiveTask.java | 2 +- .../java/util/concurrent/Semaphore.java | 2 +- .../util/concurrent/SynchronousQueue.java | 3 ++ .../util/concurrent/atomic/AtomicBoolean.java | 1 + .../util/concurrent/atomic/AtomicInteger.java | 1 + .../concurrent/atomic/AtomicIntegerArray.java | 1 + .../util/concurrent/atomic/AtomicLong.java | 1 + .../concurrent/atomic/AtomicLongArray.java | 1 + .../concurrent/atomic/AtomicReference.java | 1 + .../atomic/AtomicReferenceArray.java | 1 + .../concurrent/atomic/DoubleAccumulator.java | 2 + .../concurrent/atomic/LongAccumulator.java | 2 + .../locks/AbstractQueuedLongSynchronizer.java | 2 +- .../locks/AbstractQueuedSynchronizer.java | 2 +- .../util/concurrent/locks/ReentrantLock.java | 2 +- .../locks/ReentrantReadWriteLock.java | 8 ++-- .../util/regex/PatternSyntaxException.java | 5 ++- 89 files changed, 301 insertions(+), 222 deletions(-) diff --git a/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java b/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java index 4ba7cd3b1752a..cdab2081181a1 100644 --- a/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java +++ b/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, 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 @@ -42,12 +42,12 @@ public class EnumConstantNotPresentException extends RuntimeException { private static final long serialVersionUID = -6046998521960521108L; /** - * The type of the missing enum constant. + * @serial The type of the missing enum constant. */ private Class enumType; /** - * The name of the missing enum constant. + * @serial The name of the missing enum constant. */ private String constantName; diff --git a/src/java.base/share/classes/java/lang/StackTraceElement.java b/src/java.base/share/classes/java/lang/StackTraceElement.java index ed8d47a4e5095..70219a7f6ec3a 100644 --- a/src/java.base/share/classes/java/lang/StackTraceElement.java +++ b/src/java.base/share/classes/java/lang/StackTraceElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -64,35 +64,35 @@ public final class StackTraceElement implements java.io.Serializable { // Normally initialized by VM /** - * The name of the class loader. + * @serial The name of the class loader. */ private String classLoaderName; /** - * The module name. + * @serial The module name. */ private String moduleName; /** - * The module version. + * @serial The module version. */ private String moduleVersion; /** - * The declaring class. + * @serial The declaring class. */ private String declaringClass; /** - * The method name. + * @serial The method name. */ private String methodName; /** - * The source file name. + * @serial The source file name. */ private String fileName; /** - * The source line number. + * @serial The source line number. */ private int lineNumber; /** - * Control to show full or partial module, package, and class names. + * @serial Control to show full or partial module, package, and class names. */ private byte format = 0; // Default to show all diff --git a/src/java.base/share/classes/java/lang/TypeNotPresentException.java b/src/java.base/share/classes/java/lang/TypeNotPresentException.java index c5a899ef2851d..5ba43efbc09c1 100644 --- a/src/java.base/share/classes/java/lang/TypeNotPresentException.java +++ b/src/java.base/share/classes/java/lang/TypeNotPresentException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -48,7 +48,7 @@ public class TypeNotPresentException extends RuntimeException { private static final long serialVersionUID = -5101214195716534496L; /** - * The type name or the name of a type variable. + * @serial The type name or the name of a type variable. */ private String typeName; diff --git a/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java b/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java index 6a9ea51d10b7e..83054044b6009 100644 --- a/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java +++ b/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -48,7 +48,7 @@ public class AnnotationTypeMismatchException extends RuntimeException { private final transient Method element; /** - * The (erroneous) type of data found in the annotation. This string + * @serial The (erroneous) type of data found in the annotation. This string * may, but is not required to, contain the value as well. The exact * format of the string is unspecified. */ diff --git a/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java b/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java index 921d4b92fcddd..02f2638c37099 100644 --- a/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java +++ b/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -43,11 +43,11 @@ public class IncompleteAnnotationException extends RuntimeException { private static final long serialVersionUID = 8445097402741811912L; /** - * The annotation interface. + * @serial The annotation interface. */ private Class annotationType; /** - * The element name. + * @serial The element name. */ private String elementName; diff --git a/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java b/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java index 3767bf2338855..3ffe3c9a9f246 100644 --- a/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java +++ b/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -65,43 +65,43 @@ public final class SerializedLambda implements Serializable { @java.io.Serial private static final long serialVersionUID = 8025925345765570181L; /** - * The capturing class. + * @serial The capturing class. */ private final Class capturingClass; /** - * The functional interface class. + * @serial The functional interface class. */ private final String functionalInterfaceClass; /** - * The functional interface method name. + * @serial The functional interface method name. */ private final String functionalInterfaceMethodName; /** - * The functional interface method signature. + * @serial The functional interface method signature. */ private final String functionalInterfaceMethodSignature; /** - * The implementation class. + * @serial The implementation class. */ private final String implClass; /** - * The implementation method name. + * @serial The implementation method name. */ private final String implMethodName; /** - * The implementation method signature. + * @serial The implementation method signature. */ private final String implMethodSignature; /** - * The implementation method kind. + * @serial The implementation method kind. */ private final int implMethodKind; /** - * The instantiated method type. + * @serial The instantiated method type. */ private final String instantiatedMethodType; /** - * The captured arguments. + * @serial The captured arguments. */ @SuppressWarnings("serial") // Not statically typed as Serializable private final Object[] capturedArgs; diff --git a/src/java.base/share/classes/java/net/HttpRetryException.java b/src/java.base/share/classes/java/net/HttpRetryException.java index fefeb9bb68786..6d41ac3b56371 100644 --- a/src/java.base/share/classes/java/net/HttpRetryException.java +++ b/src/java.base/share/classes/java/net/HttpRetryException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, 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 @@ -40,12 +40,12 @@ public class HttpRetryException extends IOException { private static final long serialVersionUID = -9186022286469111381L; /** - * The response code. + * @serial The response code. */ private final int responseCode; /** - * The URL to be redirected to. + * @serial The URL to be redirected to. */ private String location; diff --git a/src/java.base/share/classes/java/net/URISyntaxException.java b/src/java.base/share/classes/java/net/URISyntaxException.java index 3b9889cd1b486..c0b0cbdd23462 100644 --- a/src/java.base/share/classes/java/net/URISyntaxException.java +++ b/src/java.base/share/classes/java/net/URISyntaxException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -42,12 +42,12 @@ public class URISyntaxException private static final long serialVersionUID = 2137979680897488891L; /** - * The input string. + * @serial The input string. */ private final String input; /** - * The index at which the parse error occurred, + * @serial The index at which the parse error occurred, * or {@code -1} if the index is not known. */ private final int index; diff --git a/src/java.base/share/classes/java/net/URLPermission.java b/src/java.base/share/classes/java/net/URLPermission.java index d48f784ff8427..daf3e99a6a0e0 100644 --- a/src/java.base/share/classes/java/net/URLPermission.java +++ b/src/java.base/share/classes/java/net/URLPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -168,7 +168,7 @@ public final class URLPermission extends Permission { // serialized field /** - * The actions string + * @serial The actions string */ private String actions; diff --git a/src/java.base/share/classes/java/nio/charset/MalformedInputException.java b/src/java.base/share/classes/java/nio/charset/MalformedInputException.java index c36f81f9153d9..a4e7f31fc2c73 100644 --- a/src/java.base/share/classes/java/nio/charset/MalformedInputException.java +++ b/src/java.base/share/classes/java/nio/charset/MalformedInputException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -42,7 +42,7 @@ public class MalformedInputException private static final long serialVersionUID = -3438823399834806194L; /** - * The length of the input. + * @serial The length of the input. */ private int inputLength; diff --git a/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java b/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java index 857c519974d7c..8f79a232f0349 100644 --- a/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java +++ b/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, 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 @@ -42,7 +42,7 @@ public class UnmappableCharacterException private static final long serialVersionUID = -7026962371537706123L; /** - * The length of the input character (or byte) sequence. + * @serial The length of the input character (or byte) sequence. */ private int inputLength; diff --git a/src/java.base/share/classes/java/nio/file/FileSystemException.java b/src/java.base/share/classes/java/nio/file/FileSystemException.java index a03a2708ce64c..43887756b1591 100644 --- a/src/java.base/share/classes/java/nio/file/FileSystemException.java +++ b/src/java.base/share/classes/java/nio/file/FileSystemException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -41,12 +41,12 @@ public class FileSystemException static final long serialVersionUID = -3055425747967319812L; /** - * String identifying the file or {@code null} if not known. + * @serial String identifying the file or {@code null} if not known. */ private final String file; /** - * String identifying the other file or {@code null} if there isn't + * @serial String identifying the other file or {@code null} if there isn't * another file or if not known. */ private final String other; diff --git a/src/java.base/share/classes/java/nio/file/InvalidPathException.java b/src/java.base/share/classes/java/nio/file/InvalidPathException.java index bb28b61b83b9a..495d087a39dc4 100644 --- a/src/java.base/share/classes/java/nio/file/InvalidPathException.java +++ b/src/java.base/share/classes/java/nio/file/InvalidPathException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -40,12 +40,12 @@ public class InvalidPathException static final long serialVersionUID = 4355821422286746137L; /** - * The input string. + * @serial The input string. */ private String input; /** - * The index of the input string at which the error occurred or + * @serial The index of the input string at which the error occurred or * {@code -1} if not known. */ private int index; diff --git a/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java b/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java index 209453cdaada1..9baca303ef02a 100644 --- a/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java +++ b/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -41,7 +41,7 @@ public class UserPrincipalNotFoundException static final long serialVersionUID = -5369283889045833024L; /** - * The user principal name. + * @serial The user principal name. */ private final String name; diff --git a/src/java.base/share/classes/java/security/AccessControlException.java b/src/java.base/share/classes/java/security/AccessControlException.java index 4d46cd6887e5f..d423d95513d0d 100644 --- a/src/java.base/share/classes/java/security/AccessControlException.java +++ b/src/java.base/share/classes/java/security/AccessControlException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -45,7 +45,7 @@ public class AccessControlException extends SecurityException { private static final long serialVersionUID = 5138225684096988535L; /** - * The permission that caused the exception to be thrown. + * @serial The permission that caused the exception to be thrown. */ private Permission perm; diff --git a/src/java.base/share/classes/java/security/AllPermission.java b/src/java.base/share/classes/java/security/AllPermission.java index 15a4f78123f15..23c55085ec3ca 100644 --- a/src/java.base/share/classes/java/security/AllPermission.java +++ b/src/java.base/share/classes/java/security/AllPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -151,7 +151,7 @@ final class AllPermissionCollection private static final long serialVersionUID = -4023755556366636806L; /** - * True if any {@code AllPermissionCollection} objects have been added. + * @serial True if any {@code AllPermissionCollection} objects have been added. */ private boolean all_allowed; diff --git a/src/java.base/share/classes/java/security/GuardedObject.java b/src/java.base/share/classes/java/security/GuardedObject.java index 2c9d1a345dcc3..fedb0eeae1d5c 100644 --- a/src/java.base/share/classes/java/security/GuardedObject.java +++ b/src/java.base/share/classes/java/security/GuardedObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -55,13 +55,13 @@ public class GuardedObject implements java.io.Serializable { private static final long serialVersionUID = -5240450096227834308L; /** - * The object we are guarding. + * @serial The object we are guarding. */ @SuppressWarnings("serial") // Not statically typed as Serializable private final Object object; /** - * The guard object. + * @serial The guard object. */ @SuppressWarnings("serial") // Not statically typed as Serializable private final Guard guard; diff --git a/src/java.base/share/classes/java/security/KeyPair.java b/src/java.base/share/classes/java/security/KeyPair.java index 61c1121bdee4a..cc648a677dd5a 100644 --- a/src/java.base/share/classes/java/security/KeyPair.java +++ b/src/java.base/share/classes/java/security/KeyPair.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, 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 @@ -42,10 +42,10 @@ public final class KeyPair implements java.io.Serializable { @java.io.Serial private static final long serialVersionUID = -7565189502268009837L; - /** The private key. */ + /** @serial The private key. */ private final PrivateKey privateKey; - /** The public key. */ + /** @serial The public key. */ private final PublicKey publicKey; /** diff --git a/src/java.base/share/classes/java/security/Permission.java b/src/java.base/share/classes/java/security/Permission.java index 71bad14e39595..e066bc0e591f1 100644 --- a/src/java.base/share/classes/java/security/Permission.java +++ b/src/java.base/share/classes/java/security/Permission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -69,7 +69,7 @@ public abstract class Permission implements Guard, java.io.Serializable { private static final long serialVersionUID = -5636570222231596674L; /** - * The permission name. + * @serial The permission name. */ private final String name; diff --git a/src/java.base/share/classes/java/security/PermissionCollection.java b/src/java.base/share/classes/java/security/PermissionCollection.java index d287a68505915..3718744c34916 100644 --- a/src/java.base/share/classes/java/security/PermissionCollection.java +++ b/src/java.base/share/classes/java/security/PermissionCollection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -103,7 +103,7 @@ public abstract class PermissionCollection implements java.io.Serializable { private static final long serialVersionUID = -6727011328946861783L; /** - * Whether this permission collection is read-only. + * @serial Whether this permission collection is read-only. *

    * If set, the {@code add} method will throw an exception. */ diff --git a/src/java.base/share/classes/java/security/Permissions.java b/src/java.base/share/classes/java/security/Permissions.java index 3bdeac6f92945..ecb18aca8bb2b 100644 --- a/src/java.base/share/classes/java/security/Permissions.java +++ b/src/java.base/share/classes/java/security/Permissions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -92,6 +92,7 @@ public final class Permissions extends PermissionCollection // checked private transient boolean hasUnresolved = false; + /** @serial */ // optimization. keep track of the AllPermission collection // - package private for ProtectionDomain optimization PermissionCollection allPermission; diff --git a/src/java.base/share/classes/java/security/SignedObject.java b/src/java.base/share/classes/java/security/SignedObject.java index f65300fc80814..d1b203c3aea76 100644 --- a/src/java.base/share/classes/java/security/SignedObject.java +++ b/src/java.base/share/classes/java/security/SignedObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -122,18 +122,18 @@ public final class SignedObject implements Serializable { private static final long serialVersionUID = 720502720485447167L; /** - * The original content is "deep copied" in its serialized format + * @serial The original content is "deep copied" in its serialized format * and stored in a byte array. */ private byte[] content; /** - * The signature field is stored as a byte array. + * @serial The signature field is stored as a byte array. */ private byte[] signature; /** - * The algorithm used to sign the object. + * @serial The algorithm used to sign the object. */ private String thealgorithm; diff --git a/src/java.base/share/classes/java/security/cert/CertPath.java b/src/java.base/share/classes/java/security/cert/CertPath.java index 80e68d1c598bc..ffbbf0291b141 100644 --- a/src/java.base/share/classes/java/security/cert/CertPath.java +++ b/src/java.base/share/classes/java/security/cert/CertPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -301,9 +301,9 @@ protected static class CertPathRep implements Serializable { @java.io.Serial private static final long serialVersionUID = 3015633072427920915L; - /** The type of {@code Certificate}s in the {@code CertPath}. */ + /** @serial The type of {@code Certificate}s in the {@code CertPath}. */ private final String type; - /** The encoded form of the {@code CertPath}. */ + /** @serial The encoded form of the {@code CertPath}. */ private final byte[] data; /** diff --git a/src/java.base/share/classes/java/security/cert/Certificate.java b/src/java.base/share/classes/java/security/cert/Certificate.java index 1e212f644b358..618026c894d35 100644 --- a/src/java.base/share/classes/java/security/cert/Certificate.java +++ b/src/java.base/share/classes/java/security/cert/Certificate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -244,10 +244,10 @@ protected static class CertificateRep implements java.io.Serializable { @java.io.Serial private static final long serialVersionUID = -8563758940495660020L; - /** The standard name of the certificate type. */ + /** @serial The standard name of the certificate type. */ private final String type; - /** The certificate data. */ + /** @serial The certificate data. */ private final byte[] data; /** diff --git a/src/java.base/share/classes/java/text/DateFormat.java b/src/java.base/share/classes/java/text/DateFormat.java index e29b3f0509f80..af75628908675 100644 --- a/src/java.base/share/classes/java/text/DateFormat.java +++ b/src/java.base/share/classes/java/text/DateFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, 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 @@ -953,7 +953,7 @@ public static class Field extends Format.Field { private static final Field[] calendarToFieldMapping = new Field[Calendar.FIELD_COUNT]; - /** Calendar field. */ + /** @serial Calendar field. */ private int calendarField; /** diff --git a/src/java.base/share/classes/java/time/Duration.java b/src/java.base/share/classes/java/time/Duration.java index 402ecba772871..d640121f32ddb 100644 --- a/src/java.base/share/classes/java/time/Duration.java +++ b/src/java.base/share/classes/java/time/Duration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -158,11 +158,11 @@ private static class Lazy { } /** - * The number of seconds in the duration. + * @serial The number of seconds in the duration. */ private final long seconds; /** - * The number of nanoseconds in the duration, expressed as a fraction of the + * @serial The number of nanoseconds in the duration, expressed as a fraction of the * number of seconds. This is always positive, and never exceeds 999,999,999. */ private final int nanos; diff --git a/src/java.base/share/classes/java/time/Instant.java b/src/java.base/share/classes/java/time/Instant.java index 05358cc4f3cca..82ff18c142112 100644 --- a/src/java.base/share/classes/java/time/Instant.java +++ b/src/java.base/share/classes/java/time/Instant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -252,11 +252,11 @@ public final class Instant private static final long serialVersionUID = -665713676816604388L; /** - * The number of seconds from the epoch of 1970-01-01T00:00:00Z. + * @serial The number of seconds from the epoch of 1970-01-01T00:00:00Z. */ private final long seconds; /** - * The number of nanoseconds, later along the time-line, from the seconds field. + * @serial The number of nanoseconds, later along the time-line, from the seconds field. * This is always positive, and never exceeds 999,999,999. */ private final int nanos; diff --git a/src/java.base/share/classes/java/time/LocalDate.java b/src/java.base/share/classes/java/time/LocalDate.java index 2d71fb1ceca54..caf6ccd664166 100644 --- a/src/java.base/share/classes/java/time/LocalDate.java +++ b/src/java.base/share/classes/java/time/LocalDate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -174,15 +174,15 @@ public final class LocalDate static final long DAYS_0000_TO_1970 = (DAYS_PER_CYCLE * 5L) - (30L * 365L + 7L); /** - * The year. + * @serial The year. */ private final int year; /** - * The month-of-year. + * @serial The month-of-year. */ private final short month; /** - * The day-of-month. + * @serial The day-of-month. */ private final short day; diff --git a/src/java.base/share/classes/java/time/LocalDateTime.java b/src/java.base/share/classes/java/time/LocalDateTime.java index cea9123258c6b..f8c814957dc3f 100644 --- a/src/java.base/share/classes/java/time/LocalDateTime.java +++ b/src/java.base/share/classes/java/time/LocalDateTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -158,11 +158,11 @@ public final class LocalDateTime private static final long serialVersionUID = 6207766400415563566L; /** - * The date part. + * @serial The date part. */ private final LocalDate date; /** - * The time part. + * @serial The time part. */ private final LocalTime time; diff --git a/src/java.base/share/classes/java/time/LocalTime.java b/src/java.base/share/classes/java/time/LocalTime.java index f28f8d3c5998a..06f408350caeb 100644 --- a/src/java.base/share/classes/java/time/LocalTime.java +++ b/src/java.base/share/classes/java/time/LocalTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -228,19 +228,19 @@ public final class LocalTime private static final long serialVersionUID = 6414437269572265201L; /** - * The hour. + * @serial The hour. */ private final byte hour; /** - * The minute. + * @serial The minute. */ private final byte minute; /** - * The second. + * @serial The second. */ private final byte second; /** - * The nanosecond. + * @serial The nanosecond. */ private final int nano; diff --git a/src/java.base/share/classes/java/time/MonthDay.java b/src/java.base/share/classes/java/time/MonthDay.java index acb3087a5e534..1de4fa84d3e54 100644 --- a/src/java.base/share/classes/java/time/MonthDay.java +++ b/src/java.base/share/classes/java/time/MonthDay.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -144,11 +144,11 @@ public final class MonthDay .toFormatter(); /** - * The month-of-year, not null. + * @serial The month-of-year, not null. */ private final int month; /** - * The day-of-month. + * @serial The day-of-month. */ private final int day; diff --git a/src/java.base/share/classes/java/time/OffsetDateTime.java b/src/java.base/share/classes/java/time/OffsetDateTime.java index fd8355e36cda5..6f7005b9fa447 100644 --- a/src/java.base/share/classes/java/time/OffsetDateTime.java +++ b/src/java.base/share/classes/java/time/OffsetDateTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -190,11 +190,11 @@ private static int compareInstant(OffsetDateTime datetime1, OffsetDateTime datet private static final long serialVersionUID = 2287754244819255394L; /** - * The local date-time. + * @serial The local date-time. */ private final LocalDateTime dateTime; /** - * The offset from UTC/Greenwich. + * @serial The offset from UTC/Greenwich. */ private final ZoneOffset offset; diff --git a/src/java.base/share/classes/java/time/OffsetTime.java b/src/java.base/share/classes/java/time/OffsetTime.java index 1f6feb4180fc5..ad9781e2459b3 100644 --- a/src/java.base/share/classes/java/time/OffsetTime.java +++ b/src/java.base/share/classes/java/time/OffsetTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -143,11 +143,11 @@ public final class OffsetTime private static final long serialVersionUID = 7264499704384272492L; /** - * The local date-time. + * @serial The local date-time. */ private final LocalTime time; /** - * The offset from UTC/Greenwich. + * @serial The offset from UTC/Greenwich. */ private final ZoneOffset offset; diff --git a/src/java.base/share/classes/java/time/Period.java b/src/java.base/share/classes/java/time/Period.java index 40cad4cac59ab..5ee80710edb4a 100644 --- a/src/java.base/share/classes/java/time/Period.java +++ b/src/java.base/share/classes/java/time/Period.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -155,15 +155,15 @@ public final class Period private static final List SUPPORTED_UNITS = List.of(YEARS, MONTHS, DAYS); /** - * The number of years. + * @serial The number of years. */ private final int years; /** - * The number of months. + * @serial The number of months. */ private final int months; /** - * The number of days. + * @serial The number of days. */ private final int days; diff --git a/src/java.base/share/classes/java/time/Year.java b/src/java.base/share/classes/java/time/Year.java index cdcaa390320e3..97264ab8c1cfe 100644 --- a/src/java.base/share/classes/java/time/Year.java +++ b/src/java.base/share/classes/java/time/Year.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -159,7 +159,7 @@ public final class Year .toFormatter(); /** - * The year being represented. + * @serial The year being represented. */ private final int year; diff --git a/src/java.base/share/classes/java/time/YearMonth.java b/src/java.base/share/classes/java/time/YearMonth.java index 201c01a21937f..8ad1172811fe6 100644 --- a/src/java.base/share/classes/java/time/YearMonth.java +++ b/src/java.base/share/classes/java/time/YearMonth.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -147,11 +147,11 @@ public final class YearMonth .toFormatter(); /** - * The year. + * @serial The year. */ private final int year; /** - * The month-of-year, not null. + * @serial The month-of-year, not null. */ private final int month; diff --git a/src/java.base/share/classes/java/time/ZoneOffset.java b/src/java.base/share/classes/java/time/ZoneOffset.java index 520a0e0b9a194..48f2a2ded22a2 100644 --- a/src/java.base/share/classes/java/time/ZoneOffset.java +++ b/src/java.base/share/classes/java/time/ZoneOffset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -163,7 +163,7 @@ public final class ZoneOffset public static final ZoneOffset MAX = ZoneOffset.ofTotalSeconds(MAX_SECONDS); /** - * The total offset in seconds. + * @serial The total offset in seconds. */ private final int totalSeconds; /** diff --git a/src/java.base/share/classes/java/time/ZonedDateTime.java b/src/java.base/share/classes/java/time/ZonedDateTime.java index b1426efc914a4..135d1a16ae705 100644 --- a/src/java.base/share/classes/java/time/ZonedDateTime.java +++ b/src/java.base/share/classes/java/time/ZonedDateTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -172,15 +172,15 @@ public final class ZonedDateTime private static final long serialVersionUID = -6260982410461394882L; /** - * The local date-time. + * @serial The local date-time. */ private final LocalDateTime dateTime; /** - * The offset from UTC/Greenwich. + * @serial The offset from UTC/Greenwich. */ private final ZoneOffset offset; /** - * The time-zone. + * @serial The time-zone. */ private final ZoneId zone; diff --git a/src/java.base/share/classes/java/time/format/DateTimeParseException.java b/src/java.base/share/classes/java/time/format/DateTimeParseException.java index e9dd56b02ff61..4bf69fdeb1292 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeParseException.java +++ b/src/java.base/share/classes/java/time/format/DateTimeParseException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -82,11 +82,11 @@ public class DateTimeParseException extends DateTimeException { private static final long serialVersionUID = 4304633501674722597L; /** - * The text that was being parsed. + * @serial The text that was being parsed. */ private final String parsedString; /** - * The error index in the text. + * @serial The error index in the text. */ private final int errorIndex; diff --git a/src/java.base/share/classes/java/time/temporal/ValueRange.java b/src/java.base/share/classes/java/time/temporal/ValueRange.java index 78a1342087730..442cf0a250912 100644 --- a/src/java.base/share/classes/java/time/temporal/ValueRange.java +++ b/src/java.base/share/classes/java/time/temporal/ValueRange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -96,19 +96,19 @@ public final class ValueRange implements Serializable { private static final long serialVersionUID = -7317881728594519368L; /** - * The smallest minimum value. + * @serial The smallest minimum value. */ private final long minSmallest; /** - * The largest minimum value. + * @serial The largest minimum value. */ private final long minLargest; /** - * The smallest maximum value. + * @serial The smallest maximum value. */ private final long maxSmallest; /** - * The largest maximum value. + * @serial The largest maximum value. */ private final long maxLargest; diff --git a/src/java.base/share/classes/java/time/temporal/WeekFields.java b/src/java.base/share/classes/java/time/temporal/WeekFields.java index 9b687017a36b4..bbad365553d0f 100644 --- a/src/java.base/share/classes/java/time/temporal/WeekFields.java +++ b/src/java.base/share/classes/java/time/temporal/WeekFields.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -247,11 +247,11 @@ public final class WeekFields implements Serializable { private static final long serialVersionUID = -1177360819670808121L; /** - * The first day-of-week. + * @serial The first day-of-week. */ private final DayOfWeek firstDayOfWeek; /** - * The minimal number of days in the first week. + * @serial The minimal number of days in the first week. */ private final int minimalDays; /** diff --git a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java index f5d27a0cae05f..1e358b9295d90 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java +++ b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -104,19 +104,19 @@ public final class ZoneOffsetTransition */ private static final long serialVersionUID = -6946044323557704546L; /** - * The transition epoch-second. + * @serial The transition epoch-second. */ private final long epochSecond; /** - * The local transition date-time at the transition. + * @serial The local transition date-time at the transition. */ private final LocalDateTime transition; /** - * The offset before transition. + * @serial The offset before transition. */ private final ZoneOffset offsetBefore; /** - * The offset after transition. + * @serial The offset after transition. */ private final ZoneOffset offsetAfter; diff --git a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java index 8eb232075fe30..129aae8c27f89 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java +++ b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -105,12 +105,12 @@ public final class ZoneOffsetTransitionRule implements Serializable { private static final long serialVersionUID = 6889046316657758795L; /** - * The month of the month-day of the first day of the cutover week. + * @serial The month of the month-day of the first day of the cutover week. * The actual date will be adjusted by the dowChange field. */ private final Month month; /** - * The day-of-month of the month-day of the cutover week. + * @serial The day-of-month of the month-day of the cutover week. * If positive, it is the start of the week where the cutover can occur. * If negative, it represents the end of the week where cutover can occur. * The value is the number of days from the end of the month, such that @@ -119,31 +119,31 @@ public final class ZoneOffsetTransitionRule implements Serializable { */ private final byte dom; /** - * The cutover day-of-week, null to retain the day-of-month. + * @serial The cutover day-of-week, null to retain the day-of-month. */ private final DayOfWeek dow; /** - * The cutover time in the 'before' offset. + * @serial The cutover time in the 'before' offset. */ private final LocalTime time; /** - * Whether the cutover time is midnight at the end of day. + * @serial Whether the cutover time is midnight at the end of day. */ private final boolean timeEndOfDay; /** - * The definition of how the local time should be interpreted. + * @serial The definition of how the local time should be interpreted. */ private final TimeDefinition timeDefinition; /** - * The standard offset at the cutover. + * @serial The standard offset at the cutover. */ private final ZoneOffset standardOffset; /** - * The offset before the cutover. + * @serial The offset before the cutover. */ private final ZoneOffset offsetBefore; /** - * The offset after the cutover. + * @serial The offset after the cutover. */ private final ZoneOffset offsetAfter; diff --git a/src/java.base/share/classes/java/time/zone/ZoneRules.java b/src/java.base/share/classes/java/time/zone/ZoneRules.java index 5945e801f1529..788c080fc175e 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneRules.java +++ b/src/java.base/share/classes/java/time/zone/ZoneRules.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -118,29 +118,29 @@ public final class ZoneRules implements Serializable { private static final int LAST_CACHED_YEAR = 2100; /** - * The transitions between standard offsets (epoch seconds), sorted. + * @serial The transitions between standard offsets (epoch seconds), sorted. */ private final long[] standardTransitions; /** - * The standard offsets. + * @serial The standard offsets. */ private final ZoneOffset[] standardOffsets; /** - * The transitions between instants (epoch seconds), sorted. + * @serial The transitions between instants (epoch seconds), sorted. */ private final long[] savingsInstantTransitions; /** - * The transitions between local date-times, sorted. + * @serial The transitions between local date-times, sorted. * This is a paired array, where the first entry is the start of the transition * and the second entry is the end of the transition. */ private final LocalDateTime[] savingsLocalTransitions; /** - * The wall offsets. + * @serial The wall offsets. */ private final ZoneOffset[] wallOffsets; /** - * The last rule. + * @serial The last rule. */ private final ZoneOffsetTransitionRule[] lastRules; /** diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index c5ea53e17db8e..7c0b4d9dd1bfd 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -587,8 +587,10 @@ public static class SimpleEntry @java.io.Serial private static final long serialVersionUID = -8499721149061103585L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final K key; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private V value; @@ -733,8 +735,10 @@ public static class SimpleImmutableEntry @java.io.Serial private static final long serialVersionUID = 7138329143949025153L; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final K key; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final V value; diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index 03fdf7a3c997c..657b8123ec56e 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -4189,6 +4189,7 @@ private static class ArrayList extends AbstractList { @java.io.Serial private static final long serialVersionUID = -2764017481108945198L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final E[] a; diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 4ec5756f71261..2afb94af1142b 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -1054,6 +1054,7 @@ static class UnmodifiableCollection implements Collection, Serializable { @java.io.Serial private static final long serialVersionUID = 1820017752578914078L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Collection c; @@ -1337,6 +1338,7 @@ static class UnmodifiableSortedSet implements SortedSet, Serializable { @java.io.Serial private static final long serialVersionUID = -4929149591599911165L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedSet ss; @@ -1419,7 +1421,7 @@ public EmptyNavigableSet() { new EmptyNavigableSet<>(); /** - * The instance we are protecting. + * @serial The instance we are protecting. */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableSet ns; @@ -1488,6 +1490,7 @@ static class UnmodifiableList extends UnmodifiableCollection @java.io.Serial private static final long serialVersionUID = -283967356065247728L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final List list; @@ -1641,6 +1644,7 @@ private static class UnmodifiableMap implements Map, Serializable { @java.io.Serial private static final long serialVersionUID = -1034234728574286014L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Map m; @@ -2068,6 +2072,7 @@ static class UnmodifiableSortedMap @java.io.Serial private static final long serialVersionUID = -8806743815996713206L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedMap sm; @@ -2149,7 +2154,7 @@ public NavigableSet navigableKeySet() new EmptyNavigableMap<>(); /** - * The instance we wrap and protect. + * @serial The instance we wrap and protect. */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableMap nm; @@ -2283,8 +2288,10 @@ static class SynchronizedCollection implements Collection, Serializable { @java.io.Serial private static final long serialVersionUID = 3053995032091335093L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Collection c; // Backing Collection + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Object mutex; // Object on which to synchronize @@ -2487,6 +2494,7 @@ static class SynchronizedSortedSet @java.io.Serial private static final long serialVersionUID = 8695801310862127406L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedSet ss; @@ -2583,6 +2591,7 @@ static class SynchronizedNavigableSet @java.io.Serial private static final long serialVersionUID = -5505529816273629798L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableSet ns; @@ -2694,6 +2703,7 @@ static class SynchronizedList @java.io.Serial private static final long serialVersionUID = -7754090372962971524L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final List list; @@ -2862,8 +2872,10 @@ private static class SynchronizedMap @java.io.Serial private static final long serialVersionUID = 1978198479659022715L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Map m; // Backing Map + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Object mutex; // Object on which to synchronize @@ -3061,6 +3073,7 @@ static class SynchronizedSortedMap @java.io.Serial private static final long serialVersionUID = -8798146769416483793L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedMap sm; @@ -3165,6 +3178,7 @@ static class SynchronizedNavigableMap @java.io.Serial private static final long serialVersionUID = 699392247599746807L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableMap nm; @@ -3345,8 +3359,10 @@ static class CheckedCollection implements Collection, Serializable { @java.io.Serial private static final long serialVersionUID = 1578914078182001775L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Collection c; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Class type; @@ -3403,6 +3419,7 @@ public void forEachRemaining(Consumer action) { public boolean add(E e) { return c.add(typeCheck(e)); } + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private E[] zeroLengthElementArray; // Lazily initialized @@ -3497,6 +3514,7 @@ static class CheckedQueue { @java.io.Serial private static final long serialVersionUID = 1433151992604707767L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Queue queue; @@ -3602,6 +3620,7 @@ static class CheckedSortedSet extends CheckedSet @java.io.Serial private static final long serialVersionUID = 1599911165492914959L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedSet ss; @@ -3667,6 +3686,7 @@ static class CheckedNavigableSet extends CheckedSortedSet @java.io.Serial private static final long serialVersionUID = -5429120189805438922L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableSet ns; @@ -3751,6 +3771,7 @@ static class CheckedList { @java.io.Serial private static final long serialVersionUID = 65247728283967356L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final List list; @@ -3901,10 +3922,13 @@ private static class CheckedMap @java.io.Serial private static final long serialVersionUID = 5742860141034234728L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Map m; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Class keyType; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Class valueType; @@ -4301,6 +4325,7 @@ static class CheckedSortedMap extends CheckedMap @java.io.Serial private static final long serialVersionUID = 1599671320688067438L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedMap sm; @@ -4377,6 +4402,7 @@ static class CheckedNavigableMap extends CheckedSortedMap @java.io.Serial private static final long serialVersionUID = -4852462692372534096L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableMap nm; @@ -5108,6 +5134,7 @@ private static class SingletonSet @java.io.Serial private static final long serialVersionUID = 3193687207550431679L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final E element; @@ -5163,6 +5190,7 @@ private static class SingletonList @java.io.Serial private static final long serialVersionUID = 3093736618740652951L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final E element; @@ -5233,8 +5261,10 @@ private static class SingletonMap @java.io.Serial private static final long serialVersionUID = -6979724477215052911L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final K k; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final V v; @@ -5373,7 +5403,9 @@ private static class CopiesList @java.io.Serial private static final long serialVersionUID = 2739099268398711800L; + /** @serial */ final int n; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final E element; @@ -5914,6 +5946,7 @@ public static Set newSetFromMap(Map map) { private static class SetFromMap extends AbstractSet implements Set, Serializable { + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Map m; // The backing map private transient Set s; // Its keySet @@ -6088,6 +6121,7 @@ static class AsLIFOQueue extends AbstractQueue implements Queue, Serializable { @java.io.Serial private static final long serialVersionUID = 1802017725587941708L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Deque q; AsLIFOQueue(Deque q) { this.q = q; } diff --git a/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java b/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java index ebeb3d5c44c0a..e84cd9d52e612 100644 --- a/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java +++ b/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -40,6 +40,7 @@ public non-sealed class DuplicateFormatFlagsException extends IllegalFormatExcep @java.io.Serial private static final long serialVersionUID = 18890531L; + /** @serial */ private String flags; /** diff --git a/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java b/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java index cca7b3eb55322..77d52c5e2ba6e 100644 --- a/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java +++ b/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -40,8 +40,10 @@ public non-sealed class FormatFlagsConversionMismatchException @java.io.Serial private static final long serialVersionUID = 19120414L; + /** @serial */ private String f; + /** @serial */ private char c; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java b/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java index 2f1803d220ecf..c928cd0a3d4c2 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -41,6 +41,7 @@ public non-sealed class IllegalFormatCodePointException extends IllegalFormatExc @java.io.Serial private static final long serialVersionUID = 19080630L; + /** @serial */ private int c; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatConversionException.java b/src/java.base/share/classes/java/util/IllegalFormatConversionException.java index 67237f63cdf20..3f2b4512dc6a9 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatConversionException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatConversionException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -40,7 +40,9 @@ public non-sealed class IllegalFormatConversionException extends IllegalFormatEx @java.io.Serial private static final long serialVersionUID = 17000126L; + /** @serial */ private char c; + /** @serial */ private Class arg; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java b/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java index 408fa1efa5c24..c0770b7153ced 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -39,6 +39,7 @@ public non-sealed class IllegalFormatFlagsException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 790824L; + /** @serial */ private String flags; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java b/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java index 4527953790c1d..dbfb712683faf 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -39,6 +39,7 @@ public non-sealed class IllegalFormatPrecisionException extends IllegalFormatExc @java.io.Serial private static final long serialVersionUID = 18711008L; + /** @serial */ private int p; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatWidthException.java b/src/java.base/share/classes/java/util/IllegalFormatWidthException.java index df8d59b9e812b..f22bc61a091fd 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatWidthException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatWidthException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -38,6 +38,7 @@ public non-sealed class IllegalFormatWidthException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 16660902L; + /** @serial */ private int w; /** diff --git a/src/java.base/share/classes/java/util/IllformedLocaleException.java b/src/java.base/share/classes/java/util/IllformedLocaleException.java index 47febaae0187e..f4cafe0a9433b 100644 --- a/src/java.base/share/classes/java/util/IllformedLocaleException.java +++ b/src/java.base/share/classes/java/util/IllformedLocaleException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ public class IllformedLocaleException extends RuntimeException { @java.io.Serial private static final long serialVersionUID = -5245986824925681401L; + /** @serial */ private int _errIdx = -1; /** diff --git a/src/java.base/share/classes/java/util/MissingFormatArgumentException.java b/src/java.base/share/classes/java/util/MissingFormatArgumentException.java index 6363566216bdb..42d15559415f3 100644 --- a/src/java.base/share/classes/java/util/MissingFormatArgumentException.java +++ b/src/java.base/share/classes/java/util/MissingFormatArgumentException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -41,6 +41,7 @@ public non-sealed class MissingFormatArgumentException extends IllegalFormatExce @java.io.Serial private static final long serialVersionUID = 19190115L; + /** @serial */ private String s; /** diff --git a/src/java.base/share/classes/java/util/MissingFormatWidthException.java b/src/java.base/share/classes/java/util/MissingFormatWidthException.java index b553a3876ac13..47f787a0c7b9c 100644 --- a/src/java.base/share/classes/java/util/MissingFormatWidthException.java +++ b/src/java.base/share/classes/java/util/MissingFormatWidthException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -39,6 +39,7 @@ public non-sealed class MissingFormatWidthException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 15560123L; + /** @serial */ private String s; /** diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index 332effeb44b69..bacce5ef97efb 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -103,12 +103,12 @@ public class PriorityQueue extends AbstractQueue transient Object[] queue; // non-private to simplify nested class access /** - * The number of elements in the priority queue. + * @serial The number of elements in the priority queue. */ int size; /** - * The comparator, or null if priority queue uses elements' + * @serial The comparator, or null if priority queue uses elements' * natural ordering. */ @SuppressWarnings("serial") // Conditionally serializable diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 1e61136bee408..ab565f371a94e 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -1656,12 +1656,12 @@ abstract static class NavigableSubMap extends AbstractMap @java.io.Serial private static final long serialVersionUID = -2102997345730753016L; /** - * The backing map. + * @serial The backing map. */ final TreeMap m; /** - * Endpoints are represented as triples (fromStart, lo, + * @serial Endpoints are represented as triples (fromStart, lo, * loInclusive) and (toEnd, hi, hiInclusive). If fromStart is * true, then the low (absolute) bound is the start of the * backing map, and the other values are ignored. Otherwise, @@ -1670,9 +1670,12 @@ abstract static class NavigableSubMap extends AbstractMap */ @SuppressWarnings("serial") // Conditionally serializable final K lo; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final K hi; + /** @serial */ final boolean fromStart, toEnd; + /** @serial */ final boolean loInclusive, hiInclusive; NavigableSubMap(TreeMap m, @@ -2288,6 +2291,7 @@ static final class DescendingSubMap extends NavigableSubMap { super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); } + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Comparator reverseComparator = Collections.reverseOrder(m.comparator); @@ -2376,9 +2380,12 @@ private class SubMap extends AbstractMap implements SortedMap, java.io.Serializable { @java.io.Serial private static final long serialVersionUID = -6520786458950516097L; + /** @serial */ private boolean fromStart = false, toEnd = false; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private K fromKey; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private K toKey; @java.io.Serial diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java index e334f7263e46f..db0dbe28802ca 100644 --- a/src/java.base/share/classes/java/util/UUID.java +++ b/src/java.base/share/classes/java/util/UUID.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -83,17 +83,13 @@ public final class UUID implements java.io.Serializable, Comparable { @java.io.Serial private static final long serialVersionUID = -4856846361193249489L; - /* - * The most significant 64 bits of this UUID. - * - * @serial + /** + * @serial The most significant 64 bits of this UUID. */ private final long mostSigBits; - /* - * The least significant 64 bits of this UUID. - * - * @serial + /** + * @serial The least significant 64 bits of this UUID. */ private final long leastSigBits; diff --git a/src/java.base/share/classes/java/util/UnknownFormatConversionException.java b/src/java.base/share/classes/java/util/UnknownFormatConversionException.java index 13d428e0b60f3..992d9106644d7 100644 --- a/src/java.base/share/classes/java/util/UnknownFormatConversionException.java +++ b/src/java.base/share/classes/java/util/UnknownFormatConversionException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -39,6 +39,7 @@ public non-sealed class UnknownFormatConversionException extends IllegalFormatEx @java.io.Serial private static final long serialVersionUID = 19060418L; + /** @serial */ private String s; /** diff --git a/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java b/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java index 93eaf85b389e2..bcd228b7d0fe2 100644 --- a/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java +++ b/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -39,6 +39,7 @@ public non-sealed class UnknownFormatFlagsException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 19370506L; + /** @serial */ private String flags; /** diff --git a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java index b16f3459601d0..854bf927464ff 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -100,17 +100,17 @@ public class ArrayBlockingQueue extends AbstractQueue */ private static final long serialVersionUID = -817911632652898426L; - /** The queued items */ + /** @serial The queued items */ @SuppressWarnings("serial") // Conditionally serializable final Object[] items; - /** items index for next take, poll, peek or remove */ + /** @serial items index for next take, poll, peek or remove */ int takeIndex; - /** items index for next put, offer, or add */ + /** @serial items index for next put, offer, or add */ int putIndex; - /** Number of elements in the queue */ + /** @serial Number of elements in the queue */ int count; /* @@ -118,14 +118,14 @@ public class ArrayBlockingQueue extends AbstractQueue * found in any textbook. */ - /** Main lock guarding all access */ + /** @serial Main lock guarding all access */ final ReentrantLock lock; - /** Condition for waiting takes */ + /** @serial Condition for waiting takes */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty; - /** Condition for waiting puts */ + /** @serial Condition for waiting puts */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notFull; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 53919011c6f17..0cabc63f36e3d 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -4611,6 +4611,7 @@ public final boolean retainAll(Collection c) { public static final class KeySetView extends CollectionView implements Set, java.io.Serializable { private static final long serialVersionUID = 7249069246763182397L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final V value; KeySetView(ConcurrentHashMap map, V value) { // non-public diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 6a60a2397ceef..bcfdd997102f7 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -2401,19 +2401,19 @@ static final class SubMap extends AbstractMap implements ConcurrentNavigableMap, Serializable { private static final long serialVersionUID = -7647078645895051609L; - /** Underlying map */ + /** @serial Underlying map */ final ConcurrentSkipListMap m; - /** lower bound key, or null if from start */ + /** @serial lower bound key, or null if from start */ @SuppressWarnings("serial") // Conditionally serializable private final K lo; - /** upper bound key, or null if to end */ + /** @serial upper bound key, or null if to end */ @SuppressWarnings("serial") // Conditionally serializable private final K hi; - /** inclusion flag for lo */ + /** @serial inclusion flag for lo */ private final boolean loInclusive; - /** inclusion flag for hi */ + /** @serial inclusion flag for hi */ private final boolean hiInclusive; - /** direction */ + /** @serial direction */ final boolean isDescending; // Lazily initialized view holders diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 0bcb7978e907d..649eaa563c7c1 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -99,7 +99,7 @@ public class ConcurrentSkipListSet private static final long serialVersionUID = -2479143111061671589L; /** - * The underlying map. Uses Boolean.TRUE as value for each + * @serial The underlying map. Uses Boolean.TRUE as value for each * element. This field is declared final for the sake of thread * safety, which entails some ugliness in clone(). */ diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java index ab48a44c97acf..cef1682b0b110 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -99,6 +99,7 @@ public class CopyOnWriteArraySet extends AbstractSet implements java.io.Serializable { private static final long serialVersionUID = 5457747651344034263L; + /** @serial */ private final CopyOnWriteArrayList al; /** diff --git a/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java b/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java index 7884a131ffb70..3ca7a5ab9c92c 100644 --- a/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java +++ b/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java @@ -427,9 +427,9 @@ public abstract class CountedCompleter extends ForkJoinTask { private static final long serialVersionUID = 5232453752276485070L; - /** This task's completer, or null if none */ + /** @serial This task's completer, or null if none */ final CountedCompleter completer; - /** The number of pending tasks until completion */ + /** @serial The number of pending tasks until completion */ volatile int pending; /** diff --git a/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java b/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java index 7c1e974aafa0b..6062a0f645595 100644 --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java @@ -278,6 +278,7 @@ final boolean casNext(Aux c, Aux v) { // used only in cancellation static final int UNCOMPENSATE = 1 << 16; // helpJoin sentinel // Fields + /** @serial */ volatile int status; // accessed directly by pool and workers private transient volatile Aux aux; // either waiters or thrown Exception diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java index 7b6523021dcb8..b22786a09f6be 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -152,17 +152,17 @@ static final class Node { /** Number of items in the deque */ private transient int count; - /** Maximum number of items in the deque */ + /** @serial Maximum number of items in the deque */ private final int capacity; - /** Main lock guarding all access */ + /** @serial Main lock guarding all access */ final ReentrantLock lock = new ReentrantLock(); - /** Condition for waiting takes */ + /** @serial Condition for waiting takes */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty = lock.newCondition(); - /** Condition for waiting puts */ + /** @serial Condition for waiting puts */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notFull = lock.newCondition(); diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java index a67be9a987de7..4f627d0ff5e6d 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -134,10 +134,10 @@ static class Node { Node(E x) { item = x; } } - /** The capacity bound, or Integer.MAX_VALUE if none */ + /** @serial The capacity bound, or Integer.MAX_VALUE if none */ private final int capacity; - /** Current number of elements */ + /** @serial Current number of elements */ private final AtomicInteger count = new AtomicInteger(); /** @@ -152,17 +152,17 @@ static class Node { */ private transient Node last; - /** Lock held by take, poll, etc */ + /** @serial Lock held by take, poll, etc */ private final ReentrantLock takeLock = new ReentrantLock(); - /** Wait queue for waiting takes */ + /** @serial Wait queue for waiting takes */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty = takeLock.newCondition(); - /** Lock held by put, offer, etc */ + /** @serial Lock held by put, offer, etc */ private final ReentrantLock putLock = new ReentrantLock(); - /** Wait queue for waiting puts */ + /** @serial Wait queue for waiting puts */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notFull = putLock.newCondition(); diff --git a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java index f51e356736dea..ebaecaa525d07 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -160,12 +160,12 @@ public class PriorityBlockingQueue extends AbstractQueue private transient Comparator comparator; /** - * Lock used for all public operations. + * @serial Lock used for all public operations. */ private final ReentrantLock lock = new ReentrantLock(); /** - * Condition for blocking when empty. + * @serial Condition for blocking when empty. */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty = lock.newCondition(); @@ -176,7 +176,7 @@ public class PriorityBlockingQueue extends AbstractQueue private transient volatile int allocationSpinLock; /** - * A plain PriorityQueue used only for serialization, + * @serial A plain PriorityQueue used only for serialization, * to maintain compatibility with previous versions * of this class. Non-null only during serialization/deserialization. */ diff --git a/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java b/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java index e143760bbc752..4760234c25e43 100644 --- a/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java +++ b/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java @@ -84,7 +84,7 @@ public abstract class RecursiveTask extends ForkJoinTask { public RecursiveTask() {} /** - * The result of the computation. + * @serial The result of the computation. */ @SuppressWarnings("serial") // Conditionally serializable V result; diff --git a/src/java.base/share/classes/java/util/concurrent/Semaphore.java b/src/java.base/share/classes/java/util/concurrent/Semaphore.java index 5c299659d6a3f..0e7a9ccc0b332 100644 --- a/src/java.base/share/classes/java/util/concurrent/Semaphore.java +++ b/src/java.base/share/classes/java/util/concurrent/Semaphore.java @@ -161,7 +161,7 @@ */ public class Semaphore implements java.io.Serializable { private static final long serialVersionUID = -3222578661600680210L; - /** All mechanics via AbstractQueuedSynchronizer subclass */ + /** @serial All mechanics via AbstractQueuedSynchronizer subclass */ private final Sync sync; /** diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index f5a2ce4d9b4cc..49efe5d5c2c0d 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -555,8 +555,11 @@ static class LifoWaitQueue extends WaitQueue { static class FifoWaitQueue extends WaitQueue { private static final long serialVersionUID = -3623113410248163686L; } + /** @serial */ private ReentrantLock qlock; + /** @serial */ private WaitQueue waitingProducers; + /** @serial */ private WaitQueue waitingConsumers; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java index fb171e9c1d99f..0cae4266b4201 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java @@ -55,6 +55,7 @@ public class AtomicBoolean implements java.io.Serializable { private static final VarHandle VALUE = MhUtil.findVarHandle( MethodHandles.lookup(), "value", int.class); + /** @serial */ private volatile int value; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java index 4ebd758ccc7a3..90b4791f05a09 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java @@ -63,6 +63,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value"); + /** @serial */ private volatile int value; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java index 7e253ead3354f..3757f30372f7b 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java @@ -51,6 +51,7 @@ public class AtomicIntegerArray implements java.io.Serializable { private static final long serialVersionUID = 2862133569453604235L; private static final VarHandle AA = MethodHandles.arrayElementVarHandle(int[].class); + /** @serial */ private final int[] array; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java index d0e50b0fda885..81c60305a2afb 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java @@ -63,6 +63,7 @@ public class AtomicLong extends Number implements java.io.Serializable { private static final long VALUE = U.objectFieldOffset(AtomicLong.class, "value"); + /** @serial */ private volatile long value; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java index 2145c79579971..1486b30964057 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java @@ -51,6 +51,7 @@ public class AtomicLongArray implements java.io.Serializable { private static final long serialVersionUID = -2308431214976778248L; private static final VarHandle AA = MethodHandles.arrayElementVarHandle(long[].class); + /** @serial */ private final long[] array; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java index 1d7268609d717..27df942134ce1 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java @@ -55,6 +55,7 @@ public class AtomicReference implements java.io.Serializable { private static final VarHandle VALUE = MhUtil.findVarHandle( MethodHandles.lookup(), "value", Object.class); + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private volatile V value; diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java index dbec6b81dd91e..ff4e9fa735552 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java @@ -55,6 +55,7 @@ public class AtomicReferenceArray implements java.io.Serializable { private static final long serialVersionUID = -6209656149925076980L; private static final VarHandle AA = MethodHandles.arrayElementVarHandle(Object[].class); + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Object[] array; // must have exact type Object[] diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java index eb837a0fd29ad..47da669acce65 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java @@ -84,8 +84,10 @@ public class DoubleAccumulator extends Striped64 implements Serializable { private static final long serialVersionUID = 7249069246863182397L; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final DoubleBinaryOperator function; + /** @serial */ private final long identity; // use long representation /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java index 0d48a686cf2a1..20e69a5f0ce1a 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java @@ -82,8 +82,10 @@ public class LongAccumulator extends Striped64 implements Serializable { private static final long serialVersionUID = 7249069246863182397L; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final LongBinaryOperator function; + /** @serial */ private final long identity; /** diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java index 95ac1b2e46fc2..bdb81f3cb60b8 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java @@ -152,7 +152,7 @@ public final boolean block() { private transient volatile Node tail; /** - * The synchronization state. + * @serial The synchronization state. */ private volatile long state; diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java index 6794bab3110b8..5d899ffb0c58d 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java @@ -532,7 +532,7 @@ public final boolean block() { private transient volatile Node tail; /** - * The synchronization state. + * @serial The synchronization state. */ private volatile int state; diff --git a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java index 3378ce3983aa1..d0ad4cae42881 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java @@ -108,7 +108,7 @@ */ public class ReentrantLock implements Lock, java.io.Serializable { private static final long serialVersionUID = 7373984872572414699L; - /** Synchronizer providing all implementation mechanics */ + /** @serial Synchronizer providing all implementation mechanics */ private final Sync sync; /** diff --git a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java index 517708e70f3f2..cc9b75a7e37e3 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java @@ -217,11 +217,11 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable { private static final long serialVersionUID = -6992448646407690164L; - /** Inner class providing readlock */ + /** @serial Inner class providing readlock */ private final ReentrantReadWriteLock.ReadLock readerLock; - /** Inner class providing writelock */ + /** @serial Inner class providing writelock */ private final ReentrantReadWriteLock.WriteLock writerLock; - /** Performs all synchronization mechanics */ + /** @serial Performs all synchronization mechanics */ final Sync sync; /** @@ -713,6 +713,7 @@ final boolean readerShouldBlock() { */ public static class ReadLock implements Lock, java.io.Serializable { private static final long serialVersionUID = -5992448646407690164L; + /** @serial */ private final Sync sync; /** @@ -927,6 +928,7 @@ public String toString() { */ public static class WriteLock implements Lock, java.io.Serializable { private static final long serialVersionUID = -4992448646407690164L; + /** @serial */ private final Sync sync; /** diff --git a/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java b/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java index 2b5da62f5bd96..578a97754df7e 100644 --- a/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java +++ b/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -38,8 +38,11 @@ public class PatternSyntaxException @java.io.Serial private static final long serialVersionUID = -3864639126226059218L; + /** @serial */ private final String desc; + /** @serial */ private final String pattern; + /** @serial */ private final int index; /** From 2801bc6bf3d5e7eff23be1a7501f7e64dda85f67 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Thu, 9 Jan 2025 12:02:25 +0000 Subject: [PATCH 071/286] 8346460: NotifyFramePop should return JVMTI_ERROR_DUPLICATE Reviewed-by: cjplummer, amenkov --- src/hotspot/share/prims/jvmti.xml | 3 +++ src/hotspot/share/prims/jvmtiEnvBase.cpp | 6 ++++- .../MethodExitTest/libMethodExitTest.cpp | 26 ++++++++++++------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/prims/jvmti.xml b/src/hotspot/share/prims/jvmti.xml index e8e127486ca63..b63dfdfedb1aa 100644 --- a/src/hotspot/share/prims/jvmti.xml +++ b/src/hotspot/share/prims/jvmti.xml @@ -3084,6 +3084,9 @@ err = (*jvmti)->Deallocate(jvmti, stack_info); Thread was not suspended and was not the current thread. + + There is already a frame pop event request at the specified depth. + diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp index debfc77c32ca7..ec269e60e1b56 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp @@ -1359,7 +1359,11 @@ JvmtiEnvBase::set_frame_pop(JvmtiThreadState* state, javaVFrame* jvf, jint depth } assert(jvf->frame_pointer() != nullptr, "frame pointer mustn't be null"); int frame_number = (int)get_frame_count(jvf); - state->env_thread_state((JvmtiEnvBase*)this)->set_frame_pop(frame_number); + JvmtiEnvThreadState* ets = state->env_thread_state(this); + if (ets->is_frame_pop(frame_number)) { + return JVMTI_ERROR_DUPLICATE; + } + ets->set_frame_pop(frame_number); return JVMTI_ERROR_NONE; } diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp b/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp index b7077b10c8135..f5e2b267a9f7c 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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 @@ -452,13 +452,25 @@ VirtualThreadMount(jvmtiEnv *jvmti, ...) { mname = get_method_name(jvmti, jni, method); cname = get_method_class_name(jvmti, jni, method); + print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadMount", ++vthread_mounted_count); + LOG("\nHit #%d: VirtualThreadMount #%d: enabling FramePop for method: %s::%s on virtual thread: %p\n", - brkptBreakpointHit, ++vthread_mounted_count, cname, mname, (void*)thread); + brkptBreakpointHit, vthread_mounted_count, cname, mname, (void*)thread); err = jvmti->NotifyFramePop(thread, 0); check_jvmti_status(jni, err, "VirtualThreadMount: error in JVMTI NotifyFramePop"); - print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadMount", vthread_mounted_count); + LOG("\nHit #%d: VirtualThreadMount #%d: enabling duplicated FramePop for method: %s::%s on virtual thread: %p\n", + brkptBreakpointHit, vthread_mounted_count, cname, mname, (void*)thread); + + err = jvmti->NotifyFramePop(thread, 0); + if (err == JVMTI_ERROR_DUPLICATE) { + LOG("NotifyFramePop at VirtualThreadUnmount event returned expected JVMTI_ERROR_DUPLICATE\n"); + } else { + LOG("Failed: NotifyFramePop at VirtualThreadUnmount returned %s(%d) instead of expected JVMTI_ERROR_DUPLICATE\n", + TranslateError(err), err); + jni->FatalError("NotifyFramePop error: expected error code JVMTI_ERROR_DUPLICATE"); + } // Test SetThreadLocalStorage for virtual thread. err = jvmti->SetThreadLocalStorage(thread, tls_data2); @@ -497,13 +509,7 @@ VirtualThreadUnmount(jvmtiEnv *jvmti, ...) { mname = get_method_name(jvmti, jni, method); cname = get_method_class_name(jvmti, jni, method); - LOG("\nHit #%d: VirtualThreadUnmount #%d: enabling FramePop for method: %s::%s on virtual thread: %p\n", - brkptBreakpointHit, ++vthread_unmounted_count, cname, mname, (void*)thread); - - err = jvmti->NotifyFramePop(thread, 0); - check_jvmti_status(jni, err, "VirtualThreadUnmount: error in JVMTI NotifyFramePop"); - - print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadUnmount", vthread_unmounted_count); + print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadUnmount", ++vthread_unmounted_count); deallocate(jvmti, jni, (void*)mname); deallocate(jvmti, jni, (void*)cname); From 3024a7384f0a1f5177792fa78e872b3053e19f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nordstr=C3=B6m?= Date: Thu, 9 Jan 2025 12:41:52 +0000 Subject: [PATCH 072/286] 8345782: Refining the cases that libjsig deprecation warning is issued Reviewed-by: dholmes, kevinw --- src/java.base/unix/native/libjsig/jsig.c | 23 ++++-- test/hotspot/jtreg/runtime/signal/README | 5 +- .../jtreg/runtime/signal/SigTestDriver.java | 72 +++++++++++++++---- 3 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/java.base/unix/native/libjsig/jsig.c b/src/java.base/unix/native/libjsig/jsig.c index ebb4d6989460e..5dfc56208c194 100644 --- a/src/java.base/unix/native/libjsig/jsig.c +++ b/src/java.base/unix/native/libjsig/jsig.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -47,6 +47,7 @@ #define MAX_SIGNALS NSIG static struct sigaction sact[MAX_SIGNALS]; /* saved signal handlers */ +static bool deprecated_usage[MAX_SIGNALS]; /* usage of signal/sigset */ static sigset_t jvmsigs; /* Signals used by jvm. */ @@ -69,6 +70,7 @@ static sigaction_t os_sigaction = 0; /* os's version of sigaction() */ static bool jvm_signal_installing = false; static bool jvm_signal_installed = false; +static bool warning_printed = false; static void signal_lock() { @@ -89,15 +91,20 @@ static void signal_unlock() { pthread_mutex_unlock(&mutex); } +static void print_deprecation_warning() { + if (!warning_printed) { + warning_printed = true; + fprintf(stderr, HOTSPOT_VM_DISTRO " VM warning: the use of signal() and sigset() " + "for signal chaining was deprecated in version 16.0 and will " + "be removed in a future release. Use sigaction() instead.\n"); + } +} + static sa_handler_t call_os_signal(int sig, sa_handler_t disp, bool is_sigset) { sa_handler_t res; if (os_signal == NULL) { - // Deprecation warning first time through - fprintf(stderr, HOTSPOT_VM_DISTRO " VM warning: the use of signal() and sigset() " - "for signal chaining was deprecated in version 16.0 and will " - "be removed in a future release. Use sigaction() instead.\n"); if (!is_sigset) { os_signal = (signal_function_t)dlsym(RTLD_NEXT, "signal"); } else { @@ -140,8 +147,11 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) { signal_lock(); + deprecated_usage[sig] = true; + sigused = sigismember(&jvmsigs, sig); if (jvm_signal_installed && sigused) { + print_deprecation_warning(); /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ if (is_sigset) { @@ -250,6 +260,9 @@ JNIEXPORT int sigaction(int sig, const struct sigaction *act, struct sigaction * * within the JVM_begin_signal_setting-JVM_end_signal_setting-window. There can be any number of non-modifying * calls, but they will only return the expected preexisting handler if executed before the modifying call. */ + if (deprecated_usage[sig] == true) { + print_deprecation_warning(); + } res = call_os_sigaction(sig, act, &oldAct); if (res == 0) { if (act != NULL) { diff --git a/test/hotspot/jtreg/runtime/signal/README b/test/hotspot/jtreg/runtime/signal/README index 7109a0bed5baf..d051bbd0ed067 100644 --- a/test/hotspot/jtreg/runtime/signal/README +++ b/test/hotspot/jtreg/runtime/signal/README @@ -1,4 +1,4 @@ -Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2008, 2025, 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 @@ -41,6 +41,9 @@ Also 2 different ways of setting signal handlers are tested: sigaction, sigset. For 'postpre' and 'postpro' libjsig.so is used to chain signal handlers behind VM installed ones. +When libjsig.so is used, the warning for deprecated usage of signal/sigset is checked. For this +purpose, all scenarios are also run once with libjsig preloaded. + => Current tests cover the following cases (don't count 'nojvm' scenario): 1. Support for pre-installed signal handlers when the HotSpot VM is created. 2. Support for signal handler installation after the HotSpot VM is created inside JNI code diff --git a/test/hotspot/jtreg/runtime/signal/SigTestDriver.java b/test/hotspot/jtreg/runtime/signal/SigTestDriver.java index f2b37af1c3931..58c8d40f09c2d 100644 --- a/test/hotspot/jtreg/runtime/signal/SigTestDriver.java +++ b/test/hotspot/jtreg/runtime/signal/SigTestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -91,12 +91,16 @@ public static void main(String[] args) { .subList(1, args.length); cmd.addAll(argList); + String failureMessage = null; boolean passed = true; for (String mode : new String[] {"sigset", "sigaction"}) { - for (String scenario : new String[] {"nojvm", "prepre", "prepost", "postpre", "postpost"}) { + // Scenarios postpre and postpost requires libjsig. + // The other scenarios are run with libjsig to validate the deprecation warning. + for (String scenario : new String[] {"nojvm", "prepre", "prepost", "postpre#libjsig", "postpost#libjsig", + "nojvm#libjsig", "prepre#libjsig", "prepost#libjsig", }) { cmd.set(modeIdx, mode); - cmd.set(scenarioIdx, scenario); + cmd.set(scenarioIdx, scenario.replace("#libjsig", "")); System.out.printf("START TESTING: SIGNAL = %s, MODE = %s, SCENARIO=%s%n", signame, mode, scenario); System.out.printf("Do execute: %s%n", cmd.toString()); @@ -105,12 +109,10 @@ public static void main(String[] args) { (x, y) -> y + File.pathSeparator + x); pb.environment().put("CLASSPATH", Utils.TEST_CLASS_PATH); - switch (scenario) { - case "postpre": - case "postpost": { - pb.environment().merge("LD_PRELOAD", libjsig().toString(), - (x, y) -> y + File.pathSeparator + x); - } + boolean useLibjsig = scenario.endsWith("#libjsig"); + if (useLibjsig) { + pb.environment().merge("LD_PRELOAD", libjsig().toString(), + (x, y) -> y + File.pathSeparator + x); } try { @@ -118,11 +120,35 @@ public static void main(String[] args) { oa.reportDiagnosticSummary(); int exitCode = oa.getExitValue(); if (exitCode == 0) { - System.out.println("PASSED with exit code 0"); + // Skip deprecation warning check on MacOSX (see JDK-8346381) + if (useLibjsig && !Platform.isOSX()) { + // verify that deprecation warning for sigset/signal is printed + // only in the correct scenarios + boolean deprecatedSigFunctionUsed = mode.equals("sigset"); + boolean jvmInvolved = !scenario.contains("nojvm"); + boolean warningPrinted = oa.contains("VM warning"); + boolean sigUsedByJVM = sigIsUsedByJVM(signame); + if (deprecatedSigFunctionUsed && jvmInvolved && sigUsedByJVM) { + if (!warningPrinted) { + failureMessage = "FAILED: Missing deprecation warning for mode " + mode + + ", scenario: "+ scenario + ", signal " + signame; + passed = false; + } + } else if (warningPrinted) { + failureMessage = "FAILED: Deprecation warning shouldn't be printed for mode " + mode + + ", scenario: "+ scenario + ", signal " + signame; + passed = false; + } + } else { + System.out.println("PASSED with exit code 0"); + } } else { - System.out.println("FAILED with exit code " + exitCode); + failureMessage = "FAILED with exit code " + exitCode; passed = false; } + if (!passed) { + System.out.println(failureMessage); + } } catch (Exception e) { throw new Error("execution failed", e); } @@ -130,7 +156,7 @@ public static void main(String[] args) { } if (!passed) { - throw new Error("test failed"); + throw new Error(failureMessage != null ? failureMessage : "test failed"); } } @@ -146,4 +172,26 @@ private static List vmargs() { private static Path libjsig() { return Platform.jvmLibDir().resolve(Platform.buildSharedLibraryName("jsig")); } + + /** + * Return true for the chainable signals that are used by the JVM. + * See src/hotspot/os/posix/signals_posix.cpp + * @param signame + * @return true if signal is used by JVM, false otherwise + */ + private static boolean sigIsUsedByJVM(String signame) { + switch(signame) { + case "SIGSEGV": + case "SIGPIPE": + case "SIGBUS": + case "SIGILL": + case "SIGFPE": + case "SIGXFSZ": + return true; + case "SIGTRAP": + return Platform.isPPC(); + default: + return false; + } + } } From 9c72dedd072e838d363d0eec364514584fd4e2e6 Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Thu, 9 Jan 2025 12:47:47 +0000 Subject: [PATCH 073/286] 8346036: Unnecessary Hashtable usage in javax.swing.text.html.parser.Entity Reviewed-by: aivanov, azvegint --- .../javax/swing/text/html/parser/Entity.java | 41 +++++++------------ 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java index 8631a6897a749..0b2a9b013afd4 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -25,13 +25,7 @@ package javax.swing.text.html.parser; -import java.util.Hashtable; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.CharArrayReader; -import java.net.URL; +import java.util.Map; /** * An entity is described in a DTD using the ENTITY construct. @@ -40,8 +34,7 @@ * @see DTD * @author Arthur van Hoff */ -public final -class Entity implements DTDConstants { +public final class Entity implements DTDConstants { /** * The name of the entity. */ @@ -117,20 +110,17 @@ public String getString() { return new String(data); } - - static Hashtable entityTypes = new Hashtable(); - - static { - entityTypes.put("PUBLIC", Integer.valueOf(PUBLIC)); - entityTypes.put("CDATA", Integer.valueOf(CDATA)); - entityTypes.put("SDATA", Integer.valueOf(SDATA)); - entityTypes.put("PI", Integer.valueOf(PI)); - entityTypes.put("STARTTAG", Integer.valueOf(STARTTAG)); - entityTypes.put("ENDTAG", Integer.valueOf(ENDTAG)); - entityTypes.put("MS", Integer.valueOf(MS)); - entityTypes.put("MD", Integer.valueOf(MD)); - entityTypes.put("SYSTEM", Integer.valueOf(SYSTEM)); - } + private static final Map entityTypes = Map.of( + "PUBLIC", PUBLIC, + "CDATA", CDATA, + "SDATA", SDATA, + "PI", PI, + "STARTTAG", STARTTAG, + "ENDTAG", ENDTAG, + "MS", MS, + "MD", MD, + "SYSTEM", SYSTEM + ); /** * Converts nm string to the corresponding @@ -144,7 +134,6 @@ public String getString() { * to "CDATA", if none exists */ public static int name2type(String nm) { - Integer i = entityTypes.get(nm); - return (i == null) ? CDATA : i.intValue(); + return entityTypes.getOrDefault(nm, CDATA); } } From f9b11332eccd8a8ffb4128308f442b209d07a3b1 Mon Sep 17 00:00:00 2001 From: Joachim Kern Date: Thu, 9 Jan 2025 14:24:12 +0000 Subject: [PATCH 074/286] 8346880: [aix] java/lang/ProcessHandle/InfoTest.java still fails: "reported cputime less than expected" Reviewed-by: mdoerr, clanger, mbaesken --- .../native/libjava/ProcessHandleImpl_aix.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c b/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c index 3568af24ce438..d2c63d3130822 100644 --- a/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c +++ b/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c @@ -162,7 +162,24 @@ jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, } pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t pid, jlong *total, jlong *start) { - return unix_getParentPidAndTimings(env, pid, total, start); + pid_t the_pid = pid; + struct procentry64 ProcessBuffer; + + if (getprocs64(&ProcessBuffer, sizeof(ProcessBuffer), NULL, sizeof(struct fdsinfo64), &the_pid, 1) <= 0) { + return -1; + } + + // Validate the pid before returning the info + if (kill(pid, 0) < 0) { + return -1; + } + + *total = ((ProcessBuffer.pi_ru.ru_utime.tv_sec + ProcessBuffer.pi_ru.ru_stime.tv_sec) * 1000000000L) + + ((ProcessBuffer.pi_ru.ru_utime.tv_usec + ProcessBuffer.pi_ru.ru_stime.tv_usec)); + + *start = ProcessBuffer.pi_start * (jlong)1000; + + return (pid_t) ProcessBuffer.pi_ppid; } void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { From cb9a98b31a464e683519df46796339c7cecd82ec Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Thu, 9 Jan 2025 14:46:13 +0000 Subject: [PATCH 075/286] 8347141: Several javac tests compile with an unnecessary -Xlint:-path flag Reviewed-by: vromero, darcy --- test/langtools/tools/javac/6304921/T6304921.java | 2 +- test/langtools/tools/javac/T5048776.java | 4 ++-- test/langtools/tools/javac/T6245591.java | 2 +- test/langtools/tools/javac/T6247324.java | 2 +- test/langtools/tools/javac/processing/TestWarnErrorCount.java | 4 ++-- test/langtools/tools/javac/warnings/DivZero.java | 2 +- test/langtools/tools/javac/warnings/FallThrough.java | 2 +- test/langtools/tools/javac/warnings/Unchecked.java | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/langtools/tools/javac/6304921/T6304921.java b/test/langtools/tools/javac/6304921/T6304921.java index 51967b6903374..feaf568ee90a9 100644 --- a/test/langtools/tools/javac/6304921/T6304921.java +++ b/test/langtools/tools/javac/6304921/T6304921.java @@ -1,7 +1,7 @@ /* * @test (important: no SCCS keywords to affect offsets in golden file.) /nodynamiccopyright/ * @bug 6304921 - * @compile/fail/ref=T6304921.out -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all,-path -Werror T6304921.java + * @compile/fail/ref=T6304921.out -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all -Werror T6304921.java */ import java.util.ArrayList; diff --git a/test/langtools/tools/javac/T5048776.java b/test/langtools/tools/javac/T5048776.java index ff3305a9b346c..30795020c5a9c 100644 --- a/test/langtools/tools/javac/T5048776.java +++ b/test/langtools/tools/javac/T5048776.java @@ -1,8 +1,8 @@ /* * @test /nodynamiccopyright/ * @bug 5048776 - * @compile/ref=T5048776a.out -XDrawDiagnostics T5048776.java - * @compile/ref=T5048776b.out -XDrawDiagnostics -Xlint:all,-path T5048776.java + * @compile/ref=T5048776a.out -XDrawDiagnostics T5048776.java + * @compile/ref=T5048776b.out -XDrawDiagnostics -Xlint:all T5048776.java */ class A1 { void foo(Object[] args) { } diff --git a/test/langtools/tools/javac/T6245591.java b/test/langtools/tools/javac/T6245591.java index 7e51e37eab880..8b190dfcdc14e 100644 --- a/test/langtools/tools/javac/T6245591.java +++ b/test/langtools/tools/javac/T6245591.java @@ -1,7 +1,7 @@ /* * @test /nodynamiccopyright/ * @bug 6245591 - * @compile/ref=T6245591.out -XDrawDiagnostics -Xlint:all,-path T6245591.java + * @compile/ref=T6245591.out -XDrawDiagnostics -Xlint:all T6245591.java */ enum Season { /** @deprecated */ diff --git a/test/langtools/tools/javac/T6247324.java b/test/langtools/tools/javac/T6247324.java index ae971350c4760..264827d6dc00e 100644 --- a/test/langtools/tools/javac/T6247324.java +++ b/test/langtools/tools/javac/T6247324.java @@ -1,7 +1,7 @@ /* * @test /nodynamiccopyright/ * @bug 6247324 - * @compile/fail/ref=T6247324.out -XDrawDiagnostics -Xlint -Xlint:-path T6247324.java + * @compile/fail/ref=T6247324.out -XDrawDiagnostics -Xlint T6247324.java */ class Pair { private X x; diff --git a/test/langtools/tools/javac/processing/TestWarnErrorCount.java b/test/langtools/tools/javac/processing/TestWarnErrorCount.java index 1ea2b803609c4..957bafdab7f17 100644 --- a/test/langtools/tools/javac/processing/TestWarnErrorCount.java +++ b/test/langtools/tools/javac/processing/TestWarnErrorCount.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 @@ -161,7 +161,7 @@ void test(ErrorKind ek, WarnKind mwk, WarnKind jwk) { "-d", testDir.getPath(), "-processor", myName, // "-XprintRounds", - "-Xlint:all,-path", + "-Xlint:all", "-AerrKind=" + ek, "-AmsgrWarnKind=" + mwk, "-AjavaWarnKind=" + jwk)); diff --git a/test/langtools/tools/javac/warnings/DivZero.java b/test/langtools/tools/javac/warnings/DivZero.java index 2a965f3fbaf2c..3df7db166d7a4 100644 --- a/test/langtools/tools/javac/warnings/DivZero.java +++ b/test/langtools/tools/javac/warnings/DivZero.java @@ -3,7 +3,7 @@ * @bug 4759494 4986256 * @compile/ref=DivZero.noLint.out -XDrawDiagnostics DivZero.java * @compile/ref=DivZero.lint.out -Xlint:divzero -XDrawDiagnostics DivZero.java - * @compile/ref=DivZero.lint.out -Xlint:all,-path -XDrawDiagnostics DivZero.java + * @compile/ref=DivZero.lint.out -Xlint:all -XDrawDiagnostics DivZero.java */ class DivZero diff --git a/test/langtools/tools/javac/warnings/FallThrough.java b/test/langtools/tools/javac/warnings/FallThrough.java index 6e5a5eb8bc914..6185c3e0df92f 100644 --- a/test/langtools/tools/javac/warnings/FallThrough.java +++ b/test/langtools/tools/javac/warnings/FallThrough.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @bug 4986256 * @compile/ref=FallThrough.noLint.out -XDrawDiagnostics FallThrough.java - * @compile/ref=FallThrough.lintAll.out -Xlint:all,-path -XDrawDiagnostics FallThrough.java + * @compile/ref=FallThrough.lintAll.out -Xlint:all -XDrawDiagnostics FallThrough.java * @compile/ref=FallThrough.lintFallThrough.out -Xlint:fallthrough -XDrawDiagnostics FallThrough.java */ diff --git a/test/langtools/tools/javac/warnings/Unchecked.java b/test/langtools/tools/javac/warnings/Unchecked.java index e64fd760a0764..7cd8cbfdfd049 100644 --- a/test/langtools/tools/javac/warnings/Unchecked.java +++ b/test/langtools/tools/javac/warnings/Unchecked.java @@ -3,7 +3,7 @@ * @bug 4986256 * @compile/ref=Unchecked.noLint.out -XDrawDiagnostics Unchecked.java * @compile/ref=Unchecked.lintUnchecked.out -Xlint:unchecked -XDrawDiagnostics Unchecked.java - * @compile/ref=Unchecked.lintAll.out -Xlint:all,-path -XDrawDiagnostics Unchecked.java + * @compile/ref=Unchecked.lintAll.out -Xlint:all -XDrawDiagnostics Unchecked.java */ import java.util.ArrayList; From 72f1114909854aaed5d190d1c74a98527600a0c2 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Thu, 9 Jan 2025 14:58:12 +0000 Subject: [PATCH 076/286] 8346705: SNI not sent with Java 22+ using java.net.http.HttpClient.Builder#sslParameters Reviewed-by: dfuchs, michaelm --- .../net/http/AbstractAsyncSSLConnection.java | 56 ++++- .../net/httpclient/HttpClientSNITest.java | 214 ++++++++++++++++++ .../test/lib/common/ServerNameMatcher.java | 10 + 3 files changed, 268 insertions(+), 12 deletions(-) create mode 100644 test/jdk/java/net/httpclient/HttpClientSNITest.java diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java b/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java index 7d583266bd3fd..20f727a99328e 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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,7 @@ package jdk.internal.net.http; import java.net.InetSocketAddress; +import java.net.http.HttpClient; import java.util.Arrays; import java.util.ArrayDeque; import java.util.List; @@ -75,7 +76,7 @@ abstract class AbstractAsyncSSLConnection extends HttpConnection ServerName serverName, int port, String[] alpn) { super(addr, client); - this.sniServerNames = formSNIServerNames(serverName); + this.sniServerNames = formSNIServerNames(serverName, client); SSLContext context = client.theSSLContext(); sslParameters = createSSLParameters(client, this.sniServerNames, alpn); Log.logParams(sslParameters); @@ -102,6 +103,20 @@ private static boolean contains(String[] rr, String target) { return false; } + /** + * Returns the {@link SSLParameters} to be used by the {@link SSLEngine} for this connection. + *

    + * The returned {@code SSLParameters} will have its {@link SNIServerName}s set to the given + * {@code sniServerNames}. If {@code alpn} is non-null then the returned {@code SSLParameters} + * will have its {@linkplain SSLParameters#getApplicationProtocols() application layer protocols} + * set to this value. All other parameters in the returned {@code SSLParameters} will be + * copied over from {@link HttpClient#sslParameters()} of the given {@code client}. + * + * @param client the HttpClient + * @param sniServerNames the SNIServerName(s) + * @param alpn the application layer protocols + * @return the SSLParameters to be set on the SSLEngine used by this connection. + */ private static SSLParameters createSSLParameters(HttpClientImpl client, List sniServerNames, String[] alpn) { @@ -132,22 +147,39 @@ private static SSLParameters createSSLParameters(HttpClientImpl client, return sslParameters; } - private static List formSNIServerNames(final ServerName serverName) { - if (serverName == null) { - return List.of(); - } - if (!serverName.isLiteral()) { - String name = serverName.name(); - if (name != null && name.length() > 0) { + /** + * Returns a list of {@link SNIServerName}s that are expected to be used to + * configure the {@link SSLEngine} used by this connection. + *

    + * The given {@code serverName} is given preference, and if it is not null and + * is not an IP address literal, then the returned list will contain only one + * {@code SNIServerName} formed out of the {@code serverName}. If {@code serverName} + * is null or is an IP address literal then the {@code SNIServerName}(s) + * configured through {@link HttpClient#sslParameters()} will be returned. If none have + * been configured, then an empty list is returned. + * + * @param serverName the {@link ServerName}, typically computed based on the request URI + * @param client the {@code HttpClient} + * @return a list of {@code SNIServerName}s to be used by the {@code SSLEngine} + * of this connection. + */ + private static List formSNIServerNames(final ServerName serverName, + final HttpClientImpl client) { + if (serverName != null && !serverName.isLiteral()) { + final String name = serverName.name(); + if (name != null && !name.isEmpty()) { return List.of(new SNIHostName(name)); } } - return List.of(); + // fallback on any SNIServerName(s) configured through HttpClient.sslParameters() + final SSLParameters clientSSLParams = client.sslParameters(); + final List clientConfigured = clientSSLParams.getServerNames(); + return clientConfigured != null ? clientConfigured : List.of(); } - private static SSLEngine createEngine(SSLContext context, String serverName, int port, + private static SSLEngine createEngine(SSLContext context, String peerHost, int port, SSLParameters sslParameters) { - SSLEngine engine = context.createSSLEngine(serverName, port); + SSLEngine engine = context.createSSLEngine(peerHost, port); engine.setUseClientMode(true); engine.setSSLParameters(sslParameters); diff --git a/test/jdk/java/net/httpclient/HttpClientSNITest.java b/test/jdk/java/net/httpclient/HttpClientSNITest.java new file mode 100644 index 0000000000000..1505a21659349 --- /dev/null +++ b/test/jdk/java/net/httpclient/HttpClientSNITest.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.util.List; + +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIMatcher; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; + +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsParameters; +import com.sun.net.httpserver.HttpsServer; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestExchange; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestHandler; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer; +import jdk.httpclient.test.lib.common.ServerNameMatcher; +import jdk.test.lib.net.SimpleSSLContext; +import jdk.test.lib.net.URIBuilder; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static java.nio.charset.StandardCharsets.US_ASCII; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/* + * @test + * @bug 8346705 + * @summary verify the behaviour of java.net.http.HttpClient + * when sending a Server Name Indication in the TLS + * connections that it establishes for the requests + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.net.URIBuilder + * @run junit HttpClientSNITest + */ +public class HttpClientSNITest { + private static final String RESP_BODY_TEXT = "hello world"; + + private static SSLContext sslContext; + + private static final class Handler implements HttpTestHandler { + + @Override + public void handle(final HttpTestExchange exch) throws IOException { + System.out.println("handling request " + exch.getRequestURI()); + final byte[] respBody = RESP_BODY_TEXT.getBytes(US_ASCII); + exch.sendResponseHeaders(200, respBody.length); + try (final OutputStream os = exch.getResponseBody()) { + os.write(respBody); + } + } + } + + @BeforeAll + static void beforeAll() throws Exception { + sslContext = new SimpleSSLContext().get(); + assertNotNull(sslContext, "could not create a SSLContext"); + } + + /* + * Creates and configures a HTTPS server with a SNIMatcher that + * expects a specific SNI name to be sent by the connection client. + * The test uses a HttpClient to issue a couple of requests with the URI having + * a IP address literal as the host. For one of the request, the HttpClient + * is configured with specific ServerName(s) through HttpClient.sslParameters() + * and for the other request, it isn't. + * The test then verifies that for such requests with a IP address literal as the host, + * the HttpClient sends across the ServerName(s) if any has been configured on the client. + */ + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testRequestToIPLiteralHost(final boolean sniConfiguredOnClient) throws Exception { + final String expectedSNI = "non-dns-resolvable.foo.bar.localhost"; + final ServerNameMatcher matcher = new ServerNameMatcher(expectedSNI); + final HttpTestServer server = createServer(matcher); + try { + final HttpClient.Builder builder = HttpClient.newBuilder().sslContext(sslContext); + if (sniConfiguredOnClient) { + final SSLParameters clientConfiguredSSLParams = new SSLParameters(); + clientConfiguredSSLParams.setServerNames(List.of(new SNIHostName(expectedSNI))); + builder.sslParameters(clientConfiguredSSLParams); + } + try (final HttpClient client = builder.build()) { + final String ipLiteral = InetAddress.getLoopbackAddress().getHostAddress(); + final URI reqURI = URIBuilder.newBuilder() + .host(ipLiteral) + .port(server.getAddress().getPort()) + .scheme("https") + .path("/") + .build(); + final HttpRequest req = HttpRequest.newBuilder(reqURI).build(); + System.out.println("issuing request " + reqURI); + final HttpResponse resp = client.send(req, BodyHandlers.ofString(US_ASCII)); + assertEquals(200, resp.statusCode(), "unexpected response status code"); + assertEquals(RESP_BODY_TEXT, resp.body(), "unexpected response body"); + if (sniConfiguredOnClient) { + assertTrue(matcher.wasInvoked(), "SNIMatcher wasn't invoked on the server"); + } else { + assertFalse(matcher.wasInvoked(), "SNIMatcher was unexpectedly invoked" + + " on the server"); + } + } + } finally { + System.out.println("stopping server " + server.getAddress()); + server.stop(); + } + } + + /* + * Creates and configures a HTTPS server with a SNIMatcher that + * expects a specific SNI name to be sent by the connection client. + * The test uses a HttpClient to issue a couple of requests with the URI having + * a hostname (i.e. not a IP address literal) as the host. For one of the request, + * the HttpClient is configured with specific ServerName(s) through + * HttpClient.sslParameters() and for the other request, it isn't. + * The test then verifies that for such requests with a hostname + * (i.e. not a IP address literal) in the request URI, + * the HttpClient never sends ServerName(s) that may have been configured on the + * client and instead it sends the hostname (from the request URI) as the ServerName + * for each of the request. + */ + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testRequestResolvedHostName(final boolean sniConfiguredOnClient) throws Exception { + final String resolvedHostName = InetAddress.getLoopbackAddress().getHostName(); + final String expectedSNI = resolvedHostName; + final ServerNameMatcher matcher = new ServerNameMatcher(expectedSNI); + final HttpTestServer server = createServer(matcher); + try { + final HttpClient.Builder builder = HttpClient.newBuilder().sslContext(sslContext); + if (sniConfiguredOnClient) { + final SSLParameters clientConfiguredSSLParams = new SSLParameters(); + clientConfiguredSSLParams.setServerNames(List.of(new SNIHostName("does-not-matter"))); + builder.sslParameters(clientConfiguredSSLParams); + } + try (final HttpClient client = builder.build()) { + final URI reqURI = URIBuilder.newBuilder() + .host(resolvedHostName) + .port(server.getAddress().getPort()) + .scheme("https") + .path("/") + .build(); + final HttpRequest req = HttpRequest.newBuilder(reqURI).build(); + System.out.println("issuing request " + reqURI); + final HttpResponse resp = client.send(req, BodyHandlers.ofString(US_ASCII)); + assertEquals(200, resp.statusCode(), "unexpected response status code"); + assertEquals(RESP_BODY_TEXT, resp.body(), "unexpected response body"); + assertTrue(matcher.wasInvoked(), "SNIMatcher wasn't invoked on the server"); + } + } finally { + System.out.println("stopping server " + server.getAddress()); + server.stop(); + } + } + + /* + * Creates a HttpsServer configured to use the given SNIMatcher + */ + private static HttpTestServer createServer(final SNIMatcher matcher) throws Exception { + final InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); + final int backlog = 0; + final HttpsServer httpsServer = HttpsServer.create(addr, backlog); + final HttpsConfigurator configurator = new HttpsConfigurator(sslContext) { + @Override + public void configure(final HttpsParameters params) { + final SSLParameters sslParameters = sslContext.getDefaultSSLParameters(); + // add the SNIMatcher + sslParameters.setSNIMatchers(List.of(matcher)); + params.setSSLParameters(sslParameters); + System.out.println("configured HttpsServer with SNIMatcher: " + matcher); + } + }; + httpsServer.setHttpsConfigurator(configurator); + final HttpTestServer server = HttpTestServer.of(httpsServer); + server.addHandler(new Handler(), "/"); + server.start(); + System.out.println("server started at " + server.getAddress()); + return server; + } +} diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java index 5e7a5790807ae..47353927e9cf2 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java @@ -58,6 +58,7 @@ public class ServerNameMatcher extends SNIMatcher { private final Logger debug; private final boolean attemptDNSResolution; private final Set recognizedSNINames; + private volatile boolean invoked; /** * Creates a ServerNameMatcher which recognizes the passed {@code recognizedSNIName} @@ -97,6 +98,7 @@ public ServerNameMatcher(final boolean attemptDNSResolution, */ @Override public boolean matches(final SNIServerName clientRequestedSNI) { + this.invoked = true; Objects.requireNonNull(clientRequestedSNI); if (!SNIHostName.class.isInstance(clientRequestedSNI)) { if (debug.on()) { @@ -128,6 +130,14 @@ public boolean matches(final SNIServerName clientRequestedSNI) { return false; } + /** + * @return true if the {@link #matches(SNIServerName)} method of this SNIMatcher instance + * was invoked at least once, false otherwise. + */ + public boolean wasInvoked() { + return this.invoked; + } + private boolean matchesAfterDNSResolution(final String clientRequestedSNI) { final InetAddress clientRequestedAddr; try { From 1ef77cdd51b91f6d6d3367444a37a3f0f2e4bc99 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 9 Jan 2025 15:26:38 +0000 Subject: [PATCH 077/286] 8347171: (dc) java/nio/channels/DatagramChannel/InterruptibleOrNot.java fails with virtual thread factory Reviewed-by: alanb, lmesnik --- .../java/nio/channels/DatagramChannel/InterruptibleOrNot.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java b/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java index 794ede84a924a..e6fde147bd9ba 100644 --- a/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java +++ b/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -47,6 +47,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.function.Executable; import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; public class InterruptibleOrNot { // DatagramChannel implementation class @@ -98,6 +99,7 @@ public void testInterruptDuringInterruptibleReceive() throws Exception { */ @Test public void testInterruptBeforeUninterruptibleReceive() throws Exception { + assumeFalse(Thread.currentThread().isVirtual()); try (DatagramChannel dc = boundDatagramChannel(false)) { ByteBuffer buf = ByteBuffer.allocate(100); onReceive(() -> { From 3bfa9521d5b7e702e842fe1297dbb2ed643f0b0a Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Thu, 9 Jan 2025 17:34:20 +0000 Subject: [PATCH 078/286] 8283795: Add TLSv1.3 and CNSA 1.0 algorithms to implementation requirements Reviewed-by: jnimeh --- .../classes/java/security/AlgorithmParameters.java | 11 +++++++++-- .../share/classes/java/security/KeyFactory.java | 3 +++ .../classes/java/security/KeyPairGenerator.java | 12 ++++++++---- .../share/classes/java/security/MessageDigest.java | 3 ++- .../share/classes/java/security/Signature.java | 10 +++++++++- src/java.base/share/classes/javax/crypto/Cipher.java | 3 ++- .../share/classes/javax/crypto/KeyAgreement.java | 7 +++++-- .../share/classes/javax/crypto/KeyGenerator.java | 3 ++- .../share/classes/javax/net/ssl/SSLContext.java | 5 +++-- 9 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/java.base/share/classes/java/security/AlgorithmParameters.java b/src/java.base/share/classes/java/security/AlgorithmParameters.java index 1fdb47077cf64..7747d642c20c1 100644 --- a/src/java.base/share/classes/java/security/AlgorithmParameters.java +++ b/src/java.base/share/classes/java/security/AlgorithmParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -48,12 +48,19 @@ * obtained via a call to {@code getEncoded}. * *

    Every implementation of the Java platform is required to support the - * following standard {@code AlgorithmParameters} algorithms: + * following standard {@code AlgorithmParameters} algorithms. For the "EC" + * algorithm, implementations must support the curves in parentheses. For the + * "RSASSA-PSS" algorithm, implementations must support the parameters in + * parentheses. *

      *
    • {@code AES}
    • + *
    • {@code ChaCha20-Poly1305}
    • *
    • {@code DESede}
    • *
    • {@code DiffieHellman}
    • *
    • {@code DSA}
    • + *
    • {@code EC} (secp256r1, secp384r1)
    • + *
    • {@code RSASSA-PSS} (MGF1 mask generation function and SHA-256 or SHA-384 + * hash algorithms)
    • *
    * These algorithms are described in the diff --git a/src/java.base/share/classes/java/security/KeyFactory.java b/src/java.base/share/classes/java/security/KeyFactory.java index 5a9394d283baa..7c51faf6aa2db 100644 --- a/src/java.base/share/classes/java/security/KeyFactory.java +++ b/src/java.base/share/classes/java/security/KeyFactory.java @@ -72,7 +72,10 @@ *
      *
    • {@code DiffieHellman}
    • *
    • {@code DSA}
    • + *
    • {@code EC}
    • *
    • {@code RSA}
    • + *
    • {@code RSASSA-PSS}
    • + *
    • {@code X25519}
    • *
    * These algorithms are described in the
    diff --git a/src/java.base/share/classes/java/security/KeyPairGenerator.java b/src/java.base/share/classes/java/security/KeyPairGenerator.java index 31c3d8d382fc1..3583248f81e6c 100644 --- a/src/java.base/share/classes/java/security/KeyPairGenerator.java +++ b/src/java.base/share/classes/java/security/KeyPairGenerator.java @@ -113,12 +113,16 @@ * supply their own implementations of key pair generators. * *

    Every implementation of the Java platform is required to support the - * following standard {@code KeyPairGenerator} algorithms and keysizes in - * parentheses: + * following standard {@code KeyPairGenerator} algorithms. For the "EC" + * algorithm, implementations must support the curves in parentheses. For other + * algorithms, implementations must support the key sizes in parentheses. *

      - *
    • {@code DiffieHellman} (1024, 2048, 4096)
    • + *
    • {@code DiffieHellman} (1024, 2048, 3072, 4096)
    • *
    • {@code DSA} (1024, 2048)
    • - *
    • {@code RSA} (1024, 2048, 4096)
    • + *
    • {@code EC} (secp256r1, secp384r1)
    • + *
    • {@code RSA} (1024, 2048, 3072, 4096)
    • + *
    • {@code RSASSA-PSS} (2048, 3072, 4096)
    • + *
    • {@code X25519}
    • *
    * These algorithms are described in the
    diff --git a/src/java.base/share/classes/java/security/MessageDigest.java b/src/java.base/share/classes/java/security/MessageDigest.java index 46455e184b013..f83c4ed6d3b8b 100644 --- a/src/java.base/share/classes/java/security/MessageDigest.java +++ b/src/java.base/share/classes/java/security/MessageDigest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -87,6 +87,7 @@ *
      *
    • {@code SHA-1}
    • *
    • {@code SHA-256}
    • + *
    • {@code SHA-384}
    • *
    * These algorithms are described in the
    diff --git a/src/java.base/share/classes/java/security/Signature.java b/src/java.base/share/classes/java/security/Signature.java index 482db8d401504..006188aac616a 100644 --- a/src/java.base/share/classes/java/security/Signature.java +++ b/src/java.base/share/classes/java/security/Signature.java @@ -100,12 +100,20 @@ * supply their own implementations of digital signature algorithms. * *

    Every implementation of the Java platform is required to support the - * following standard {@code Signature} algorithms: + * following standard {@code Signature} algorithms. For the "RSASSA-PSS" + * algorithm, implementations must support the parameters in parentheses. For + * the "SHA256withECDSA" and "SHA384withECDSA" algorithms, implementations must + * support the curves in parentheses. *

      + *
    • {@code RSASSA-PSS} (MGF1 mask generation function and SHA-256 or SHA-384 + * hash algorithms)
    • *
    • {@code SHA1withDSA}
    • *
    • {@code SHA256withDSA}
    • + *
    • {@code SHA256withECDSA} (secp256r1)
    • + *
    • {@code SHA384withECDSA} (secp384r1)
    • *
    • {@code SHA1withRSA}
    • *
    • {@code SHA256withRSA}
    • + *
    • {@code SHA384withRSA}
    • *
    * These algorithms are described in the
    diff --git a/src/java.base/share/classes/javax/crypto/Cipher.java b/src/java.base/share/classes/javax/crypto/Cipher.java index 2cfdcf5582359..8187f863b5c2a 100644 --- a/src/java.base/share/classes/javax/crypto/Cipher.java +++ b/src/java.base/share/classes/javax/crypto/Cipher.java @@ -148,7 +148,8 @@ *
  • {@code AES/CBC/PKCS5Padding} (128)
  • *
  • {@code AES/ECB/NoPadding} (128)
  • *
  • {@code AES/ECB/PKCS5Padding} (128)
  • - *
  • {@code AES/GCM/NoPadding} (128)
  • + *
  • {@code AES/GCM/NoPadding} (128, 256)
  • + *
  • {@code ChaCha20-Poly1305}
  • *
  • {@code DESede/CBC/NoPadding} (168)
  • *
  • {@code DESede/CBC/PKCS5Padding} (168)
  • *
  • {@code DESede/ECB/NoPadding} (168)
  • diff --git a/src/java.base/share/classes/javax/crypto/KeyAgreement.java b/src/java.base/share/classes/javax/crypto/KeyAgreement.java index 8a055b6d809e9..5e2ceb185aa5b 100644 --- a/src/java.base/share/classes/javax/crypto/KeyAgreement.java +++ b/src/java.base/share/classes/javax/crypto/KeyAgreement.java @@ -57,11 +57,14 @@ * specific or as specified by the standard key agreement algorithm. * *

    Every implementation of the Java platform is required to support the - * following standard {@code KeyAgreement} algorithm: + * following standard {@code KeyAgreement} algorithms. For the "ECDH" + * algorithm, implementations must support the curves in parentheses. *

      *
    • {@code DiffieHellman}
    • + *
    • {@code ECDH} (secp256r1, secp384r1)
    • + *
    • {@code X25519}
    • *
    - * This algorithm is described in the
    * KeyAgreement section of the * Java Security Standard Algorithm Names Specification. diff --git a/src/java.base/share/classes/javax/crypto/KeyGenerator.java b/src/java.base/share/classes/javax/crypto/KeyGenerator.java index 0826bf2adb56e..ad112e6ffebe7 100644 --- a/src/java.base/share/classes/javax/crypto/KeyGenerator.java +++ b/src/java.base/share/classes/javax/crypto/KeyGenerator.java @@ -96,7 +96,8 @@ * following standard {@code KeyGenerator} algorithms with the keysizes in * parentheses: *
      - *
    • {@code AES} (128)
    • + *
    • {@code AES} (128, 256)
    • + *
    • {@code ChaCha20}
    • *
    • {@code DESede} (168)
    • *
    • {@code HmacSHA1}
    • *
    • {@code HmacSHA256}
    • diff --git a/src/java.base/share/classes/javax/net/ssl/SSLContext.java b/src/java.base/share/classes/javax/net/ssl/SSLContext.java index 0c2087efa88d2..861c7645b733e 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLContext.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLContext.java @@ -39,11 +39,12 @@ * secure random bytes. * *

      Every implementation of the Java platform is required to support the - * following standard {@code SSLContext} protocol: + * following standard {@code SSLContext} protocols: *

        *
      • {@code TLSv1.2}
      • + *
      • {@code TLSv1.3}
      • *
      - * This protocol is described in the * SSLContext section of the * Java Security Standard Algorithm Names Specification. From 22f70a742abbf528340c133c4ed215b97b4a9717 Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Thu, 9 Jan 2025 17:36:15 +0000 Subject: [PATCH 079/286] 8321413: IllegalArgumentException: Code length outside the allowed range while creating a jlink image Reviewed-by: mchung --- .../jdk/tools/jlink/internal/Snippets.java | 464 ++++++++ .../plugins/ModuleDescriptorBuilder.java | 389 +++++++ .../internal/plugins/SystemModulesPlugin.java | 990 ++++-------------- test/jdk/tools/jlink/JLink20000Packages.java | 129 +++ test/jdk/tools/jlink/SnippetsTest.java | 271 +++++ 5 files changed, 1475 insertions(+), 768 deletions(-) create mode 100644 src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java create mode 100644 src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java create mode 100644 test/jdk/tools/jlink/JLink20000Packages.java create mode 100644 test/jdk/tools/jlink/SnippetsTest.java diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java new file mode 100644 index 0000000000000..d662e297f9a6b --- /dev/null +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java @@ -0,0 +1,464 @@ +/* + * 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. 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 jdk.tools.jlink.internal; + +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.CodeBuilder; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; + +import static java.lang.classfile.ClassFile.ACC_STATIC; +import java.lang.classfile.TypeKind; +import java.lang.constant.ConstantDesc; +import static java.lang.constant.ConstantDescs.CD_Integer; +import static java.lang.constant.ConstantDescs.CD_Object; +import static java.lang.constant.ConstantDescs.CD_Set; +import static java.lang.constant.ConstantDescs.CD_int; +import java.util.function.Function; + +public class Snippets { + /** + * Snippet of bytecodes + */ + @FunctionalInterface + public interface Snippet { + /** + * Emit the bytecode snippet to the CodeBuilder. + * + * @param cob The CodeBuilder + */ + void emit(CodeBuilder cob); + + /** + * Load a constant onto the operand stack. + */ + static Snippet loadConstant(T v) { + return cob -> cob.loadConstant(v); + } + + /** + * Load an enum constant onto the operand stack. + */ + static Snippet loadEnum(Enum e) { + var classDesc = e.getClass().describeConstable().get(); + return cob -> cob.getstatic(classDesc, e.name(), classDesc); + } + + /** + * Load an Integer, boxed int value onto the operand stack. + */ + static Snippet loadInteger(int value) { + return cob -> + cob.loadConstant(value) + .invokestatic(CD_Integer, "valueOf", MethodTypeDesc.of(CD_Integer, CD_int)); + } + + /** + * Build snippets each to process the corresponding element. + * @param elements The elements to be processed + * @param fn The snippet building function for a given element + * @return Snippets + */ + static Snippet[] buildAll(Collection elements, Function fn) { + return elements.stream() + .map(fn) + .toArray(Snippet[]::new); + } + } + + /** + * Describe an operand that can be load onto the operand stack. + * For example, an array of string can be described as a Loadable. + * + * @param classDesc The type of the operand + * @param load The snippet to load the operand onto the operand stack + */ + public record Loadable(ClassDesc classDesc, Snippet load) implements Snippet { + /** + * Generate the bytecode to load the Loadable onto the operand stack. + * @param cob The CodeBuilder to add the bytecode for loading + */ + @Override + public void emit(CodeBuilder cob) { + load.emit(cob); + } + } + + /** + * Build a snippet for an element with a given index. Typically used for elements in a + * collection to identify the specific element. + */ + @FunctionalInterface + public interface IndexedElementSnippetBuilder { + /** + * Build a snippet for the element at the index. + * @param element The element + * @param index The index of the element in the containing collection + * @return A snippet of bytecodes to process the element + */ + Snippet build(T element, int index); + + default Snippet[] buildAll(Collection elements) { + var loadElementSnippets = new ArrayList(elements.size()); + for (var element: elements) { + loadElementSnippets.add(build(element, loadElementSnippets.size())); + } + + assert(loadElementSnippets.size() == elements.size()); + return loadElementSnippets.toArray(Snippet[]::new); + } + } + + /** + * Some basic information about pagination. + * @param total The total count of elements + * @param pageSize the number or elements to be included in a page + */ + public static record PagingContext(int total, int pageSize) { + /** + * If the last page has less elements than given page size. + */ + public boolean isLastPagePartial() { + return (total % pageSize) != 0; + } + + /** + * The number of pages. + */ + public int pageCount() { + var pages = total / pageSize; + return isLastPagePartial() ? pages + 1 : pages; + } + + /** + * The number of elements in the last page. + */ + public int lastPageSize() { + if (total == 0) return 0; + var remaining = total % pageSize; + return remaining == 0 ? pageSize : remaining; + } + } + + /** + * Generate bytecodes for loading a collection of elements, support using pagination to avoid + * overloading the 64k code limit. + */ + public static abstract class CollectionSnippetBuilder { + /** + * Default page size of string array + */ + public static final int STRING_PAGE_SIZE = 8000; + + /** + * Default page size of enum array + */ + public static final int ENUM_PAGE_SIZE = 5000; + + /** + * Good enough for average ~30 bytes per element + */ + public static final int DEFAULT_PAGE_SIZE = 2000; + + /** + * Default threshold based on 15K code size on ~30 bytes per element + */ + protected static final int DEFAULT_THRESHOLD = 512; + + protected ClassDesc elementType; + protected ClassDesc ownerClassDesc; + protected ClassBuilder clb; + + // Default values, disable pagination by default + protected String methodNamePrefix = null; + protected int activatePagingThreshold = -1; + protected int pageSize = DEFAULT_PAGE_SIZE; + + /** + * @param elementType The element type + */ + protected CollectionSnippetBuilder(ClassDesc elementType) { + this.elementType = Objects.requireNonNull(elementType); + } + + /** + * Enable pagination if the count of elements is larger than the given threshold. + * + * @param methodNamePrefix The method name prefix for generated paging helper methods + * @param pageSize The page size + * @param threshold The element count to actiave the pagination + */ + public CollectionSnippetBuilder enablePagination(String methodNamePrefix, int pageSize, int threshold) { + return this.pageSize(pageSize) + .activatePagingThreshold(threshold) + .methodNamePrefix(methodNamePrefix); + } + + /** + * Enable pagination if the count of elements is larger than pageSize or DEFAULT_THRESHOLD + */ + public CollectionSnippetBuilder enablePagination(String methodNamePrefix, int pageSize) { + return enablePagination(methodNamePrefix, pageSize, Math.min(pageSize, DEFAULT_THRESHOLD)); + } + + /** + * Enable pagination if the count of elements is larger than pageSize or DEFAULT_THRESHOLD + * with page size DEFAULT_PAGE_SIZE. + */ + public CollectionSnippetBuilder enablePagination(String methodNamePrefix) { + return enablePagination(methodNamePrefix, DEFAULT_PAGE_SIZE, DEFAULT_THRESHOLD); + } + + /** + * Disable pagination. Generated bytecode will always try to construct the collection inline. + */ + public CollectionSnippetBuilder disablePagination() { + this.activatePagingThreshold = -1; + this.methodNamePrefix = null; + return this; + } + + /** + * Set the threshold of element count to enable pagination. + * + * @param activatePagingThreshold Use pagination methods if the count of elements is larger + * than the given value + */ + public CollectionSnippetBuilder activatePagingThreshold(int activatePagingThreshold) { + if (activatePagingThreshold <= 0) { + throw new IllegalArgumentException(); + } + this.activatePagingThreshold = activatePagingThreshold; + return this; + } + + /** + * Set the owner class host the pagination methods. + * + * @param ownerClassDesc The owner class for the pagination methods + */ + public CollectionSnippetBuilder ownerClassDesc(ClassDesc ownerClassDesc) { + this.ownerClassDesc = Objects.requireNonNull(ownerClassDesc); + return this; + } + + /** + * Set the method name prefix for the pagination methods. + * @param methodNamePrefix The method name prefix. Generated method will have the name of + * this value appended with page number + */ + public CollectionSnippetBuilder methodNamePrefix(String methodNamePrefix) { + this.methodNamePrefix = Objects.requireNonNull(methodNamePrefix); + if (methodNamePrefix.isBlank()) { + throw new IllegalArgumentException(); + } + return this; + } + + /** + * Set the page size. The max page size is STRING_PAGE_SIZE. + * @param pageSize The count of elements per page* + */ + public CollectionSnippetBuilder pageSize(int pageSize) { + // ldc is likely the smallest element snippet + if (pageSize <= 0 || pageSize > STRING_PAGE_SIZE) { + throw new IllegalArgumentException(); + } + + this.pageSize = pageSize; + return this; + } + + /** + * Set the class builder used to generate the pagination methods. + * + * This value must be set if pagination is needed, otherwise the build + * would lead to NullPointerException. + */ + public CollectionSnippetBuilder classBuilder(ClassBuilder clb) { + this.clb = Objects.requireNonNull(clb); + return this; + } + + protected boolean shouldPaginate(int length) { + return methodNamePrefix != null && activatePagingThreshold > 0 && length > activatePagingThreshold; + } + + /** + * Build the Loadable snippet to load the collection of elements onto + * the operand stack. When pagination is enabled and needed as the total + * count of elements is larger than the given threshold, missing + * required field will lead to NullPointerException. + * + * @param loadElementSnippets The array of Snippets used to load individual + * element in the collection. + * @return The Loadable snippet + * @throws NullPointerException + */ + abstract public Loadable build(Snippet[] loadElementSnippets); + } + + /** + * Generate bytecode to load an array of the given referene type onto the operand stack. + * + * The generated code will create an array inline, and then populate the array either inline or + * by invoking the first pagination method if pagination is activated. + * + * If pagination is activated, pagination methods are generated with the given ClassBuilder + * with method name formatted with the methodNamePrefix appended with page numberand. + * Each pagination method will assign value to the corresponding page and chain calling next page. + * + * Effectively as + * methodNamePrefix_0(new T[elements.size()]); + * + * where + * T[] methodNamePrefix_0(T[] ar) { + * ar[0] = elements[0]; + * ar[1] = elements[1]; + * ... + * ar[pageSize-1] = elements[pageSize - 1]; + * methodNamePrefix_1(ar); + * return ar; + * } + * and the last page will stop the chain and can be partial instead of full page size. + */ + public static class ArraySnippetBuilder extends CollectionSnippetBuilder { + final MethodTypeDesc MTD_PageHelper; + final ClassDesc classDesc; + Snippet[] loadElementSnippets; + + public ArraySnippetBuilder(ClassDesc elementType) { + super(elementType); + classDesc = elementType.arrayType(); + MTD_PageHelper = MethodTypeDesc.of(classDesc, classDesc); + } + + protected void fill(CodeBuilder cob, int fromIndex, int toIndex) { + for (var index = fromIndex; index < toIndex; index++) { + cob.dup() // arrayref + .loadConstant(index); + loadElementSnippets[index].emit(cob); // value + cob.aastore(); + } + } + + private void invokePageHelper(CodeBuilder cob) { + // Invoke the first page, which will call next page until fulfilled + cob.loadConstant(loadElementSnippets.length) + .anewarray(elementType) + .invokestatic(ownerClassDesc, methodNamePrefix + "_0", MTD_PageHelper); + } + + private void newArray(CodeBuilder cob) { + cob.loadConstant(loadElementSnippets.length) + .anewarray(elementType); + fill(cob, 0, loadElementSnippets.length); + } + + /** + * Generate helper methods to fill each page + */ + private void setupHelpers() { + Objects.requireNonNull(clb); + Objects.requireNonNull(methodNamePrefix); + Objects.requireNonNull(ownerClassDesc); + var lastPageNo = new PagingContext(loadElementSnippets.length, pageSize).pageCount() - 1; + for (int pageNo = 0; pageNo <= lastPageNo; pageNo++) { + genFillPageHelper(pageNo, pageNo < lastPageNo); + } + } + + // each helper function is T[] methodNamePrefix_{pageNo}(T[]) + // fill the page portion and chain calling to fill next page + private void genFillPageHelper(int pageNo, boolean hasNextPage) { + var fromIndex = pageSize * pageNo; + var toIndex = hasNextPage ? (fromIndex + pageSize) : loadElementSnippets.length; + clb.withMethodBody(methodNamePrefix + "_" + pageNo, + MTD_PageHelper, + ACC_STATIC, + cob -> { + cob.aload(0); // arrayref + fill(cob, fromIndex, toIndex); + if (hasNextPage) { + cob.invokestatic( + ownerClassDesc, + methodNamePrefix + "_" + (pageNo + 1), + MTD_PageHelper); + } + cob.return_(TypeKind.from(classDesc)); + }); + } + + @Override + public Loadable build(Snippet[] loadElementSnippets) { + this.loadElementSnippets = Objects.requireNonNull(loadElementSnippets); + if (shouldPaginate(loadElementSnippets.length)) { + setupHelpers(); + return new Loadable(classDesc, this::invokePageHelper); + } else { + return new Loadable(classDesc, this::newArray); + } + } + } + + /** + * Generate bytecodes to load a set onto the operand stack. + * + * The Set is constructed with Set::of method. When there are more than 2 + * elements in the set, an array is constructed. + */ + public static class SetSnippetBuilder extends ArraySnippetBuilder { + public SetSnippetBuilder(ClassDesc elementType) { + super(elementType); + } + + private void buildTinySet(CodeBuilder cob) { + for (var snippet: loadElementSnippets) { + snippet.emit(cob); + } + var mtdArgs = new ClassDesc[loadElementSnippets.length]; + Arrays.fill(mtdArgs, CD_Object); + cob.invokestatic(CD_Set, "of", MethodTypeDesc.of(CD_Set, mtdArgs), true); + } + + @Override + public Loadable build(Snippet[] loadElementSnippets) { + if (loadElementSnippets.length <= 2) { + this.loadElementSnippets = loadElementSnippets; + return new Loadable(CD_Set, this::buildTinySet); + } else { + var array = super.build(loadElementSnippets); + return new Loadable(CD_Set, cob -> { + array.emit(cob); + cob.invokestatic(CD_Set, "of", MethodTypeDesc.of(CD_Set, CD_Object.arrayType()), true); + }); + } + } + } +} \ No newline at end of file diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java new file mode 100644 index 0000000000000..dac50c861612e --- /dev/null +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2015, 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. 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 jdk.tools.jlink.internal.plugins; + +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.CodeBuilder; +import java.lang.constant.ClassDesc; +import static java.lang.constant.ConstantDescs.*; + +import java.lang.constant.MethodTypeDesc; +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleDescriptor.Exports; +import java.lang.module.ModuleDescriptor.Opens; +import java.lang.module.ModuleDescriptor.Provides; +import java.lang.module.ModuleDescriptor.Requires; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static jdk.tools.jlink.internal.Snippets.*; +import static jdk.tools.jlink.internal.Snippets.CollectionSnippetBuilder.STRING_PAGE_SIZE; + +import jdk.tools.jlink.internal.plugins.SystemModulesPlugin.ModuleInfo; +import jdk.tools.jlink.internal.plugins.SystemModulesPlugin.SystemModulesClassGenerator.DedupSnippets; + +/** + * Build a Snippet to load a ModuleDescriptor onto the operand stack. + */ +class ModuleDescriptorBuilder implements IndexedElementSnippetBuilder { + private static final ClassDesc CD_MODULE_DESCRIPTOR = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor"); + private static final ClassDesc CD_MODULE_BUILDER = + ClassDesc.ofInternalName("jdk/internal/module/Builder"); + + private final DedupSnippets dedupSnippets; + private final ClassDesc ownerClassDesc; + private final ClassBuilder clb; + + ModuleDescriptorBuilder(ClassBuilder clb, DedupSnippets dedupSnippets, ClassDesc ownerClassDesc) { + this.clb = clb; + this.dedupSnippets = dedupSnippets; + this.ownerClassDesc = ownerClassDesc; + } + + @Override + public Snippet build(ModuleInfo moduleInfo, int index) { + return new ModuleDescriptorSnippet(clb, moduleInfo.descriptor(), moduleInfo.packages(), index); + } + + class ModuleDescriptorSnippet implements Snippet { + static final ClassDesc CD_EXPORTS = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Exports"); + static final ClassDesc CD_OPENS = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Opens"); + static final ClassDesc CD_PROVIDES = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Provides"); + static final ClassDesc CD_REQUIRES = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Requires"); + + // method signature for static Builder::newExports, newOpens, + // newProvides, newRequires methods + static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING_SET = + MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String, CD_Set); + static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING = + MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String); + static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING_SET = + MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String, CD_Set); + static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING = + MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String); + static final MethodTypeDesc MTD_PROVIDES_STRING_LIST = + MethodTypeDesc.of(CD_PROVIDES, CD_String, CD_List); + static final MethodTypeDesc MTD_REQUIRES_SET_STRING = + MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String); + static final MethodTypeDesc MTD_REQUIRES_SET_STRING_STRING = + MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String, CD_String); + + // method signature for Builder instance methods that + // return this Builder instance + static final MethodTypeDesc MTD_EXPORTS_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_EXPORTS.arrayType()); + static final MethodTypeDesc MTD_OPENS_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_OPENS.arrayType()); + static final MethodTypeDesc MTD_PROVIDES_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_PROVIDES.arrayType()); + static final MethodTypeDesc MTD_REQUIRES_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_REQUIRES.arrayType()); + static final MethodTypeDesc MTD_SET = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_Set); + static final MethodTypeDesc MTD_STRING = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_String); + static final MethodTypeDesc MTD_BOOLEAN = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_boolean); + static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String); + static final MethodTypeDesc MTD_ModuleDescriptor_int = MethodTypeDesc.of(CD_MODULE_DESCRIPTOR, CD_int); + static final MethodTypeDesc MTD_List_ObjectArray = MethodTypeDesc.of(CD_List, CD_Object.arrayType()); + + final ModuleDescriptor md; + final int index; + final Snippet requiresArray; + final Snippet exportsArray; + final Snippet opensArray; + final Snippet providesArray; + final Snippet packagesSet; + + ModuleDescriptorSnippet(ClassBuilder clb, ModuleDescriptor md, Set packages, int index) { + if (md.isAutomatic()) { + throw new InternalError("linking automatic module is not supported"); + } + + this.md = md; + this.index = index; + requiresArray = buildRequiresArray(clb); + exportsArray = buildExportsArray(clb); + opensArray = buildOpensArray(clb); + providesArray = buildProvidesArray(clb); + packagesSet = buildPackagesSet(clb, packages); + } + + /* + * Invoke Builder.newRequires(Set mods, String mn, String compiledVersion) + * + * Set mods = ... + * Builder.newRequires(mods, mn, compiledVersion); + */ + Snippet loadRequire(Requires require) { + return cob -> { + dedupSnippets.requiresModifiersSets().get(require.modifiers()).emit(cob); + cob.loadConstant(require.name()); + if (require.compiledVersion().isPresent()) { + cob.loadConstant(require.compiledVersion().get().toString()) + .invokestatic(CD_MODULE_BUILDER, + "newRequires", + MTD_REQUIRES_SET_STRING_STRING); + } else { + cob.invokestatic(CD_MODULE_BUILDER, + "newRequires", + MTD_REQUIRES_SET_STRING); + } + }; + } + + private Snippet buildRequiresArray(ClassBuilder clb) { + return new ArraySnippetBuilder(CD_REQUIRES) + .enablePagination("module" + index + "Requires") + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .build(Snippet.buildAll(sorted(md.requires()), this::loadRequire)); + } + + /* + * Invoke + * Builder.newExports(Set ms, String pn, + * Set targets) + * or + * Builder.newExports(Set ms, String pn) + * + * ms = export.modifiers() + * pn = export.source() + * targets = export.targets() + */ + Snippet loadExports(Exports export) { + return cob -> { + dedupSnippets.exportsModifiersSets().get(export.modifiers()).emit(cob); + cob.loadConstant(export.source()); + var targets = export.targets(); + if (!targets.isEmpty()) { + dedupSnippets.stringSets().get(targets).emit(cob); + cob.invokestatic(CD_MODULE_BUILDER, + "newExports", + MTD_EXPORTS_MODIFIER_SET_STRING_SET); + } else { + cob.invokestatic(CD_MODULE_BUILDER, + "newExports", + MTD_EXPORTS_MODIFIER_SET_STRING); + } + }; + } + + private Snippet buildExportsArray(ClassBuilder clb) { + return new ArraySnippetBuilder(CD_EXPORTS) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Exports") + .build(Snippet.buildAll(sorted(md.exports()), this::loadExports)); + } + + /* + * Invoke + * Builder.newOpens(Set ms, String pn, + * Set targets) + * or + * Builder.newOpens(Set ms, String pn) + * + * ms = open.modifiers() + * pn = open.source() + * targets = open.targets() + * Builder.newOpens(mods, pn, targets); + */ + Snippet loadOpens(Opens open) { + return cob -> { + dedupSnippets.opensModifiersSets().get(open.modifiers()).emit(cob); + cob.loadConstant(open.source()); + var targets = open.targets(); + if (!targets.isEmpty()) { + dedupSnippets.stringSets().get(targets).emit(cob); + cob.invokestatic(CD_MODULE_BUILDER, + "newOpens", + MTD_OPENS_MODIFIER_SET_STRING_SET); + } else { + cob.invokestatic(CD_MODULE_BUILDER, + "newOpens", + MTD_OPENS_MODIFIER_SET_STRING); + } + }; + } + + private Snippet buildOpensArray(ClassBuilder clb) { + return new ArraySnippetBuilder(CD_OPENS) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Opens") + .build(Snippet.buildAll(sorted(md.opens()), this::loadOpens)); + } + + /* + * Invoke Builder.newProvides(String service, List providers) + * + * service = provide.service() + * providers = List.of(new String[] { provide.providers() } + * Builder.newProvides(service, providers); + */ + private Snippet loadProvides(ClassBuilder clb, Provides provide, int offset) { + return cob -> { + var providersArray = new ArraySnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Provider" + offset) + .pageSize(STRING_PAGE_SIZE) + .build(Snippet.buildAll(provide.providers(), Snippet::loadConstant)); + + cob.loadConstant(provide.service()); + providersArray.emit(cob); + cob.invokestatic(CD_List, + "of", + MTD_List_ObjectArray, + true) + .invokestatic(CD_MODULE_BUILDER, + "newProvides", + MTD_PROVIDES_STRING_LIST); + }; + } + + private Snippet buildProvidesArray(ClassBuilder clb) { + IndexedElementSnippetBuilder builder = (e, i) -> loadProvides(clb, e, i); + return new ArraySnippetBuilder(CD_PROVIDES) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Provides") + .build(builder.buildAll(md.provides())); + } + + private Snippet buildPackagesSet(ClassBuilder clb, Collection packages) { + return new SetSnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Packages") + .pageSize(STRING_PAGE_SIZE) + .build(Snippet.buildAll(sorted(packages), Snippet::loadConstant)); + } + + @Override + public void emit(CodeBuilder cob) { + // new jdk.internal.module.Builder + cob.new_(CD_MODULE_BUILDER) + .dup() + .loadConstant(md.name()) + .invokespecial(CD_MODULE_BUILDER, + INIT_NAME, + MTD_void_String); + if (md.isOpen()) { + setModuleBit(cob, "open", true); + } + if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC)) { + setModuleBit(cob, "synthetic", true); + } + if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED)) { + setModuleBit(cob, "mandated", true); + } + + // requires + requiresArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "requires", + MTD_REQUIRES_ARRAY); + + // exports + exportsArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "exports", + MTD_EXPORTS_ARRAY); + + // opens + opensArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "opens", + MTD_OPENS_ARRAY); + + // uses + dedupSnippets.stringSets().get(md.uses()).emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "uses", + MTD_SET); + + // provides + providesArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "provides", + MTD_PROVIDES_ARRAY); + + // all packages + packagesSet.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "packages", + MTD_SET); + + // version + md.version().ifPresent(v -> setModuleProperty(cob, "version", v.toString())); + + // main class + md.mainClass().ifPresent(cn -> setModuleProperty(cob, "mainClass", cn)); + + cob.loadConstant(md.hashCode()) + .invokevirtual(CD_MODULE_BUILDER, + "build", + MTD_ModuleDescriptor_int); + } + + /* + * Invoke Builder.(boolean value) + */ + void setModuleBit(CodeBuilder cob, String methodName, boolean value) { + cob.loadConstant(value ? 1 : 0) + .invokevirtual(CD_MODULE_BUILDER, + methodName, + MTD_BOOLEAN); + } + + void setModuleProperty(CodeBuilder cob, String methodName, String value) { + cob.loadConstant(value) + .invokevirtual(CD_MODULE_BUILDER, + methodName, + MTD_STRING); + } + } + + /** + * Returns a sorted copy of a collection. + * + * This is useful to ensure a deterministic iteration order. + * + * @return a sorted copy of the given collection. + */ + private static > List sorted(Collection c) { + var l = new ArrayList<>(c); + Collections.sort(l); + return l; + } +} \ No newline at end of file diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java index 1a9404b210d5e..1c126d7321c24 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.lang.constant.ClassDesc; -import java.lang.constant.ConstantDesc; import static java.lang.constant.ConstantDescs.*; import java.lang.constant.MethodTypeDesc; import java.lang.module.Configuration; @@ -38,7 +37,6 @@ import java.lang.module.ModuleDescriptor.Opens; import java.lang.module.ModuleDescriptor.Provides; import java.lang.module.ModuleDescriptor.Requires; -import java.lang.module.ModuleDescriptor.Version; import java.lang.module.ModuleFinder; import java.lang.module.ModuleReader; import java.lang.module.ModuleReference; @@ -46,7 +44,6 @@ import java.lang.reflect.ClassFileFormatVersion; import java.net.URI; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; @@ -60,7 +57,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import java.util.function.IntSupplier; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -78,15 +74,22 @@ import java.lang.classfile.ClassBuilder; import java.lang.classfile.ClassFile; import java.lang.classfile.TypeKind; -import static java.lang.classfile.ClassFile.*; import java.lang.classfile.CodeBuilder; +import java.nio.file.Files; +import java.nio.file.Path; + import jdk.tools.jlink.internal.ModuleSorter; import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; import jdk.tools.jlink.plugin.ResourcePoolBuilder; import jdk.tools.jlink.plugin.ResourcePoolEntry; +import static java.lang.classfile.ClassFile.*; +import static jdk.tools.jlink.internal.Snippets.*; +import static jdk.tools.jlink.internal.Snippets.CollectionSnippetBuilder.ENUM_PAGE_SIZE; +import static jdk.tools.jlink.internal.Snippets.CollectionSnippetBuilder.STRING_PAGE_SIZE; + /** * Jlink plugin to reconstitute module descriptors and other attributes for system * modules. The plugin generates implementations of SystemModules to avoid parsing @@ -329,6 +332,17 @@ private String genSystemModulesClass(List moduleInfos, SystemModulesClassGenerator generator = new SystemModulesClassGenerator(className, moduleInfos, moduleDescriptorsPerMethod); byte[] bytes = generator.genClassBytes(cf); + // Diagnosis help, can be removed + if (Boolean.parseBoolean(System.getProperty("jlink.dumpSystemModuleClass", "false"))) { + try { + var filePath = Path.of(className + ".class").toAbsolutePath(); + System.err.println("Write " + filePath.toString()); + Files.createDirectories(filePath.getParent()); + Files.write(filePath, bytes); + } catch (IOException ioe) { + ioe.printStackTrace(System.err); + } + } String rn = "/java.base/" + className + ".class"; ResourcePoolEntry e = ResourcePoolEntry.create(rn, bytes); out.add(e); @@ -513,14 +527,6 @@ byte[] getBytes() throws IOException { static class SystemModulesClassGenerator { private static final ClassDesc CD_MODULE_DESCRIPTOR = ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor"); - private static final ClassDesc CD_MODULE_BUILDER = - ClassDesc.ofInternalName("jdk/internal/module/Builder"); - private static final ClassDesc CD_REQUIRES_MODIFIER = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Requires$Modifier"); - private static final ClassDesc CD_EXPORTS_MODIFIER = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Exports$Modifier"); - private static final ClassDesc CD_OPENS_MODIFIER = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Opens$Modifier"); private static final ClassDesc CD_MODULE_TARGET = ClassDesc.ofInternalName("jdk/internal/module/ModuleTarget"); private static final ClassDesc CD_MODULE_HASHES = @@ -538,16 +544,12 @@ static class SystemModulesClassGenerator { private static final MethodTypeDesc MTD_Map = MethodTypeDesc.of(CD_Map); private static final MethodTypeDesc MTD_MapEntry_Object_Object = MethodTypeDesc.of(CD_Map_Entry, CD_Object, CD_Object); private static final MethodTypeDesc MTD_Map_MapEntryArray = MethodTypeDesc.of(CD_Map, CD_Map_Entry.arrayType()); - private static final MethodTypeDesc MTD_Set_ObjectArray = MethodTypeDesc.of(CD_Set, CD_Object.arrayType()); private static final int MAX_LOCAL_VARS = 256; - private final int MD_VAR = 1; // variable for ModuleDescriptor private final int MT_VAR = 1; // variable for ModuleTarget private final int MH_VAR = 1; // variable for ModuleHashes - private final int DEDUP_LIST_VAR = 2; - private final int BUILDER_VAR = 3; - private int nextLocalVar = 4; // index to next local variable + private final int BUILDER_VAR = 2; // name of class to generate private final ClassDesc classDesc; @@ -560,8 +562,8 @@ static class SystemModulesClassGenerator { // A builder to create one single Set instance for a given set of // names or modifiers to reduce the footprint // e.g. target modules of qualified exports - private final DedupSetBuilder dedupSetBuilder - = new DedupSetBuilder(this::getNextLocalVar); + private final DedupSetBuilder dedupSetBuilder; + private final ArrayList clinitSnippets = new ArrayList<>(); public SystemModulesClassGenerator(String className, List moduleInfos, @@ -569,13 +571,10 @@ public SystemModulesClassGenerator(String className, this.classDesc = ClassDesc.ofInternalName(className); this.moduleInfos = moduleInfos; this.moduleDescriptorsPerMethod = moduleDescriptorsPerMethod; + this.dedupSetBuilder = new DedupSetBuilder(this.classDesc); moduleInfos.forEach(mi -> dedups(mi.descriptor())); } - private int getNextLocalVar() { - return nextLocalVar++; - } - /* * Adds the given ModuleDescriptor to the system module list. * It performs link-time validation and prepares mapping from various @@ -636,6 +635,9 @@ public byte[] genClassBytes(Configuration cf) { // generate moduleReads genModuleReads(clb, cf); + + // generate static initializer + genClassInitializer(clb); }); } @@ -654,6 +656,19 @@ private void genConstructor(ClassBuilder clb) { .return_()); } + private void genClassInitializer(ClassBuilder clb) { + if (!clinitSnippets.isEmpty()) { + clb.withMethodBody( + CLASS_INIT_NAME, + MTD_void, + ACC_STATIC, + cob -> { + clinitSnippets.forEach(s -> s.emit(cob)); + cob.return_(); + }); + } + } + /** * Generate bytecode for hasSplitPackages method */ @@ -694,146 +709,25 @@ private void genIncubatorModules(ClassBuilder clb) { * Generate bytecode for moduleDescriptors method */ private void genModuleDescriptorsMethod(ClassBuilder clb) { - if (moduleInfos.size() <= moduleDescriptorsPerMethod) { - clb.withMethodBody( - "moduleDescriptors", - MTD_ModuleDescriptorArray, - ACC_PUBLIC, - cob -> { - cob.loadConstant(moduleInfos.size()) - .anewarray(CD_MODULE_DESCRIPTOR) - .astore(MD_VAR); - - for (int index = 0; index < moduleInfos.size(); index++) { - ModuleInfo minfo = moduleInfos.get(index); - new ModuleDescriptorBuilder(cob, - minfo.descriptor(), - minfo.packages(), - index).build(); - } - cob.aload(MD_VAR) - .areturn(); - }); - return; - } - + var dedupSets = dedupSetBuilder.build(clb); + dedupSets.cacheSetupSnippet().ifPresent(clinitSnippets::add); - // Split the module descriptors be created by multiple helper methods. - // Each helper method "subi" creates the maximum N number of module descriptors - // mi, m{i+1} ... - // to avoid exceeding the 64kb limit of method length. Then it will call - // "sub{i+1}" to creates the next batch of module descriptors m{i+n}, m{i+n+1}... - // and so on. During the construction of the module descriptors, the string sets and - // modifier sets are deduplicated (see SystemModulesClassGenerator.DedupSetBuilder) - // and cached in the locals. These locals are saved in an array list so - // that the helper method can restore the local variables that may be - // referenced by the bytecode generated for creating module descriptors. - // Pseudo code looks like this: - // - // void subi(ModuleDescriptor[] mdescs, ArrayList localvars) { - // // assign localvars to local variables - // var l3 = localvars.get(0); - // var l4 = localvars.get(1); - // : - // // fill mdescs[i] to mdescs[i+n-1] - // mdescs[i] = ... - // mdescs[i+1] = ... - // : - // // save new local variables added - // localvars.add(lx) - // localvars.add(l{x+1}) - // : - // sub{i+i}(mdescs, localvars); - // } - - List> splitModuleInfos = new ArrayList<>(); - List currentModuleInfos = null; - for (int index = 0; index < moduleInfos.size(); index++) { - if (index % moduleDescriptorsPerMethod == 0) { - currentModuleInfos = new ArrayList<>(); - splitModuleInfos.add(currentModuleInfos); - } - currentModuleInfos.add(moduleInfos.get(index)); - } - - String helperMethodNamePrefix = "sub"; - ClassDesc arrayListClassDesc = ClassDesc.ofInternalName("java/util/ArrayList"); + var converter = new ModuleDescriptorBuilder(clb, dedupSets, classDesc); + var elementSnippets = converter.buildAll(moduleInfos); + var moduleDescriptors = new ArraySnippetBuilder(CD_MODULE_DESCRIPTOR) + .classBuilder(clb) + .ownerClassDesc(classDesc) + .enablePagination("sub", moduleDescriptorsPerMethod) + .build(elementSnippets); clb.withMethodBody( "moduleDescriptors", MTD_ModuleDescriptorArray, ACC_PUBLIC, cob -> { - cob.loadConstant(moduleInfos.size()) - .anewarray(CD_MODULE_DESCRIPTOR) - .dup() - .astore(MD_VAR); - cob.new_(arrayListClassDesc) - .dup() - .loadConstant(moduleInfos.size()) - .invokespecial(arrayListClassDesc, INIT_NAME, MethodTypeDesc.of(CD_void, CD_int)) - .astore(DEDUP_LIST_VAR); - cob.aload(0) - .aload(MD_VAR) - .aload(DEDUP_LIST_VAR) - .invokevirtual( - this.classDesc, - helperMethodNamePrefix + "0", - MethodTypeDesc.of(CD_void, CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc) - ) - .areturn(); + moduleDescriptors.emit(cob); + cob.areturn(); }); - - int dedupVarStart = nextLocalVar; - for (int n = 0, count = 0; n < splitModuleInfos.size(); count += splitModuleInfos.get(n).size(), n++) { - int index = n; // the index of which ModuleInfo being processed in the current batch - int start = count; // the start index to the return ModuleDescriptor array for the current batch - int curDedupVar = nextLocalVar; - clb.withMethodBody( - helperMethodNamePrefix + index, - MethodTypeDesc.of(CD_void, CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc), - ACC_PUBLIC, - cob -> { - if (curDedupVar > dedupVarStart) { - for (int i = dedupVarStart; i < curDedupVar; i++) { - cob.aload(DEDUP_LIST_VAR) - .loadConstant(i - dedupVarStart) - .invokevirtual(arrayListClassDesc, "get", MethodTypeDesc.of(CD_Object, CD_int)) - .astore(i); - } - } - - List currentBatch = splitModuleInfos.get(index); - for (int j = 0; j < currentBatch.size(); j++) { - ModuleInfo minfo = currentBatch.get(j); - new ModuleDescriptorBuilder(cob, - minfo.descriptor(), - minfo.packages(), - start + j).build(); - } - - if (index < splitModuleInfos.size() - 1) { - if (nextLocalVar > curDedupVar) { - for (int i = curDedupVar; i < nextLocalVar; i++) { - cob.aload(DEDUP_LIST_VAR) - .aload(i) - .invokevirtual(arrayListClassDesc, "add", MethodTypeDesc.of(CD_boolean, CD_Object)) - .pop(); - } - } - cob.aload(0) - .aload(MD_VAR) - .aload(DEDUP_LIST_VAR) - .invokevirtual( - this.classDesc, - helperMethodNamePrefix + (index+1), - MethodTypeDesc.of(CD_void, CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc) - ); - } - - cob.return_(); - }); - } } /** @@ -977,6 +871,7 @@ private void generate(ClassBuilder clb, // map of Set -> local Map, Integer> locals; + int setBuilt = 0; // generate code to create the sets that are duplicated if (dedup) { @@ -988,7 +883,7 @@ private void generate(ClassBuilder clb, locals = new HashMap<>(); int index = 1; for (Set s : duplicateSets) { - genImmutableSet(cob, s); + genImmutableSet(clb, cob, s, methodName + setBuilt++); cob.astore(index); locals.put(s, index); if (++index >= MAX_LOCAL_VARS) { @@ -1015,7 +910,7 @@ private void generate(ClassBuilder clb, // if de-duplicated then load the local, otherwise generate code Integer varIndex = locals.get(s); if (varIndex == null) { - genImmutableSet(cob, s); + genImmutableSet(clb, cob, s, methodName + setBuilt++); } else { cob.aload(varIndex); } @@ -1040,449 +935,14 @@ private void generate(ClassBuilder clb, /** * Generate code to generate an immutable set. */ - private void genImmutableSet(CodeBuilder cob, Set set) { - int size = set.size(); - - // use Set.of(Object[]) when there are more than 2 elements - // use Set.of(Object) or Set.of(Object, Object) when fewer - if (size > 2) { - cob.loadConstant(size) - .anewarray(CD_String); - int i = 0; - for (String element : sorted(set)) { - cob.dup() - .loadConstant(i) - .loadConstant(element) - .aastore(); - i++; - } - cob.invokestatic(CD_Set, - "of", - MTD_Set_ObjectArray, - true); - } else { - for (String element : sorted(set)) { - cob.loadConstant(element); - } - var mtdArgs = new ClassDesc[size]; - Arrays.fill(mtdArgs, CD_Object); - cob.invokestatic(CD_Set, - "of", - MethodTypeDesc.of(CD_Set, mtdArgs), - true); - } - } - - class ModuleDescriptorBuilder { - static final ClassDesc CD_EXPORTS = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Exports"); - static final ClassDesc CD_OPENS = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Opens"); - static final ClassDesc CD_PROVIDES = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Provides"); - static final ClassDesc CD_REQUIRES = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Requires"); - - // method signature for static Builder::newExports, newOpens, - // newProvides, newRequires methods - static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING_SET = - MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String, CD_Set); - static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING = - MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String); - static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING_SET = - MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String, CD_Set); - static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING = - MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String); - static final MethodTypeDesc MTD_PROVIDES_STRING_LIST = - MethodTypeDesc.of(CD_PROVIDES, CD_String, CD_List); - static final MethodTypeDesc MTD_REQUIRES_SET_STRING = - MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String); - static final MethodTypeDesc MTD_REQUIRES_SET_STRING_STRING = - MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String, CD_String); - - // method signature for Builder instance methods that - // return this Builder instance - static final MethodTypeDesc MTD_EXPORTS_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_EXPORTS.arrayType()); - static final MethodTypeDesc MTD_OPENS_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_OPENS.arrayType()); - static final MethodTypeDesc MTD_PROVIDES_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_PROVIDES.arrayType()); - static final MethodTypeDesc MTD_REQUIRES_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_REQUIRES.arrayType()); - static final MethodTypeDesc MTD_SET = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_Set); - static final MethodTypeDesc MTD_STRING = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_String); - static final MethodTypeDesc MTD_BOOLEAN = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_boolean); - static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String); - static final MethodTypeDesc MTD_ModuleDescriptor_int = MethodTypeDesc.of(CD_MODULE_DESCRIPTOR, CD_int); - static final MethodTypeDesc MTD_List_ObjectArray = MethodTypeDesc.of(CD_List, CD_Object.arrayType()); - - final CodeBuilder cob; - final ModuleDescriptor md; - final Set packages; - final int index; - - ModuleDescriptorBuilder(CodeBuilder cob, ModuleDescriptor md, Set packages, int index) { - if (md.isAutomatic()) { - throw new InternalError("linking automatic module is not supported"); - } - this.cob = cob; - this.md = md; - this.packages = packages; - this.index = index; - } - - void build() { - // new jdk.internal.module.Builder - newBuilder(); - - // requires - requires(md.requires()); - - // exports - exports(md.exports()); - - // opens - opens(md.opens()); - - // uses - uses(md.uses()); - - // provides - provides(md.provides()); - - // all packages - packages(packages); - - // version - md.version().ifPresent(this::version); - - // main class - md.mainClass().ifPresent(this::mainClass); - - putModuleDescriptor(); - } - - void newBuilder() { - cob.new_(CD_MODULE_BUILDER) - .dup() - .loadConstant(md.name()) - .invokespecial(CD_MODULE_BUILDER, - INIT_NAME, - MTD_void_String) - .astore(BUILDER_VAR); - - if (md.isOpen()) { - setModuleBit("open", true); - } - if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC)) { - setModuleBit("synthetic", true); - } - if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED)) { - setModuleBit("mandated", true); - } - } - - /* - * Invoke Builder.(boolean value) - */ - void setModuleBit(String methodName, boolean value) { - cob.aload(BUILDER_VAR) - .loadConstant(value ? 1 : 0) - .invokevirtual(CD_MODULE_BUILDER, - methodName, - MTD_BOOLEAN) - .pop(); - } - - /* - * Put ModuleDescriptor into the modules array - */ - void putModuleDescriptor() { - cob.aload(MD_VAR) - .loadConstant(index) - .aload(BUILDER_VAR) - .loadConstant(md.hashCode()) - .invokevirtual(CD_MODULE_BUILDER, - "build", - MTD_ModuleDescriptor_int) - .aastore(); - } - - /* - * Call Builder::newRequires to create Requires instances and - * then pass it to the builder by calling: - * Builder.requires(Requires[]) - * - */ - void requires(Set requires) { - cob.aload(BUILDER_VAR) - .loadConstant(requires.size()) - .anewarray(CD_REQUIRES); - int arrayIndex = 0; - for (Requires require : sorted(requires)) { - String compiledVersion = null; - if (require.compiledVersion().isPresent()) { - compiledVersion = require.compiledVersion().get().toString(); - } - - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newRequires(require.modifiers(), require.name(), compiledVersion); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "requires", - MTD_REQUIRES_ARRAY) - .pop(); - } - - /* - * Invoke Builder.newRequires(Set mods, String mn, String compiledVersion) - * - * Set mods = ... - * Builder.newRequires(mods, mn, compiledVersion); - */ - void newRequires(Set mods, String name, String compiledVersion) { - int varIndex = dedupSetBuilder.indexOfRequiresModifiers(cob, mods); - cob.aload(varIndex) - .loadConstant(name); - if (compiledVersion != null) { - cob.loadConstant(compiledVersion) - .invokestatic(CD_MODULE_BUILDER, - "newRequires", - MTD_REQUIRES_SET_STRING_STRING); - } else { - cob.invokestatic(CD_MODULE_BUILDER, - "newRequires", - MTD_REQUIRES_SET_STRING); - } - } - - /* - * Call Builder::newExports to create Exports instances and - * then pass it to the builder by calling: - * Builder.exports(Exports[]) - * - */ - void exports(Set exports) { - cob.aload(BUILDER_VAR) - .loadConstant(exports.size()) - .anewarray(CD_EXPORTS); - int arrayIndex = 0; - for (Exports export : sorted(exports)) { - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newExports(export.modifiers(), export.source(), export.targets()); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "exports", - MTD_EXPORTS_ARRAY) - .pop(); - } - - /* - * Invoke - * Builder.newExports(Set ms, String pn, - * Set targets) - * or - * Builder.newExports(Set ms, String pn) - * - * Set targets = new HashSet<>(); - * targets.add(t); - * : - * : - * - * Set mods = ... - * Builder.newExports(mods, pn, targets); - */ - void newExports(Set ms, String pn, Set targets) { - int modifiersSetIndex = dedupSetBuilder.indexOfExportsModifiers(cob, ms); - if (!targets.isEmpty()) { - int stringSetIndex = dedupSetBuilder.indexOfStringSet(cob, targets); - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .aload(stringSetIndex) - .invokestatic(CD_MODULE_BUILDER, - "newExports", - MTD_EXPORTS_MODIFIER_SET_STRING_SET); - } else { - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .invokestatic(CD_MODULE_BUILDER, - "newExports", - MTD_EXPORTS_MODIFIER_SET_STRING); - } - } - - - /** - * Call Builder::newOpens to create Opens instances and - * then pass it to the builder by calling: - * Builder.opens(Opens[]) - */ - void opens(Set opens) { - cob.aload(BUILDER_VAR) - .loadConstant(opens.size()) - .anewarray(CD_OPENS); - int arrayIndex = 0; - for (Opens open : sorted(opens)) { - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newOpens(open.modifiers(), open.source(), open.targets()); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "opens", - MTD_OPENS_ARRAY) - .pop(); - } - - /* - * Invoke - * Builder.newOpens(Set ms, String pn, - * Set targets) - * or - * Builder.newOpens(Set ms, String pn) - * - * Set targets = new HashSet<>(); - * targets.add(t); - * : - * : - * - * Set mods = ... - * Builder.newOpens(mods, pn, targets); - */ - void newOpens(Set ms, String pn, Set targets) { - int modifiersSetIndex = dedupSetBuilder.indexOfOpensModifiers(cob, ms); - if (!targets.isEmpty()) { - int stringSetIndex = dedupSetBuilder.indexOfStringSet(cob, targets); - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .aload(stringSetIndex) - .invokestatic(CD_MODULE_BUILDER, - "newOpens", - MTD_OPENS_MODIFIER_SET_STRING_SET); - } else { - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .invokestatic(CD_MODULE_BUILDER, - "newOpens", - MTD_OPENS_MODIFIER_SET_STRING); - } - } - - /* - * Invoke Builder.uses(Set uses) - */ - void uses(Set uses) { - int varIndex = dedupSetBuilder.indexOfStringSet(cob, uses); - cob.aload(BUILDER_VAR) - .aload(varIndex) - .invokevirtual(CD_MODULE_BUILDER, - "uses", - MTD_SET) - .pop(); - } - - /* - * Call Builder::newProvides to create Provides instances and - * then pass it to the builder by calling: - * Builder.provides(Provides[] provides) - * - */ - void provides(Collection provides) { - cob.aload(BUILDER_VAR) - .loadConstant(provides.size()) - .anewarray(CD_PROVIDES); - int arrayIndex = 0; - for (Provides provide : sorted(provides)) { - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newProvides(provide.service(), provide.providers()); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "provides", - MTD_PROVIDES_ARRAY) - .pop(); - } - - /* - * Invoke Builder.newProvides(String service, Set providers) - * - * Set providers = new HashSet<>(); - * providers.add(impl); - * : - * : - * Builder.newProvides(service, providers); - */ - void newProvides(String service, List providers) { - cob.loadConstant(service) - .loadConstant(providers.size()) - .anewarray(CD_String); - int arrayIndex = 0; - for (String provider : providers) { - cob.dup() // arrayref - .loadConstant(arrayIndex++) - .loadConstant(provider) - .aastore(); - } - cob.invokestatic(CD_List, - "of", - MTD_List_ObjectArray, - true) - .invokestatic(CD_MODULE_BUILDER, - "newProvides", - MTD_PROVIDES_STRING_LIST); - } - - /* - * Invoke Builder.packages(String pn) - */ - void packages(Set packages) { - int varIndex = dedupSetBuilder.newStringSet(cob, packages); - cob.aload(BUILDER_VAR) - .aload(varIndex) - .invokevirtual(CD_MODULE_BUILDER, - "packages", - MTD_SET) - .pop(); - } - - /* - * Invoke Builder.mainClass(String cn) - */ - void mainClass(String cn) { - cob.aload(BUILDER_VAR) - .loadConstant(cn) - .invokevirtual(CD_MODULE_BUILDER, - "mainClass", - MTD_STRING) - .pop(); - } - - /* - * Invoke Builder.version(Version v); - */ - void version(Version v) { - cob.aload(BUILDER_VAR) - .loadConstant(v.toString()) - .invokevirtual(CD_MODULE_BUILDER, - "version", - MTD_STRING) - .pop(); - } - - void invokeBuilderMethod(String methodName, String value) { - cob.aload(BUILDER_VAR) - .loadConstant(value) - .invokevirtual(CD_MODULE_BUILDER, - methodName, - MTD_STRING) - .pop(); - } + private void genImmutableSet(ClassBuilder clb, CodeBuilder cob, Set set, String methodNamePrefix) { + var snippets = Snippet.buildAll(sorted(set), Snippet::loadConstant); + new SetSnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(classDesc) + .enablePagination(methodNamePrefix, STRING_PAGE_SIZE) + .build(snippets) + .emit(cob); } class ModuleHashesBuilder { @@ -1577,240 +1037,234 @@ void hashForModule(String name, byte[] hash) { } } + /* + * Snippets to load the deduplicated set onto the operand stack. + * Set referenced more than once will be read from the cache, cacheSetupSnippet contains + * the bytecode to populate that cache. + */ + static record DedupSnippets(Map, Snippet> stringSets, + Map, Snippet> requiresModifiersSets, + Map, Snippet> opensModifiersSets, + Map, Snippet> exportsModifiersSets, + Optional cacheSetupSnippet) {}; + /* * Wraps set creation, ensuring identical sets are properly deduplicated. */ static class DedupSetBuilder { - // map Set to a specialized builder to allow them to be - // deduplicated as they are requested - final Map, SetBuilder> stringSets = new HashMap<>(); - - // map Set to a specialized builder to allow them to be - // deduplicated as they are requested - final Map, EnumSetBuilder> + final Map, RefCounter> stringSets = new HashMap<>(); + final Map, RefCounter> requiresModifiersSets = new HashMap<>(); - - // map Set to a specialized builder to allow them to be - // deduplicated as they are requested - final Map, EnumSetBuilder> + final Map, RefCounter> exportsModifiersSets = new HashMap<>(); - - // map Set to a specialized builder to allow them to be - // deduplicated as they are requested - final Map, EnumSetBuilder> + final Map, RefCounter> opensModifiersSets = new HashMap<>(); - private final int stringSetVar; - private final int enumSetVar; - private final IntSupplier localVarSupplier; + final ClassDesc owner; + final CacheBuilder cacheBuilder = new CacheBuilder(); + int setBuilt = 0; - DedupSetBuilder(IntSupplier localVarSupplier) { - this.stringSetVar = localVarSupplier.getAsInt(); - this.enumSetVar = localVarSupplier.getAsInt(); - this.localVarSupplier = localVarSupplier; + DedupSetBuilder(ClassDesc owner) { + this.owner = owner; } /* * Add the given set of strings to this builder. */ void stringSet(Set strings) { - stringSets.computeIfAbsent(strings, - s -> new SetBuilder<>(s, stringSetVar, localVarSupplier) - ).increment(); + stringSets.computeIfAbsent(strings, RefCounter::new).increment(); } /* * Add the given set of Exports.Modifiers */ void exportsModifiers(Set mods) { - exportsModifiersSets.computeIfAbsent(mods, s -> - new EnumSetBuilder<>(s, CD_EXPORTS_MODIFIER, - enumSetVar, localVarSupplier) - ).increment(); + exportsModifiersSets.computeIfAbsent(mods, RefCounter::new).increment(); } /* * Add the given set of Opens.Modifiers */ void opensModifiers(Set mods) { - opensModifiersSets.computeIfAbsent(mods, s -> - new EnumSetBuilder<>(s, CD_OPENS_MODIFIER, - enumSetVar, localVarSupplier) - ).increment(); + opensModifiersSets.computeIfAbsent(mods, RefCounter::new).increment(); } /* * Add the given set of Requires.Modifiers */ void requiresModifiers(Set mods) { - requiresModifiersSets.computeIfAbsent(mods, s -> - new EnumSetBuilder<>(s, CD_REQUIRES_MODIFIER, - enumSetVar, localVarSupplier) - ).increment(); + requiresModifiersSets.computeIfAbsent(mods, RefCounter::new).increment(); } /* - * Retrieve the index to the given set of Strings. Emit code to - * generate it when SetBuilder::build is called. + * Generate bytecode to load a set onto the operand stack. + * Use cache if the set is referenced more than once. */ - int indexOfStringSet(CodeBuilder cob, Set names) { - return stringSets.get(names).build(cob); + private Snippet buildStringSet(ClassBuilder clb, RefCounter setRef) { + return cacheBuilder.transform(setRef, + new SetSnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(owner) + .enablePagination("dedupSet" + setBuilt++, STRING_PAGE_SIZE) + .build(Snippet.buildAll(setRef.sortedList(), Snippet::loadConstant))); } /* - * Retrieve the index to the given set of Exports.Modifier. - * Emit code to generate it when EnumSetBuilder::build is called. + * Generate the mapping from a set to the bytecode loading the set onto the operand stack. + * Ordering the sets to ensure same generated bytecode. */ - int indexOfExportsModifiers(CodeBuilder cob, Set mods) { - return exportsModifiersSets.get(mods).build(cob); + private Map, Snippet> buildStringSets(ClassBuilder clb, Map, RefCounter> map) { + Map, Snippet> snippets = new HashMap<>(map.size()); + map.entrySet().stream() + .sorted(Map.Entry.comparingByValue()) + .forEach(e -> snippets.put(e.getKey(), buildStringSet(clb, e.getValue()))); + return snippets; } - /** - * Retrieve the index to the given set of Opens.Modifier. - * Emit code to generate it when EnumSetBuilder::build is called. + /* + * Enum set support */ - int indexOfOpensModifiers(CodeBuilder cob, Set mods) { - return opensModifiersSets.get(mods).build(cob); + private > Snippet buildEnumSet(ClassBuilder clb, RefCounter setRef) { + return cacheBuilder.transform(setRef, + new SetSnippetBuilder(CD_Object) + .classBuilder(clb) + .ownerClassDesc(owner) + .enablePagination("dedupSet" + setBuilt++, ENUM_PAGE_SIZE) + .build(Snippet.buildAll(setRef.sortedList(), Snippet::loadEnum))); } + private > Map, Snippet> buildEnumSets(ClassBuilder clb, Map, RefCounter> map) { + Map, Snippet> snippets = new HashMap<>(map.size()); + map.entrySet().stream() + .sorted(Map.Entry.comparingByValue()) + .forEach(e -> snippets.put(e.getKey(), buildEnumSet(clb, e.getValue()))); + return snippets; + } /* - * Retrieve the index to the given set of Requires.Modifier. - * Emit code to generate it when EnumSetBuilder::build is called. + * Build snippets for all sets and optionally the cache. */ - int indexOfRequiresModifiers(CodeBuilder cob, Set mods) { - return requiresModifiersSets.get(mods).build(cob); + DedupSnippets build(ClassBuilder clb) { + return new DedupSnippets( + buildStringSets(clb, stringSets), + buildEnumSets(clb, requiresModifiersSets), + buildEnumSets(clb, opensModifiersSets), + buildEnumSets(clb, exportsModifiersSets), + cacheBuilder.build(clb) + ); } /* - * Build a new string set without any attempt to deduplicate it. + * RefCounter count references to the set, and keeps sorted elements to ensure + * generate same bytecode for a given set. + * RefCounter itself needs ordering to ensure generate same bytecode for the cache. */ - int newStringSet(CodeBuilder cob, Set names) { - int index = new SetBuilder<>(names, stringSetVar, localVarSupplier).build(cob); - assert index == stringSetVar; - return index; - } - } + class RefCounter> implements Comparable> { + // sorted elements of the set to ensure same generated code + private final List elements; + private int refCount; - /* - * SetBuilder generates bytecode to create one single instance of Set - * for a given set of elements and assign to a local variable slot. - * When there is only one single reference to a Set, - * it will reuse defaultVarIndex. For a Set with multiple references, - * it will use a new local variable retrieved from the nextLocalVar - */ - static class SetBuilder> { - private static final MethodTypeDesc MTD_Set_ObjectArray = MethodTypeDesc.of( - CD_Set, CD_Object.arrayType()); - - private final Set elements; - private final int defaultVarIndex; - private final IntSupplier nextLocalVar; - private int refCount; - private int localVarIndex; - - SetBuilder(Set elements, - int defaultVarIndex, - IntSupplier nextLocalVar) { - this.elements = elements; - this.defaultVarIndex = defaultVarIndex; - this.nextLocalVar = nextLocalVar; - } + RefCounter(Set elements) { + this.elements = sorted(elements); + } - /* - * Increments the number of references to this particular set. - */ - final void increment() { - refCount++; + int increment() { + return ++refCount; + } + + int refCount() { + return refCount; + } + + List sortedList() { + return elements; + } + + @Override + public int compareTo(RefCounter o) { + if (o == this) { + return 0; + } + if (elements.size() == o.elements.size()) { + var a1 = elements; + var a2 = o.elements; + for (int i = 0; i < elements.size(); i++) { + var r = a1.get(i).compareTo(a2.get(i)); + if (r != 0) { + return r; + } + } + return 0; + } else { + return elements.size() - o.elements.size(); + } + } } /** - * Generate the appropriate instructions to load an object reference - * to the element onto the stack. + * Build an array to host sets referenced more than once so a given set will only be constructed once. + * Transform the bytecode for loading the set onto the operand stack as needed. */ - void visitElement(T element, CodeBuilder cob) { - cob.loadConstant((ConstantDesc)element); - } + class CacheBuilder { + private static final String VALUES_ARRAY = "dedupSetValues"; + final ArrayList cachedValues = new ArrayList<>(); + + // Load the set from the cache to the operand stack + // dedupSetValues[index] + private Snippet loadFromCache(int index) { + assert index >= 0; + return cob -> + cob.getstatic(owner, VALUES_ARRAY, CD_Set.arrayType()) + .loadConstant(index) + .aaload(); + } - /* - * Build bytecode for the Set represented by this builder, - * or get the local variable index of a previously generated set - * (in the local scope). - * - * @return local variable index of the generated set. - */ - final int build(CodeBuilder cob) { - int index = localVarIndex; - if (localVarIndex == 0) { - // if non-empty and more than one set reference this builder, - // emit to a unique local - index = refCount <= 1 ? defaultVarIndex - : nextLocalVar.getAsInt(); - if (index < MAX_LOCAL_VARS) { - localVarIndex = index; + /** + * Transform the bytecode for loading the set onto the operand stack. + * @param loadSnippet The origin snippet to load the set onto the operand stack. + */ + Snippet transform(RefCounter setRef, Snippet loadSnippet) { + if (setRef.refCount() > 1) { + cachedValues.add(loadSnippet); + return loadFromCache(cachedValues.size() - 1); } else { - // overflow: disable optimization by using localVarIndex = 0 - index = defaultVarIndex; + return loadSnippet; } - - generateSetOf(cob, index); } - return index; - } - private void generateSetOf(CodeBuilder cob, int index) { - if (elements.size() <= 10) { - // call Set.of(e1, e2, ...) - for (T t : sorted(elements)) { - visitElement(t, cob); + /* + * Returns a snippet that populates the cached values in . + * + * The generated cache is essentially as the following: + * + * static final Set[] dedupSetValues; + * + * static { + * dedupSetValues = new Set[countOfStoredValues]; + * dedupSetValues[0] = Set.of(elements); // for inline set + * dedupSetValues[1] = dedupSet_0(); // for paginated set + * ... + * dedupSetValues[countOfStoredValues - 1] = ... + * } + */ + Optional build(ClassBuilder clb) { + if (cachedValues.isEmpty()) { + return Optional.empty(); } - var mtdArgs = new ClassDesc[elements.size()]; - Arrays.fill(mtdArgs, CD_Object); - cob.invokestatic(CD_Set, - "of", - MethodTypeDesc.of(CD_Set, mtdArgs), - true); - } else { - // call Set.of(E... elements) - cob.loadConstant(elements.size()) - .anewarray(CD_String); - int arrayIndex = 0; - for (T t : sorted(elements)) { - cob.dup() // arrayref - .loadConstant(arrayIndex); - visitElement(t, cob); // value - cob.aastore(); - arrayIndex++; - } - cob.invokestatic(CD_Set, - "of", - MTD_Set_ObjectArray, - true); - } - cob.astore(index); - } - } - /* - * Generates bytecode to create one single instance of EnumSet - * for a given set of modifiers and assign to a local variable slot. - */ - static class EnumSetBuilder> extends SetBuilder { - private final ClassDesc classDesc; - - EnumSetBuilder(Set modifiers, ClassDesc classDesc, - int defaultVarIndex, - IntSupplier nextLocalVar) { - super(modifiers, defaultVarIndex, nextLocalVar); - this.classDesc = classDesc; - } + var cacheValuesArray = new ArraySnippetBuilder(CD_Set) + .classBuilder(clb) + .ownerClassDesc(owner) + .enablePagination(VALUES_ARRAY) + .build(cachedValues.toArray(Snippet[]::new)); - /** - * Loads an Enum field. - */ - @Override - void visitElement(T t, CodeBuilder cob) { - cob.getstatic(classDesc, t.toString(), classDesc); + clb.withField(VALUES_ARRAY, CD_Set.arrayType(), ACC_STATIC | ACC_FINAL); + + return Optional.of(cob -> { + cacheValuesArray.emit(cob); + cob.putstatic(owner, VALUES_ARRAY, CD_Set.arrayType()); + }); + } } } } diff --git a/test/jdk/tools/jlink/JLink20000Packages.java b/test/jdk/tools/jlink/JLink20000Packages.java new file mode 100644 index 0000000000000..865cf7ca98c2f --- /dev/null +++ b/test/jdk/tools/jlink/JLink20000Packages.java @@ -0,0 +1,129 @@ +/* + * 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. + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.StringJoiner; +import java.util.spi.ToolProvider; + +import tests.JImageGenerator; + +/* + * @test + * @summary Make sure that ~20000 packages in a uber jar can be linked using jlink. Now that + * pagination is in place, the limitation is on the constant pool size, not number + * of packages. + * @bug 8321413 + * @library ../lib + * @enablePreview + * @modules java.base/jdk.internal.jimage + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink.plugin + * jdk.jlink/jdk.tools.jmod + * jdk.jlink/jdk.tools.jimage + * jdk.compiler + * @build tests.* + * @run main/othervm -Xmx1g -Xlog:init=debug -XX:+UnlockDiagnosticVMOptions -XX:+BytecodeVerificationLocal JLink20000Packages + */ +public class JLink20000Packages { + private static final ToolProvider JAVAC_TOOL = ToolProvider.findFirst("javac") + .orElseThrow(() -> new RuntimeException("javac tool not found")); + + static void report(String command, String[] args) { + System.out.println(command + " " + String.join(" ", Arrays.asList(args))); + } + + static void javac(String[] args) { + report("javac", args); + JAVAC_TOOL.run(System.out, System.err, args); + } + + public static void main(String[] args) throws Exception { + Path src = Paths.get("bug8321413"); + Path imageDir = src.resolve("out-jlink"); + Path mainModulePath = src.resolve("bug8321413x"); + + StringJoiner mainModuleInfoContent = new StringJoiner(";\n exports ", "module bug8321413x {\n exports ", ";\n}"); + + for (int i = 0; i < 20000; i++) { + String packageName = "p" + i; + String className = "C" + i; + + Path packagePath = Files.createDirectories(mainModulePath.resolve(packageName)); + + StringBuilder classContent = new StringBuilder("package "); + classContent.append(packageName).append(";\n"); + classContent.append("class ").append(className).append(" {}\n"); + Files.writeString(packagePath.resolve(className + ".java"), classContent.toString()); + + mainModuleInfoContent.add(packageName); + } + + // create module reading the generated modules + Path mainModuleInfo = mainModulePath.resolve("module-info.java"); + Files.writeString(mainModuleInfo, mainModuleInfoContent.toString()); + + Path mainClassDir = mainModulePath.resolve("testpackage"); + Files.createDirectories(mainClassDir); + + Files.writeString(mainClassDir.resolve("JLink20000PackagesTest.java"), """ + package testpackage; + + public class JLink20000PackagesTest { + public static void main(String[] args) throws Exception { + System.out.println("JLink20000PackagesTest started."); + } + } + """); + + String out = src.resolve("out").toString(); + javac(new String[]{ + "-d", out, + "--module-source-path", src.toString(), + "--module", "bug8321413x" + }); + + JImageGenerator.getJLinkTask() + .modulePath(out) + .output(imageDir) + .addMods("bug8321413x") + .call() + .assertSuccess(); + + Path binDir = imageDir.resolve("bin").toAbsolutePath(); + Path bin = binDir.resolve("java"); + + ProcessBuilder processBuilder = new ProcessBuilder(bin.toString(), + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+BytecodeVerificationLocal", + "-m", "bug8321413x/testpackage.JLink20000PackagesTest"); + processBuilder.inheritIO(); + processBuilder.directory(binDir.toFile()); + Process process = processBuilder.start(); + int exitCode = process.waitFor(); + if (exitCode != 0) + throw new AssertionError("JLink20000PackagesTest failed to launch"); + } +} diff --git a/test/jdk/tools/jlink/SnippetsTest.java b/test/jdk/tools/jlink/SnippetsTest.java new file mode 100644 index 0000000000000..ec0c94e3d264b --- /dev/null +++ b/test/jdk/tools/jlink/SnippetsTest.java @@ -0,0 +1,271 @@ +/* + * 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. 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. + */ + +import java.io.IOException; +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassFile; +import static java.lang.classfile.ClassFile.ACC_PUBLIC; +import java.lang.constant.ClassDesc; +import static java.lang.constant.ConstantDescs.CD_Integer; +import static java.lang.constant.ConstantDescs.CD_Object; +import static java.lang.constant.ConstantDescs.CD_String; +import static java.lang.constant.ConstantDescs.INIT_NAME; +import static java.lang.constant.ConstantDescs.MTD_void; +import java.lang.constant.MethodTypeDesc; +import static java.lang.invoke.MethodHandles.lookup; +import java.lang.invoke.MethodType; +import java.lang.module.ModuleDescriptor; +import java.lang.reflect.AccessFlag; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.*; + +import jdk.tools.jlink.internal.Snippets.*; + +/* + * @test + * @summary Test snippets generation for array and set. + * @bug 8321413 + * @enablePreview + * @modules jdk.jlink/jdk.tools.jlink.internal + * @run junit SnippetsTest + */ +public class SnippetsTest { + private static final boolean WRITE_CLASS_FILE = Boolean.parseBoolean(System.getProperty("DumpArraySnippetsTestClasses", "false")); + + @ParameterizedTest + @ValueSource(ints = { 10, 75, 90, 120, 200, 399, 400, 401}) + void testLoad400StringsArray(int pageSize) { + testPaginatedArray(400, pageSize); + } + + @Test + void testStringArrayLimitsWithPagination() { + // Each string takes 2 constant pool slot, one for String, another for Utf8 + testPaginatedArray(31_000, 8000); + try { + testPaginatedArray(32_000, 8000); + } catch (IllegalArgumentException iae) { + // expected constant pool explode + } + } + + @Test + void testStringArrayLimitsWithoutPagination() { + // each string array assignment takes ~8 bytes + testSimpleArray(8200); + try { + testSimpleArray(8300); + fail(); + } catch (IllegalArgumentException iae) { + // expected code size explode + } + } + + @Test + void testLoadableEnum() { + Enum[] enums = { + AccessFlag.FINAL, + ModuleDescriptor.Requires.Modifier.MANDATED, + ModuleDescriptor.Opens.Modifier.SYNTHETIC, + ModuleDescriptor.Requires.Modifier.TRANSITIVE + }; + + Snippet[] elementSnippets = Snippet.buildAll(Arrays.asList(enums), Snippet::loadEnum); + + var loadable = new ArraySnippetBuilder(Enum.class.describeConstable().get()) + .build(elementSnippets); + + Supplier[]> supplier = generateSupplier("LoadableEnumTest", clb -> loadable); + assertArrayEquals(enums, supplier.get()); + } + + @Test + void testArraySnippetBuilder() { + Integer[] expected = IntStream.range(0, 200) + .boxed() + .toArray(Integer[]::new); + var className = "LoadableArrayOf200Paged"; + var elementSnippets = Snippet.buildAll(Arrays.asList(expected), Snippet::loadInteger); + var instance = new ArraySnippetBuilder(CD_Integer) + .ownerClassDesc(ClassDesc.of(className)) + .enablePagination("page", 100); + + try { + instance.build(elementSnippets); + fail("Should throw NPE without ClassBuilder"); + } catch (NullPointerException npe) { + // expected + } + + Supplier supplier = generateSupplier(className, clb -> instance.classBuilder(clb).build(elementSnippets)); + verifyPaginationMethods(supplier.getClass(), Integer.class, "page", 2); + assertArrayEquals(expected, supplier.get()); + + var loadable = instance.disablePagination() + .ownerClassDesc(ClassDesc.of("LoadableArrayOf200NotPaged")) + .build(elementSnippets); + + // SimpleArray generate bytecode inline, so can be generated in any class + supplier = generateSupplier("TestLoadableArrayFactory", clb -> loadable); + verifyPaginationMethods(supplier.getClass(), Integer.class, "page", 0); + assertArrayEquals(expected, supplier.get()); + } + + @Test + void testSetSnippetBuilder() { + String[] data = IntStream.range(0, 100) + .mapToObj(i -> "SetData" + i) + .toArray(String[]::new); + + var tiny = Set.of(data[0], data[1], data[2]); + var all = Set.of(data); + var setBuilder = new SetSnippetBuilder(CD_String); + + Supplier> supplier = generateSupplier("TinySetTest", clb -> + setBuilder.build(Snippet.buildAll(tiny, Snippet::loadConstant))); + // Set does not guarantee ordering, so not assertIterableEquals + assertEquals(tiny, supplier.get()); + + var allSnippets = Snippet.buildAll(all, Snippet::loadConstant); + + supplier = generateSupplier("AllSetTestNoPage", clb -> + setBuilder.build(allSnippets)); + assertEquals(all, supplier.get()); + + var className = "AllSetTestPageNotActivated"; + var methodNamePrefix = "page"; + var loadable = setBuilder.disablePagination() + .ownerClassDesc(ClassDesc.of(className)) + .build(allSnippets); + supplier = generateSupplier(className, clb -> loadable); + assertEquals(all, supplier.get()); + + className = "AllSetTestPageSize20"; + setBuilder.ownerClassDesc(ClassDesc.of(className)); + supplier = generateSupplier(className, clb -> setBuilder.classBuilder(clb) + .enablePagination(methodNamePrefix, 20) + .build(allSnippets)); + verifyPaginationMethods(supplier.getClass(), String.class, methodNamePrefix, 5); + assertEquals(all, supplier.get()); + } + + void testPaginatedArray(int elementCount, int pageSize) { + String[] expected = IntStream.range(0, elementCount) + .mapToObj(i -> "Package" + i) + .toArray(String[]::new); + var className = String.format("SnippetArrayProviderTest%dPagedBy%d", elementCount, pageSize); + ClassDesc testClassDesc = ClassDesc.of(className); + var builder = new ArraySnippetBuilder(CD_String) + .enablePagination("ArrayPage", pageSize, 1) + .ownerClassDesc(testClassDesc); + var snippets = Snippet.buildAll(Arrays.asList(expected), Snippet::loadConstant); + var pagingContext = new PagingContext(expected.length, pageSize); + + Supplier supplier = generateSupplier(className, clb -> builder.classBuilder(clb).build(snippets)); + verifyPaginationMethods(supplier.getClass(), String.class, "ArrayPage", pagingContext.pageCount()); + assertEquals((elementCount % pageSize) != 0, pagingContext.isLastPagePartial()); + assertArrayEquals(expected, supplier.get()); + } + + void testSimpleArray(int elementCount) { + String[] expected = IntStream.range(0, elementCount) + .mapToObj(i -> "NoPage" + i) + .toArray(String[]::new); + String className = "SnippetArrayProviderTest" + elementCount; + var array = new ArraySnippetBuilder(CD_String) + .disablePagination() + .build(Snippet.buildAll(Arrays.asList(expected), Snippet::loadConstant)); + + Supplier supplier = generateSupplier(className, clb -> array); + verifyPaginationMethods(supplier.getClass(), String.class, "page", 0); + assertArrayEquals(expected, supplier.get()); + } + + Supplier generateSupplier(String className, Function builder) { + var testClassDesc = ClassDesc.of(className); + byte[] classBytes = generateSupplierClass(testClassDesc, builder); + try { + writeClassFile(className, classBytes); + var testClass = lookup().defineClass(classBytes); + lookup().findVirtual(testClass, "get", MethodType.methodType(Object.class)); + return (Supplier) testClass.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + void verifyPaginationMethods(Class testClass, Class elementType, String methodNamePrefix, int pageCount) { + var methodType = MethodType.methodType(elementType.arrayType(), elementType.arrayType()); + if (pageCount <= 0) { + try { + lookup().findStatic(testClass, methodNamePrefix + "_0", methodType); + fail("Unexpected paginate helper function"); + } catch (Exception ex) {} + } + + for (int i = 0; i < pageCount; i++) { + try { + lookup().findStatic(testClass, methodNamePrefix + "_" + i, methodType); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + } + + byte[] generateSupplierClass(ClassDesc testClassDesc, Function builder) { + return ClassFile.of().build(testClassDesc, + clb -> { + clb.withSuperclass(CD_Object); + clb.withInterfaceSymbols(ClassDesc.ofInternalName("java/util/function/Supplier")); + clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> { + cob.aload(0); + cob.invokespecial(CD_Object, INIT_NAME, MTD_void); + cob.return_(); + }); + + var loadable = builder.apply(clb); + + clb.withMethodBody("get", MethodTypeDesc.of(CD_Object), ACC_PUBLIC, cob -> { + loadable.emit(cob); + cob.areturn(); + }); + }); + } + + void writeClassFile(String className, byte[] classBytes) throws IOException { + if (WRITE_CLASS_FILE) { + Files.write(Path.of(className + ".class"), classBytes); + } + } +} \ No newline at end of file From 9f3c5f95361c75d2b4d9e083901ce5a0ebf355e0 Mon Sep 17 00:00:00 2001 From: Harshitha Onkar Date: Thu, 9 Jan 2025 18:22:33 +0000 Subject: [PATCH 080/286] 8344907: NullPointerException in Win32ShellFolder2.getSystemIcon when "icon" is null Reviewed-by: aivanov, kizune --- .../sun/awt/shell/Win32ShellFolder2.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java index 0a4fb12cda6c7..c85c2d4ced93a 100644 --- a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java +++ b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -1201,8 +1201,12 @@ public Image getIcon(int width, int height) { */ static Image getSystemIcon(SystemIcon iconType) { long hIcon = getSystemIcon(iconType.getIconID()); + if (hIcon == 0) { + return null; + } + Image icon = makeIcon(hIcon); - if (LARGE_ICON_SIZE != icon.getWidth(null)) { + if (icon != null && LARGE_ICON_SIZE != icon.getWidth(null)) { icon = new MultiResolutionIconImage(LARGE_ICON_SIZE, icon); } disposeIcon(hIcon); @@ -1214,15 +1218,16 @@ static Image getSystemIcon(SystemIcon iconType) { */ static Image getShell32Icon(int iconID, int size) { long hIcon = getIconResource("shell32.dll", iconID, size, size); - if (hIcon != 0) { - Image icon = makeIcon(hIcon); - if (size != icon.getWidth(null)) { - icon = new MultiResolutionIconImage(size, icon); - } - disposeIcon(hIcon); - return icon; + if (hIcon == 0) { + return null; } - return null; + + Image icon = makeIcon(hIcon); + if (icon != null && size != icon.getWidth(null)) { + icon = new MultiResolutionIconImage(size, icon); + } + disposeIcon(hIcon); + return icon; } /** From df28cec6e98f45ae535a35f97710710415522f99 Mon Sep 17 00:00:00 2001 From: Alisen Chung Date: Thu, 9 Jan 2025 20:47:22 +0000 Subject: [PATCH 081/286] 8345144: Robot does not specify all causes of IllegalThreadStateException Reviewed-by: prr --- .../share/classes/java/awt/Robot.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/java.desktop/share/classes/java/awt/Robot.java b/src/java.desktop/share/classes/java/awt/Robot.java index 8b7506f5f2d41..d0877b3bddd95 100644 --- a/src/java.desktop/share/classes/java/awt/Robot.java +++ b/src/java.desktop/share/classes/java/awt/Robot.java @@ -58,6 +58,15 @@ * queue. For example, {@code Robot.mouseMove} will actually move * the mouse cursor instead of just generating mouse move events. *

      + * @apiNote When {@code autoWaitForIdle()} is enabled, mouse and key related methods + * cannot be called on the AWT EDT. This is because when {@code autoWaitForIdle()} + * is enabled, the mouse and key methods implicitly call {@code waitForIdle()} + * which will throw {@code IllegalThreadStateException} when called on the AWT EDT. + * In addition, screen capture operations can be lengthy + * and {@code delay(long ms)} clearly inserts a delay, so these also + * should not be called on the EDT. Taken together, this means that as much as possible, + * methods on this class should not be called on the EDT. + *

      * Note that some platforms require special privileges or extensions * to access low-level input control. If the current platform configuration * does not allow input control, an {@code AWTException} will be thrown @@ -216,6 +225,8 @@ private static void checkIsScreenDevice(GraphicsDevice device) { * * @param x X position * @param y Y position + * @throws IllegalThreadStateException if called on the AWT event dispatching + * thread and {@code isAutoWaitForIdle} would return true */ public synchronized void mouseMove(int x, int y) { peer.mouseMove(x, y); @@ -268,6 +279,7 @@ public synchronized void mouseMove(int x, int y) { * and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button * that does not exist on the mouse and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java + * @throws IllegalThreadStateException if called on the AWT event dispatching thread and {@code isAutoWaitForIdle} would return true * @see #mouseRelease(int) * @see InputEvent#getMaskForButton(int) * @see Toolkit#areExtraMouseButtonsEnabled() @@ -325,6 +337,7 @@ public synchronized void mousePress(int buttons) { * and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button * that does not exist on the mouse and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java + * @throws IllegalThreadStateException if called on the AWT event dispatching thread and {@code isAutoWaitForIdle} would return true * @see #mousePress(int) * @see InputEvent#getMaskForButton(int) * @see Toolkit#areExtraMouseButtonsEnabled() @@ -349,6 +362,8 @@ private static void checkButtonsArgument(int buttons) { * @param wheelAmt number of "notches" to move the mouse wheel * Negative values indicate movement up/away from the user, * positive values indicate movement down/towards the user. + * @throws IllegalThreadStateException if called on the AWT event dispatching + * thread and {@code isAutoWaitForIdle} would return true * * @since 1.4 */ @@ -368,6 +383,8 @@ public synchronized void mouseWheel(int wheelAmt) { * @param keycode Key to press (e.g. {@code KeyEvent.VK_A}) * @throws IllegalArgumentException if {@code keycode} is not * a valid key + * @throws IllegalThreadStateException if called on the AWT event + * dispatching thread and {@code isAutoWaitForIdle} would return true * @see #keyRelease(int) * @see java.awt.event.KeyEvent */ @@ -387,7 +404,9 @@ public synchronized void keyPress(int keycode) { * @param keycode Key to release (e.g. {@code KeyEvent.VK_A}) * @throws IllegalArgumentException if {@code keycode} is not a * valid key - * @see #keyPress(int) + * @throws IllegalThreadStateException if called on the AWT event + * dispatching thread and {@code isAutoWaitForIdle} would return true + * @see #keyPress(int) * @see java.awt.event.KeyEvent */ public synchronized void keyRelease(int keycode) { @@ -487,6 +506,12 @@ public synchronized BufferedImage createScreenCapture(Rectangle screenRect) { * nativeResImage = resolutionVariants.get(0); * } * } + * + * @apiNote It is recommended to avoid calling this method on + * the AWT Event Dispatch Thread since screen capture may be a lengthy + * operation, particularly if acquiring permissions is needed and involves + * user interaction. + * * @param screenRect Rect to capture in screen coordinates * @return The captured image * @throws IllegalArgumentException if {@code screenRect} width and height @@ -641,6 +666,10 @@ public synchronized boolean isAutoWaitForIdle() { /** * Sets whether this Robot automatically invokes {@code waitForIdle} * after generating an event. + *

      + * @apiNote Setting this to true means you cannot call mouse and key-controlling events + * on the AWT Event Dispatching Thread + * * @param isOn Whether {@code waitForIdle} is automatically invoked */ public synchronized void setAutoWaitForIdle(boolean isOn) { @@ -692,6 +721,10 @@ private void autoDelay() { * already set, this method returns immediately with the interrupt status * set. * + * @apiNote It is recommended to avoid calling this method on + * the AWT Event Dispatch Thread since delay may be a lengthy + * operation. + * * @param ms time to sleep in milliseconds * @throws IllegalArgumentException if {@code ms} is not between {@code 0} * and {@code 60,000} milliseconds inclusive From b335ea92963fc4524de41db6b1e866131b12f385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 9 Jan 2025 21:37:36 +0000 Subject: [PATCH 082/286] 8347122: Add missing @serial tags to module java.desktop Reviewed-by: prr --- .../share/classes/java/applet/Applet.java | 4 ++-- .../share/classes/java/awt/AWTEvent.java | 4 ++-- .../share/classes/java/awt/AWTKeyStroke.java | 10 ++++----- .../share/classes/java/awt/Component.java | 19 +++++++++------- .../java/awt/ComponentOrientation.java | 4 ++-- .../share/classes/java/awt/Container.java | 3 ++- .../ContainerOrderFocusTraversalPolicy.java | 8 +++---- .../share/classes/java/awt/FlowLayout.java | 4 ++-- .../share/classes/java/awt/Frame.java | 4 ++-- .../share/classes/java/awt/GridBagLayout.java | 4 ++-- .../classes/java/awt/GridBagLayoutInfo.java | 22 +++++++++---------- .../share/classes/java/awt/List.java | 6 ++--- .../share/classes/java/awt/MenuComponent.java | 4 ++-- .../java/awt/ScrollPaneAdjustable.java | 4 ++-- .../share/classes/java/awt/TextComponent.java | 6 ++--- .../share/classes/java/awt/Window.java | 8 +++---- .../classes/java/awt/color/ColorSpace.java | 6 ++--- .../java/awt/color/ICC_ColorSpace.java | 14 ++++++------ .../classes/java/awt/desktop/FilesEvent.java | 4 ++-- .../java/awt/desktop/OpenFilesEvent.java | 4 ++-- .../java/awt/desktop/OpenURIEvent.java | 4 ++-- .../java/awt/desktop/UserSessionEvent.java | 4 ++-- .../java/awt/event/HierarchyEvent.java | 8 +++---- .../java/awt/event/InvocationEvent.java | 15 ++++++++----- .../classes/java/awt/event/KeyEvent.java | 6 ++--- .../classes/java/awt/event/MouseEvent.java | 4 ++-- .../java/awt/event/MouseWheelEvent.java | 10 ++++----- .../classes/java/awt/event/WindowEvent.java | 6 ++--- .../classes/java/awt/font/NumericShaper.java | 8 +++---- .../java/awt/font/TransformAttribute.java | 4 ++-- .../awt/image/renderable/ParameterBlock.java | 12 +++++++--- .../beans/IndexedPropertyChangeEvent.java | 4 ++-- .../beancontext/BeanContextChildSupport.java | 8 ++++++- .../beans/beancontext/BeanContextEvent.java | 4 +++- .../BeanContextMembershipEvent.java | 4 +++- .../BeanContextServiceAvailableEvent.java | 4 +++- .../BeanContextServiceRevokedEvent.java | 6 +++-- .../BeanContextServicesSupport.java | 4 +++- .../beans/beancontext/BeanContextSupport.java | 14 ++++++++---- .../metadata/IIOInvalidTreeException.java | 4 +++- .../attribute/AttributeSetUtilities.java | 6 ++--- .../print/attribute/standard/DialogOwner.java | 4 ++-- .../standard/MediaPrintableArea.java | 6 ++--- .../print/attribute/standard/MediaSize.java | 4 ++-- .../print/event/PrintJobAttributeEvent.java | 4 ++-- .../javax/print/event/PrintJobEvent.java | 4 ++-- .../event/PrintServiceAttributeEvent.java | 4 ++-- 47 files changed, 173 insertions(+), 134 deletions(-) diff --git a/src/java.desktop/share/classes/java/applet/Applet.java b/src/java.desktop/share/classes/java/applet/Applet.java index 2228ea419d48e..56b2392f0e25d 100644 --- a/src/java.desktop/share/classes/java/applet/Applet.java +++ b/src/java.desktop/share/classes/java/applet/Applet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -541,7 +541,7 @@ public void destroy() { // /** - * The accessible context associated with this {@code Applet}. + * @serial The accessible context associated with this {@code Applet}. */ @SuppressWarnings("serial") // Not statically typed as Serializable AccessibleContext accessibleContext = null; diff --git a/src/java.desktop/share/classes/java/awt/AWTEvent.java b/src/java.desktop/share/classes/java/awt/AWTEvent.java index 17c7b775c787b..d48fae68cbe6a 100644 --- a/src/java.desktop/share/classes/java/awt/AWTEvent.java +++ b/src/java.desktop/share/classes/java/awt/AWTEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, 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 @@ -87,7 +87,7 @@ public abstract class AWTEvent extends EventObject { /** - * The private data. + * @serial The private data. */ private byte[] bdata; diff --git a/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java b/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java index df38220d24c76..fee1c9a4e1974 100644 --- a/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java +++ b/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -86,22 +86,22 @@ public class AWTKeyStroke implements Serializable { private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke(); /** - * The character value for a keyboard key. + * @serial The character value for a keyboard key. */ private char keyChar = KeyEvent.CHAR_UNDEFINED; /** - * The key code for this {@code AWTKeyStroke}. + * @serial The key code for this {@code AWTKeyStroke}. */ private int keyCode = KeyEvent.VK_UNDEFINED; /** - * The bitwise-ored combination of any modifiers. + * @serial The bitwise-ored combination of any modifiers. */ private int modifiers; /** - * {@code true} if this {@code AWTKeyStroke} corresponds to a key release; + * @serial {@code true} if this {@code AWTKeyStroke} corresponds to a key release; * {@code false} otherwise. */ private boolean onKeyRelease; diff --git a/src/java.desktop/share/classes/java/awt/Component.java b/src/java.desktop/share/classes/java/awt/Component.java index 8bfe16619bb11..55fb06247af46 100644 --- a/src/java.desktop/share/classes/java/awt/Component.java +++ b/src/java.desktop/share/classes/java/awt/Component.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -305,7 +305,7 @@ public abstract class Component implements ImageObserver, MenuContainer, volatile Font font; /** - * The font which the peer is currently using. + * @serial The font which the peer is currently using. * ({@code null} if no peer exists.) */ Font peerFont; @@ -508,7 +508,7 @@ static class AWTTreeLock {} Dimension minSize; /** - * Whether or not setMinimumSize has been invoked with a non-null value. + * @serial Whether or not setMinimumSize has been invoked with a non-null value. */ boolean minSizeSet; @@ -521,7 +521,7 @@ static class AWTTreeLock {} Dimension prefSize; /** - * Whether or not setPreferredSize has been invoked with a non-null value. + * @serial Whether or not setPreferredSize has been invoked with a non-null value. */ boolean prefSizeSet; @@ -533,7 +533,7 @@ static class AWTTreeLock {} Dimension maxSize; /** - * Whether or not setMaximumSize has been invoked with a non-null value. + * @serial Whether or not setMaximumSize has been invoked with a non-null value. */ boolean maxSizeSet; @@ -698,12 +698,12 @@ Object getObjectLock() { } /** - * Whether the component is packed or not; + * @serial Whether the component is packed or not; */ boolean isPacked = false; /** - * Pseudoparameter for direct Geometry API (setLocation, setBounds setSize + * @serial Pseudoparameter for direct Geometry API (setLocation, setBounds setSize * to signal setBounds what's changing. Should be used under TreeLock. * This is only needed due to the inability to change the cross-calling * order of public and deprecated methods. @@ -8290,7 +8290,7 @@ public boolean isFocusOwner() { } /** - * Used to disallow auto-focus-transfer on disposal of the focus owner + * @serial Used to disallow auto-focus-transfer on disposal of the focus owner * in the process of disposing its parent container. */ private boolean autoFocusTransferOnDisposal = true; @@ -9234,6 +9234,7 @@ Window getContainingWindow() { /** * The {@code AccessibleContext} associated with this {@code Component}. + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected AccessibleContext accessibleContext = null; @@ -9290,6 +9291,7 @@ protected AccessibleAWTComponent() { /** * A component listener to track show/hide/resize events * and convert them to PropertyChange events. + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected ComponentListener accessibleAWTComponentHandler = null; @@ -9297,6 +9299,7 @@ protected AccessibleAWTComponent() { /** * A listener to track focus events * and convert them to PropertyChange events. + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected FocusListener accessibleAWTFocusHandler = null; diff --git a/src/java.desktop/share/classes/java/awt/ComponentOrientation.java b/src/java.desktop/share/classes/java/awt/ComponentOrientation.java index afa1e8af94a23..f12d4014ee90b 100644 --- a/src/java.desktop/share/classes/java/awt/ComponentOrientation.java +++ b/src/java.desktop/share/classes/java/awt/ComponentOrientation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -200,7 +200,7 @@ public static ComponentOrientation getOrientation(ResourceBundle bdl) } /** - * The bitwise-ored combination of flags. + * @serial The bitwise-ored combination of flags. */ private int orientation; diff --git a/src/java.desktop/share/classes/java/awt/Container.java b/src/java.desktop/share/classes/java/awt/Container.java index b6fbfb808a682..9bfb41a871e49 100644 --- a/src/java.desktop/share/classes/java/awt/Container.java +++ b/src/java.desktop/share/classes/java/awt/Container.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -3853,6 +3853,7 @@ public Accessible getAccessibleAt(Point p) { /** * The handler to fire {@code PropertyChange} * when children are added or removed + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected ContainerListener accessibleContainerHandler = null; diff --git a/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java b/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java index 6f905f3d2c7c1..4183c3dc230be 100644 --- a/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java +++ b/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -66,12 +66,12 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.ContainerOrderFocusTraversalPolicy"); /** - * This constant is used when the forward focus traversal order is active. + * @serial This constant is used when the forward focus traversal order is active. */ private final int FORWARD_TRAVERSAL = 0; /** - * This constant is used when the backward focus traversal order is active. + * @serial This constant is used when the backward focus traversal order is active. */ private final int BACKWARD_TRAVERSAL = 1; @@ -82,7 +82,7 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy private static final long serialVersionUID = 486933713763926351L; /** - * Whether this {@code ContainerOrderFocusTraversalPolicy} transfers focus + * @serial Whether this {@code ContainerOrderFocusTraversalPolicy} transfers focus * down-cycle implicitly. */ private boolean implicitDownCycleTraversal = true; diff --git a/src/java.desktop/share/classes/java/awt/FlowLayout.java b/src/java.desktop/share/classes/java/awt/FlowLayout.java index 3ad34f0177693..18f46c54c0c53 100644 --- a/src/java.desktop/share/classes/java/awt/FlowLayout.java +++ b/src/java.desktop/share/classes/java/awt/FlowLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -188,7 +188,7 @@ public class FlowLayout implements LayoutManager, java.io.Serializable { int vgap; /** - * If true, components will be aligned on their baseline. + * @serial If true, components will be aligned on their baseline. */ private boolean alignOnBaseline; diff --git a/src/java.desktop/share/classes/java/awt/Frame.java b/src/java.desktop/share/classes/java/awt/Frame.java index e01ef082d4229..fcdb4d5e032f4 100644 --- a/src/java.desktop/share/classes/java/awt/Frame.java +++ b/src/java.desktop/share/classes/java/awt/Frame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -347,7 +347,7 @@ public class Frame extends Window implements MenuContainer { boolean mbManagement = false; /* used only by the Motif impl. */ /** - * The bitwise mask of frame state constants. + * @serial The bitwise mask of frame state constants. */ // XXX: uwe: abuse old field for now // will need to take care of serialization diff --git a/src/java.desktop/share/classes/java/awt/GridBagLayout.java b/src/java.desktop/share/classes/java/awt/GridBagLayout.java index 9fdd7ee77743e..2dc65ab126590 100644 --- a/src/java.desktop/share/classes/java/awt/GridBagLayout.java +++ b/src/java.desktop/share/classes/java/awt/GridBagLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -473,7 +473,7 @@ public class GridBagLayout implements LayoutManager2, public double[] rowWeights; /** - * The component being positioned. This is set before calling into + * @serial The component being positioned. This is set before calling into * {@code adjustForGravity}. */ private Component componentAdjusting; diff --git a/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java b/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java index 1a4ed2942c505..ecdc400136964 100644 --- a/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java +++ b/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, 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 @@ -45,37 +45,37 @@ public final class GridBagLayoutInfo implements java.io.Serializable { private static final long serialVersionUID = -4899416460737170217L; /** - * The number of cells: horizontal and vertical. + * @serial The number of cells: horizontal and vertical. */ int width, height; /** - * The starting point for layout. + * @serial The starting point for layout. */ int startx, starty; /** - * The largest minWidth in each column. + * @serial The largest minWidth in each column. */ int[] minWidth; /** - * The largest minHeight in each row. + * @serial The largest minHeight in each row. */ int[] minHeight; /** - * The largest weight in each column. + * @serial The largest weight in each column. */ double[] weightX; /** - * The largest weight in each row. + * @serial The largest weight in each row. */ double[] weightY; /** - * Whether or not baseline layout has been requested and one of the + * @serial Whether or not baseline layout has been requested and one of the * components has a valid baseline. */ boolean hasBaseline; @@ -83,18 +83,18 @@ public final class GridBagLayoutInfo implements java.io.Serializable { // These are only valid if hasBaseline is true and are indexed by // row. /** - * The type of baseline for a particular row. A mix of the + * @serial The type of baseline for a particular row. A mix of the * BaselineResizeBehavior constants {@code (1 << ordinal())} */ short[] baselineType; /** - * Max ascent (baseline). + * @serial Max ascent (baseline). */ int[] maxAscent; /** - * Max descent (height - baseline) + * @serial Max descent (height - baseline) */ int[] maxDescent; diff --git a/src/java.desktop/share/classes/java/awt/List.java b/src/java.desktop/share/classes/java/awt/List.java index fe7ebb58431ea..30b26aa371b42 100644 --- a/src/java.desktop/share/classes/java/awt/List.java +++ b/src/java.desktop/share/classes/java/awt/List.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -1552,12 +1552,12 @@ protected class AccessibleAWTListChild extends AccessibleAWTComponent // [[[FIXME]]] need to finish implementing this!!! /** - * The parent {@code List}. + * @serial The parent {@code List}. */ private List parent; /** - * The index in the parent. + * @serial The index in the parent. */ private int indexInParent; diff --git a/src/java.desktop/share/classes/java/awt/MenuComponent.java b/src/java.desktop/share/classes/java/awt/MenuComponent.java index facf995416ff4..1391a397f82d3 100644 --- a/src/java.desktop/share/classes/java/awt/MenuComponent.java +++ b/src/java.desktop/share/classes/java/awt/MenuComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -436,7 +436,7 @@ private void readObject(ObjectInputStream s) * --- Accessibility Support --- */ /** - * MenuComponent will contain all of the methods in interface Accessible, + * @serial MenuComponent will contain all of the methods in interface Accessible, * though it won't actually implement the interface - that will be up * to the individual objects which extend MenuComponent. */ diff --git a/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java b/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java index d8d70fd2476d5..9b539a311d378 100644 --- a/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java +++ b/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -140,7 +140,7 @@ public final class ScrollPaneAdjustable implements Adjustable, Serializable { private int blockIncrement = 1; /** - * Specified adjustment listener to receive adjustment events from this + * @serial Specified adjustment listener to receive adjustment events from this * {@code ScrollPaneAdjustable}. */ @SuppressWarnings("serial") // Not statically typed as Serializable diff --git a/src/java.desktop/share/classes/java/awt/TextComponent.java b/src/java.desktop/share/classes/java/awt/TextComponent.java index 5185646a07eee..da722090afb8c 100644 --- a/src/java.desktop/share/classes/java/awt/TextComponent.java +++ b/src/java.desktop/share/classes/java/awt/TextComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -115,7 +115,7 @@ public sealed class TextComponent extends Component implements Accessible int selectionEnd; /** - * A flag used to tell whether the background has been set by + * @serial A flag used to tell whether the background has been set by * developer code (as opposed to AWT code). Used to determine * the background color of non-editable TextComponents. */ @@ -1207,7 +1207,7 @@ public String getBeforeIndex(int part, int index) { } // end of AccessibleAWTTextComponent /** - * Whether support of input methods should be checked or not. + * @serial Whether support of input methods should be checked or not. */ private boolean checkForEnableIM = true; } diff --git a/src/java.desktop/share/classes/java/awt/Window.java b/src/java.desktop/share/classes/java/awt/Window.java index 4e576f3dc9ea9..329e25744738f 100644 --- a/src/java.desktop/share/classes/java/awt/Window.java +++ b/src/java.desktop/share/classes/java/awt/Window.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -229,7 +229,7 @@ public static enum Type { static boolean systemSyncLWRequests = false; /** - * Focus transfers should be synchronous for lightweight component requests. + * @serial Focus transfers should be synchronous for lightweight component requests. */ boolean syncLWRequests = false; transient boolean beforeFirstShow = true; @@ -2777,7 +2777,7 @@ private void removeFromWindowList() { } /** - * Window type. + * @serial Window type. * * Synchronization: ObjectLock */ @@ -3337,7 +3337,7 @@ boolean canContainFocusOwner(Component focusOwnerCandidate) { } /** - * {@code true} if this Window should appear at the default location, + * @serial {@code true} if this Window should appear at the default location, * {@code false} if at the current location. */ private volatile boolean locationByPlatform = locationByPlatformProp; diff --git a/src/java.desktop/share/classes/java/awt/color/ColorSpace.java b/src/java.desktop/share/classes/java/awt/color/ColorSpace.java index 80944e5301757..2eab6aa46efde 100644 --- a/src/java.desktop/share/classes/java/awt/color/ColorSpace.java +++ b/src/java.desktop/share/classes/java/awt/color/ColorSpace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -100,12 +100,12 @@ public abstract class ColorSpace implements Serializable { private static final long serialVersionUID = -409452704308689724L; /** - * One of the {@code ColorSpace} type constants. + * @serial One of the {@code ColorSpace} type constants. */ private final int type; /** - * The number of components in the color space. + * @serial The number of components in the color space. */ private final int numComponents; diff --git a/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java b/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java index 56ea5c573d81c..5a0af93cb5e84 100644 --- a/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java +++ b/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -88,32 +88,32 @@ public class ICC_ColorSpace extends ColorSpace { private static final long serialVersionUID = 3455889114070431483L; /** - * The specified {@code ICC_Profile} object. + * @serial The specified {@code ICC_Profile} object. */ private ICC_Profile thisProfile; /** - * The minimum normalized component values. + * @serial The minimum normalized component values. */ private float[] minVal; /** - * The maximum normalized component values. + * @serial The maximum normalized component values. */ private float[] maxVal; /** - * Difference between min and max values. + * @serial Difference between min and max values. */ private float[] diffMinMax; /** - * Inverted value of the difference between min and max values. + * @serial Inverted value of the difference between min and max values. */ private float[] invDiffMinMax; /** - * Whether the values should be scaled or not. + * @serial Whether the values should be scaled or not. */ private boolean needScaleInit = true; diff --git a/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java b/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java index 3367d87456fb6..b7ce13abadc29 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -50,7 +50,7 @@ public sealed class FilesEvent extends AppEvent private static final long serialVersionUID = 5271763715462312871L; /** - * The list of files. + * @serial The list of files. */ @SuppressWarnings("serial") // Not statically typed as Serializable final List files; diff --git a/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java b/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java index d815d867475d0..7c8ba56132787 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -47,7 +47,7 @@ public final class OpenFilesEvent extends FilesEvent { private static final long serialVersionUID = -3982871005867718956L; /** - * The search term used to find the files. + * @serial The search term used to find the files. */ final String searchTerm; diff --git a/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java b/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java index a1869d35fa337..f7e66065f549b 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -46,7 +46,7 @@ public final class OpenURIEvent extends AppEvent { private static final long serialVersionUID = 221209100935933476L; /** - * The {@code URI} the app was asked to open. + * @serial The {@code URI} the app was asked to open. */ final URI uri; diff --git a/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java b/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java index 9199358b68804..4cb011c05f55a 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -47,7 +47,7 @@ public final class UserSessionEvent extends AppEvent { private static final long serialVersionUID = 6747138462796569055L; /** - * The reason of the user session change. + * @serial The reason of the user session change. */ private final Reason reason; diff --git a/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java b/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java index 0588706df7a71..ae463369f38e7 100644 --- a/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -166,18 +166,18 @@ public class HierarchyEvent extends AWTEvent { public static final int SHOWING_CHANGED = 0x4; /** - * The {@code Component} at the top of the hierarchy which was changed. + * @serial The {@code Component} at the top of the hierarchy which was changed. */ Component changed; /** - * The parent of the {@code changed} component. This may be the parent + * @serial The parent of the {@code changed} component. This may be the parent * before or after the change, depending on the type of change. */ Container changedParent; /** - * A bitmask which indicates the type(s) of the {@code HIERARCHY_CHANGED} + * @serial A bitmask which indicates the type(s) of the {@code HIERARCHY_CHANGED} * events represented in this event object. For information on allowable * values, see the class description for {@link HierarchyEvent} */ diff --git a/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java b/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java index c73b77282d539..b9966af5865d9 100644 --- a/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -85,6 +85,8 @@ public void dispose(InvocationEvent invocationEvent) { /** * The Runnable whose run() method will be called. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected Runnable runnable; @@ -95,12 +97,13 @@ public void dispose(InvocationEvent invocationEvent) { * or after the event was disposed. * * @see #isDispatched + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected volatile Object notifier; /** - * The (potentially null) Runnable whose run() method will be called + * @serial The (potentially null) Runnable whose run() method will be called * immediately after the event was dispatched or disposed. * * @see #isDispatched @@ -110,7 +113,7 @@ public void dispose(InvocationEvent invocationEvent) { private final Runnable listener; /** - * Indicates whether the {@code run()} method of the {@code runnable} + * @serial Indicates whether the {@code run()} method of the {@code runnable} * was executed or not. * * @see #isDispatched @@ -122,18 +125,20 @@ public void dispose(InvocationEvent invocationEvent) { * Set to true if dispatch() catches Throwable and stores it in the * exception instance variable. If false, Throwables are propagated up * to the EventDispatchThread's dispatch loop. + * + * @serial */ protected boolean catchExceptions; /** - * The (potentially null) Exception thrown during execution of the + * @serial The (potentially null) Exception thrown during execution of the * Runnable.run() method. This variable will also be null if a particular * instance does not catch exceptions. */ private Exception exception = null; /** - * The (potentially null) Throwable thrown during execution of the + * @serial The (potentially null) Throwable thrown during execution of the * Runnable.run() method. This variable will also be null if a particular * instance does not catch exceptions. */ diff --git a/src/java.desktop/share/classes/java/awt/event/KeyEvent.java b/src/java.desktop/share/classes/java/awt/event/KeyEvent.java index abc1082d5bd20..7470a23881e17 100644 --- a/src/java.desktop/share/classes/java/awt/event/KeyEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/KeyEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, 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 @@ -154,7 +154,7 @@ public non-sealed class KeyEvent extends InputEvent { /** - * Stores the state of native event dispatching system + * @serial Stores the state of native event dispatching system * - true, if when the event was created event proxying * mechanism was active * - false, if it was inactive @@ -1229,7 +1229,7 @@ public boolean isProxyActive(KeyEvent ev) { private static native void initIDs(); /** - * The original event source. + * @serial The original event source. * * Event source can be changed during processing, but in some cases * we need to be able to obtain original source. diff --git a/src/java.desktop/share/classes/java/awt/event/MouseEvent.java b/src/java.desktop/share/classes/java/awt/event/MouseEvent.java index 56ac76eeaff30..cabcb7b1d7d87 100644 --- a/src/java.desktop/share/classes/java/awt/event/MouseEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/MouseEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, 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 @@ -334,7 +334,7 @@ public non-sealed class MouseEvent extends InputEvent { int clickCount; /** - * Indicates whether the event is a result of a touch event. + * @serial Indicates whether the event is a result of a touch event. */ private boolean causedByTouchEvent; diff --git a/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java b/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java index 37efe0a04d77c..33a357888dd71 100644 --- a/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -118,7 +118,7 @@ public class MouseWheelEvent extends MouseEvent { @Native public static final int WHEEL_BLOCK_SCROLL = 1; /** - * Indicates what sort of scrolling should take place in response to this + * @serial Indicates what sort of scrolling should take place in response to this * event, based on platform settings. Legal values are: *

        *
      • WHEEL_UNIT_SCROLL @@ -130,7 +130,7 @@ public class MouseWheelEvent extends MouseEvent { int scrollType; /** - * Only valid for scrollType WHEEL_UNIT_SCROLL. + * @serial Only valid for scrollType WHEEL_UNIT_SCROLL. * Indicates number of units that should be scrolled per * click of mouse wheel rotation, based on platform settings. * @@ -140,14 +140,14 @@ public class MouseWheelEvent extends MouseEvent { int scrollAmount; /** - * Indicates how far the mouse wheel was rotated. + * @serial Indicates how far the mouse wheel was rotated. * * @see #getWheelRotation */ int wheelRotation; /** - * Indicates how far the mouse wheel was rotated. + * @serial Indicates how far the mouse wheel was rotated. * * @see #getPreciseWheelRotation */ diff --git a/src/java.desktop/share/classes/java/awt/event/WindowEvent.java b/src/java.desktop/share/classes/java/awt/event/WindowEvent.java index 51370170e510c..d898860f15373 100644 --- a/src/java.desktop/share/classes/java/awt/event/WindowEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/WindowEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, 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 @@ -165,12 +165,12 @@ public class WindowEvent extends ComponentEvent { transient Window opposite; /** - * Previous state of the window for window state change event. + * @serial Previous state of the window for window state change event. */ int oldState; /** - * New state of the window for window state change event. + * @serial New state of the window for window state change event. */ int newState; diff --git a/src/java.desktop/share/classes/java/awt/font/NumericShaper.java b/src/java.desktop/share/classes/java/awt/font/NumericShaper.java index c12d63e995151..ae50703611264 100644 --- a/src/java.desktop/share/classes/java/awt/font/NumericShaper.java +++ b/src/java.desktop/share/classes/java/awt/font/NumericShaper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -393,16 +393,16 @@ private boolean inRange(int c) { } } - /** index of context for contextual shaping - values range from 0 to 18 */ + /** @serial index of context for contextual shaping - values range from 0 to 18 */ private int key; - /** flag indicating whether to shape contextually (high bit) and which + /** @serial flag indicating whether to shape contextually (high bit) and which * digit ranges to shape (bits 0-18) */ private int mask; /** - * The context {@code Range} for contextual shaping or the {@code + * @serial The context {@code Range} for contextual shaping or the {@code * Range} for non-contextual shaping. {@code null} for the bit * mask-based API. * diff --git a/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java b/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java index 2dd25eec4d80a..9bcf83ddc83d0 100644 --- a/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java +++ b/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -53,7 +53,7 @@ public final class TransformAttribute implements Serializable { /** - * The {@code AffineTransform} for this + * @serial The {@code AffineTransform} for this * {@code TransformAttribute}, or {@code null} * if {@code AffineTransform} is the identity transform. */ diff --git a/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java b/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java index 10f627775268c..c98a5b2c771b2 100644 --- a/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java +++ b/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -102,10 +102,16 @@ public class ParameterBlock implements Cloneable, Serializable { @Serial private static final long serialVersionUID = -7577115551785240750L; - /** A Vector of sources, stored as arbitrary Objects. */ + /** + * A Vector of sources, stored as arbitrary Objects. + * @serial + */ protected Vector sources = new Vector(); - /** A Vector of non-source parameters, stored as arbitrary Objects. */ + /** + * A Vector of non-source parameters, stored as arbitrary Objects. + * @serial + */ protected Vector parameters = new Vector(); /** A dummy constructor. */ diff --git a/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java b/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java index 983dd8100797a..90c0fb109d2da 100644 --- a/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java +++ b/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -52,7 +52,7 @@ public class IndexedPropertyChangeEvent extends PropertyChangeEvent { private static final long serialVersionUID = -320227448495806870L; /** - * The index of the property element that was changed. + * @serial The index of the property element that was changed. */ private int index; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java index 532661dc29bf1..527a8be9cc06b 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -358,6 +358,8 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound /** * The {@code BeanContext} in which * this {@code BeanContextChild} is nested. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable public BeanContextChild beanContextChildPeer; @@ -365,12 +367,16 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound /** * The {@code PropertyChangeSupport} associated with this * {@code BeanContextChildSupport}. + * + * @serial */ protected PropertyChangeSupport pcSupport; /** * The {@code VetoableChangeSupport} associated with this * {@code BeanContextChildSupport}. + * + * @serial */ protected VetoableChangeSupport vcSupport; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java index 62fd45eee79fc..1b600bc29b401 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -105,6 +105,8 @@ public synchronized boolean isPropagated() { /** * The {@code BeanContext} from which this event was propagated + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected BeanContext propagatedFrom; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java index 5c5d112d36a45..ab63aae86e53b 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -133,6 +133,8 @@ public boolean contains(Object child) { /** * The list of children affected by this * event notification. + * + * @serial */ @SuppressWarnings({"rawtypes", "serial"}) // Not statically typed as Serializable diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java index dd4cc457a3110..b2132ad8f9755 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -84,6 +84,8 @@ public Iterator getCurrentServiceSelectors() { /** * A {@code Class} reference to the newly available service + * + * @serial */ protected Class serviceClass; } diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java index d32b18376a4fb..6ef996b348256 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -99,11 +99,13 @@ public boolean isServiceClass(Class service) { /** * A {@code Class} reference to the service that is being revoked. + * + * @serial */ protected Class serviceClass; /** - * {@code true} if current service is being forcibly revoked. + * @serial {@code true} if current service is being forcibly revoked. */ private boolean invalidateRefs; } diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java index 98d68d92fa15c..0e2e4211a9cef 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -627,6 +627,8 @@ protected BeanContextServiceProvider getServiceProvider() { /** * The service provider. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected BeanContextServiceProvider serviceProvider; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java index fedd6667de1bf..dbbecb87d7e7e 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -342,13 +342,13 @@ protected class BCSChild implements Serializable { /** - * The child. + * @serial The child. */ @SuppressWarnings("serial") // Not statically typed as Serializable private Object child; /** - * The peer if the child and the peer are related by an implementation + * @serial The peer if the child and the peer are related by an implementation * of BeanContextProxy */ @SuppressWarnings("serial") // Not statically typed as Serializable @@ -1393,7 +1393,7 @@ protected static final boolean classEquals(Class first, Class second) { protected transient HashMap children; /** - * Currently serializable children. + * @serial Currently serializable children. */ private int serializable = 0; // children serializable @@ -1407,12 +1407,16 @@ protected static final boolean classEquals(Class first, Class second) { /** * The current locale of this BeanContext. + * + * @serial */ protected Locale locale; /** * A {@code boolean} indicating if this * instance may now render a GUI. + * + * @serial */ protected boolean okToUseGui; @@ -1420,6 +1424,8 @@ protected static final boolean classEquals(Class first, Class second) { /** * A {@code boolean} indicating whether or not * this object is currently in design time mode. + * + * @serial */ protected boolean designTime; diff --git a/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java b/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java index 2c851ec2f0ee0..bc14958de1c38 100644 --- a/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java +++ b/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -57,6 +57,8 @@ public class IIOInvalidTreeException extends IIOException { /** * The {@code Node} that led to the parsing error, or * {@code null}. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected Node offendingNode = null; diff --git a/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java b/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java index 9244c12270a62..f762eb899257f 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java +++ b/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -86,7 +86,7 @@ private static class UnmodifiableAttributeSet private static final long serialVersionUID = -6131802583863447813L; /** - * The attribute set. + * @serial The attribute set. */ @SuppressWarnings("serial") // Not statically typed as Serializable private AttributeSet attrset; @@ -352,7 +352,7 @@ private static class SynchronizedAttributeSet private static final long serialVersionUID = 8365731020128564925L; /** - * The attribute set. + * @serial The attribute set. */ @SuppressWarnings("serial") // Not statically typed as Serializable private AttributeSet attrset; diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java index 807eaa2b12256..593e656cf6b79 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -67,7 +67,7 @@ public long getOwnerID(DialogOwner owner) { private static final long serialVersionUID = -1901909867156076547L; /** - * The owner of the dialog. + * @serial The owner of the dialog. */ private Window owner; private transient long id; diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java index c1d16c23154d2..72a58f2b6979b 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -85,12 +85,12 @@ public final class MediaPrintableArea implements DocAttribute, PrintRequestAttribute, PrintJobAttribute { /** - * Printable {@code x}, {@code y}, {@code width} and {@code height}. + * @serial Printable {@code x}, {@code y}, {@code width} and {@code height}. */ private int x, y, w, h; /** - * The units in which the values are expressed. + * @serial The units in which the values are expressed. */ private int units; diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java index bf33eabafac67..6a8db3b94c2e2 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -60,7 +60,7 @@ public class MediaSize extends Size2DSyntax implements Attribute { private static final long serialVersionUID = -1967958664615414771L; /** - * The media name. + * @serial The media name. */ private MediaSizeName mediaName; diff --git a/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java b/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java index ec244468c19b8..717898d8c5046 100644 --- a/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java +++ b/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -45,7 +45,7 @@ public class PrintJobAttributeEvent extends PrintEvent { private static final long serialVersionUID = -6534469883874742101L; /** - * The printing service attributes that changed. + * @serial The printing service attributes that changed. */ @SuppressWarnings("serial") // Not statically typed as Serializable private PrintJobAttributeSet attributes; diff --git a/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java b/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java index f68e2df5a0307..629a487e04a27 100644 --- a/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java +++ b/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -42,7 +42,7 @@ public class PrintJobEvent extends PrintEvent { private static final long serialVersionUID = -1711656903622072997L; /** - * The reason of this event. + * @serial The reason of this event. */ private int reason; diff --git a/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java b/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java index 4281c31b397e8..6cdc22246df37 100644 --- a/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java +++ b/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -45,7 +45,7 @@ public class PrintServiceAttributeEvent extends PrintEvent { private static final long serialVersionUID = -7565987018140326600L; /** - * The printing service attributes that changed. + * @serial The printing service attributes that changed. */ @SuppressWarnings("serial") // Not statically typed as Serializable private PrintServiceAttributeSet attributes; From 665c39c93109f9ba23f3d9555878c0fb565622df Mon Sep 17 00:00:00 2001 From: Alisen Chung Date: Thu, 9 Jan 2025 21:51:51 +0000 Subject: [PATCH 083/286] 8347375: Extra

        tag in robot specification Reviewed-by: kbarrett --- src/java.desktop/share/classes/java/awt/Robot.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/Robot.java b/src/java.desktop/share/classes/java/awt/Robot.java index d0877b3bddd95..957e30126e1c3 100644 --- a/src/java.desktop/share/classes/java/awt/Robot.java +++ b/src/java.desktop/share/classes/java/awt/Robot.java @@ -57,7 +57,7 @@ * events are generated in the platform's native input * queue. For example, {@code Robot.mouseMove} will actually move * the mouse cursor instead of just generating mouse move events. - *

        + * * @apiNote When {@code autoWaitForIdle()} is enabled, mouse and key related methods * cannot be called on the AWT EDT. This is because when {@code autoWaitForIdle()} * is enabled, the mouse and key methods implicitly call {@code waitForIdle()} @@ -666,7 +666,7 @@ public synchronized boolean isAutoWaitForIdle() { /** * Sets whether this Robot automatically invokes {@code waitForIdle} * after generating an event. - *

        + * * @apiNote Setting this to true means you cannot call mouse and key-controlling events * on the AWT Event Dispatching Thread * From 931914af76932c9b91fc9affd55d24b2562c72d2 Mon Sep 17 00:00:00 2001 From: Matias Saavedra Silva Date: Thu, 9 Jan 2025 22:06:37 +0000 Subject: [PATCH 084/286] 8340631: assert(reserved_rgn->contain_region(base_addr, size)) failed: Reserved CDS region should contain this mapping region Reviewed-by: iklam, jsjolen, stefank --- src/hotspot/share/cds/filemap.cpp | 27 ++++++++++++++++++++------- src/hotspot/share/cds/filemap.hpp | 4 +++- src/hotspot/share/include/cds.h | 3 ++- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index c87081d9d14e6..c6be8ab7947e0 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -1508,6 +1508,7 @@ void FileMapRegion::init(int region_index, size_t mapping_offset, size_t size, b _crc = crc; _mapped_from_file = false; _mapped_base = nullptr; + _in_reserved_space = false; } void FileMapRegion::init_oopmap(size_t offset, size_t size_in_bits) { @@ -1889,10 +1890,11 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba FileMapRegion* r = region_at(i); size_t size = r->used_aligned(); char *requested_addr = mapped_base_address + r->mapping_offset(); - assert(r->mapped_base() == nullptr, "must be not mapped yet"); + assert(!is_mapped(), "must be not mapped yet"); assert(requested_addr != nullptr, "must be specified"); r->set_mapped_from_file(false); + r->set_in_reserved_space(false); if (MetaspaceShared::use_windows_memory_mapping()) { // Windows cannot remap read-only shared memory to read-write when required for @@ -1917,7 +1919,6 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba return MAP_ARCHIVE_OTHER_FAILURE; // oom or I/O error. } else { assert(r->mapped_base() != nullptr, "must be initialized"); - return MAP_ARCHIVE_SUCCESS; } } else { // Note that this may either be a "fresh" mapping into unreserved address @@ -1939,9 +1940,16 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba r->set_mapped_from_file(true); r->set_mapped_base(requested_addr); + } - return MAP_ARCHIVE_SUCCESS; + if (rs.is_reserved()) { + char* mapped_base = r->mapped_base(); + assert(rs.base() <= mapped_base && mapped_base + size <= rs.end(), + PTR_FORMAT " <= " PTR_FORMAT " < " PTR_FORMAT " <= " PTR_FORMAT, + p2i(rs.base()), p2i(mapped_base), p2i(mapped_base + size), p2i(rs.end())); + r->set_in_reserved_space(rs.is_reserved()); } + return MAP_ARCHIVE_SUCCESS; } // The return value is the location of the archive relocation bitmap. @@ -2359,7 +2367,6 @@ bool FileMapInfo::map_heap_region_impl() { if (bitmap_base == nullptr) { log_info(cds)("CDS heap cannot be used because bitmap region cannot be mapped"); dealloc_heap_region(); - unmap_region(MetaspaceShared::hp); _heap_pointers_need_patching = false; return false; } @@ -2428,8 +2435,14 @@ void FileMapInfo::unmap_region(int i) { if (size > 0 && r->mapped_from_file()) { log_info(cds)("Unmapping region #%d at base " INTPTR_FORMAT " (%s)", i, p2i(mapped_base), shared_region_name[i]); - if (!os::unmap_memory(mapped_base, size)) { - fatal("os::unmap_memory failed"); + if (r->in_reserved_space()) { + // This region was mapped inside a ReservedSpace. Its memory will be freed when the ReservedSpace + // is released. Zero it so that we don't accidentally read its content. + log_info(cds)("Region #%d (%s) is in a reserved space, it will be freed when the space is released", i, shared_region_name[i]); + } else { + if (!os::unmap_memory(mapped_base, size)) { + fatal("os::unmap_memory failed"); + } } } r->set_mapped_base(nullptr); diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index d097cb0eda6c9..ae11c6c81cc17 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -163,11 +163,13 @@ class FileMapRegion: private CDSFileMapRegion { size_t oopmap_size_in_bits() const { assert_is_heap_region(); return _oopmap_size_in_bits; } size_t ptrmap_offset() const { return _ptrmap_offset; } size_t ptrmap_size_in_bits() const { return _ptrmap_size_in_bits; } + bool in_reserved_space() const { return _in_reserved_space; } void set_file_offset(size_t s) { _file_offset = s; } void set_read_only(bool v) { _read_only = v; } void set_mapped_base(char* p) { _mapped_base = p; } void set_mapped_from_file(bool v) { _mapped_from_file = v; } + void set_in_reserved_space(bool is_reserved) { _in_reserved_space = is_reserved; } void init(int region_index, size_t mapping_offset, size_t size, bool read_only, bool allow_exec, int crc); void init_oopmap(size_t offset, size_t size_in_bits); diff --git a/src/hotspot/share/include/cds.h b/src/hotspot/share/include/cds.h index eb8010d625fdc..16d9d74e3982f 100644 --- a/src/hotspot/share/include/cds.h +++ b/src/hotspot/share/include/cds.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -70,6 +70,7 @@ typedef struct CDSFileMapRegion { // (The base address is the bottom of the BM region). size_t _ptrmap_size_in_bits; char* _mapped_base; // Actually mapped address (null if this region is not mapped). + bool _in_reserved_space; // Is this region in a ReservedSpace } CDSFileMapRegion; // This portion of the archive file header must remain unchanged for From 89ee1a5517ea1e3915f4362ada3d2086b63c107e Mon Sep 17 00:00:00 2001 From: Liming Liu Date: Thu, 9 Jan 2025 23:38:20 +0000 Subject: [PATCH 085/286] 8343978: Update the default value of CodeEntryAlignment for Ampere-1A and 1B Reviewed-by: dlong, kvn --- src/hotspot/cpu/aarch64/vm_version_aarch64.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 87c7862e2503d..418e5145f71de 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -158,6 +158,10 @@ void VM_Version::initialize() { if (FLAG_IS_DEFAULT(OnSpinWaitInstCount)) { FLAG_SET_DEFAULT(OnSpinWaitInstCount, 2); } + if (FLAG_IS_DEFAULT(CodeEntryAlignment) && + (_model == CPU_MODEL_AMPERE_1A || _model == CPU_MODEL_AMPERE_1B)) { + FLAG_SET_DEFAULT(CodeEntryAlignment, 32); + } } // ThunderX From a9351dfec9e69f6d5671b9372a44de999e8ed3e6 Mon Sep 17 00:00:00 2001 From: Fei Yang Date: Fri, 10 Jan 2025 00:26:38 +0000 Subject: [PATCH 086/286] 8346787: Fix two C2 IR matching tests for RISC-V Reviewed-by: fjiang, mli, dfenacci --- .../compiler/c2/irTests/ModINodeIdealizationTests.java | 8 +++++--- .../compiler/c2/irTests/ModLNodeIdealizationTests.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java b/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java index 2437b05586ac1..dffafea7ea8cf 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -121,8 +121,10 @@ public int powerOf2Random(int x) { } @Test - @IR(failOn = {IRNode.MOD_I}) - @IR(counts = {IRNode.AND_I, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_I, "2"}) + @IR(applyIfPlatform = {"riscv64", "false"}, + failOn = {IRNode.MOD_I}) + @IR(applyIfPlatform = {"riscv64", "false"}, + counts = {IRNode.AND_I, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_I, "2"}) // Special optimization for the case 2^k-1 for bigger k public int powerOf2Minus1(int x) { return x % 127; diff --git a/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java b/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java index 515a7d535f449..e931ff87c093d 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -105,8 +105,10 @@ public long powerOf2Random(long x) { } @Test - @IR(failOn = {IRNode.MOD_L}) - @IR(counts = {IRNode.AND_L, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_L, "2"}) + @IR(applyIfPlatform = {"riscv64", "false"}, + failOn = {IRNode.MOD_L}) + @IR(applyIfPlatform = {"riscv64", "false"}, + counts = {IRNode.AND_L, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_L, "2"}) // Special optimization for the case 2^k-1 for bigger k public long powerOf2Minus1(long x) { return x % ((1L << 33) - 1); From 0210a63d3b9e6c5a8640ac3a9908b755ac57f2d9 Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Fri, 10 Jan 2025 00:53:58 +0000 Subject: [PATCH 087/286] 8347379: Problem list failed tests after JDK-8321413 Reviewed-by: dholmes --- test/jdk/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 6a2ab0d1e0451..b82d661bd2d99 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -716,6 +716,8 @@ javax/swing/plaf/synth/7158712/bug7158712.java 8324782 macosx-all # core_tools +tools/jlink/runtimeImage/JavaSEReproducibleTest.java 8347376 generic-all +tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java 8347376 generic-all ############################################################################ From f6492aa63486393593ea8761cef5362ef46abf13 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Fri, 10 Jan 2025 01:38:18 +0000 Subject: [PATCH 088/286] 8347279: Problemlist TestEvilSyncBug.java#generational Reviewed-by: tschatzl, wkemper --- test/hotspot/jtreg/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index e17b5a9b600d7..07d5795a59789 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -96,6 +96,7 @@ gc/TestAlwaysPreTouchBehavior.java#Z 8334513 generic-all gc/TestAlwaysPreTouchBehavior.java#Epsilon 8334513 generic-all gc/stress/gclocker/TestExcessGCLockerCollections.java 8229120 generic-all gc/shenandoah/oom/TestAllocOutOfMemory.java#large 8344312 linux-ppc64le +gc/shenandoah/TestEvilSyncBug.java#generational 8345501 generic-all ############################################################################# From 8b076172a523ee9e845ee9d8b36e7d430206448c Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Fri, 10 Jan 2025 07:59:26 +0000 Subject: [PATCH 089/286] 8347345: Remove redundant test policy file from ModelMBeanInfoSupport directory Reviewed-by: rriggs, sspitsyn --- .../modelmbean/ModelMBeanInfoSupport/policy | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 test/jdk/javax/management/modelmbean/ModelMBeanInfoSupport/policy diff --git a/test/jdk/javax/management/modelmbean/ModelMBeanInfoSupport/policy b/test/jdk/javax/management/modelmbean/ModelMBeanInfoSupport/policy deleted file mode 100644 index ac5336ce882d9..0000000000000 --- a/test/jdk/javax/management/modelmbean/ModelMBeanInfoSupport/policy +++ /dev/null @@ -1,14 +0,0 @@ -grant { - permission javax.management.MBeanServerPermission "createMBeanServer"; - permission javax.management.MBeanPermission "javax.management.modelmbean.RequiredModelMBean#-[-]", "instantiate"; - permission javax.management.MBeanPermission "javax.management.modelmbean.RequiredModelMBean#-[*:*]", "registerMBean"; - permission javax.management.MBeanPermission "javax.management.modelmbean.RequiredModelMBean#*[*:*]", "getAttribute"; - permission javax.management.MBeanPermission "javax.management.modelmbean.RequiredModelMBean#*[*:*]", "setAttribute"; - permission javax.management.MBeanPermission "javax.management.modelmbean.RequiredModelMBean#*[*:*]", "invoke"; - permission javax.management.MBeanPermission "GetAllDescriptorsTest$Resource#-[*:*]", "registerMBean"; - permission javax.management.MBeanPermission "GetAllDescriptorsTest$Resource#*[*:*]", "invoke"; - permission javax.management.MBeanPermission "GetAllDescriptorsTest$Resource#*[*:*]", "getAttribute"; - permission javax.management.MBeanPermission "GetAllDescriptorsTest$Resource#*[*:*]", "setAttribute"; - permission javax.management.MBeanPermission "GetAllDescriptorsTest$Resource#*[*:*]", "getMBeanInfo"; - -}; From 1a0fe49732187db9e8776f80feefab4373114f75 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Fri, 10 Jan 2025 08:42:42 +0000 Subject: [PATCH 090/286] 8347256: Epsilon: Demote heap size and AlwaysPreTouch warnings to info level Reviewed-by: tschatzl, phh --- .../share/gc/epsilon/epsilonInitLogger.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp b/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp index a75e9e7679da7..bc35eddeba5c6 100644 --- a/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp @@ -32,18 +32,6 @@ #include "utilities/globalDefinitions.hpp" void EpsilonInitLogger::print_gc_specific() { - // Warn users that non-resizable heap might be better for some configurations. - // We are not adjusting the heap size by ourselves, because it affects startup time. - if (InitialHeapSize != MaxHeapSize) { - log_warning(gc, init)("Consider setting -Xms equal to -Xmx to avoid resizing hiccups"); - } - - // Warn users that AlwaysPreTouch might be better for some configurations. - // We are not turning this on by ourselves, because it affects startup time. - if (FLAG_IS_DEFAULT(AlwaysPreTouch) && !AlwaysPreTouch) { - log_warning(gc, init)("Consider enabling -XX:+AlwaysPreTouch to avoid memory commit hiccups"); - } - if (UseTLAB) { size_t max_tlab = EpsilonHeap::heap()->max_tlab_size() * HeapWordSize; log_info(gc, init)("TLAB Size Max: " SIZE_FORMAT "%s", @@ -57,6 +45,18 @@ void EpsilonInitLogger::print_gc_specific() { } else { log_info(gc, init)("TLAB: Disabled"); } + + // Suggest that non-resizable heap might be better for some configurations. + // We are not adjusting the heap size by ourselves, because it affects startup time. + if (InitialHeapSize != MaxHeapSize) { + log_info(gc)("Consider setting -Xms equal to -Xmx to avoid resizing hiccups"); + } + + // Suggest that AlwaysPreTouch might be better for some configurations. + // We are not turning this on by ourselves, because it affects startup time. + if (FLAG_IS_DEFAULT(AlwaysPreTouch) && !AlwaysPreTouch) { + log_info(gc)("Consider enabling -XX:+AlwaysPreTouch to avoid memory commit hiccups"); + } } void EpsilonInitLogger::print() { From 55c6904e8f3d02530749bf28f2cc966e8983a984 Mon Sep 17 00:00:00 2001 From: Theo Weidmann Date: Fri, 10 Jan 2025 08:59:31 +0000 Subject: [PATCH 091/286] 8331717: C2: Crash with SIGFPE Because Loop Predication Wrongly Hoists Division Requiring Zero Check Reviewed-by: chagedorn, qamai, kvn --- src/hotspot/share/opto/loopPredicate.cpp | 2 +- .../TestLoopPredicationDivZeroCheck.java | 89 +++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/compiler/loopopts/TestLoopPredicationDivZeroCheck.java diff --git a/src/hotspot/share/opto/loopPredicate.cpp b/src/hotspot/share/opto/loopPredicate.cpp index 02649d3711a99..0ff08712624a0 100644 --- a/src/hotspot/share/opto/loopPredicate.cpp +++ b/src/hotspot/share/opto/loopPredicate.cpp @@ -469,7 +469,7 @@ class Invariance : public StackObj { // loop, it was marked invariant but n is only invariant if // it depends only on that test. Otherwise, unless that test // is out of the loop, it's not invariant. - if (n->is_CFG() || n->depends_only_on_test() || n->in(0) == nullptr || !_phase->is_member(_lpt, n->in(0))) { + if (n->is_CFG() || (n->depends_only_on_test() && _phase->igvn().no_dependent_zero_check(n)) || n->in(0) == nullptr || !_phase->is_member(_lpt, n->in(0))) { _invariant.set(n->_idx); // I am a invariant too } } diff --git a/test/hotspot/jtreg/compiler/loopopts/TestLoopPredicationDivZeroCheck.java b/test/hotspot/jtreg/compiler/loopopts/TestLoopPredicationDivZeroCheck.java new file mode 100644 index 0000000000000..82935475aa0a5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestLoopPredicationDivZeroCheck.java @@ -0,0 +1,89 @@ +/* + * 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 8331717 + * @summary C2: Crash with SIGFPE + * + * @run main/othervm -XX:CompileCommand=compileonly,*TestLoopPredicationDivZeroCheck*::* -XX:-TieredCompilation -Xbatch TestLoopPredicationDivZeroCheck + */ + +public class TestLoopPredicationDivZeroCheck { + static int iArr[] = new int[100]; + static volatile long lFld; + static int iFld; + + public static void main(String[] strArr) { + for (int i = 0; i < 10000; i++) { + test(); + } + for (int i = 0; i < 10000; i++) { + test2(); + } + } + + /* + * The division 2 / i4 requires a non-zero check. As the result is an array access, it will be the input to a range + * check. Loop predication will try to move the range check and the division to right before the loop as the division + * appears to be invariant (i4 is always 0). However, the division is not truly invariant as it requires the zero + * check for i4 that can throw an exception. The bug fixed in 8331717 caused the division to still be moved before the + * for loop with the range check. + */ + static void test() { + int i1 = 0; + + for (int i4 : iArr) { + i4 = i1; + try { + iArr[0] = 1 / i4; + i4 = iArr[2 / i4]; + } catch (ArithmeticException a_e) { + } + } + } + + /* + * Loop predication will try to move 3 / y (input to the range check for bArr[x / 30]) before its containing for loop + * but it may not as y must be zero-checked. The same problem as above occurred before the fix in 8331717. + */ + static void test2() { + int x = 0; + int y = iFld; + long lArr[] = new long[400]; + boolean bArr[] = new boolean[400]; + for (int i = 0; i < 10000; i++) { + for (int j = 1; j < 13; j++) { + for (int k = 1; k < 2; k++) { + lFld = 0; + lArr[1] = 7; + try { + x = 3 / y; + } catch (ArithmeticException a_e) { + } + bArr[x / 30] = true; + } + } + } + } +} From 5e92a4ceafd0626e3600e44a3370ca2f5d9347c8 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 10 Jan 2025 10:02:24 +0000 Subject: [PATCH 092/286] 8347267: [macOS]: UnixOperatingSystem.c:67:40: runtime error: division by zero Reviewed-by: kevinw, cjplummer --- .../macosx/native/libmanagement_ext/UnixOperatingSystem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c b/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c index 2c11cd9ca9d8d..269c4d4535909 100644 --- a/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c +++ b/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 @@ -63,6 +63,9 @@ Java_com_sun_management_internal_OperatingSystemImpl_getCpuLoad0 jlong used_delta = used - last_used; jlong total_delta = total - last_total; + if (total_delta == 0) { + return 0; + } jdouble cpu = (jdouble) used_delta / total_delta; From 1f457977f062e4ed219c6fa0fe26cb42acaf4bf2 Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Fri, 10 Jan 2025 10:06:24 +0000 Subject: [PATCH 093/286] 8347124: Clean tests with --enable-linkable-runtime Reviewed-by: shade, alanb --- test/jdk/jdk/jfr/jvm/TestModularImage.java | 9 +++++++-- test/jdk/tools/launcher/SourceMode.java | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/test/jdk/jdk/jfr/jvm/TestModularImage.java b/test/jdk/jdk/jfr/jvm/TestModularImage.java index 0f10150af601a..7a01936517870 100644 --- a/test/jdk/jdk/jfr/jvm/TestModularImage.java +++ b/test/jdk/jdk/jfr/jvm/TestModularImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -43,7 +43,12 @@ * as expected * @requires vm.hasJFR * @library /test/lib - * @run driver jdk.jfr.jvm.TestModularImage + * @comment Test is being run in othervm to support JEP 493 enabled + * JDKs which don't allow patched modules. Note that jtreg patches + * module java.base to add java.lang.JTRegModuleHelper. If then a + * jlink run is attempted in-process - using the ToolProvider API - + * on a JEP 493 enabled JDK, the test fails. + * @run main/othervm jdk.jfr.jvm.TestModularImage */ public class TestModularImage { private static final String STARTED_RECORDING = "Started recording"; diff --git a/test/jdk/tools/launcher/SourceMode.java b/test/jdk/tools/launcher/SourceMode.java index 20e8822856362..23f0b12e9b491 100644 --- a/test/jdk/tools/launcher/SourceMode.java +++ b/test/jdk/tools/launcher/SourceMode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, 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,7 +26,12 @@ * @bug 8192920 8204588 8210275 8286571 * @summary Test source mode * @modules jdk.compiler jdk.jlink - * @run main SourceMode + * @comment Test is being run in othervm to support JEP 493 enabled + * JDKs which don't allow patched modules. Note that jtreg patches + * module java.base to add java.lang.JTRegModuleHelper. If then a + * jlink run is attempted in-process - using the ToolProvider API - + * on a JEP 493 enabled JDK, the test fails. + * @run main/othervm SourceMode */ From 57af52c57390f6f7413b5d3ffe64921c9b83aae4 Mon Sep 17 00:00:00 2001 From: Alexey Ivanov Date: Fri, 10 Jan 2025 10:34:22 +0000 Subject: [PATCH 094/286] 8346581: JRadioButton/ButtonGroupFocusTest.java fails in CI on Linux Reviewed-by: honkar, dnguyen --- .../ButtonGroupFocusTest.java | 150 +++++++++++++----- 1 file changed, 111 insertions(+), 39 deletions(-) diff --git a/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java b/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java index c696b166dd085..633b0356f85df 100644 --- a/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java +++ b/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,26 +28,53 @@ * @run main ButtonGroupFocusTest */ -import javax.swing.*; -import java.awt.*; +import java.awt.AWTEvent; +import java.awt.Container; +import java.awt.FlowLayout; +import java.awt.KeyboardFocusManager; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.concurrent.CountDownLatch; -public class ButtonGroupFocusTest { +import javax.imageio.ImageIO; +import javax.swing.ButtonGroup; +import javax.swing.JFrame; +import javax.swing.JRadioButton; +import javax.swing.SwingUtilities; + +import static java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +public final class ButtonGroupFocusTest { private static JRadioButton button1; private static JRadioButton button2; private static JRadioButton button3; private static JRadioButton button4; private static JRadioButton button5; - private static Robot robot; + + private static final CountDownLatch button2FocusLatch = new CountDownLatch(1); + private static final CountDownLatch button3FocusLatch = new CountDownLatch(1); + private static final CountDownLatch button4FocusLatch = new CountDownLatch(1); + + private static final CountDownLatch button2FocusLatch2 = new CountDownLatch(2); + + private static final long FOCUS_TIMEOUT = 4; + private static JFrame frame; public static void main(String[] args) throws Exception { - robot = new Robot(); - robot.setAutoDelay(100); + final Robot robot = new Robot(); SwingUtilities.invokeAndWait(() -> { - frame = new JFrame(); + frame = new JFrame("ButtonGroupFocusTest"); Container contentPane = frame.getContentPane(); contentPane.setLayout(new FlowLayout()); button1 = new JRadioButton("Button 1"); @@ -60,6 +87,7 @@ public static void main(String[] args) throws Exception { contentPane.add(button4); button5 = new JRadioButton("Button 5"); contentPane.add(button5); + ButtonGroup group = new ButtonGroup(); group.add(button1); group.add(button2); @@ -69,52 +97,96 @@ public static void main(String[] args) throws Exception { group.add(button4); group.add(button5); + button2.addFocusListener(new LatchFocusListener(button2FocusLatch)); + button3.addFocusListener(new LatchFocusListener(button3FocusLatch)); + button4.addFocusListener(new LatchFocusListener(button4FocusLatch)); + + button2.addFocusListener(new LatchFocusListener(button2FocusLatch2)); + button2.setSelected(true); + // Debugging aid: log focus owner changes... + KeyboardFocusManager focusManager = getCurrentKeyboardFocusManager(); + focusManager.addPropertyChangeListener("focusOwner", + e -> System.out.println(e.getPropertyName() + + "\n\t" + e.getOldValue() + + "\n\t" + e.getNewValue())); + + // ...and dispatched key events + Toolkit.getDefaultToolkit().addAWTEventListener( + e -> System.out.println("Dispatched " + e), + AWTEvent.KEY_EVENT_MASK); + frame.pack(); + frame.setLocationRelativeTo(null); frame.setVisible(true); }); - robot.waitForIdle(); - robot.delay(200); - - SwingUtilities.invokeAndWait(() -> { - if( !button2.hasFocus() ) { - frame.dispose(); - throw new RuntimeException( - "Button 2 should get focus after activation"); + try { + if (!button2FocusLatch.await(FOCUS_TIMEOUT, SECONDS)) { + throw new RuntimeException("Button 2 should get focus " + + "after activation"); } - }); + robot.waitForIdle(); + robot.delay(200); - robot.keyPress(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_TAB); + System.out.println("\n\n*** Tab 1st"); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); - robot.waitForIdle(); - robot.delay(200); + if (!button4FocusLatch.await(FOCUS_TIMEOUT, SECONDS)) { + throw new RuntimeException("Button 4 should get focus"); + } + robot.waitForIdle(); + robot.delay(200); - SwingUtilities.invokeAndWait(() -> { - if( !button4.hasFocus() ) { - frame.dispose(); - throw new RuntimeException( - "Button 4 should get focus"); + if (button2FocusLatch2.await(1, MILLISECONDS)) { + throw new RuntimeException("Focus moved back to Button 2"); } - button3.setSelected(true); - }); - robot.keyPress(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_TAB); + SwingUtilities.invokeAndWait(() -> button3.setSelected(true)); + robot.waitForIdle(); + robot.delay(200); - robot.waitForIdle(); - robot.delay(200); + System.out.println("\n\n*** Tab 2nd"); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); - SwingUtilities.invokeAndWait(() -> { - if( !button3.hasFocus() ) { - frame.dispose(); - throw new RuntimeException( - "selected Button 3 should get focus"); + if (!button3FocusLatch.await(FOCUS_TIMEOUT, SECONDS)) { + throw new RuntimeException("Selected Button 3 should get focus"); } - }); + } catch (Exception e) { + BufferedImage image = robot.createScreenCapture(getFrameBounds()); + ImageIO.write(image, "png", + new File("image.png")); + + SwingUtilities.invokeAndWait(() -> + System.err.println("Current focus owner: " + + getCurrentKeyboardFocusManager() + .getFocusOwner())); + + throw e; + } finally { + SwingUtilities.invokeAndWait(frame::dispose); + } + } + + private static Rectangle getFrameBounds() throws Exception { + Rectangle[] bounds = new Rectangle[1]; + SwingUtilities.invokeAndWait(() -> bounds[0] = frame.getBounds()); + return bounds[0]; + } + + private static final class LatchFocusListener extends FocusAdapter { + private final CountDownLatch focusGainedLatch; + + private LatchFocusListener(CountDownLatch focusGainedLatch) { + this.focusGainedLatch = focusGainedLatch; + } - SwingUtilities.invokeLater(frame::dispose); + @Override + public void focusGained(FocusEvent e) { + focusGainedLatch.countDown(); + } } } From 12752b0031643b3bf868de50b4455654162b2ee4 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Fri, 10 Jan 2025 10:51:34 +0000 Subject: [PATCH 095/286] 8347346: Remove redundant ClassForName.java and test.policy from runtime/Dictionary Reviewed-by: coleenp --- .../runtime/Dictionary/ClassForName.java | 47 ------------------- .../jtreg/runtime/Dictionary/test.policy | 6 --- 2 files changed, 53 deletions(-) delete mode 100644 test/hotspot/jtreg/runtime/Dictionary/ClassForName.java delete mode 100644 test/hotspot/jtreg/runtime/Dictionary/test.policy diff --git a/test/hotspot/jtreg/runtime/Dictionary/ClassForName.java b/test/hotspot/jtreg/runtime/Dictionary/ClassForName.java deleted file mode 100644 index a2bbbd0369643..0000000000000 --- a/test/hotspot/jtreg/runtime/Dictionary/ClassForName.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.net.URLClassLoader; - -/* - * This class is loaded by the custom URLClassLoader, and then calls - * Class.forName() with the protection domain for the checkPackageAccess - * call created from the code source jar file. - */ -public class ClassForName { - static { - if (!(ClassForName.class.getClassLoader() instanceof URLClassLoader)) { - throw new RuntimeException("Supposed to be loaded by URLClassLoader"); - } - } - - public ClassForName() { - try { - // class_loader = App$ClassLoader, protection_domain = ClassForName.getProtectionDomain() - Class.forName(java.util.List.class.getName(), false, - ClassLoader.getSystemClassLoader()); - } catch (Throwable e) { - e.printStackTrace(); - } - } -} diff --git a/test/hotspot/jtreg/runtime/Dictionary/test.policy b/test/hotspot/jtreg/runtime/Dictionary/test.policy deleted file mode 100644 index 06998b8bcae85..0000000000000 --- a/test/hotspot/jtreg/runtime/Dictionary/test.policy +++ /dev/null @@ -1,6 +0,0 @@ -grant { - permission java.io.FilePermission "<>", "read, write, delete, execute"; - permission java.lang.RuntimePermission "createClassLoader"; - permission java.lang.RuntimePermission "getClassLoader"; - permission java.util.PropertyPermission "*", "read"; /* for Utils */ -}; From ec7393e9190c1b93ca08e1107f734c869f400b89 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 10 Jan 2025 13:46:57 +0000 Subject: [PATCH 096/286] 8347287: JFR: Remove use of Security Manager Reviewed-by: mgronlun --- .../share/jfr/support/jfrIntrinsics.hpp | 4 +- .../share/jfr/support/jfrResolution.cpp | 18 +- .../classes/jdk/jfr/AnnotationElement.java | 4 +- .../share/classes/jdk/jfr/EventFactory.java | 5 +- .../share/classes/jdk/jfr/FlightRecorder.java | 14 +- .../jdk/jfr/FlightRecorderPermission.java | 12 +- .../share/classes/jdk/jfr/Recording.java | 14 +- .../share/classes/jdk/jfr/SettingControl.java | 26 +- .../classes/jdk/jfr/ValueDescriptor.java | 4 +- .../classes/jdk/jfr/consumer/EventStream.java | 17 +- .../jdk/jfr/consumer/RecordingFile.java | 9 +- .../jdk/jfr/consumer/RecordingStream.java | 10 +- .../jdk/jfr/internal/ChunkInputStream.java | 5 +- .../classes/jdk/jfr/internal/Control.java | 81 +--- .../jdk/jfr/internal/EventControl.java | 11 +- .../jfr/internal/EventInstrumentation.java | 8 +- .../classes/jdk/jfr/internal/FilePurger.java | 24 +- .../classes/jdk/jfr/internal/JDKEvents.java | 36 +- .../classes/jdk/jfr/internal/JVMSupport.java | 4 +- .../classes/jdk/jfr/internal/JVMUpcalls.java | 8 +- .../jdk/jfr/internal/MetadataLoader.java | 4 +- .../jdk/jfr/internal/MetadataRepository.java | 6 +- .../classes/jdk/jfr/internal/Options.java | 17 +- .../jdk/jfr/internal/PlatformRecorder.java | 61 +-- .../jdk/jfr/internal/PlatformRecording.java | 105 ++-- .../jdk/jfr/internal/PrivateAccess.java | 9 +- .../classes/jdk/jfr/internal/Repository.java | 86 ++-- .../jdk/jfr/internal/RepositoryChunk.java | 32 +- .../jdk/jfr/internal/SecuritySupport.java | 459 +----------------- .../jdk/jfr/internal/ShutdownHook.java | 12 +- .../classes/jdk/jfr/internal/TypeLibrary.java | 4 +- .../JDKEventTask.java => WriteablePath.java} | 56 ++- .../jdk/jfr/internal/WriteableUserPath.java | 148 ------ .../consumer/AbstractEventStream.java | 31 +- .../consumer/EventDirectoryStream.java | 19 +- .../internal/consumer/EventFileStream.java | 9 +- .../jdk/jfr/internal/consumer/FileAccess.java | 97 ---- .../jfr/internal/consumer/OngoingStream.java | 10 +- .../jfr/internal/consumer/RecordingInput.java | 19 +- .../internal/consumer/RepositoryFiles.java | 26 +- .../internal/consumer/filter/ChunkWriter.java | 5 +- .../jdk/jfr/internal/dcmd/AbstractDCmd.java | 33 +- .../jdk/jfr/internal/dcmd/DCmdConfigure.java | 8 +- .../jdk/jfr/internal/dcmd/DCmdDump.java | 18 +- .../jdk/jfr/internal/dcmd/DCmdStart.java | 24 +- .../jdk/jfr/internal/dcmd/DCmdStop.java | 16 +- .../jdk/jfr/internal/event/EventWriter.java | 34 +- .../classes/jdk/jfr/internal/jfc/JFC.java | 65 +-- .../jdk/jfr/internal/jfc/model/JFCModel.java | 10 +- .../internal/management/ChunkFilename.java | 24 +- .../management/ManagementSupport.java | 25 +- .../jfr/internal/periodic/JavaEventTask.java | 11 +- .../jdk/jfr/internal/periodic/LookupKey.java | 9 +- .../jfr/internal/periodic/PeriodicEvents.java | 11 +- .../jfr/internal/periodic/PeriodicTask.java | 9 +- .../jfr/internal/periodic/UserEventTask.java | 71 --- .../jfr/internal/settings/BooleanSetting.java | 5 +- .../jfr/internal/settings/CutoffSetting.java | 5 +- .../internal/settings/JDKSettingControl.java | 35 -- .../jfr/internal/settings/LevelSetting.java | 5 +- .../jfr/internal/settings/PeriodSetting.java | 5 +- .../internal/settings/ThresholdSetting.java | 5 +- .../internal/settings/ThrottleSetting.java | 5 +- .../jdk/jfr/internal/tool/Command.java | 4 +- .../jdk/jfr/internal/tool/Configure.java | 23 +- .../jdk/jfr/internal/tool/Disassemble.java | 5 +- .../jdk/jfr/internal/tool/Summary.java | 5 +- .../DirectoryCleaner.java} | 40 +- .../classes/jdk/jfr/internal/util/Utils.java | 13 +- .../jdk/management/jfr/DiskRepository.java | 4 +- .../jfr/FlightRecorderMXBeanImpl.java | 73 +-- .../jdk/management/jfr/MBeanUtils.java | 23 +- .../management/jfr/RemoteRecordingStream.java | 13 +- test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java | 10 +- .../jfr/jvm/MyCommitRegisteredFalseEvent.java | 4 +- .../jfr/jvm/MyCommitRegisteredTrueEvent.java | 4 +- test/jdk/jdk/jfr/jvm/NonEvent.java | 4 +- .../jdk/jfr/jvm/PlaceholderEventWriter.java | 6 +- .../jvm/PlaceholderEventWriterFactory.java | 35 -- .../jdk/jdk/jfr/jvm/RegisteredFalseEvent.java | 4 +- test/jdk/jdk/jfr/jvm/RegisteredTrueEvent.java | 4 +- test/jdk/jdk/jfr/jvm/StaticCommitEvent.java | 4 +- test/jdk/jdk/jfr/jvm/TestGetEventWriter.java | 32 +- test/jdk/jdk/jfr/tool/TestAssemble.java | 5 +- 84 files changed, 547 insertions(+), 1730 deletions(-) rename src/jdk.jfr/share/classes/jdk/jfr/internal/{periodic/JDKEventTask.java => WriteablePath.java} (52%) delete mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/WriteableUserPath.java delete mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/FileAccess.java delete mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/UserEventTask.java delete mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/settings/JDKSettingControl.java rename src/jdk.jfr/share/classes/jdk/jfr/internal/{EventWriterFactoryRecipe.java => util/DirectoryCleaner.java} (56%) delete mode 100644 test/jdk/jdk/jfr/jvm/PlaceholderEventWriterFactory.java diff --git a/src/hotspot/share/jfr/support/jfrIntrinsics.hpp b/src/hotspot/share/jfr/support/jfrIntrinsics.hpp index 77affc69926f0..31a81e7d7b544 100644 --- a/src/hotspot/share/jfr/support/jfrIntrinsics.hpp +++ b/src/hotspot/share/jfr/support/jfrIntrinsics.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2012, 2025, 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 @@ -49,7 +49,7 @@ class JfrIntrinsicSupport : AllStatic { #define JFR_TEMPLATES(template) \ template(jdk_jfr_internal_management_HiddenWait, "jdk/jfr/internal/management/HiddenWait") \ template(jdk_jfr_internal_JVM, "jdk/jfr/internal/JVM") \ - template(jdk_jfr_internal_event_EventWriterFactory, "jdk/jfr/internal/event/EventWriterFactory") \ + template(jdk_jfr_internal_event_EventWriter, "jdk/jfr/internal/event/EventWriter") \ template(jdk_jfr_internal_event_EventConfiguration_signature, "Ljdk/jfr/internal/event/EventConfiguration;") \ template(getEventWriter_signature, "()Ljdk/jfr/internal/event/EventWriter;") \ template(eventConfiguration_name, "eventConfiguration") \ diff --git a/src/hotspot/share/jfr/support/jfrResolution.cpp b/src/hotspot/share/jfr/support/jfrResolution.cpp index 486067c485a72..0a4c8a1f3f100 100644 --- a/src/hotspot/share/jfr/support/jfrResolution.cpp +++ b/src/hotspot/share/jfr/support/jfrResolution.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -182,7 +182,7 @@ static inline const Method* ljf_sender_method(JavaThread* jt) { return ljf.method(); } -static const char* const link_error_msg = "illegal access linking method 'jdk.jfr.internal.event.EventWriterFactory.getEventWriter(long)'"; +static const char* const link_error_msg = "illegal access linking method 'jdk.jfr.internal.event.EventWriter.getEventWriter()'"; void JfrResolution::on_runtime_resolution(const CallInfo & info, TRAPS) { assert(info.selected_method() != nullptr, "invariant"); @@ -199,12 +199,12 @@ void JfrResolution::on_runtime_resolution(const CallInfo & info, TRAPS) { if (method->name() != event_writer_method_name) { return; } - static const Symbol* const event_writer_factory_klass_name = vmSymbols::jdk_jfr_internal_event_EventWriterFactory(); - assert(event_writer_factory_klass_name != nullptr, "invariant"); - if (info.resolved_klass()->name() != event_writer_factory_klass_name) { + static const Symbol* const event_writer_klass_name = vmSymbols::jdk_jfr_internal_event_EventWriter(); + assert(event_writer_klass_name != nullptr, "invariant"); + if (info.resolved_klass()->name() != event_writer_klass_name) { return; } - // Attempting to link against jdk.jfr.internal.event.EventWriterFactory.getEventWriter(). + // Attempting to link against jdk.jfr.internal.event.EventWriter.getEventWriter(). // The sender, i.e. the method attempting to link, is in the ljf (if one exists). const Method* const sender = ljf_sender_method(THREAD); if (sender == nullptr) { @@ -228,9 +228,9 @@ void JfrResolution::on_runtime_resolution(const CallInfo & info, TRAPS) { } static inline bool is_compiler_linking_event_writer(const Symbol* holder, const Symbol* name) { - static const Symbol* const event_writer_factory_klass_name = vmSymbols::jdk_jfr_internal_event_EventWriterFactory(); - assert(event_writer_factory_klass_name != nullptr, "invariant"); - if (holder != event_writer_factory_klass_name) { + static const Symbol* const event_writer_klass_name = vmSymbols::jdk_jfr_internal_event_EventWriter(); + assert(event_writer_klass_name != nullptr, "invariant"); + if (holder != event_writer_klass_name) { return false; } static const Symbol* const event_writer_method_name = vmSymbols::getEventWriter_name(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/AnnotationElement.java b/src/jdk.jfr/share/classes/jdk/jfr/AnnotationElement.java index 108498c340d42..046709fa92e16 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/AnnotationElement.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/AnnotationElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -37,7 +37,6 @@ import java.util.Set; import java.util.StringJoiner; -import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.Type; import jdk.jfr.internal.TypeLibrary; import jdk.jfr.internal.util.Utils; @@ -115,7 +114,6 @@ public final class AnnotationElement { public AnnotationElement(Class annotationType, Map values) { Objects.requireNonNull(annotationType, "annotationType"); Objects.requireNonNull(values, "values"); - SecuritySupport.checkRegisterPermission(); // copy values to avoid modification after validation HashMap map = new HashMap<>(values); for (Map.Entry entry : map.entrySet()) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java b/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java index fc7b61e875634..282e1ae598f7f 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -37,7 +37,6 @@ import jdk.jfr.internal.EventClassBuilder; import jdk.jfr.internal.JVMSupport; import jdk.jfr.internal.MetadataRepository; -import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.Type; import jdk.jfr.internal.util.Utils; @@ -99,8 +98,6 @@ public static EventFactory create(List annotationElements, Li Objects.requireNonNull(fields, "fields"); JVMSupport.ensureWithInternalError(); - SecuritySupport.checkRegisterPermission(); - List sanitizedAnnotation = Utils.sanitizeNullFreeList(annotationElements, AnnotationElement.class); List sanitizedFields = Utils.sanitizeNullFreeList(fields, ValueDescriptor.class); Set nameSet = HashSet.newHashSet(sanitizedFields.size()); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java index 774b36b97d796..a7bf3976d14df 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -29,8 +29,6 @@ import static jdk.jfr.internal.LogLevel.INFO; import static jdk.jfr.internal.LogTag.JFR; -import java.security.AccessControlContext; -import java.security.AccessController; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -44,7 +42,6 @@ import jdk.jfr.internal.PlatformRecorder; import jdk.jfr.internal.PlatformRecording; import jdk.jfr.internal.Repository; -import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.periodic.PeriodicEvents; @@ -157,7 +154,6 @@ public static void unregister(Class eventClass) { */ public static FlightRecorder getFlightRecorder() throws IllegalStateException { synchronized (PlatformRecorder.class) { - SecuritySupport.checkAccessFlightRecorder(); JVMSupport.ensureWithIllegalStateException(); if (platformRecorder == null) { try { @@ -213,10 +209,7 @@ public static void addPeriodicEvent(Class eventClass, Runnable } Utils.ensureValidEventSubclass(eventClass); - SecuritySupport.checkRegisterPermission(); - @SuppressWarnings("removal") - AccessControlContext acc = AccessController.getContext(); - PeriodicEvents.addUserEvent(acc, eventClass, hook); + PeriodicEvents.addJavaEvent(eventClass, hook); } /** @@ -227,7 +220,6 @@ public static void addPeriodicEvent(Class eventClass, Runnable */ public static boolean removePeriodicEvent(Runnable hook) { Objects.requireNonNull(hook, "hook"); - SecuritySupport.checkRegisterPermission(); if (JVMSupport.isNotAvailable()) { return false; } @@ -260,7 +252,6 @@ public List getEventTypes() { */ public static void addListener(FlightRecorderListener changeListener) { Objects.requireNonNull(changeListener, "changeListener"); - SecuritySupport.checkAccessFlightRecorder(); if (JVMSupport.isNotAvailable()) { return; } @@ -280,7 +271,6 @@ public static void addListener(FlightRecorderListener changeListener) { */ public static boolean removeListener(FlightRecorderListener changeListener) { Objects.requireNonNull(changeListener, "changeListener"); - SecuritySupport.checkAccessFlightRecorder(); if (JVMSupport.isNotAvailable()) { return false; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorderPermission.java b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorderPermission.java index 5a2dc51bc4170..67e844ac269a9 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorderPermission.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorderPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,7 +25,6 @@ package jdk.jfr; -import java.security.AccessControlContext; import java.util.List; import java.util.Map; import java.util.Objects; @@ -34,7 +33,6 @@ import jdk.jfr.internal.PlatformRecorder; import jdk.jfr.internal.PlatformRecording; import jdk.jfr.internal.PrivateAccess; -import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.Type; import jdk.jfr.internal.management.EventSettingsModifier; @@ -156,12 +154,6 @@ public PlatformRecorder getPlatformRecorder() { return FlightRecorder.getFlightRecorder().getInternal(); } - @SuppressWarnings("removal") - @Override - public AccessControlContext getContext(SettingControl settingControl) { - return settingControl.getContext(); - } - @Override public EventSettings newEventSettings(EventSettingsModifier esm) { return new EventSettings.DelegatedEventSettings(esm); @@ -184,7 +176,7 @@ public boolean isVisible(EventType t) { */ public FlightRecorderPermission(String name) { super(Objects.requireNonNull(name, "name")); - if (!name.equals(SecuritySupport.ACCESS_FLIGHT_RECORDER) && !name.equals(SecuritySupport.REGISTER_EVENT)) { + if (!name.equals("accessFlightRecorder") && !name.equals("registerEvent")) { throw new IllegalArgumentException("name: " + name); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/Recording.java b/src/jdk.jfr/share/classes/jdk/jfr/Recording.java index 6168ddb28329f..333645f1731ff 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/Recording.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/Recording.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -39,7 +39,7 @@ import jdk.jfr.internal.PlatformRecording; import jdk.jfr.internal.Type; import jdk.jfr.internal.util.Utils; -import jdk.jfr.internal.WriteableUserPath; +import jdk.jfr.internal.WriteablePath; /** * Provides means to configure, start, stop and dump recording data to disk. @@ -368,7 +368,7 @@ public Recording copy(boolean stop) { */ public void dump(Path destination) throws IOException { Objects.requireNonNull(destination, "destination"); - internal.dump(new WriteableUserPath(destination)); + internal.dump(new WriteablePath(destination)); } /** @@ -461,7 +461,7 @@ public void setMaxAge(Duration maxAge) { * @throws IOException if the path is not writable */ public void setDestination(Path destination) throws IOException { - internal.setDestination(destination != null ? new WriteableUserPath(destination) : null); + internal.setDestination(destination != null ? new WriteablePath(destination) : null); } /** @@ -471,11 +471,11 @@ public void setDestination(Path destination) throws IOException { * @return the destination file, or {@code null} if not set. */ public Path getDestination() { - WriteableUserPath usp = internal.getDestination(); - if (usp == null) { + WriteablePath wp = internal.getDestination(); + if (wp == null) { return null; } else { - return usp.getPotentiallyMaliciousOriginal(); + return wp.getPath(); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/SettingControl.java b/src/jdk.jfr/share/classes/jdk/jfr/SettingControl.java index 1c699247800c0..ac73f6d4c12b2 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/SettingControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/SettingControl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,12 +25,8 @@ package jdk.jfr; -import java.security.AccessControlContext; -import java.security.AccessController; import java.util.Set; -import jdk.jfr.internal.settings.JDKSettingControl; - /** * Base class to extend to create setting controls. *

        @@ -77,30 +73,10 @@ @MetadataDefinition public abstract class SettingControl { - @SuppressWarnings("removal") - private final AccessControlContext context; - private final boolean initialized; - /** * Constructor for invocation by subclass constructors. */ - @SuppressWarnings("removal") protected SettingControl() { - context = this instanceof JDKSettingControl ? null : AccessController.getContext(); - initialized = true; - } - - @SuppressWarnings("removal") - final AccessControlContext getContext() { - // Ensure object state is safe - if (!initialized) { - throw new InternalError("Object must be initialized before security context can be retrieved"); - } - AccessControlContext c = this.context; - if (c == null && !(this instanceof JDKSettingControl)) { - throw new InternalError("Security context can only be null for trusted setting controls"); - } - return c; } /** diff --git a/src/jdk.jfr/share/classes/jdk/jfr/ValueDescriptor.java b/src/jdk.jfr/share/classes/jdk/jfr/ValueDescriptor.java index ff485aa96e7eb..9994b689d093e 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/ValueDescriptor.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/ValueDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -31,7 +31,6 @@ import java.util.Objects; import jdk.jfr.internal.AnnotationConstruct; -import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.Type; import jdk.jfr.internal.util.Utils; @@ -143,7 +142,6 @@ public ValueDescriptor(Class type, String name, List annot Objects.requireNonNull(type, "type"); Objects.requireNonNull(name, "name"); Objects.requireNonNull(annotations, "annotations"); - SecuritySupport.checkRegisterPermission(); if (!allowArray) { if (type.isArray()) { throw new IllegalArgumentException("Array types are not allowed"); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventStream.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventStream.java index 1a1c468add9c3..ac325f19f222d 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -27,18 +27,14 @@ import java.io.IOException; import java.nio.file.Path; -import java.security.AccessControlContext; -import java.security.AccessController; import java.time.Duration; import java.time.Instant; import java.util.Collections; import java.util.Objects; import java.util.function.Consumer; -import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.consumer.EventDirectoryStream; import jdk.jfr.internal.consumer.EventFileStream; -import jdk.jfr.internal.consumer.FileAccess; /** * Represents a stream of events. @@ -113,13 +109,9 @@ public interface EventStream extends AutoCloseable { * @throws IOException if a stream can't be opened, or an I/O error occurs * when trying to access the repository */ - @SuppressWarnings("removal") public static EventStream openRepository() throws IOException { - SecuritySupport.checkAccessFlightRecorder(); return new EventDirectoryStream( - AccessController.getContext(), null, - SecuritySupport.PRIVILEGED, null, Collections.emptyList(), false @@ -143,12 +135,8 @@ public static EventStream openRepository() throws IOException { */ public static EventStream openRepository(Path directory) throws IOException { Objects.requireNonNull(directory, "directory"); - @SuppressWarnings("removal") - AccessControlContext acc = AccessController.getContext(); return new EventDirectoryStream( - acc, directory, - FileAccess.UNPRIVILEGED, null, Collections.emptyList(), true @@ -169,10 +157,9 @@ public static EventStream openRepository(Path directory) throws IOException { * @throws IOException if the file can't be opened, or an I/O error occurs * during reading */ - @SuppressWarnings("removal") static EventStream openFile(Path file) throws IOException { Objects.requireNonNull(file, "file"); - return new EventFileStream(AccessController.getContext(), file); + return new EventFileStream(file); } /** diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java index 0437ec5958934..0e51da0411925 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -43,7 +43,6 @@ import jdk.jfr.internal.consumer.ParserFilter; import jdk.jfr.internal.consumer.ChunkHeader; import jdk.jfr.internal.consumer.ChunkParser; -import jdk.jfr.internal.consumer.FileAccess; import jdk.jfr.internal.consumer.ParserState; import jdk.jfr.internal.consumer.RecordingInput; import jdk.jfr.internal.consumer.filter.ChunkWriter; @@ -81,7 +80,7 @@ public final class RecordingFile implements Closeable { public RecordingFile(Path file) throws IOException { Objects.requireNonNull(file, "file"); this.file = file.toFile(); - this.input = new RecordingInput(this.file, FileAccess.UNPRIVILEGED); + this.input = new RecordingInput(this.file); this.chunkWriter = null; findNext(); } @@ -146,7 +145,7 @@ public List readEventTypes() throws IOException { MetadataDescriptor previous = null; List types = new ArrayList<>(); HashSet foundIds = new HashSet<>(); - try (RecordingInput ri = new RecordingInput(file, FileAccess.UNPRIVILEGED)) { + try (RecordingInput ri = new RecordingInput(file)) { ChunkHeader ch = new ChunkHeader(ri); aggregateEventTypeForChunk(ch, null, types, foundIds); while (!ch.isLastChunk()) { @@ -162,7 +161,7 @@ List readTypes() throws IOException { MetadataDescriptor previous = null; List types = new ArrayList<>(200); HashSet foundIds = HashSet.newHashSet(types.size()); - try (RecordingInput ri = new RecordingInput(file, FileAccess.UNPRIVILEGED)) { + try (RecordingInput ri = new RecordingInput(file)) { ChunkHeader ch = new ChunkHeader(ri); ch.awaitFinished(); aggregateTypeForChunk(ch, null, types, foundIds); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java index 2e7d23bb84cc5..3d6c8de3015a2 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -27,8 +27,6 @@ import java.io.IOException; import java.nio.file.Path; -import java.security.AccessControlContext; -import java.security.AccessController; import java.time.Duration; import java.time.Instant; import java.util.Collections; @@ -45,7 +43,6 @@ import jdk.jfr.RecordingState; import jdk.jfr.internal.PlatformRecording; import jdk.jfr.internal.PrivateAccess; -import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.consumer.EventDirectoryStream; import jdk.jfr.internal.management.StreamBarrier; @@ -98,18 +95,13 @@ public RecordingStream() { } private RecordingStream(Map settings) { - SecuritySupport.checkAccessFlightRecorder(); - @SuppressWarnings("removal") - AccessControlContext acc = AccessController.getContext(); this.recording = new Recording(); this.creationTime = Instant.now(); this.recording.setName("Recording Stream: " + creationTime); try { PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording); this.directoryStream = new EventDirectoryStream( - acc, null, - SecuritySupport.PRIVILEGED, pr, configurations(), false diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunkInputStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunkInputStream.java index 7cc399019e697..4c8913e96a088 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunkInputStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunkInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, 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.BufferedInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -65,7 +66,7 @@ private boolean nextStream() throws IOException { return false; } - stream = new BufferedInputStream(SecuritySupport.newFileInputStream(currentChunk.getFile())); + stream = new BufferedInputStream(Files.newInputStream(currentChunk.getFile())); unstreamedSize -= currentChunk.getSize(); return true; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java index 8f246948710fc..b21b539cab87e 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,23 +25,16 @@ package jdk.jfr.internal; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Collections; import java.util.HashSet; import java.util.Objects; import java.util.Set; import jdk.jfr.SettingControl; -import jdk.jfr.internal.settings.JDKSettingControl; import jdk.jfr.internal.settings.PeriodSetting; import jdk.jfr.internal.settings.StackTraceSetting; import jdk.jfr.internal.settings.ThresholdSetting; final class Control { - @SuppressWarnings("removal") - private final AccessControlContext context; private static final int CACHE_SIZE = 5; private final Set[] cachedUnions = new HashSet[CACHE_SIZE]; private final String[] cachedValues = new String[CACHE_SIZE]; @@ -51,12 +44,8 @@ final class Control { // called by exposed subclass in external API public Control(SettingControl delegate, String defaultValue) { - this.context = PrivateAccess.getInstance().getContext(delegate); this.delegate = delegate; this.defaultValue = defaultValue; - if (this.context == null && !(delegate instanceof JDKSettingControl)) { - throw new InternalError("Security context can only be null for trusted setting controls"); - } } boolean isType(Class clazz) { @@ -74,25 +63,8 @@ final void setDefault() { apply(defaultValue); } - @SuppressWarnings("removal") public String getValue() { - if (context == null) { - // VM events requires no access control context - return delegate.getValue(); - } else { - return AccessController.doPrivileged(new PrivilegedAction() { - @Override - public String run() { - try { - return delegate.getValue(); - } catch (Throwable t) { - // Prevent malicious user to propagate exception callback in the wrong context - Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when trying to get value for " + getClass()); - } - return defaultValue != null ? defaultValue : ""; // Need to return something - } - }, context); - } + return delegate.getValue(); } private void apply(String value) { @@ -102,53 +74,18 @@ private void apply(String value) { setValue(value); } - @SuppressWarnings("removal") public void setValue(String value) { - if (context == null) { - // VM events requires no access control context - try { - delegate.setValue(value); - lastValue = delegate.getValue(); - } catch (Throwable t) { - Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when setting value \"" + value + "\" for " + getClass()); - lastValue = null; - } - } else { - lastValue = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public String run() { - try { - delegate.setValue(value); - return delegate.getValue(); - } catch (Throwable t) { - // Prevent malicious user to propagate exception callback in the wrong context - Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when setting value \"" + value + "\" for " + getClass()); - } - return null; - } - }, context); + try { + delegate.setValue(value); + lastValue = delegate.getValue(); + } catch (Throwable t) { + Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when setting value \"" + value + "\". " + t.getMessage()); + lastValue = null; } } - - @SuppressWarnings("removal") public String combine(Set values) { - if (context == null) { - // VM events requires no access control context - return delegate.combine(values); - } - return AccessController.doPrivileged(new PrivilegedAction() { - @Override - public String run() { - try { - return delegate.combine(Collections.unmodifiableSet(values)); - } catch (Throwable t) { - // Prevent malicious user to propagate exception callback in the wrong context - Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when combining " + values + " for " + getClass()); - } - return null; - } - }, context); + return delegate.combine(values); } private final String findCombine(Set values) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java index f086bbf884701..19e2febf88e24 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -280,7 +280,7 @@ private SettingControl instantiateSettingControl(Class } catch (Exception e) { throw (Error) new InternalError("Could not get constructor for " + settingControlClass.getName()).initCause(e); } - SecuritySupport.setAccessible(cc); + cc.setAccessible(true); try { return (SettingControl) cc.newInstance(); } catch (IllegalArgumentException | InvocationTargetException e) { @@ -373,13 +373,6 @@ public String getSettingsId() { return idName; } - /** - * A malicious user must never be able to run a callback in the wrong - * context. Methods on SettingControl must therefore never be invoked directly - * by JFR, instead use jdk.jfr.internal.Control. - * - * The returned list is only to be used inside EventConfiguration - */ public List getSettingControls() { return settingControls; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java index d962a535829ef..636ae3756e63b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -89,7 +89,6 @@ private record SettingDesc(ClassDesc paramType, String methodName) { private static final ClassDesc TYPE_EVENT_CONFIGURATION = classDesc(EventConfiguration.class); private static final ClassDesc TYPE_ISE = Bytecode.classDesc(IllegalStateException.class); private static final ClassDesc TYPE_EVENT_WRITER = classDesc(EventWriter.class); - private static final ClassDesc TYPE_EVENT_WRITER_FACTORY = ClassDesc.of("jdk.jfr.internal.event.EventWriterFactory"); private static final ClassDesc TYPE_OBJECT = Bytecode.classDesc(Object.class); private static final ClassDesc TYPE_SETTING_DEFINITION = Bytecode.classDesc(SettingDefinition.class); private static final MethodDesc METHOD_BEGIN = MethodDesc.of("begin", "()V"); @@ -100,7 +99,7 @@ private record SettingDesc(ClassDesc paramType, String methodName) { private static final MethodDesc METHOD_EVENT_CONFIGURATION_SHOULD_COMMIT = MethodDesc.of("shouldCommit", "(J)Z"); private static final MethodDesc METHOD_EVENT_CONFIGURATION_GET_SETTING = MethodDesc.of("getSetting", SettingControl.class, int.class); private static final MethodDesc METHOD_EVENT_SHOULD_COMMIT = MethodDesc.of("shouldCommit", "()Z"); - private static final MethodDesc METHOD_GET_EVENT_WRITER_KEY = MethodDesc.of("getEventWriter", "(J)" + TYPE_EVENT_WRITER.descriptorString()); + private static final MethodDesc METHOD_GET_EVENT_WRITER = MethodDesc.of("getEventWriter", "()" + TYPE_EVENT_WRITER.descriptorString()); private static final MethodDesc METHOD_IS_ENABLED = MethodDesc.of("isEnabled", "()Z"); private static final MethodDesc METHOD_RESET = MethodDesc.of("reset", "()V"); private static final MethodDesc METHOD_SHOULD_COMMIT_LONG = MethodDesc.of("shouldCommit", "(J)Z"); @@ -767,8 +766,7 @@ private boolean hasStaticMethod(MethodDesc method) { } private void getEventWriter(CodeBuilder codeBuilder) { - codeBuilder.ldc(EventWriterKey.getKey()); - invokestatic(codeBuilder, TYPE_EVENT_WRITER_FACTORY, METHOD_GET_EVENT_WRITER_KEY); + invokestatic(codeBuilder, TYPE_EVENT_WRITER, METHOD_GET_EVENT_WRITER); } private void getEventConfiguration(CodeBuilder codeBuilder) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/FilePurger.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/FilePurger.java index e643741adf5fe..f6649796a4d6b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/FilePurger.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/FilePurger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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,19 +26,19 @@ package jdk.jfr.internal; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.SequencedSet; -import jdk.jfr.internal.SecuritySupport.SafePath; - // This class keeps track of files that can't be deleted // so they can at a later staged be removed. final class FilePurger { - private static final SequencedSet paths = new LinkedHashSet<>(); + private static final SequencedSet paths = new LinkedHashSet<>(); - public static synchronized void add(SafePath p) { + public static synchronized void add(Path p) { paths.add(p); if (paths.size() > 1000) { removeOldest(); @@ -50,7 +50,7 @@ public static synchronized void purge() { return; } - for (SafePath p : new ArrayList<>(paths)) { + for (Path p : new ArrayList<>(paths)) { if (delete(p)) { paths.remove(p); } @@ -61,16 +61,12 @@ private static void removeOldest() { paths.removeFirst(); } - private static boolean delete(SafePath p) { - try { - if (!SecuritySupport.exists(p)) { - return true; - } - } catch (IOException e) { - // ignore + private static boolean delete(Path p) { + if (!Files.exists(p)) { + return true; } try { - SecuritySupport.delete(p); + Files.delete(p); return true; } catch (IOException e) { return false; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JDKEvents.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JDKEvents.java index d0d186e2479d0..f0b7dcc2bf2ba 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JDKEvents.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JDKEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -91,11 +91,11 @@ public static synchronized void initialize() { try { if (initializationTriggered == false) { for (Class eventClass : eventClasses) { - SecuritySupport.registerEvent((Class) eventClass); + MetadataRepository.getInstance().register((Class) eventClass); } - PeriodicEvents.addJDKEvent(jdk.internal.event.ExceptionStatisticsEvent.class, emitExceptionStatistics); - PeriodicEvents.addJDKEvent(DirectBufferStatisticsEvent.class, emitDirectBufferStatistics); - PeriodicEvents.addJDKEvent(InitialSecurityPropertyEvent.class, emitInitialSecurityProperties); + PeriodicEvents.addJavaEvent(jdk.internal.event.ExceptionStatisticsEvent.class, emitExceptionStatistics); + PeriodicEvents.addJavaEvent(DirectBufferStatisticsEvent.class, emitDirectBufferStatistics); + PeriodicEvents.addJavaEvent(InitialSecurityPropertyEvent.class, emitInitialSecurityProperties); initializeContainerEvents(); JFRTracing.enable(); @@ -116,17 +116,21 @@ private static void initializeContainerEvents() { } // The registration of events and hooks are needed to provide metadata, // even when not running in a container - SecuritySupport.registerEvent(ContainerConfigurationEvent.class); - SecuritySupport.registerEvent(ContainerCPUUsageEvent.class); - SecuritySupport.registerEvent(ContainerCPUThrottlingEvent.class); - SecuritySupport.registerEvent(ContainerMemoryUsageEvent.class); - SecuritySupport.registerEvent(ContainerIOUsageEvent.class); - - PeriodicEvents.addJDKEvent(ContainerConfigurationEvent.class, emitContainerConfiguration); - PeriodicEvents.addJDKEvent(ContainerCPUUsageEvent.class, emitContainerCPUUsage); - PeriodicEvents.addJDKEvent(ContainerCPUThrottlingEvent.class, emitContainerCPUThrottling); - PeriodicEvents.addJDKEvent(ContainerMemoryUsageEvent.class, emitContainerMemoryUsage); - PeriodicEvents.addJDKEvent(ContainerIOUsageEvent.class, emitContainerIOUsage); + registerEvent(ContainerConfigurationEvent.class); + registerEvent(ContainerCPUUsageEvent.class); + registerEvent(ContainerCPUThrottlingEvent.class); + registerEvent(ContainerMemoryUsageEvent.class); + registerEvent(ContainerIOUsageEvent.class); + + PeriodicEvents.addJavaEvent(ContainerConfigurationEvent.class, emitContainerConfiguration); + PeriodicEvents.addJavaEvent(ContainerCPUUsageEvent.class, emitContainerCPUUsage); + PeriodicEvents.addJavaEvent(ContainerCPUThrottlingEvent.class, emitContainerCPUThrottling); + PeriodicEvents.addJavaEvent(ContainerMemoryUsageEvent.class, emitContainerMemoryUsage); + PeriodicEvents.addJavaEvent(ContainerIOUsageEvent.class, emitContainerIOUsage); + } + + private static void registerEvent(Class eventClass) { + MetadataRepository.getInstance().register(eventClass); } private static void emitExceptionStatistics() { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java index 7fde28a3d21fc..ded1f78b76eff 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -56,7 +56,7 @@ public final class JVMSupport { private static boolean checkAvailability() { // set jfr.unsupported.vm to true to test API on an unsupported VM try { - if (SecuritySupport.getBooleanProperty("jfr.unsupported.vm")) { + if (Boolean.getBoolean("jfr.unsupported.vm")) { return false; } } catch (NoClassDefFoundError cnfe) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java index 6d1d5cf793823..7adafce6768bb 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -64,7 +64,6 @@ static byte[] onRetransform(long traceId, boolean dummy1, boolean dummy2, Class< Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Skipping instrumentation for " + clazz.getName() + " since container support is missing"); return oldBytes; } - EventWriterKey.ensureEventWriterFactory(); EventConfiguration configuration = JVMSupport.getConfiguration(clazz.asSubclass(jdk.internal.event.Event.class)); if (configuration == null) { Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "No event configuration found for " + clazz.getName() + ". Ignoring instrumentation request."); @@ -124,7 +123,6 @@ static byte[] bytesForEagerInstrumentation(long traceId, boolean forceInstrument return oldBytes; } } - EventWriterKey.ensureEventWriterFactory(); Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Adding " + (forceInstrumentation ? "forced " : "") + "instrumentation for event type " + eventName + " during initial class load"); byte[] bytes = ei.buildInstrumented(); Bytecode.log(ei.getClassName() + "(" + traceId + ")", bytes); @@ -155,6 +153,8 @@ static void unhideInternalTypes() { * @return a new thread */ static Thread createRecorderThread(ThreadGroup systemThreadGroup, ClassLoader contextClassLoader) { - return SecuritySupport.createRecorderThread(systemThreadGroup, contextClassLoader); + Thread thread = new Thread(systemThreadGroup, "JFR Recorder Thread"); + thread.setContextClassLoader(contextClassLoader); + return thread; } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java index d0b5385475265..60db375c87686 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -191,7 +191,7 @@ private Class createAnnotationClass(String type) { public static List createTypes() throws IOException { try (DataInputStream dis = new DataInputStream( - SecuritySupport.getResourceAsStream("/jdk/jfr/internal/types/metadata.bin"))) { + MetadataLoader.class.getResourceAsStream("/jdk/jfr/internal/types/metadata.bin"))) { MetadataLoader ml = new MetadataLoader(dis); return ml.buildTypes(); } catch (Exception e) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java index 49afd0082d8a9..951142e2493b7 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -123,7 +123,6 @@ public synchronized EventType getEventType(Class eventClass) { - SecuritySupport.checkRegisterPermission(); EventConfiguration configuration = getConfiguration(eventClass, false); if (configuration != null) { configuration.getPlatformEventType().setRegistered(false); @@ -135,7 +134,6 @@ public synchronized EventType register(Class } public synchronized EventType register(Class eventClass, List dynamicAnnotations, List dynamicFields) { - SecuritySupport.checkRegisterPermission(); if (JVM.isExcluded(eventClass)) { // Event classes are marked as excluded during class load // if they override methods in the jdk.jfr.Event class, i.e. commit(). @@ -186,7 +184,7 @@ private EventConfiguration newEventConfiguration(EventType eventType, EventContr if (cachedEventConfigurationConstructor == null) { var argClasses = new Class[] { EventType.class, EventControl.class}; Constructor c = EventConfiguration.class.getDeclaredConstructor(argClasses); - SecuritySupport.setAccessible(c); + c.setAccessible(true); cachedEventConfigurationConstructor = c; } return cachedEventConfigurationConstructor.newInstance(eventType, ec); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Options.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/Options.java index d07f1e6cb5e71..beeb46e1a60f3 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Options.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Options.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,8 +26,9 @@ package jdk.jfr.internal; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.internal.misc.Unsafe; import static java.nio.file.LinkOption.*; @@ -50,7 +51,7 @@ public final class Options { private static long DEFAULT_THREAD_BUFFER_SIZE; private static final int DEFAULT_STACK_DEPTH = 64; private static final long DEFAULT_MAX_CHUNK_SIZE = 12 * 1024 * 1024; - private static final SafePath DEFAULT_DUMP_PATH = null; + private static final Path DEFAULT_DUMP_PATH = null; private static final boolean DEFAULT_PRESERVE_REPOSITORY = false; private static long memorySize; @@ -115,10 +116,10 @@ public static synchronized void setGlobalBufferSize(long globalBufsize) { globalBufferSize = globalBufsize; } - public static synchronized void setDumpPath(SafePath path) throws IOException { + public static synchronized void setDumpPath(Path path) throws IOException { if (path != null) { - if (SecuritySupport.isWritable(path)) { - path = SecuritySupport.toRealPath(path, NOFOLLOW_LINKS); + if (Files.isWritable(path)) { + path = path.toRealPath(NOFOLLOW_LINKS); } else { throw new IOException("Cannot write JFR emergency dump to " + path.toString()); } @@ -126,8 +127,8 @@ public static synchronized void setDumpPath(SafePath path) throws IOException { JVM.setDumpPath(path == null ? null : path.toString()); } - public static synchronized SafePath getDumpPath() { - return new SafePath(JVM.getDumpPath()); + public static synchronized Path getDumpPath() { + return Path.of(JVM.getDumpPath()); } public static synchronized void setStackDepth(Integer stackTraceDepth) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java index b33a894304260..646c53f896134 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -33,8 +33,7 @@ import static jdk.jfr.internal.LogTag.JFR_SYSTEM; import java.io.IOException; -import java.security.AccessControlContext; -import java.security.AccessController; +import java.nio.file.Path; import java.time.Duration; import java.time.Instant; import java.util.ArrayList; @@ -46,7 +45,6 @@ import java.util.Set; import java.util.Timer; import java.util.TimerTask; -import java.util.concurrent.CopyOnWriteArrayList; import jdk.jfr.FlightRecorder; import jdk.jfr.FlightRecorderListener; @@ -54,8 +52,6 @@ import jdk.jfr.RecordingState; import jdk.jfr.events.ActiveRecordingEvent; import jdk.jfr.events.ActiveSettingEvent; -import jdk.jfr.internal.SecuritySupport.SafePath; -import jdk.jfr.internal.SecuritySupport.SecureRecorderListener; import jdk.jfr.internal.consumer.EventLog; import jdk.jfr.internal.periodic.PeriodicEvents; import jdk.jfr.internal.util.Utils; @@ -64,7 +60,7 @@ public final class PlatformRecorder { private final ArrayList recordings = new ArrayList<>(); - private static final List changeListeners = new ArrayList<>(); + private static final List changeListeners = new ArrayList<>(); private final Repository repository; private final Thread shutdownHook; @@ -83,25 +79,9 @@ public PlatformRecorder() throws Exception { JDKEvents.initialize(); Logger.log(JFR_SYSTEM, INFO, "Registered JDK events"); startDiskMonitor(); - shutdownHook = SecuritySupport.createThreadWitNoPermissions("JFR Shutdown Hook", new ShutdownHook(this)); - SecuritySupport.setUncaughtExceptionHandler(shutdownHook, new ShutdownHook.ExceptionHandler()); - SecuritySupport.registerShutdownHook(shutdownHook); - } - - - private static Timer createTimer() { - try { - List result = new CopyOnWriteArrayList<>(); - Thread t = SecuritySupport.createThreadWitNoPermissions("Permissionless thread", ()-> { - result.add(new Timer("JFR Recording Scheduler", true)); - }); - JVM.exclude(t); - t.start(); - t.join(); - return result.getFirst(); - } catch (InterruptedException e) { - throw new IllegalStateException("Not able to create timer task. " + e.getMessage(), e); - } + shutdownHook = new ShutdownHook(this); + shutdownHook.setUncaughtExceptionHandler(new ShutdownHook.ExceptionHandler()); + Runtime.getRuntime().addShutdownHook(shutdownHook); } public synchronized PlatformRecording newRecording(Map settings) { @@ -138,27 +118,18 @@ public synchronized List getRecordings() { } public static synchronized void addListener(FlightRecorderListener changeListener) { - @SuppressWarnings("removal") - AccessControlContext context = AccessController.getContext(); - SecureRecorderListener sl = new SecureRecorderListener(context, changeListener); boolean runInitialized; synchronized (PlatformRecorder.class) { runInitialized = FlightRecorder.isInitialized(); - changeListeners.add(sl); + changeListeners.add(changeListener); } if (runInitialized) { - sl.recorderInitialized(FlightRecorder.getFlightRecorder()); + changeListener.recorderInitialized(FlightRecorder.getFlightRecorder()); } } public static synchronized boolean removeListener(FlightRecorderListener changeListener) { - for (SecureRecorderListener s : new ArrayList<>(changeListeners)) { - if (s.getChangeListener() == changeListener) { - changeListeners.remove(s); - return true; - } - } - return false; + return changeListeners.remove(changeListener); } static synchronized List getListeners() { @@ -167,7 +138,7 @@ static synchronized List getListeners() { synchronized Timer getTimer() { if (timer == null) { - timer = createTimer(); + timer = new Timer("JFR Recording Scheduler", true); } return timer; } @@ -366,7 +337,7 @@ synchronized void stop(PlatformRecording recording) { } private Instant dumpMemoryToDestination(PlatformRecording recording) { - WriteableUserPath dest = recording.getDestination(); + WriteablePath dest = recording.getDestination(); if (dest != null) { Instant t = MetadataRepository.getInstance().setOutput(dest.getRealPathText()); recording.clearDestination(); @@ -441,8 +412,8 @@ public List makeChunkList(Instant startTime, Instant endTime) { } private void startDiskMonitor() { - Thread t = SecuritySupport.createThreadWitNoPermissions("JFR Periodic Tasks", () -> periodicTask()); - SecuritySupport.setDaemonThread(t, true); + Thread t = new Thread(() -> periodicTask(), "JFR Periodic Tasks"); + t.setDaemon(true); t.start(); } @@ -472,7 +443,7 @@ private void writeMetaEvents() { if (ActiveRecordingEvent.enabled()) { for (PlatformRecording r : getRecordings()) { if (r.getState() == RecordingState.RUNNING && r.shouldWriteMetadataEvent()) { - WriteableUserPath path = r.getDestination(); + WriteablePath path = r.getDestination(); Duration age = r.getMaxAge(); Duration flush = r.getFlushInterval(); Long size = r.getMaxSize(); @@ -519,7 +490,7 @@ private void periodicTask() { wait = Math.min(minDelta, Options.getWaitInterval()); } catch (Throwable t) { // Catch everything and log, but don't allow it to end the periodic task - Logger.log(JFR_SYSTEM, ERROR, "Error in Periodic task: " + t.getClass().getName()); + Logger.log(JFR_SYSTEM, WARN, "Error in Periodic task: " + t.getMessage()); } finally { takeNap(wait); } @@ -660,7 +631,7 @@ private void fillWithDiskChunks(PlatformRecording target) { target.setInternalDuration(startTime.until(endTime)); } - public synchronized void migrate(SafePath repo) throws IOException { + public synchronized void migrate(Path repo) throws IOException { // Must set repository while holding recorder lock so // the final chunk in repository gets marked correctly Repository.getRepository().setBasePath(repo); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java index 6014bbbf9d251..025b2878253ed 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -35,11 +35,8 @@ import java.io.InputStream; import java.nio.channels.FileChannel; import java.nio.file.NoSuchFileException; +import java.nio.file.Path; import java.nio.file.StandardOpenOption; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; @@ -59,7 +56,6 @@ import jdk.jfr.FlightRecorderListener; import jdk.jfr.Recording; import jdk.jfr.RecordingState; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.util.ValueFormatter; @@ -73,12 +69,12 @@ public final class PlatformRecording implements AutoCloseable { private Duration maxAge; private long maxSize; - private WriteableUserPath destination; + private WriteablePath destination; private boolean toDisk = true; private String name; private boolean dumpOnExit; - private SafePath dumpDirectory; + private Path dumpDirectory; // Timestamp information private Instant stopTime; private Instant startTime; @@ -90,8 +86,6 @@ public final class PlatformRecording implements AutoCloseable { private volatile Recording recording; private TimerTask stopTask; private TimerTask startTask; - @SuppressWarnings("removal") - private final AccessControlContext dumpDirectoryControlContext; private boolean shouldWriteActiveRecordingEvent = true; private Duration flushInterval = Duration.ofSeconds(1); private long finalStartChunkNanos = Long.MIN_VALUE; @@ -99,13 +93,6 @@ public final class PlatformRecording implements AutoCloseable { @SuppressWarnings("removal") PlatformRecording(PlatformRecorder recorder, long id) { - // Typically the access control context is taken - // when you call dump(Path) or setDestination(Path), - // but if no destination is set and the filename is auto-generated, - // the control context of the recording is taken when the - // Recording object is constructed. This works well for - // -XX:StartFlightRecording and JFR.dump - this.dumpDirectoryControlContext = AccessController.getContext(); this.id = id; this.recorder = recorder; this.name = String.valueOf(id); @@ -175,7 +162,7 @@ public boolean stop(String reason) { Logger.log(LogTag.JFR, LogLevel.INFO, "Stopped recording \"" + getName() + "\" (" + getId() + ")" + endText); newState = getState(); } - WriteableUserPath dest = getDestination(); + WriteablePath dest = getDestination(); if (dest == null && dumpDirectory != null) { dest = makeDumpPath(); } @@ -195,30 +182,18 @@ public boolean stop(String reason) { return true; } - @SuppressWarnings("removal") - public WriteableUserPath makeDumpPath() { + public WriteablePath makeDumpPath() { try { String name = JVMSupport.makeFilename(getRecording()); - return AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public WriteableUserPath run() throws Exception { - SafePath p = dumpDirectory; - if (p == null) { - p = new SafePath("."); - } - return new WriteableUserPath(p.toPath().resolve(name)); - } - }, dumpDirectoryControlContext); - } catch (PrivilegedActionException e) { - Throwable t = e.getCause(); - if (t instanceof SecurityException) { - Logger.log(LogTag.JFR, LogLevel.WARN, "Not allowed to create dump path for recording " + recording.getId() + " on exit."); - } - if (t instanceof IOException) { - Logger.log(LogTag.JFR, LogLevel.WARN, "Could not dump " + recording.getId() + " on exit."); + Path p = dumpDirectory; + if (p == null) { + p = Path.of("."); } - return null; + return new WriteablePath(p.resolve(name)); + } catch (IOException e) { + Logger.log(LogTag.JFR, LogLevel.WARN, "Could not dump " + recording.getId() + " on exit. " + e.getMessage()); } + return null; } @@ -422,14 +397,16 @@ public void setMaxSize(long maxSize) { } } - public void setDestination(WriteableUserPath userSuppliedPath) throws IOException { + public void setDestination(WriteablePath destination) throws IOException { synchronized (recorder) { - checkSetDestination(userSuppliedPath); - this.destination = userSuppliedPath; + checkSetDestination(destination); + this.destination = destination; } } - public void checkSetDestination(WriteableUserPath userSuppliedPath) throws IOException { + public void checkSetDestination(WriteablePath writeablePath) throws IOException { + // The writeablePath argument is not checked. It's sufficient that an instance has + // been created. synchronized (recorder) { if (Utils.isState(getState(), RecordingState.STOPPED, RecordingState.CLOSED)) { throw new IllegalStateException("Destination can't be set on a recording that has been stopped/closed"); @@ -437,7 +414,7 @@ public void checkSetDestination(WriteableUserPath userSuppliedPath) throws IOExc } } - public WriteableUserPath getDestination() { + public WriteablePath getDestination() { synchronized (recorder) { return destination; } @@ -707,8 +684,7 @@ public void run() { try { stop("End of duration reached"); } catch (Throwable t) { - // Prevent malicious user to propagate exception callback in the wrong context - Logger.log(LogTag.JFR, LogLevel.ERROR, "Could not stop recording."); + Logger.log(LogTag.JFR, LogLevel.ERROR, "Could not stop recording. " + t.getMessage()); } } }; @@ -737,37 +713,34 @@ boolean shouldWriteMetadataEvent() { } // Dump running and stopped recordings - public void dump(WriteableUserPath writeableUserPath) throws IOException { + public void dump(WriteablePath writeablePath) throws IOException { synchronized (recorder) { try(PlatformRecording p = newSnapshotClone("Dumped by user", null)) { - p.dumpStopped(writeableUserPath); + p.dumpStopped(writeablePath); } } } - public void dumpStopped(WriteableUserPath userPath) throws IOException { + public void dumpStopped(WriteablePath path) throws IOException { synchronized (recorder) { - transferChunksWithRetry(userPath); + transferChunksWithRetry(path); } } - private void transferChunksWithRetry(WriteableUserPath userPath) throws IOException { - userPath.doPrivilegedIO(() -> { - try { - transferChunks(userPath); - } catch (NoSuchFileException nsfe) { - Logger.log(LogTag.JFR, LogLevel.ERROR, "Missing chunkfile when writing recording \"" + name + "\" (" + id + ") to " + userPath.getRealPathText() + "."); - // if one chunkfile was missing, its likely more are missing - removeNonExistantPaths(); - // and try the transfer again - transferChunks(userPath); - } - return null; - }); + private void transferChunksWithRetry(WriteablePath path) throws IOException { + try { + transferChunks(path); + } catch (NoSuchFileException nsfe) { + Logger.log(LogTag.JFR, LogLevel.ERROR, "Missing chunkfile when writing recording \"" + name + "\" (" + id + ") to " + path.getRealPathText() + "."); + // if one chunkfile was missing, its likely more are missing + removeNonExistantPaths(); + // and try the transfer again + transferChunks(path); + } } - private void transferChunks(WriteableUserPath userPath) throws IOException { - try (ChunksChannel cc = new ChunksChannel(chunks); FileChannel fc = FileChannel.open(userPath.getReal(), StandardOpenOption.WRITE, StandardOpenOption.APPEND)) { + private void transferChunks(WriteablePath path) throws IOException { + try (ChunksChannel cc = new ChunksChannel(chunks); FileChannel fc = FileChannel.open(path.getReal(), StandardOpenOption.WRITE, StandardOpenOption.APPEND)) { long bytes = cc.transferTo(fc); Logger.log(LogTag.JFR, LogLevel.INFO, "Transferred " + bytes + " bytes from the disk repository"); // No need to force if no data was transferred, which avoids IOException when device is /dev/null @@ -859,7 +832,7 @@ private static List reduceFromEnd(Long maxSize, List * Only to be used by DCmdStart. */ - public void setDumpDirectory(SafePath directory) { + public void setDumpDirectory(Path directory) { this.dumpDirectory = directory; } @@ -913,7 +886,7 @@ public void removeBefore(Instant timestamp) { } - public void removePath(SafePath path) { + public void removePath(Path path) { synchronized (recorder) { Iterator it = chunks.iterator(); while (it.hasNext()) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PrivateAccess.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PrivateAccess.java index dd28a27884f6f..e9945f71158c0 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PrivateAccess.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PrivateAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,7 +25,6 @@ package jdk.jfr.internal; -import java.security.AccessControlContext; import java.util.List; import java.util.Map; @@ -35,7 +34,6 @@ import jdk.jfr.EventType; import jdk.jfr.FlightRecorderPermission; import jdk.jfr.Recording; -import jdk.jfr.SettingControl; import jdk.jfr.SettingDescriptor; import jdk.jfr.ValueDescriptor; import jdk.jfr.internal.management.EventSettingsModifier; @@ -60,7 +58,7 @@ public static PrivateAccess getInstance() { // Will trigger // FlightRecorderPermission. // which will call PrivateAccess.setPrivateAccess - new FlightRecorderPermission(SecuritySupport.REGISTER_EVENT); + new FlightRecorderPermission("accessFlightRecorder"); } return instance; } @@ -99,9 +97,6 @@ public static void setPrivateAccess(PrivateAccess pa) { public abstract PlatformRecorder getPlatformRecorder(); - @SuppressWarnings("removal") - public abstract AccessControlContext getContext(SettingControl sc); - public abstract EventSettings newEventSettings(EventSettingsModifier esm); public abstract boolean isVisible(EventType t); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Repository.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/Repository.java index ff09d58a9c059..f2cd873790aa7 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Repository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Repository.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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,7 @@ package jdk.jfr.internal; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.time.DateTimeException; import java.time.LocalDateTime; @@ -33,20 +34,20 @@ import java.util.HashSet; import java.util.Set; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.management.ChunkFilename; import jdk.jfr.internal.util.ValueFormatter; +import jdk.jfr.internal.util.DirectoryCleaner; +import jdk.jfr.internal.util.Utils; public final class Repository { + private static final Path JAVA_IO_TMPDIR = Utils.getPathInProperty("java.io.tmpdir", null); private static final int MAX_REPO_CREATION_RETRIES = 1000; private static final Repository instance = new Repository(); - private static final String JFR_REPOSITORY_LOCATION_PROPERTY = "jdk.jfr.repository"; - - private final Set cleanupDirectories = new HashSet<>(); - private SafePath baseLocation; - private SafePath repository; + private final Set cleanupDirectories = new HashSet<>(); + private Path baseLocation; + private Path repository; private ChunkFilename chunkFilename; private Repository() { @@ -56,7 +57,7 @@ public static Repository getRepository() { return instance; } - public synchronized void setBasePath(SafePath baseLocation) throws IOException { + public synchronized void setBasePath(Path baseLocation) throws IOException { if(baseLocation.equals(this.baseLocation)) { Logger.log(LogTag.JFR, LogLevel.INFO, "Same base repository path " + baseLocation.toString() + " is set"); return; @@ -68,7 +69,7 @@ public synchronized void setBasePath(SafePath baseLocation) throws IOException { try { // Remove so we don't "leak" repositories, if JFR is never started // and shutdown hook not added. - SecuritySupport.delete(repository); + Files.delete(repository); } catch (IOException ioe) { Logger.log(LogTag.JFR, LogLevel.INFO, "Could not delete disk repository " + repository); } @@ -77,25 +78,25 @@ public synchronized void setBasePath(SafePath baseLocation) throws IOException { public synchronized void ensureRepository() throws IOException { if (baseLocation == null) { - setBasePath(SecuritySupport.JAVA_IO_TMPDIR); + setBasePath(JAVA_IO_TMPDIR); } } synchronized RepositoryChunk newChunk() { LocalDateTime timestamp = timestamp(); try { - if (!SecuritySupport.existDirectory(repository)) { + if (!Files.exists(repository)) { this.repository = createRepository(baseLocation); JVM.setRepositoryLocation(repository.toString()); - SecuritySupport.setProperty(JFR_REPOSITORY_LOCATION_PROPERTY, repository.toString()); + System.setProperty(JFR_REPOSITORY_LOCATION_PROPERTY, repository.toString()); cleanupDirectories.add(repository); chunkFilename = null; } if (chunkFilename == null) { - chunkFilename = ChunkFilename.newPriviliged(repository.toPath()); + chunkFilename = new ChunkFilename(repository); } String filename = chunkFilename.next(timestamp); - return new RepositoryChunk(new SafePath(filename)); + return new RepositoryChunk(Path.of(filename)); } catch (Exception e) { String errorMsg = String.format("Could not create chunk in repository %s, %s: %s", repository, e.getClass(), e.getMessage()); Logger.log(LogTag.JFR, LogLevel.ERROR, errorMsg); @@ -113,16 +114,16 @@ private static LocalDateTime timestamp() { } } - private static SafePath createRepository(SafePath basePath) throws IOException { - SafePath canonicalBaseRepositoryPath = createRealBasePath(basePath); - SafePath f = null; + private static Path createRepository(Path basePath) throws IOException { + Path canonicalBaseRepositoryPath = createRealBasePath(basePath); + Path f = null; String basename = ValueFormatter.formatDateTime(timestamp()) + "_" + JVM.getPid(); String name = basename; int i = 0; for (; i < MAX_REPO_CREATION_RETRIES; i++) { - f = new SafePath(canonicalBaseRepositoryPath.toPath().resolve(name)); + f = canonicalBaseRepositoryPath.resolve(name); if (tryToUseAsRepository(f)) { break; } @@ -132,41 +133,36 @@ private static SafePath createRepository(SafePath basePath) throws IOException { if (i == MAX_REPO_CREATION_RETRIES) { throw new IOException("Unable to create JFR repository directory using base location (" + basePath + ")"); } - return SecuritySupport.toRealPath(f); + return f.toRealPath(); } - private static SafePath createRealBasePath(SafePath safePath) throws IOException { - if (SecuritySupport.exists(safePath)) { - if (!SecuritySupport.isWritable(safePath)) { - throw new IOException("JFR repository directory (" + safePath.toString() + ") exists, but isn't writable"); + private static Path createRealBasePath(Path path) throws IOException { + if (Files.exists(path)) { + if (!Files.isWritable(path)) { + throw new IOException("JFR repository directory (" + path.toString() + ") exists, but isn't writable"); } - return SecuritySupport.toRealPath(safePath); + return path.toRealPath(); } - SafePath p = SecuritySupport.createDirectories(safePath); - return SecuritySupport.toRealPath(p); + return Files.createDirectories(path).toRealPath(); } - private static boolean tryToUseAsRepository(final SafePath path) { - Path parent = path.toPath().getParent(); + private static boolean tryToUseAsRepository(Path path) { + Path parent = path.getParent(); if (parent == null) { return false; } try { - try { - SecuritySupport.createDirectories(path); - } catch (Exception e) { - // file already existed or some other problem occurred - } - if (!SecuritySupport.exists(path)) { - return false; - } - if (!SecuritySupport.isDirectory(path)) { - return false; - } - return true; - } catch (IOException io) { + Files.createDirectories(path); + } catch (Exception e) { + // file already existed or some other problem occurred + } + if (!Files.exists(path)) { + return false; + } + if (!Files.isDirectory(path)) { return false; } + return true; } synchronized void clear() { @@ -174,9 +170,9 @@ synchronized void clear() { return; } - for (SafePath p : cleanupDirectories) { + for (Path p : cleanupDirectories) { try { - SecuritySupport.clearDirectory(p); + DirectoryCleaner.clear(p); Logger.log(LogTag.JFR, LogLevel.INFO, "Removed repository " + p); } catch (IOException e) { Logger.log(LogTag.JFR, LogLevel.INFO, "Repository " + p + " could not be removed at shutdown: " + e.getMessage()); @@ -184,11 +180,11 @@ synchronized void clear() { } } - public synchronized SafePath getRepositoryPath() { + public synchronized Path getRepositoryPath() { return repository; } - public synchronized SafePath getBaseLocation() { + public synchronized Path getBaseLocation() { return baseLocation; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java index e46b6020d5dbd..6507c5f666854 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -27,12 +27,14 @@ import java.io.IOException; import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.time.Instant; import java.util.Comparator; -import jdk.jfr.internal.SecuritySupport.SafePath; - public final class RepositoryChunk { static final Comparator END_TIME_COMPARATOR = new Comparator() { @@ -42,7 +44,7 @@ public int compare(RepositoryChunk c1, RepositoryChunk c2) { } }; - private final SafePath chunkFile; + private final Path chunkFile; private final RandomAccessFile unFinishedRAF; private Instant endTime = null; // unfinished @@ -50,15 +52,15 @@ public int compare(RepositoryChunk c1, RepositoryChunk c2) { private int refCount = 1; private long size; - RepositoryChunk(SafePath path) throws Exception { + RepositoryChunk(Path path) throws Exception { this.chunkFile = path; - this.unFinishedRAF = SecuritySupport.createRandomAccessFile(chunkFile); + this.unFinishedRAF = new RandomAccessFile(path.toFile(), "rw"); } boolean finish(Instant endTime) { try { unFinishedRAF.close(); - size = SecuritySupport.getFileSize(chunkFile); + size = Files.size(chunkFile); this.endTime = endTime; if (Logger.shouldLog(LogTag.JFR_SYSTEM, LogLevel.DEBUG)) { Logger.log(LogTag.JFR_SYSTEM, LogLevel.DEBUG, "Chunk finished: " + chunkFile); @@ -89,9 +91,9 @@ public Instant getEndTime() { return endTime; } - private void delete(SafePath f) { + private void delete(Path f) { try { - SecuritySupport.delete(f); + Files.delete(f); if (Logger.shouldLog(LogTag.JFR, LogLevel.DEBUG)) { Logger.log(LogTag.JFR, LogLevel.DEBUG, "Repository chunk " + f + " deleted"); } @@ -153,7 +155,7 @@ ReadableByteChannel newChannel() throws IOException { if (!isFinished()) { throw new IOException("Chunk not finished"); } - return ((SecuritySupport.newFileChannelToRead(chunkFile))); + return FileChannel.open(chunkFile, StandardOpenOption.READ); } public boolean inInterval(Instant startTime, Instant endTime) { @@ -166,23 +168,19 @@ public boolean inInterval(Instant startTime, Instant endTime) { return true; } - public SafePath getFile() { + public Path getFile() { return chunkFile; } public long getCurrentFileSize() { try { - return SecuritySupport.getFileSize(chunkFile); + return Files.size(chunkFile); } catch (IOException e) { return 0L; } } boolean isMissingFile() { - try { - return !SecuritySupport.exists(chunkFile); - } catch (IOException ioe) { - return true; - } + return !Files.exists(chunkFile); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java index 7398b6a91b7ad..98bc0c86bfaf5 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,63 +25,13 @@ package jdk.jfr.internal; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.RandomAccessFile; -import java.io.Reader; import java.lang.invoke.MethodHandles; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.ReflectPermission; -import java.nio.channels.FileChannel; -import java.nio.channels.ReadableByteChannel; -import java.nio.file.DirectoryStream; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.LinkOption; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardOpenOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.attribute.FileTime; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permission; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.PropertyPermission; -import java.util.concurrent.Callable; - import jdk.internal.module.Modules; import jdk.jfr.Event; -import jdk.jfr.FlightRecorder; -import jdk.jfr.FlightRecorderListener; -import jdk.jfr.FlightRecorderPermission; -import jdk.jfr.Recording; -import jdk.jfr.internal.consumer.FileAccess; -/** - * Contains JFR code that does - * {@link AccessController#doPrivileged(PrivilegedAction)} - */ public final class SecuritySupport { - private static final String EVENTS_PACKAGE_NAME = "jdk.jfr.events"; - private static final String EVENT_PACKAGE_NAME = "jdk.jfr.internal.event"; - - public static final String REGISTER_EVENT = "registerEvent"; - public static final String ACCESS_FLIGHT_RECORDER = "accessFlightRecorder"; - private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); private static final Module JFR_MODULE = Event.class.getModule(); - public static final SafePath JFC_DIRECTORY = getPathInProperty("java.home", "lib/jfr"); - public static final FileAccess PRIVILEGED = new Privileged(); - static final SafePath JAVA_IO_TMPDIR = getPathInProperty("java.io.tmpdir", null); + private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); static { // ensure module java.base can read module jdk.jfr as early as possible @@ -90,215 +40,6 @@ public final class SecuritySupport { addEventsExport(Object.class); } - static final class SecureRecorderListener implements FlightRecorderListener { - - @SuppressWarnings("removal") - private final AccessControlContext context; - private final FlightRecorderListener changeListener; - - SecureRecorderListener(@SuppressWarnings("removal") AccessControlContext context, FlightRecorderListener changeListener) { - this.context = Objects.requireNonNull(context); - this.changeListener = Objects.requireNonNull(changeListener); - } - - @SuppressWarnings("removal") - @Override - public void recordingStateChanged(Recording recording) { - AccessController.doPrivileged((PrivilegedAction) () -> { - try { - changeListener.recordingStateChanged(recording); - } catch (Throwable t) { - // Prevent malicious user to propagate exception callback in the wrong context - Logger.log(LogTag.JFR, LogLevel.WARN, "Unexpected exception in listener " + changeListener.getClass()+ " at recording state change"); - } - return null; - }, context); - } - - @SuppressWarnings("removal") - @Override - public void recorderInitialized(FlightRecorder recorder) { - AccessController.doPrivileged((PrivilegedAction) () -> { - try { - changeListener.recorderInitialized(recorder); - } catch (Throwable t) { - // Prevent malicious user to propagate exception callback in the wrong context - Logger.log(LogTag.JFR, LogLevel.WARN, "Unexpected exception in listener " + changeListener.getClass()+ " when initializing FlightRecorder"); - } - return null; - }, context); - } - - public FlightRecorderListener getChangeListener() { - return changeListener; - } - } - - private static final class DirectoryCleaner extends SimpleFileVisitor { - @Override - public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { - Files.delete(path); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - if (exc != null) { - throw exc; - } - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - } - - /** - * Path created by the default file provider, and not - * a malicious provider. - * - */ - public static final class SafePath implements Comparable { - private final Path path; - private final String text; - - public SafePath(Path p) { - // sanitize - text = p.toString(); - path = Paths.get(text); - } - - public SafePath(String path) { - this(Paths.get(path)); - } - - public Path toPath() { - return path; - } - - public File toFile() { - return path.toFile(); - } - - @Override - public String toString() { - return text; - } - - @Override - public int compareTo(SafePath that) { - return that.text.compareTo(this.text); - } - - @Override - public boolean equals(Object other) { - if(other != null && other instanceof SafePath s){ - return this.toPath().equals(s.toPath()); - } - return false; - } - - @Override - public int hashCode() { - return this.toPath().hashCode(); - } - } - - private interface RunnableWithCheckedException { - public void run() throws Exception; - } - - private interface CallableWithoutCheckException { - public T call(); - } - - public static void checkAccessFlightRecorder() throws SecurityException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new FlightRecorderPermission(ACCESS_FLIGHT_RECORDER)); - } - } - - public static void checkRegisterPermission() throws SecurityException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new FlightRecorderPermission(REGISTER_EVENT)); - } - } - - @SuppressWarnings("removal") - private static U doPrivilegedIOWithReturn(Callable function) throws IOException { - try { - return AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public U run() throws Exception { - return function.call(); - } - }, null); - } catch (PrivilegedActionException e) { - Throwable t = e.getCause(); - if (t instanceof IOException) { - throw (IOException) t; - } - throw new IOException("Unexpected error during I/O operation. " + t.getMessage(), t); - } - } - - private static void doPriviligedIO(RunnableWithCheckedException function) throws IOException { - doPrivilegedIOWithReturn(() -> { - function.run(); - return null; - }); - } - - @SuppressWarnings("removal") - private static void doPrivileged(Runnable function, Permission... perms) { - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - function.run(); - return null; - } - }, null, perms); - } - - @SuppressWarnings("removal") - private static void doPrivileged(Runnable function) { - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - function.run(); - return null; - } - }); - } - - @SuppressWarnings("removal") - private static T doPrivilegedWithReturn(CallableWithoutCheckException function, Permission... perms) { - return AccessController.doPrivileged(new PrivilegedAction() { - @Override - public T run() { - return function.call(); - } - }, null, perms); - } - - public static List getPredefinedJFCFiles() { - List list = new ArrayList<>(); - try (var ds = doPrivilegedIOWithReturn(() -> Files.newDirectoryStream(JFC_DIRECTORY.toPath()))) { - for (Path path : ds) { - SafePath s = new SafePath(path); - String text = s.toString(); - if (text.endsWith(".jfc") && !SecuritySupport.isDirectory(s)) { - list.add(s); - } - } - } catch (IOException ioe) { - Logger.log(LogTag.JFR, LogLevel.WARN, "Could not access .jfc-files in " + JFC_DIRECTORY + ", " + ioe.getMessage()); - } - return list; - } - static void makeVisibleToJFR(Class clazz) { Module classModule = clazz.getModule(); Modules.addReads(JFR_MODULE, classModule); @@ -314,213 +55,31 @@ static void makeVisibleToJFR(Class clazz) { * (for EventConfiguration and EventWriter) */ static void addInternalEventExport(Class clazz) { - Modules.addExports(JFR_MODULE, EVENT_PACKAGE_NAME, clazz.getModule()); + Modules.addExports(JFR_MODULE, "jdk.jfr.internal.event", clazz.getModule()); } static void addEventsExport(Class clazz) { - Modules.addExports(JFR_MODULE, EVENTS_PACKAGE_NAME, clazz.getModule()); + Modules.addExports(JFR_MODULE, "jdk.jfr.events", clazz.getModule()); } static void addReadEdge(Class clazz) { Modules.addReads(clazz.getModule(), JFR_MODULE); } - public static void registerEvent(Class eventClass) { - doPrivileged(() -> MetadataRepository.getInstance().register(eventClass), new FlightRecorderPermission(REGISTER_EVENT)); - } - - public static void setProperty(String propertyName, String value) { - doPrivileged(() -> System.setProperty(propertyName, value), new PropertyPermission(propertyName, "write")); - } - - static boolean getBooleanProperty(String propertyName) { - return doPrivilegedWithReturn(() -> Boolean.getBoolean(propertyName), new PropertyPermission(propertyName, "read")); - } - - private static SafePath getPathInProperty(String prop, String subPath) { - return doPrivilegedWithReturn(() -> { - String path = System.getProperty(prop); - if (path == null) { - return null; - } - File file = subPath == null ? new File(path) : new File(path, subPath); - return new SafePath(file.getAbsolutePath()); - }, new PropertyPermission("*", "read")); - } - - // Called by JVM during initialization of JFR - static Thread createRecorderThread(ThreadGroup systemThreadGroup, ClassLoader contextClassLoader) { - // The thread should have permission = new Permission[0], and not "modifyThreadGroup" and "modifyThread" on the stack, - // but it's hard circumvent if we are going to pass in system thread group in the constructor - Thread thread = doPrivilegedWithReturn(() -> new Thread(systemThreadGroup, "JFR Recorder Thread"), new RuntimePermission("modifyThreadGroup"), new RuntimePermission("modifyThread")); - doPrivileged(() -> thread.setContextClassLoader(contextClassLoader), new RuntimePermission("setContextClassLoader"), new RuntimePermission("modifyThread")); - return thread; - } - - static void registerShutdownHook(Thread shutdownHook) { - doPrivileged(() -> Runtime.getRuntime().addShutdownHook(shutdownHook), new RuntimePermission("shutdownHooks")); - } - - static void setUncaughtExceptionHandler(Thread thread, Thread.UncaughtExceptionHandler eh) { - doPrivileged(() -> thread.setUncaughtExceptionHandler(eh), new RuntimePermission("modifyThread")); - } - - static void clearDirectory(SafePath safePath) throws IOException { - doPriviligedIO(() -> Files.walkFileTree(safePath.toPath(), new DirectoryCleaner())); - } - - static SafePath toRealPath(SafePath safePath, LinkOption... options) throws IOException { - return new SafePath(doPrivilegedIOWithReturn(() -> safePath.toPath().toRealPath(options))); - } - - static boolean existDirectory(SafePath directory) throws IOException { - return doPrivilegedIOWithReturn(() -> Files.exists(directory.toPath())); - } - - static RandomAccessFile createRandomAccessFile(SafePath path) throws Exception { - return doPrivilegedIOWithReturn(() -> new RandomAccessFile(path.toPath().toFile(), "rw")); - } - - public static InputStream newFileInputStream(SafePath safePath) throws IOException { - return doPrivilegedIOWithReturn(() -> Files.newInputStream(safePath.toPath())); - } - - public static long getFileSize(SafePath safePath) throws IOException { - return doPrivilegedIOWithReturn(() -> Files.size(safePath.toPath())); - } - - static SafePath createDirectories(SafePath safePath) throws IOException { - Path p = doPrivilegedIOWithReturn(() -> Files.createDirectories(safePath.toPath())); - return new SafePath(p); - } - - public static boolean exists(SafePath safePath) throws IOException { - // Files.exist(path) is allocation intensive - return doPrivilegedIOWithReturn(() -> safePath.toPath().toFile().exists()); - } - - public static boolean isDirectory(SafePath safePath) throws IOException { - return doPrivilegedIOWithReturn(() -> Files.isDirectory(safePath.toPath())); - } - - static void delete(SafePath localPath) throws IOException { - doPriviligedIO(() -> Files.delete(localPath.toPath())); - } - - static boolean isWritable(SafePath safePath) throws IOException { - return doPrivilegedIOWithReturn(() -> Files.isWritable(safePath.toPath())); - } - - static ReadableByteChannel newFileChannelToRead(SafePath safePath) throws IOException { - return doPrivilegedIOWithReturn(() -> FileChannel.open(safePath.toPath(), StandardOpenOption.READ)); - } - - public static InputStream getResourceAsStream(String name) throws IOException { - return doPrivilegedIOWithReturn(() -> SecuritySupport.class.getResourceAsStream(name)); - } - - public static Reader newFileReader(SafePath safePath) throws FileNotFoundException, IOException { - return doPrivilegedIOWithReturn(() -> Files.newBufferedReader(safePath.toPath())); - } - - static void setAccessible(Method method) { - doPrivileged(() -> method.setAccessible(true), new ReflectPermission("suppressAccessChecks")); - } - - static void setAccessible(Constructor constructor) { - doPrivileged(() -> constructor.setAccessible(true), new ReflectPermission("suppressAccessChecks")); - } - - @SuppressWarnings("removal") public static void ensureClassIsInitialized(Class clazz) { try { - MethodHandles.Lookup lookup; - if (System.getSecurityManager() == null) { - lookup = MethodHandles.privateLookupIn(clazz, LOOKUP); - } else { - lookup = AccessController.doPrivileged(new PrivilegedExceptionAction<>() { - @Override - public MethodHandles.Lookup run() throws IllegalAccessException { - return MethodHandles.privateLookupIn(clazz, LOOKUP); - } - }, null, new ReflectPermission("suppressAccessChecks")); - } + MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(clazz, LOOKUP); lookup.ensureInitialized(clazz); } catch (IllegalAccessException e) { throw new InternalError(e); - } catch (PrivilegedActionException e) { - throw new InternalError(e.getCause()); } } - @SuppressWarnings("removal") static Class defineClass(Class lookupClass, byte[] bytes) { - return AccessController.doPrivileged(new PrivilegedAction>() { - @Override - public Class run() { - try { - return MethodHandles.privateLookupIn(lookupClass, LOOKUP).defineClass(bytes); - } catch (IllegalAccessException e) { - throw new InternalError(e); - } - } - }); - } - - public static Thread createThreadWitNoPermissions(String threadName, Runnable runnable) { - return doPrivilegedWithReturn(() -> new Thread(runnable, threadName), new Permission[0]); - } - - public static void setDaemonThread(Thread t, boolean daemon) { - doPrivileged(()-> t.setDaemon(daemon), new RuntimePermission("modifyThread")); - } - - public static SafePath getAbsolutePath(SafePath path) throws IOException { - return new SafePath(doPrivilegedIOWithReturn((()-> path.toPath().toAbsolutePath()))); - } - - private static final class Privileged extends FileAccess { - @Override - public RandomAccessFile openRAF(File f, String mode) throws IOException { - return doPrivilegedIOWithReturn( () -> new RandomAccessFile(f, mode)); - } - - @Override - public DirectoryStream newDirectoryStream(Path directory) throws IOException { - return doPrivilegedIOWithReturn( () -> Files.newDirectoryStream(directory)); - } - - @Override - public String getAbsolutePath(File f) throws IOException { - return doPrivilegedIOWithReturn( () -> f.getAbsolutePath()); - } - @Override - public long length(File f) throws IOException { - return doPrivilegedIOWithReturn( () -> f.length()); - } - - @Override - public long fileSize(Path p) throws IOException { - return doPrivilegedIOWithReturn( () -> Files.size(p)); - } - - @Override - public boolean exists(Path p) throws IOException { - return doPrivilegedIOWithReturn( () -> Files.exists(p)); - } - - @Override - public boolean isDirectory(Path p) { - return doPrivilegedWithReturn( () -> Files.isDirectory(p)); - } - - @Override - public FileTime getLastModified(Path p) throws IOException { - // Timestamp only needed when examining repository for other JVMs, - // in which case an unprivileged mode should be used. - throw new InternalError("Should not reach here"); + try { + return MethodHandles.privateLookupIn(lookupClass, LOOKUP).defineClass(bytes); + } catch (IllegalAccessException e) { + throw new InternalError(e); } } - - } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/ShutdownHook.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/ShutdownHook.java index 8375dab0bcce3..ef9e5d53bf951 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/ShutdownHook.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/ShutdownHook.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,22 +25,18 @@ package jdk.jfr.internal; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; - import jdk.jfr.RecordingState; /** * Class responsible for dumping recordings on exit * */ -final class ShutdownHook implements Runnable { +final class ShutdownHook extends Thread { private final PlatformRecorder recorder; Object tlabDummyObject; ShutdownHook(PlatformRecorder recorder) { + super("JFR Shutdown Hook"); this.recorder = recorder; } @@ -61,7 +57,7 @@ public void run() { private void dump(PlatformRecording recording) { try { - WriteableUserPath dest = recording.getDestination(); + WriteablePath dest = recording.getDestination(); if (dest == null) { dest = recording.makeDumpPath(); recording.setDestination(dest); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java index 350bf55ccd4ee..bf26294ef579b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -189,7 +189,7 @@ private static Object invokeAnnotation(Annotation annotation, String methodName) Modules.addExports(proxyModule, proxyPackage, jfrModule); } } - SecuritySupport.setAccessible(m); + m.setAccessible(true); try { return m.invoke(annotation, new Object[0]); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/JDKEventTask.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/WriteablePath.java similarity index 52% rename from src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/JDKEventTask.java rename to src/jdk.jfr/share/classes/jdk/jfr/internal/WriteablePath.java index a891b1c3775c1..5f3672d5d4cc5 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/JDKEventTask.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/WriteablePath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -22,34 +22,42 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.jfr.internal.periodic; -import jdk.internal.event.Event; -import jdk.jfr.internal.util.Utils; +package jdk.jfr.internal; -/** - * Periodic task that runs trusted code that doesn't require an access control - * context. - *

        - * This class can be removed once the Security Manager is no longer supported. - */ -final class JDKEventTask extends JavaEventTask { +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; - public JDKEventTask(Class eventClass, Runnable runnable) { - super(eventClass, runnable); - if (!getEventType().isJDK()) { - throw new InternalError("Must be a JDK event"); - } - if (!Utils.isJDKClass(eventClass)) { - throw new SecurityException("Periodic task can only be registered for event classes that belongs to the JDK"); - } - if (!Utils.isJDKClass(runnable.getClass())) { - throw new SecurityException("Runnable class must belong to the JDK"); +public final class WriteablePath { + private final Path path; + private final Path real; + + public WriteablePath(Path path) throws IOException { + // verify that the path is writeable + if (Files.exists(path) && !Files.isWritable(path)) { + // throw same type of exception as FileOutputStream + // constructor, if file can't be opened. + throw new FileNotFoundException("Could not write to file: " + path.toAbsolutePath()); } + // will throw if non-writeable + BufferedWriter fw = Files.newBufferedWriter(path); + fw.close(); + this.path = path; + this.real = path.toRealPath(); + } + + public Path getPath() { + return path; + } + + public Path getReal() { + return real; } - @Override - public void execute(long timestamp, PeriodicType periodicType) { - getRunnable().run(); + public String getRealPathText() { + return real.toString(); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/WriteableUserPath.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/WriteableUserPath.java deleted file mode 100644 index b53ff48d606c0..0000000000000 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/WriteableUserPath.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. 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 jdk.jfr.internal; - -import java.io.BufferedWriter; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; -import java.util.concurrent.Callable; - -/** - * Purpose of this class is to simplify analysis of security risks. - *

        - * Paths in the public API should be wrapped in this class so we - * at all time know what kind of paths we are dealing with. - *

        - * A user supplied path must never be used in an unsafe context, such as a - * shutdown hook or any other thread created by JFR. - *

        - * All operation using this path must happen in {@link #doPrivilegedIO(Callable)} - */ -public final class WriteableUserPath { - @SuppressWarnings("removal") - private final AccessControlContext controlContext; - private final Path original; - private final Path real; - private final String realPathText; - private final String originalText; - - // Not to ensure security, but to help - // against programming errors - private volatile boolean inPrivileged; - - @SuppressWarnings("removal") - public WriteableUserPath(Path path) throws IOException { - controlContext = AccessController.getContext(); - // verify that the path is writeable - if (Files.exists(path) && !Files.isWritable(path)) { - // throw same type of exception as FileOutputStream - // constructor, if file can't be opened. - throw new FileNotFoundException("Could not write to file: " + path.toAbsolutePath()); - } - // will throw if non-writeable - BufferedWriter fw = Files.newBufferedWriter(path); - fw.close(); - this.original = path; - this.originalText = path.toString(); - this.real = path.toRealPath(); - this.realPathText = real.toString(); - } - - /** - * Returns a potentially malicious path where the user may have implemented - * their own version of Path. This method should never be called in an - * unsafe context and the Path value should never be passed along to other - * methods. - * - * @return path from a potentially malicious user - */ - public Path getPotentiallyMaliciousOriginal() { - return original; - } - - /** - * Returns a string representation of the real path. - * - * @return path as text - */ - public String getRealPathText() { - return realPathText; - } - - /** - * Returns a string representation of the original path. - * - * @return path as text - */ - public String getOriginalText() { - return originalText; - } - - - /** - * Returns a potentially malicious path where the user may have implemented - * their own version of Path. This method should never be called in an - * unsafe context and the Path value should never be passed along to other - * methods. - * - * @return path from a potentially malicious user - */ - public Path getReal() { - if (!inPrivileged) { - throw new InternalError("A user path was accessed outside the context it was supplied in"); - } - return real; - } - - @SuppressWarnings("removal") - public void doPrivilegedIO(Callable function) throws IOException { - try { - inPrivileged = true; - AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - function.call(); - return null; - } - }, controlContext); - } catch (Throwable t) { - // prevent malicious user to propagate exception callback - // in the wrong context - Throwable cause = null; - if (System.getSecurityManager() == null) { - cause = t; - } - throw new IOException("Unexpected error during I/O operation", cause); - } finally { - inPrivileged = false; - } - } -} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java index cdfc8f017a657..b9994c1e51cbe 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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,9 +26,6 @@ package jdk.jfr.internal.consumer; import java.io.IOException; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.time.Duration; import java.time.Instant; import java.util.List; @@ -46,7 +43,6 @@ import jdk.jfr.internal.LogLevel; import jdk.jfr.internal.LogTag; import jdk.jfr.internal.Logger; -import jdk.jfr.internal.SecuritySupport; /* * Purpose of this class is to simplify the implementation of @@ -57,8 +53,6 @@ public abstract class AbstractEventStream implements EventStream { private final CountDownLatch terminated = new CountDownLatch(1); private final Runnable flushOperation = () -> dispatcher().runFlushActions(); - @SuppressWarnings("removal") - private final AccessControlContext accessControllerContext; private final StreamConfiguration streamConfiguration = new StreamConfiguration(); private final List configurations; private final ParserState parserState = new ParserState(); @@ -67,8 +61,7 @@ public abstract class AbstractEventStream implements EventStream { private boolean daemon = false; - AbstractEventStream(@SuppressWarnings("removal") AccessControlContext acc, List configurations) throws IOException { - this.accessControllerContext = Objects.requireNonNull(acc); + AbstractEventStream(List configurations) throws IOException { this.configurations = configurations; } @@ -221,22 +214,21 @@ protected final ParserState parserState() { public final void startAsync(long startNanos) { startInternal(startNanos); - Runnable r = () -> run(accessControllerContext); - Thread thread = SecuritySupport.createThreadWitNoPermissions(nextThreadName(), r); - SecuritySupport.setDaemonThread(thread, daemon); + Runnable r = () -> execute(); + Thread thread = new Thread(r, nextThreadName()); + thread.setDaemon(daemon); thread.start(); } public final void start(long startNanos) { startInternal(startNanos); - run(accessControllerContext); + execute(); } protected final Runnable getFlushOperation() { return flushOperation; } - protected final void onFlush() { Runnable r = getFlushOperation(); if (r != null) { @@ -276,17 +268,6 @@ private void execute() { } } - @SuppressWarnings("removal") - private void run(AccessControlContext accessControlContext) { - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - execute(); - return null; - } - }, accessControlContext); - } - private String nextThreadName() { return "JFR Event Stream " + counter.incrementAndGet(); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java index bc9aa7987c3b5..8560efb9347a7 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -27,12 +27,10 @@ import java.io.IOException; import java.nio.file.Path; -import java.security.AccessControlContext; import java.time.Instant; import java.util.Arrays; import java.util.Comparator; import java.util.List; -import java.util.Objects; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; @@ -44,7 +42,6 @@ import jdk.jfr.internal.LogTag; import jdk.jfr.internal.Logger; import jdk.jfr.internal.PlatformRecording; -import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.management.StreamBarrier; @@ -58,7 +55,6 @@ public final class EventDirectoryStream extends AbstractEventStream { private static final Comparator EVENT_COMPARATOR = JdkJfrConsumer.instance().eventComparator(); private final RepositoryFiles repositoryFiles; - private final FileAccess fileAccess; private final PlatformRecording recording; private final StreamBarrier barrier = new StreamBarrier(); private final AtomicLong streamId = new AtomicLong(); @@ -69,20 +65,13 @@ public final class EventDirectoryStream extends AbstractEventStream { private volatile Consumer onCompleteHandler; public EventDirectoryStream( - @SuppressWarnings("removal") - AccessControlContext acc, Path p, - FileAccess fileAccess, PlatformRecording recording, List configurations, boolean allowSubDirectories) throws IOException { - super(acc, configurations); + super(configurations); this.recording = recording; - if (p != null && SecuritySupport.PRIVILEGED == fileAccess) { - throw new SecurityException("Priviliged file access not allowed with potentially malicious Path implementation"); - } - this.fileAccess = Objects.requireNonNull(fileAccess); - this.repositoryFiles = new RepositoryFiles(fileAccess, p, allowSubDirectories); + this.repositoryFiles = new RepositoryFiles(p, allowSubDirectories); this.streamId.incrementAndGet(); Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Stream " + streamId + " started."); } @@ -153,7 +142,7 @@ protected void processRecursionSafe() throws IOException { return; } currentChunkStartNanos = repositoryFiles.getTimestamp(path); - try (RecordingInput input = new RecordingInput(path.toFile(), fileAccess)) { + try (RecordingInput input = new RecordingInput(path.toFile())) { input.setStreamed(); currentParser = new ChunkParser(input, disp.parserConfiguration, parserState()); long segmentStart = currentParser.getStartNanos() + currentParser.getChunkDuration(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java index f03e8d8acb48e..56d9fe01d790c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -27,7 +27,6 @@ import java.io.IOException; import java.nio.file.Path; -import java.security.AccessControlContext; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; @@ -45,9 +44,9 @@ public final class EventFileStream extends AbstractEventStream { private ChunkParser currentParser; private RecordedEvent[] cacheSorted; - public EventFileStream(@SuppressWarnings("removal") AccessControlContext acc, Path file) throws IOException { - super(acc, Collections.emptyList()); - this.input = new RecordingInput(file.toFile(), FileAccess.UNPRIVILEGED); + public EventFileStream(Path file) throws IOException { + super(Collections.emptyList()); + this.input = new RecordingInput(file.toFile()); this.input.setStreamed(); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/FileAccess.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/FileAccess.java deleted file mode 100644 index 74a783b0d19b4..0000000000000 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/FileAccess.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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 jdk.jfr.internal.consumer; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.FileTime; - -// Protected by modular boundaries. -public abstract class FileAccess { - public static final FileAccess UNPRIVILEGED = new UnPrivileged(); - - public abstract RandomAccessFile openRAF(File f, String mode) throws IOException; - - public abstract DirectoryStream newDirectoryStream(Path repository) throws IOException; - - public abstract String getAbsolutePath(File f) throws IOException; - - public abstract long length(File f) throws IOException; - - public abstract long fileSize(Path p) throws IOException; - - public abstract boolean exists(Path s) throws IOException; - - public abstract boolean isDirectory(Path p); - - public abstract FileTime getLastModified(Path p) throws IOException; - - private static class UnPrivileged extends FileAccess { - @Override - public RandomAccessFile openRAF(File f, String mode) throws IOException { - return new RandomAccessFile(f, mode); - } - - @Override - public DirectoryStream newDirectoryStream(Path dir) throws IOException { - return Files.newDirectoryStream(dir); - } - - @Override - public String getAbsolutePath(File f) throws IOException { - return f.getAbsolutePath(); - } - - @Override - public long length(File f) throws IOException { - return f.length(); - } - - @Override - public long fileSize(Path p) throws IOException { - return Files.size(p); - } - - @Override - public boolean exists(Path p) { - return Files.exists(p); - } - - @Override - public boolean isDirectory(Path p) { - return Files.isDirectory(p); - } - - @Override - public FileTime getLastModified(Path p) throws IOException { - return Files.getLastModifiedTime(p); - } - } -} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java index e0dd7fa2ad8d5..83d8b8c5f17d5 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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,12 +26,12 @@ import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.file.Files; import java.nio.file.Path; import jdk.jfr.Recording; import jdk.jfr.RecordingState; import jdk.jfr.internal.SecuritySupport; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.management.EventByteStream; import jdk.jfr.internal.management.HiddenWait; import jdk.jfr.internal.management.ManagementSupport; @@ -63,7 +63,7 @@ public OngoingStream(Recording recording, int blockSize, long startTimeNanos, lo this.blockSize = blockSize; this.startTimeNanos = startTimeNanos; this.endTimeNanos = endTimeNanos; - this.repositoryFiles = new RepositoryFiles(SecuritySupport.PRIVILEGED, null, false); + this.repositoryFiles = new RepositoryFiles(null, false); } @Override @@ -206,10 +206,10 @@ private byte[] readWithHeader(int size) throws IOException { private boolean ensureInput() throws IOException { if (input == null) { - if (SecuritySupport.getFileSize(new SafePath(path)) < HEADER_SIZE) { + if (Files.size(path) < HEADER_SIZE) { return false; } - input = new RecordingInput(path.toFile(), SecuritySupport.PRIVILEGED); + input = new RecordingInput(path.toFile()); input.setStreamed(); header = new ChunkHeader(input); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java index 69ec73f57fd6f..33cb928bbbfd7 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -33,7 +33,6 @@ import java.nio.file.Path; import jdk.jfr.internal.management.HiddenWait; -import jdk.jfr.internal.util.Utils; public final class RecordingInput implements DataInput, AutoCloseable { @@ -68,7 +67,6 @@ public void reset() { } } private final int blockSize; - private final FileAccess fileAccess; private final HiddenWait threadSleeper = new HiddenWait(); private long pollCount = 1000; private RandomAccessFile file; @@ -79,26 +77,25 @@ public void reset() { private long size = -1; // Fail fast if setSize(...) has not been called // before parsing - RecordingInput(File f, FileAccess fileAccess, int blockSize) throws IOException { + RecordingInput(File f, int blockSize) throws IOException { this.blockSize = blockSize; - this.fileAccess = fileAccess; initialize(f); } private void initialize(File f) throws IOException { - this.filename = fileAccess.getAbsolutePath(f); - this.file = fileAccess.openRAF(f, "r"); + this.filename = f.getAbsolutePath(); + this.file = new RandomAccessFile(f, "r"); this.position = 0; this.size = -1; this.currentBlock.reset(); previousBlock.reset(); - if (fileAccess.length(f) < 8) { - throw new IOException("Not a valid Flight Recorder file. File length is only " + fileAccess.length(f) + " bytes."); + if (f.length() < 8) { + throw new IOException("Not a valid Flight Recorder file. File length is only " + f.length() + " bytes."); } } - public RecordingInput(File f, FileAccess fileAccess) throws IOException { - this(f, fileAccess, DEFAULT_BLOCK_SIZE); + public RecordingInput(File f) throws IOException { + this(f, DEFAULT_BLOCK_SIZE); } void positionPhysical(long position) throws IOException { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java index 2cf56c67cb558..09b64efbdd0ef 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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.IOException; import java.nio.file.DirectoryIteratorException; import java.nio.file.DirectoryStream; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.FileTime; import java.util.ArrayList; @@ -45,7 +46,6 @@ import jdk.jfr.internal.LogTag; import jdk.jfr.internal.Logger; import jdk.jfr.internal.Repository; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.management.HiddenWait;; public final class RepositoryFiles { @@ -57,7 +57,6 @@ public static void notifyNewFile() { } } - private final FileAccess fileAccess; private final NavigableMap pathSet = new TreeMap<>(); private final Map pathLookup = new HashMap<>(); private final HiddenWait waitObject; @@ -65,9 +64,8 @@ public static void notifyNewFile() { private volatile boolean closed; private Path repository; - public RepositoryFiles(FileAccess fileAccess, Path repository, boolean allowSubDirectory) { + public RepositoryFiles(Path repository, boolean allowSubDirectory) { this.repository = repository; - this.fileAccess = fileAccess; this.waitObject = repository == null ? WAIT_OBJECT : new HiddenWait(); this.allowSubDirectory = allowSubDirectory; } @@ -172,14 +170,14 @@ private boolean updatePaths() throws IOException, DirectoryIteratorException { if (repoPath == null) { // Always get the latest repository if 'jcmd JFR.configure // repositorypath=...' has been executed - SafePath sf = Repository.getRepository().getRepositoryPath(); - if (sf == null) { + Path path = Repository.getRepository().getRepositoryPath(); + if (path == null) { return false; // not initialized } - repoPath = sf.toPath(); + repoPath = path; } - try (DirectoryStream dirStream = fileAccess.newDirectoryStream(repoPath)) { + try (DirectoryStream dirStream = Files.newDirectoryStream(repoPath)) { List added = new ArrayList<>(); Set current = new HashSet<>(); for (Path p : dirStream) { @@ -208,7 +206,7 @@ private boolean updatePaths() throws IOException, DirectoryIteratorException { for (Path p : added) { // Only add files that have a complete header // as the JVM may be in progress writing the file - long size = fileAccess.fileSize(p); + long size = Files.size(p); if (size >= ChunkHeader.headerSize()) { long startNanos = readStartTime(p); if (startNanos != -1) { @@ -232,10 +230,10 @@ private boolean updatePaths() throws IOException, DirectoryIteratorException { private Path findSubDirectory(Path repoPath) { FileTime latestTimestamp = null; Path latestPath = null; - try (DirectoryStream dirStream = fileAccess.newDirectoryStream(repoPath)) { + try (DirectoryStream dirStream = Files.newDirectoryStream(repoPath)) { for (Path p : dirStream) { String filename = p.getFileName().toString(); - if (isRepository(filename) && fileAccess.isDirectory(p)) { + if (isRepository(filename) && Files.isDirectory(p)) { FileTime timestamp = getLastModified(p); if (timestamp != null) { if (latestPath == null || latestTimestamp.compareTo(timestamp) <= 0) { @@ -253,7 +251,7 @@ private Path findSubDirectory(Path repoPath) { private FileTime getLastModified(Path p) { try { - return fileAccess.getLastModified(p); + return Files.getLastModifiedTime(p); } catch (IOException e) { return null; } @@ -277,7 +275,7 @@ private static boolean isRepository(String filename) { } private long readStartTime(Path p) { - try (RecordingInput in = new RecordingInput(p.toFile(), fileAccess, 100)) { + try (RecordingInput in = new RecordingInput(p.toFile(), 100)) { Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Parsing header for chunk start time"); ChunkHeader c = new ChunkHeader(in); return c.getStartNanos(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/filter/ChunkWriter.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/filter/ChunkWriter.java index d38a5872adedb..5e3940e7d11d1 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/filter/ChunkWriter.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/filter/ChunkWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -38,7 +38,6 @@ import jdk.jfr.internal.LongMap; import jdk.jfr.internal.Type; import jdk.jfr.internal.consumer.ChunkHeader; -import jdk.jfr.internal.consumer.FileAccess; import jdk.jfr.internal.Logger; import jdk.jfr.internal.LogLevel; import jdk.jfr.internal.LogTag; @@ -67,7 +66,7 @@ public final class ChunkWriter implements Closeable { public ChunkWriter(Path source, Path destination, Predicate filter) throws IOException { this.destination = destination; this.output = new RecordingOutput(destination.toFile()); - this.input = new RecordingInput(source.toFile(), FileAccess.UNPRIVILEGED); + this.input = new RecordingInput(source.toFile()); this.filter = filter; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/AbstractDCmd.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/AbstractDCmd.java index 516d094b5daa8..e5b70f40a6cbc 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/AbstractDCmd.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/AbstractDCmd.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -43,8 +43,6 @@ import jdk.jfr.internal.LogLevel; import jdk.jfr.internal.LogTag; import jdk.jfr.internal.Logger; -import jdk.jfr.internal.SecuritySupport; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.util.ValueFormatter; /** @@ -134,7 +132,7 @@ public String getPid() { return JVM.getPid(); } - protected final SafePath resolvePath(Recording recording, String filename) throws InvalidPathException { + protected Path resolvePath(Recording recording, String filename) throws InvalidPathException { if (filename == null) { return makeGenerated(recording, Paths.get(".")); } @@ -142,11 +140,11 @@ protected final SafePath resolvePath(Recording recording, String filename) throw if (Files.isDirectory(path)) { return makeGenerated(recording, path); } - return new SafePath(path.toAbsolutePath().normalize()); + return path.toAbsolutePath().normalize(); } - private SafePath makeGenerated(Recording recording, Path directory) { - return new SafePath(directory.toAbsolutePath().resolve(JVMSupport.makeFilename(recording)).normalize()); + private Path makeGenerated(Recording recording, Path directory) { + return directory.toAbsolutePath().resolve(JVMSupport.makeFilename(recording)).normalize(); } protected final Recording findRecording(String name) throws DCmdException { @@ -158,7 +156,7 @@ protected final Recording findRecording(String name) throws DCmdException { } } - protected final void reportOperationComplete(String actionPrefix, String name, SafePath file) { + protected final void reportOperationComplete(String actionPrefix, String name, Path file) { print(actionPrefix); print(" recording"); if (name != null) { @@ -168,7 +166,7 @@ protected final void reportOperationComplete(String actionPrefix, String name, S print(","); try { print(" "); - long bytes = SecuritySupport.getFileSize(file); + long bytes = Files.size(file); printBytes(bytes); } catch (IOException e) { // Ignore, not essential @@ -219,16 +217,12 @@ protected final void printTimespan(Duration timespan, String separator) { print(ValueFormatter.formatTimespan(timespan, separator)); } - protected final void printPath(SafePath path) { + protected final void printPath(Path path) { if (path == null) { print("N/A"); return; } - try { - printPath(SecuritySupport.getAbsolutePath(path).toPath()); - } catch (IOException ioe) { - printPath(path.toPath()); - } + println(path.toAbsolutePath().toString()); } protected final void printHelpText() { @@ -237,15 +231,6 @@ protected final void printHelpText() { } } - protected final void printPath(Path path) { - try { - println(path.toAbsolutePath().toString()); - } catch (SecurityException e) { - // fall back on filename - println(path.toString()); - } - } - private Recording findRecordingById(int id) throws DCmdException { for (Recording r : getFlightRecorder().getRecordings()) { if (r.getId() == id) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java index 8ea49cbd3a52c..1d2bad2e9df82 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,7 @@ package jdk.jfr.internal.dcmd; import java.io.IOException; +import java.nio.file.Path; import jdk.jfr.FlightRecorder; import jdk.jfr.internal.LogLevel; @@ -34,7 +35,6 @@ import jdk.jfr.internal.Options; import jdk.jfr.internal.PrivateAccess; import jdk.jfr.internal.Repository; -import jdk.jfr.internal.SecuritySupport.SafePath; /** * JFR.configure - invoked from native @@ -89,7 +89,7 @@ final class DCmdConfigure extends AbstractDCmd { boolean updated = false; if (repositoryPath != null) { try { - SafePath s = new SafePath(repositoryPath); + Path s = Path.of(repositoryPath); if (FlightRecorder.isInitialized()) { PrivateAccess.getInstance().getPlatformRecorder().migrate(s); } else { @@ -115,7 +115,7 @@ final class DCmdConfigure extends AbstractDCmd { if (dumpPath != null) { try { - Options.setDumpPath(new SafePath(dumpPath)); + Options.setDumpPath(Path.of(dumpPath)); } catch (IOException e) { throw new DCmdException("Could not set " + dumpPath + " to emergency dump path. " + e.getMessage(), e); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java index 7f68ba7ee7951..f2397f44ea45b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -40,9 +40,8 @@ import jdk.jfr.internal.PlatformRecorder; import jdk.jfr.internal.PlatformRecording; import jdk.jfr.internal.PrivateAccess; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.util.ValueParser; -import jdk.jfr.internal.WriteableUserPath; +import jdk.jfr.internal.WriteablePath; /** * JFR.dump @@ -126,17 +125,16 @@ public void dump(PlatformRecorder recorder, Recording recording, String name, St // If a filename exist, use it // if a filename doesn't exist, use destination set earlier // if destination doesn't exist, generate a filename - WriteableUserPath wup = null; + WriteablePath wp = null; if (recording != null) { PlatformRecording pRecording = PrivateAccess.getInstance().getPlatformRecording(recording); - wup = pRecording.getDestination(); + wp = pRecording.getDestination(); } - if (filename != null || (filename == null && wup == null) ) { - SafePath safe = resolvePath(recording, filename); - wup = new WriteableUserPath(safe.toPath()); + if (filename != null || (filename == null && wp == null) ) { + wp = new WriteablePath(resolvePath(recording, filename)); } - r.dumpStopped(wup); - reportOperationComplete("Dumped", name, new SafePath(wup.getRealPathText())); + r.dumpStopped(wp); + reportOperationComplete("Dumped", name, wp.getReal()); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java index 26c095541b6aa..634bcd3331593 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -29,8 +29,6 @@ import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.AccessControlContext; -import java.security.AccessController; import java.text.ParseException; import java.time.Duration; import java.util.HashSet; @@ -48,8 +46,6 @@ import jdk.jfr.internal.OldObjectSample; import jdk.jfr.internal.PlatformRecording; import jdk.jfr.internal.PrivateAccess; -import jdk.jfr.internal.SecuritySupport.SafePath; -import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.Type; import jdk.jfr.internal.jfc.JFC; import jdk.jfr.internal.jfc.model.JFCModel; @@ -154,7 +150,7 @@ public void execute(ArgumentParser parser) throws DCmdException { } recording.setSettings(s); - SafePath safePath = null; + Path dumpPath = null; // Generate dump filename if user has specified a time-bound recording if (duration != null && path == null) { @@ -173,10 +169,10 @@ public void execute(ArgumentParser parser) throws DCmdException { // Purposely avoid generating filename in Recording#setDestination due to // security concerns PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording); - pr.setDumpDirectory(new SafePath(p)); + pr.setDumpDirectory(p); } else { - safePath = resolvePath(recording, path); - recording.setDestination(safePath.toPath()); + dumpPath = resolvePath(recording, path); + recording.setDestination(dumpPath); } } catch (IOException | InvalidPathException e) { recording.close(); @@ -221,10 +217,10 @@ public void execute(ArgumentParser parser) throws DCmdException { recording.setMaxSize(250*1024L*1024L); } - if (safePath != null && duration != null) { + if (dumpPath != null && duration != null) { println(" The result will be written to:"); println(); - printPath(safePath); + printPath(dumpPath); } else { println(); println(); @@ -256,7 +252,7 @@ private LinkedHashMap configureExtended(String[] settings, Argum JFCModel model = new JFCModel(l -> logWarning(l)); for (String setting : settings) { try { - model.parse(JFC.createSafePath(setting)); + model.parse(JFC.ofPath(setting)); } catch (InvalidPathException | IOException | JFCModelException | ParseException e) { throw new DCmdException(JFC.formatException("Could not", e, setting), e); } @@ -463,8 +459,8 @@ Virtual Machine (JVM) shuts down. If set to 'true' and no value private static String jfcOptions() { try { StringBuilder sb = new StringBuilder(); - for (SafePath s : SecuritySupport.getPredefinedJFCFiles()) { - String name = JFC.nameFromPath(s.toPath()); + for (Path s : JFC.getPredefined()) { + String name = JFC.nameFromPath(s); JFCModel model = JFCModel.create(s, l -> {}); sb.append('\n'); sb.append("Options for ").append(name).append(":\n"); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStop.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStop.java index 5cf983645c65c..cda6a03e596d4 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStop.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStop.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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,12 +26,12 @@ import java.io.IOException; import java.nio.file.InvalidPathException; +import java.nio.file.Path; import java.nio.file.Paths; import jdk.jfr.Recording; import jdk.jfr.internal.PrivateAccess; -import jdk.jfr.internal.SecuritySupport.SafePath; -import jdk.jfr.internal.WriteableUserPath; +import jdk.jfr.internal.WriteablePath; /** * JFR.stop @@ -47,20 +47,20 @@ protected void execute(ArgumentParser parser) throws DCmdException { String filename = parser.getOption("filename"); try { Recording recording = findRecording(name); - WriteableUserPath path = PrivateAccess.getInstance().getPlatformRecording(recording).getDestination(); - SafePath safePath = path == null ? null : new SafePath(path.getRealPathText()); + WriteablePath wp = PrivateAccess.getInstance().getPlatformRecording(recording).getDestination(); + Path path = wp == null ? null : wp.getReal(); if (filename != null) { try { - // Ensure path is valid. Don't generate safePath if filename == null, as a user may + // Ensure path is valid. Don't generate path if filename == null, as a user may // want to stop recording without a dump - safePath = resolvePath(null, filename); + path = resolvePath(null, filename); recording.setDestination(Paths.get(filename)); } catch (IOException | InvalidPathException e) { throw new DCmdException("Failed to stop %s. Could not set destination for \"%s\" to file %s", recording.getName(), filename, e.getMessage()); } } recording.stop(); - reportOperationComplete("Stopped", recording.getName(), safePath); + reportOperationComplete("Stopped", recording.getName(), path); recording.close(); } catch (InvalidPathException | DCmdException e) { if (filename != null) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventWriter.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventWriter.java index 970365ef73dfe..719fa4e1b4d70 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventWriter.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -27,7 +27,6 @@ import jdk.internal.misc.Unsafe; import jdk.jfr.internal.Bits; -import jdk.jfr.internal.EventWriterKey; import jdk.jfr.internal.StringPool; import jdk.jfr.internal.JVM; import jdk.jfr.internal.PlatformEventType; @@ -37,21 +36,8 @@ // would allow it to write arbitrary data into buffers, potentially from // different threads. // -// This is prevented in three ways: -// -// 1. For code to access the jdk.jfr.internal.event package -// at least one event class (for a particular module) must be -// registered having FlightRecorderPermission("registerEvent"). -// -// 2. The EventWriter EventWriterFactory::getEventWriter(long) method can only be linked from -// the UserEvent::commit() method instrumented by JFR. This is ensured by the JVM. -// (The EventWriterFactory class is dynamically generated before the first event -// is instrumented. See EventWriterFactoryRecipe) -// -// 3. Steps 1 and 2 are sufficient to make it fully secure, with or without a Security -// Manager, but as an additional measure, the method EventWriterFactory::getEventWriter(long) -// requires the caller to provide a key that is hard to guess. The key is generated -// into the bytecode of the method invoking getEventWriter(long). +// The EventWriter EventWriterFactory::getEventWriter(long) method can only be linked from +// the UserEvent::commit() method instrumented by JFR. This is ensured by the JVM. // public final class EventWriter { @@ -71,6 +57,14 @@ public final class EventWriter { private PlatformEventType eventType; private boolean largeSize = false; + public static EventWriter getEventWriter() { + EventWriter ew = JVM.getEventWriter(); + if (ew != null) { + return ew; + } + return JVM.newEventWriter(); + } + // User code must not be able to instantiate private EventWriter() { threadID = 0; @@ -239,11 +233,9 @@ private void flush(int usedSize, int requestedSize) { } public boolean beginEvent(EventConfiguration configuration, long typeId) { - // Malicious code could take the EventConfiguration object from one - // event class field and assign it to another. This check makes sure - // the event type matches what was added by instrumentation. + // This check makes sure the event type matches what was added by instrumentation. if (configuration.getId() != typeId) { - EventWriterKey.block(); + throw new InternalError("Unexpected type id " + typeId); } if (excluded) { // thread is excluded from writing events diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java index 0511ce57001c6..d89f527ae4b8d 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -46,18 +46,33 @@ import jdk.jfr.internal.LogLevel; import jdk.jfr.internal.LogTag; import jdk.jfr.internal.Logger; -import jdk.jfr.internal.SecuritySupport; -import jdk.jfr.internal.SecuritySupport.SafePath; +import jdk.jfr.internal.util.Utils; /** * {@link Configuration} factory for JFC files. * */ public final class JFC { + private static final Path JFC_DIRECTORY = Utils.getPathInProperty("java.home", "lib/jfr"); private static final int BUFFER_SIZE = 8192; private static final int MAXIMUM_FILE_SIZE = 1024 * 1024; private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; private static volatile List knownConfigurations; + public static List getPredefined() { + List list = new ArrayList<>(); + try (var ds = Files.newDirectoryStream(JFC_DIRECTORY)) { + for (Path path : ds) { + String text = path.toString(); + if (text.endsWith(".jfc") && !Files.isDirectory(path)) { + list.add(path); + } + } + } catch (IOException ioe) { + Logger.log(LogTag.JFR, LogLevel.WARN, "Could not access .jfc-files in " + JFC_DIRECTORY + ", " + ioe.getMessage()); + } + return list; + } + /** * Reads a known configuration file (located into a string, but doesn't * parse it until it's being used. @@ -66,14 +81,14 @@ private static final class KnownConfiguration { private final String content; private final String filename; private final String name; - private final SafePath path; + private final Path path; private Configuration configuration; - public KnownConfiguration(SafePath knownPath) throws IOException { + public KnownConfiguration(Path knownPath) throws IOException { this.path = knownPath; this.content = readContent(knownPath); - this.name = nameFromPath(knownPath.toPath()); - this.filename = nullSafeFileName(knownPath.toPath()); + this.name = nameFromPath(knownPath); + this.filename = nullSafeFileName(knownPath); } public boolean isNamed(String name) { @@ -91,12 +106,12 @@ public String getName() { return name; } - private static String readContent(SafePath knownPath) throws IOException { - if (SecuritySupport.getFileSize(knownPath) > MAXIMUM_FILE_SIZE) { + private static String readContent(Path knownPath) throws IOException { + if (Files.size(knownPath) > MAXIMUM_FILE_SIZE) { throw new IOException("Configuration with more than " + MAXIMUM_FILE_SIZE + " characters can't be read."); } - try (InputStream r = SecuritySupport.newFileInputStream(knownPath)) { + try (InputStream r = Files.newInputStream(knownPath)) { return JFC.readContent(r); } } @@ -114,10 +129,7 @@ private JFC() { * @throws ParseException if the file can't be parsed * @throws IOException if the file can't be read * - * @throws SecurityException if a security manager exists and its - * {@code checkRead} method denies read access to the file * @see java.io.File#getPath() - * @see java.lang.SecurityManager#checkRead(java.lang.String) */ public static Configuration create(String name, Reader reader) throws IOException, ParseException { try { @@ -136,12 +148,12 @@ public static Configuration create(String name, Reader reader) throws IOExceptio * * @param path textual representation of the path * - * @return a safe path, not null + * @return a path, not null */ - public static SafePath createSafePath(String path) { - for (SafePath predefined : SecuritySupport.getPredefinedJFCFiles()) { + public static Path ofPath(String path) { + for (Path predefined : JFC.getPredefined()) { try { - String name = JFC.nameFromPath(predefined.toPath()); + String name = JFC.nameFromPath(predefined); if (name.equals(path) || (name + ".jfc").equals(path)) { return predefined; } @@ -149,7 +161,7 @@ public static SafePath createSafePath(String path) { throw new InternalError("Error in predefined .jfc file", e); } } - return new SafePath(path); + return Path.of(path); } @@ -172,20 +184,19 @@ public static String nameFromPath(Path file) throws IOException { // Invoked by DCmdStart public static Configuration createKnown(String name) throws IOException, ParseException { - // Known name, no need for permission for (KnownConfiguration known : getKnownConfigurations()) { if (known.isNamed(name)) { return known.getConfigurationFile(); } } // Check JFC directory - SafePath path = SecuritySupport.JFC_DIRECTORY; - if (path != null && SecuritySupport.exists(path)) { + Path path = JFC_DIRECTORY; + if (path != null && Files.exists(path)) { for (String extension : Arrays.asList("", JFCParser.FILE_EXTENSION)) { - SafePath file = new SafePath(path.toPath().resolveSibling(name + extension)); - if (SecuritySupport.exists(file) && !SecuritySupport.isDirectory(file)) { - try (Reader r = SecuritySupport.newFileReader(file)) { - String jfcName = nameFromPath(file.toPath()); + Path file = path.resolveSibling(name + extension); + if (Files.exists(file) && !Files.isDirectory(file)) { + try (Reader r = Files.newBufferedReader(file)) { + String jfcName = nameFromPath(file); return JFCParser.createConfiguration(jfcName, r); } } @@ -260,7 +271,7 @@ public static List getConfigurations() { private static List getKnownConfigurations() { if (knownConfigurations == null) { List configProxies = new ArrayList<>(); - for (SafePath p : SecuritySupport.getPredefinedJFCFiles()) { + for (Path p : JFC.getPredefined()) { try { configProxies.add(new KnownConfiguration(p)); } catch (IOException ioe) { @@ -281,7 +292,7 @@ public static Configuration getPredefined(String name) throws IOException, Parse throw new NoSuchFileException("Could not locate configuration with name " + name); } - public static Reader newReader(SafePath sf) throws IOException { + public static Reader newReader(Path sf) throws IOException { for (KnownConfiguration c : getKnownConfigurations()) { if (c.path.equals(sf)) { return new StringReader(c.content); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/JFCModel.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/JFCModel.java index e9b4208c148d3..e0b5fb4a6f306 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/JFCModel.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/JFCModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, 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 @@ -27,6 +27,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.Reader; +import java.nio.file.Path; import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; @@ -35,7 +36,6 @@ import java.util.Map; import java.util.function.Consumer; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.jfc.JFC; import static java.nio.charset.StandardCharsets.UTF_8; @@ -65,7 +65,7 @@ public JFCModel(Consumer logger) { this.logger = logger; } - public void parse(SafePath file) throws IOException, JFCModelException, ParseException { + public void parse(Path file) throws IOException, JFCModelException, ParseException { JFCModel model = JFCModel.create(file, logger); for (var entry : model.controls.entrySet()) { String name = entry.getKey(); @@ -80,7 +80,7 @@ public void parse(SafePath file) throws IOException, JFCModelException, ParseExc } } - public static JFCModel create(SafePath file, Consumer logger) throws IOException, JFCModelException, ParseException{ + public static JFCModel create(Path file, Consumer logger) throws IOException, JFCModelException, ParseException{ if (file.toString().equals("none")) { XmlConfiguration configuration = new XmlConfiguration(); configuration.setAttribute("version", "2.0"); @@ -154,7 +154,7 @@ public LinkedHashMap getSettings() { return result; } - public void saveToFile(SafePath path) throws IOException { + public void saveToFile(Path path) throws IOException { try (PrintWriter p = new PrintWriter(path.toFile(), UTF_8)) { PrettyPrinter pp = new PrettyPrinter(p); pp.print(configuration); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ChunkFilename.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ChunkFilename.java index 66cd982bb51bd..0d8290b206ee9 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ChunkFilename.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ChunkFilename.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, 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,13 +25,12 @@ package jdk.jfr.internal.management; import java.nio.file.Paths; +import java.nio.file.Files; import java.nio.file.Path; import java.time.LocalDateTime; import java.io.IOException; -import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.util.ValueFormatter; -import jdk.jfr.internal.consumer.FileAccess; // Allows a remote streaming client to create chunk files // with same naming scheme as the JVM. @@ -40,23 +39,12 @@ public final class ChunkFilename { private static final String FILE_EXTENSION = ".jfr"; private final Path directory; - private final FileAccess fileAcess; private Path lastPath; private int counter; - public static ChunkFilename newUnpriviliged(Path directory) { - return new ChunkFilename(directory, FileAccess.UNPRIVILEGED); - } - - public static ChunkFilename newPriviliged(Path directory) { - return new ChunkFilename(directory, SecuritySupport.PRIVILEGED); - } - - private ChunkFilename(Path directory, FileAccess fileAccess) { - // Avoid malicious implementations of Path interface - this.directory = Paths.get(directory.toString()); - this.fileAcess = fileAccess; + public ChunkFilename(Path directory) { + this.directory = directory; } public String next(LocalDateTime time) throws IOException { @@ -65,7 +53,7 @@ public String next(LocalDateTime time) throws IOException { // If less than one file per second (typically case) if (lastPath == null || !p.equals(lastPath)) { - if (!fileAcess.exists(p)) { + if (!Files.exists(p)) { counter = 1; // reset counter lastPath = p; return p.toString(); @@ -77,7 +65,7 @@ public String next(LocalDateTime time) throws IOException { String extendedName = makeExtendedName(filename, counter); p = directory.resolve(extendedName); counter++; - if (!fileAcess.exists(p)) { + if (!Files.exists(p)) { return p.toString(); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ManagementSupport.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ManagementSupport.java index 165419cc34a52..1f5963d027771 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ManagementSupport.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ManagementSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -34,8 +34,6 @@ import java.util.List; import java.util.Map; import java.util.function.Consumer; -import java.security.AccessControlContext; - import jdk.jfr.Configuration; import jdk.jfr.EventSettings; import jdk.jfr.EventType; @@ -49,15 +47,12 @@ import jdk.jfr.internal.MetadataRepository; import jdk.jfr.internal.PlatformRecording; import jdk.jfr.internal.PrivateAccess; -import jdk.jfr.internal.SecuritySupport; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.util.ValueFormatter; import jdk.jfr.internal.util.ValueParser; -import jdk.jfr.internal.WriteableUserPath; +import jdk.jfr.internal.WriteablePath; import jdk.jfr.internal.consumer.AbstractEventStream; import jdk.jfr.internal.consumer.EventDirectoryStream; -import jdk.jfr.internal.consumer.FileAccess; /** * The management API in module jdk.management.jfr should be built on top of the @@ -84,7 +79,6 @@ public final class ManagementSupport { // public static List getEventTypes() { // would normally be checked when a Flight Recorder instance is created - SecuritySupport.checkAccessFlightRecorder(); if (JVMSupport.isNotAvailable()) { return List.of(); } @@ -121,17 +115,16 @@ public static void logDebug(String message) { // requires access to jdk.jfr.internal.PlatformRecording public static String getDestinationOriginalText(Recording recording) { PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording); - WriteableUserPath wup = pr.getDestination(); - return wup == null ? null : wup.getOriginalText(); + WriteablePath wp = pr.getDestination(); + return wp == null ? null : wp.getPath().toString(); } // Needed to check if destination can be set, so FlightRecorderMXBean::setRecordingOption // can abort if not all data is valid - public static void checkSetDestination(Recording recording, String destination) throws IOException{ + public static void checkSetDestination(Recording recording, String destination) throws IOException { PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording); if(destination != null){ - WriteableUserPath wup = new WriteableUserPath(Paths.get(destination)); - pr.checkSetDestination(wup); + pr.checkSetDestination(new WriteablePath(Paths.get(destination))); } } @@ -143,7 +136,7 @@ public static EventSettings newEventSettings(EventSettingsModifier esm) { // Needed callback to detect when a chunk has been parsed. public static void removePath(Recording recording, Path path) { PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording); - pr.removePath(new SafePath(path)); + pr.removePath(path); } // Needed callback to detect when a chunk has been parsed. @@ -169,14 +162,10 @@ public static Configuration newConfiguration(String name, String label, String d // EventStream::onMetadataData need to supply MetadataEvent // with configuration objects public static EventStream newEventDirectoryStream( - @SuppressWarnings("removal") - AccessControlContext acc, Path directory, List confs) throws IOException { return new EventDirectoryStream( - acc, directory, - FileAccess.UNPRIVILEGED, null, confs, false diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/JavaEventTask.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/JavaEventTask.java index 18729685a6d4b..55113f7d3f42a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/JavaEventTask.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/JavaEventTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -30,9 +30,9 @@ import jdk.jfr.internal.PlatformEventType; import jdk.jfr.internal.PrivateAccess; /** - * Base class for periodic Java events. + * Class for periodic Java events. */ -abstract class JavaEventTask extends EventTask { +final class JavaEventTask extends EventTask { private final Runnable runnable; public JavaEventTask(Class eventClass, Runnable runnable) { @@ -48,7 +48,8 @@ private static PlatformEventType toPlatformEventType(Class even return PrivateAccess.getInstance().getPlatformEventType(eventType); } - protected final Runnable getRunnable() { - return runnable; + @Override + public void execute(long timestamp, PeriodicType periodicType) { + runnable.run(); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/LookupKey.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/LookupKey.java index 5bbfbef70ae6f..bc4006aaff613 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/LookupKey.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/LookupKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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,11 +25,8 @@ package jdk.jfr.internal.periodic; /** - * Lookup key that can safely be used in a {@code Map}. - *

        - * {@code Runnable} objects can't be used with {@code LinkedHashMap} as it - * invokes {@code hashCode} and {@code equals}, for example when resizing the - * {@code Map}, possibly in a non-secure context. + * Lookup key that can be used in a {@code Map} in + * case hashCode and equals are incorrectly overridden. *

        * {@code IdentityHashMap} can't be used as it will not preserve order. */ diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/PeriodicEvents.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/PeriodicEvents.java index a68af8ad25be3..8cbf6334e64a5 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/PeriodicEvents.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/PeriodicEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,7 +24,6 @@ */ package jdk.jfr.internal.periodic; -import java.security.AccessControlContext; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; @@ -58,18 +57,14 @@ public final class PeriodicEvents { // State only to be read and modified by periodic task thread private static long lastTimeMillis; - public static void addJDKEvent(Class eventClass, Runnable runnable) { - taskRepository.add(new JDKEventTask(eventClass, runnable)); + public static void addJavaEvent(Class eventClass, Runnable runnable) { + taskRepository.add(new JavaEventTask(eventClass, runnable)); } public static void addJVMEvent(PlatformEventType eventType) { taskRepository.add(new JVMEventTask(eventType)); } - public static void addUserEvent(@SuppressWarnings("removal") AccessControlContext acc, Class eventClass, Runnable runnable) { - taskRepository.add(new UserEventTask(acc, eventClass, runnable)); - } - public static boolean removeEvent(Runnable runnable) { return taskRepository.removeTask(runnable); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/PeriodicTask.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/PeriodicTask.java index 876b9ecbc920a..b180d5074811e 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/PeriodicTask.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/PeriodicTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -40,9 +40,6 @@ * / \ * / \ * JVMEventTask JavaEventTask - * / \ - * / \ - * UserEventTask JDKEventTask * *

        * State modifications should only be done from the periodic task thread. @@ -127,8 +124,8 @@ public final void run(long timestamp, PeriodicType periodicType) { try { execute(timestamp, periodicType); } catch (Throwable e) { - // Prevent malicious user to propagate exception callback in the wrong context - Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Exception occurred during execution of " + name); + String msg = "Exception occurred during execution of " + name + ". " + e.getMessage(); + Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, msg); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/UserEventTask.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/UserEventTask.java deleted file mode 100644 index 1241cd7fb0b26..0000000000000 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/UserEventTask.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2023, 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 jdk.jfr.internal.periodic; - -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Objects; - -import jdk.internal.event.Event; -import jdk.jfr.internal.LogLevel; -import jdk.jfr.internal.LogTag; -import jdk.jfr.internal.Logger; - -/** - * Class to be used with user-defined events that runs untrusted code. - *

        - * This class can be removed once the Security Manager is no longer supported. - */ -final class UserEventTask extends JavaEventTask { - @SuppressWarnings("removal") - private final AccessControlContext controlContext; - - public UserEventTask(@SuppressWarnings("removal") AccessControlContext controlContext, Class eventClass, Runnable runnable) { - super(eventClass, runnable); - this.controlContext = Objects.requireNonNull(controlContext); - } - - @SuppressWarnings("removal") - @Override - public void execute(long timestamp, PeriodicType periodicType) { - AccessController.doPrivileged((PrivilegedAction) () -> { - execute(); - return null; - }, controlContext); - } - - private void execute() { - try { - getRunnable().run(); - if (Logger.shouldLog(LogTag.JFR_EVENT, LogLevel.DEBUG)) { - Logger.log(LogTag.JFR_EVENT, LogLevel.DEBUG, "Executed periodic task for " + getEventType().getLogName()); - } - } catch (Throwable t) { - // Prevent malicious user to propagate exception callback in the wrong context - Logger.log(LogTag.JFR_EVENT, LogLevel.WARN, "Exception occurred during execution of period task for " + getEventType().getLogName()); - } - } -} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/BooleanSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/BooleanSetting.java index 72ffcac72c926..f5cc1495738ff 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/BooleanSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/BooleanSetting.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, 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,9 +28,10 @@ import java.util.Objects; import java.util.Set; +import jdk.jfr.SettingControl; import jdk.jfr.internal.PlatformEventType; -abstract class BooleanSetting extends JDKSettingControl { +abstract class BooleanSetting extends SettingControl { private final PlatformEventType eventType; private final String defaultValue; private String value; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CutoffSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CutoffSetting.java index 68950d71b63d7..2f7d9f8e872c1 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CutoffSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CutoffSetting.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -31,6 +31,7 @@ import java.util.Set; import jdk.jfr.Description; +import jdk.jfr.SettingControl; import jdk.jfr.Label; import jdk.jfr.MetadataDefinition; import jdk.jfr.Name; @@ -44,7 +45,7 @@ @Description("Limit running time of event") @Name(Type.SETTINGS_PREFIX + "Cutoff") @Timespan -public final class CutoffSetting extends JDKSettingControl { +public final class CutoffSetting extends SettingControl { public static final String DEFAULT_VALUE = ValueParser.INFINITY; private String value = DEFAULT_VALUE; private final PlatformEventType eventType; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/JDKSettingControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/JDKSettingControl.java deleted file mode 100644 index 46f224bada607..0000000000000 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/JDKSettingControl.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. 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 jdk.jfr.internal.settings; - -import jdk.jfr.SettingControl; - -/** - * SettingControls that derive from this class avoids executing settings - * modifications in a AccessController.doPrivilege(...) block. - */ -public abstract class JDKSettingControl extends SettingControl { -} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/LevelSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/LevelSetting.java index 9531f75c9257a..750e20d9cdddd 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/LevelSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/LevelSetting.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -33,13 +33,14 @@ import jdk.jfr.Label; import jdk.jfr.MetadataDefinition; import jdk.jfr.Name; +import jdk.jfr.SettingControl; import jdk.jfr.internal.PlatformEventType; import jdk.jfr.internal.Type; @MetadataDefinition @Label("Level") @Name(Type.SETTINGS_PREFIX + "Level") -public final class LevelSetting extends JDKSettingControl { +public final class LevelSetting extends SettingControl { private final PlatformEventType eventType; private final List levels; private String value; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/PeriodSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/PeriodSetting.java index 22fef2691aa91..902584a8819ac 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/PeriodSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/PeriodSetting.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -32,6 +32,7 @@ import jdk.jfr.Label; import jdk.jfr.MetadataDefinition; import jdk.jfr.Name; +import jdk.jfr.SettingControl; import jdk.jfr.internal.PlatformEventType; import jdk.jfr.internal.Type; import jdk.jfr.internal.util.ValueParser; @@ -41,7 +42,7 @@ @Label("Period") @Description("Record event at interval") @Name(Type.SETTINGS_PREFIX + "Period") -public final class PeriodSetting extends JDKSettingControl { +public final class PeriodSetting extends SettingControl { private static final long typeId = Type.getTypeId(PeriodSetting.class); public static final String EVERY_CHUNK = "everyChunk"; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThresholdSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThresholdSetting.java index 8870417f9dd35..83a5572670753 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThresholdSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThresholdSetting.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -34,6 +34,7 @@ import jdk.jfr.Label; import jdk.jfr.MetadataDefinition; import jdk.jfr.Name; +import jdk.jfr.SettingControl; import jdk.jfr.Timespan; import jdk.jfr.internal.PlatformEventType; import jdk.jfr.internal.Type; @@ -44,7 +45,7 @@ @Name(Type.SETTINGS_PREFIX + "Threshold") @Description("Record event with duration above or equal to threshold") @Timespan -public final class ThresholdSetting extends JDKSettingControl { +public final class ThresholdSetting extends SettingControl { public static final String DEFAULT_VALUE = "0 ns"; private static final long typeId = Type.getTypeId(ThresholdSetting.class); private String value = DEFAULT_VALUE; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java index c18031d514f98..0527d7e8689be 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Datadog, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,6 +36,7 @@ import jdk.jfr.Label; import jdk.jfr.MetadataDefinition; import jdk.jfr.Name; +import jdk.jfr.SettingControl; import jdk.jfr.internal.PlatformEventType; import jdk.jfr.internal.Throttle; import jdk.jfr.internal.Type; @@ -47,7 +48,7 @@ @Label("Throttle") @Description("Throttles the emission rate for an event") @Name(Type.SETTINGS_PREFIX + "Throttle") -public final class ThrottleSetting extends JDKSettingControl { +public final class ThrottleSetting extends SettingControl { public static final String DEFAULT_VALUE = Throttle.DEFAULT; private final PlatformEventType eventType; private String value = DEFAULT_VALUE; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Command.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Command.java index 974e8846aa4d0..d76f182a8a804 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Command.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Command.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -52,7 +52,7 @@ private static List createCommands() { List commands = new ArrayList<>(); commands.add(new Print()); // Uncomment when developing new queries for the view command - // commands.add(new Query()); + commands.add(new Query()); commands.add(new View()); commands.add(new Configure()); commands.add(new Metadata()); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Configure.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Configure.java index 63b2d8fe74f08..048763c4cc115 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Configure.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Configure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, 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 @@ -38,7 +38,6 @@ import java.util.List; import java.util.Map; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.jfc.JFC; import jdk.jfr.internal.jfc.model.AbortException; import jdk.jfr.internal.jfc.model.JFCModel; @@ -129,7 +128,7 @@ private void displayParameters(PrintStream stream, String name) { stream.println("Options for " + name + ":"); stream.println(); try { - SafePath path = JFC.createSafePath(name); + Path path = JFC.ofPath(name); JFCModel parameters = JFCModel.create(path, l -> stream.println("Warning! " + l)); for (XmlInput input : parameters.getInputs()) { stream.println(" " + input.getOptionSyntax()); @@ -144,7 +143,7 @@ private void displayParameters(PrintStream stream, String name) { public void execute(Deque options) throws UserSyntaxException, UserDataException { boolean interactive = false; boolean log = false; - SafePath output = null; + Path output = null; Map keyValues = new LinkedHashMap<>(); int optionCount = options.size(); while (optionCount > 0) { @@ -192,7 +191,7 @@ private boolean acceptKeyValue(Deque options) { return false; } - private void configure(boolean interactive, boolean log, SafePath output, Map options) throws UserDataException { + private void configure(boolean interactive, boolean log, Path output, Map options) throws UserDataException { UserInterface ui = new UserInterface(); if (log) { SettingsLog.enable(); @@ -201,14 +200,14 @@ private void configure(boolean interactive, boolean log, SafePath output, Map options) throws UserSyntaxException, UserDataE } private List findChunkSizes(Path p) throws IOException { - try (RecordingInput input = new RecordingInput(p.toFile(), FileAccess.UNPRIVILEGED)) { + try (RecordingInput input = new RecordingInput(p.toFile())) { List sizes = new ArrayList<>(); ChunkHeader ch = new ChunkHeader(input); sizes.add(ch.getSize()); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Summary.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Summary.java index 12a468b2e89e4..08ab475fa680b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Summary.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Summary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -41,7 +41,6 @@ import jdk.jfr.internal.MetadataDescriptor; import jdk.jfr.internal.Type; import jdk.jfr.internal.consumer.ChunkHeader; -import jdk.jfr.internal.consumer.FileAccess; import jdk.jfr.internal.consumer.RecordingInput; import jdk.jfr.internal.util.UserDataException; import jdk.jfr.internal.util.UserSyntaxException; @@ -93,7 +92,7 @@ private void printInformation(Path p) throws IOException { long totalDuration = 0; long chunks = 0; - try (RecordingInput input = new RecordingInput(p.toFile(), FileAccess.UNPRIVILEGED)) { + try (RecordingInput input = new RecordingInput(p.toFile())) { ChunkHeader first = new ChunkHeader(input); ChunkHeader ch = first; String eventPrefix = Type.EVENT_NAME_PREFIX; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventWriterFactoryRecipe.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/DirectoryCleaner.java similarity index 56% rename from src/jdk.jfr/share/classes/jdk/jfr/internal/EventWriterFactoryRecipe.java rename to src/jdk.jfr/share/classes/jdk/jfr/internal/util/DirectoryCleaner.java index de59ea92d69a5..2067a8ebec186 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventWriterFactoryRecipe.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/DirectoryCleaner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 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 @@ -22,23 +22,33 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.jfr.internal; +package jdk.jfr.internal.util; -import jdk.jfr.internal.event.EventWriter; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; -// This class is not directly used but renamed to -// jdk.jfr.internal.event.EventWriterFactory and loaded dynamically -// when the first event class is bytecode instrumented. -// See JVMUpcalls and EventWriterKey::ensureEventWriterFactory() -public final class EventWriterFactoryRecipe { - private static final long KEY = EventWriterKey.getKey(); +public final class DirectoryCleaner extends SimpleFileVisitor { - public static EventWriter getEventWriter(long key) { - if (key == KEY) { - EventWriter ew = JVM.getEventWriter(); - return ew != null ? ew : JVM.newEventWriter(); + public static void clear(Path path) throws IOException { + Files.walkFileTree(path, new DirectoryCleaner()); + } + + @Override + public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { + Files.delete(path); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + if (exc != null) { + throw exc; } - EventWriterKey.block(); - return null; // Can't reach here. + Files.delete(dir); + return FileVisitResult.CONTINUE; } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java index c15e87709c5a8..777725f88d426 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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,7 +25,9 @@ package jdk.jfr.internal.util; +import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.RandomAccessFile; import java.lang.annotation.Annotation; import java.lang.annotation.Repeatable; @@ -448,4 +450,13 @@ public static ValueDescriptor findField(List fields, String nam } return null; } + + public static Path getPathInProperty(String prop, String subPath) { + String path = System.getProperty(prop); + if (path == null) { + return null; + } + File file = subPath == null ? new File(path) : new File(path, subPath); + return file.toPath().toAbsolutePath(); + } } diff --git a/src/jdk.management.jfr/share/classes/jdk/management/jfr/DiskRepository.java b/src/jdk.management.jfr/share/classes/jdk/management/jfr/DiskRepository.java index 24fd768dd414c..1ed2a2a05aef8 100644 --- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/DiskRepository.java +++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/DiskRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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 @@ -151,7 +151,7 @@ public State next() { public DiskRepository(Path path, boolean deleteDirectory) throws IOException { this.directory = path; this.deleteDirectory = deleteDirectory; - this.chunkFilename = ChunkFilename.newUnpriviliged(path); + this.chunkFilename = new ChunkFilename(path); } public synchronized void write(byte[] bytes) throws IOException { diff --git a/src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java b/src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java index e65b114d7aabf..bb2470d5a0bbb 100644 --- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java +++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -30,9 +30,6 @@ import java.io.StringReader; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.text.ParseException; import java.time.Instant; import java.util.ArrayList; @@ -67,7 +64,6 @@ import jdk.jfr.EventType; import jdk.jfr.FlightRecorder; import jdk.jfr.FlightRecorderListener; -import jdk.jfr.FlightRecorderPermission; import jdk.jfr.Recording; import jdk.jfr.RecordingState; import jdk.jfr.internal.management.ManagementSupport; @@ -80,12 +76,9 @@ final class MXBeanListener implements FlightRecorderListener { private final NotificationListener listener; private final NotificationFilter filter; private final Object handback; - @SuppressWarnings("removal") - private final AccessControlContext context; @SuppressWarnings("removal") public MXBeanListener(NotificationListener listener, NotificationFilter filter, Object handback) { - this.context = AccessController.getContext(); this.listener = listener; this.filter = filter; this.handback = handback; @@ -93,13 +86,7 @@ public MXBeanListener(NotificationListener listener, NotificationFilter filter, @SuppressWarnings("removal") public void recordingStateChanged(Recording recording) { - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - sendNotification(createNotification(recording)); - return null; - } - }, context); + sendNotification(createNotification(recording)); } } @@ -124,25 +111,21 @@ public Void run() { @Override public void startRecording(long id) { - MBeanUtils.checkControl(); getExistingRecording(id).start(); } @Override public boolean stopRecording(long id) { - MBeanUtils.checkControl(); return getExistingRecording(id).stop(); } @Override public void closeRecording(long id) { - MBeanUtils.checkControl(); getExistingRecording(id).close(); } @Override public long openStream(long id, Map options) throws IOException { - MBeanUtils.checkControl(); if (!FlightRecorder.isInitialized()) { throw new IllegalArgumentException("No recording available with id " + id); } @@ -169,19 +152,16 @@ public long openStream(long id, Map options) throws IOException @Override public void closeStream(long streamIdentifier) throws IOException { - MBeanUtils.checkControl(); streamHandler.getStream(streamIdentifier).close(); } @Override public byte[] readStream(long streamIdentifier) throws IOException { - MBeanUtils.checkMonitor(); return streamHandler.getStream(streamIdentifier).read(); } @Override public List getRecordings() { - MBeanUtils.checkMonitor(); if (!FlightRecorder.isInitialized()) { return Collections.emptyList(); } @@ -190,60 +170,39 @@ public List getRecordings() { @Override public List getConfigurations() { - MBeanUtils.checkMonitor(); return MBeanUtils.transformList(Configuration.getConfigurations(), ConfigurationInfo::new); } @Override public List getEventTypes() { - MBeanUtils.checkMonitor(); - @SuppressWarnings("removal") - List eventTypes = AccessController.doPrivileged(new PrivilegedAction>() { - @Override - public List run() { - return ManagementSupport.getEventTypes(); - } - }, null, new FlightRecorderPermission("accessFlightRecorder")); - - return MBeanUtils.transformList(eventTypes, EventTypeInfo::new); + return MBeanUtils.transformList(ManagementSupport.getEventTypes(), EventTypeInfo::new); } @Override public Map getRecordingSettings(long recording) throws IllegalArgumentException { - MBeanUtils.checkMonitor(); return getExistingRecording(recording).getSettings(); } @Override public void setRecordingSettings(long recording, Map settings) throws IllegalArgumentException { Objects.requireNonNull(settings, "settings"); - MBeanUtils.checkControl(); getExistingRecording(recording).setSettings(settings); } - @SuppressWarnings("removal") @Override public long newRecording() { - MBeanUtils.checkControl(); getRecorder(); // ensure notification listener is setup - return AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Recording run() { - return new Recording(); - } - }, null, new FlightRecorderPermission("accessFlightRecorder")).getId(); + return new Recording().getId(); } @Override public long takeSnapshot() { - MBeanUtils.checkControl(); return getRecorder().takeSnapshot().getId(); } @Override public void setConfiguration(long recording, String contents) throws IllegalArgumentException { Objects.requireNonNull(contents, "contents"); - MBeanUtils.checkControl(); try { Configuration c = Configuration.create(new StringReader(contents)); getExistingRecording(recording).setSettings(c.getSettings()); @@ -255,7 +214,6 @@ public void setConfiguration(long recording, String contents) throws IllegalArgu @Override public void setPredefinedConfiguration(long recording, String configurationName) throws IllegalArgumentException { Objects.requireNonNull(configurationName, "configurationName"); - MBeanUtils.checkControl(); Recording r = getExistingRecording(recording); for (Configuration c : Configuration.getConfigurations()) { if (c.getName().equals(configurationName)) { @@ -269,14 +227,12 @@ public void setPredefinedConfiguration(long recording, String configurationName) @Override public void copyTo(long recording, String outputFile) throws IOException { Objects.requireNonNull(outputFile, "outputFile"); - MBeanUtils.checkControl(); getExistingRecording(recording).dump(Paths.get(outputFile)); } @Override public void setRecordingOptions(long recording, Map options) throws IllegalArgumentException { Objects.requireNonNull(options, "options"); - MBeanUtils.checkControl(); // Make local copy to prevent concurrent modification Map ops = new HashMap(options); for (Map.Entry entry : ops.entrySet()) { @@ -315,7 +271,6 @@ public void setRecordingOptions(long recording, Map options) thr @Override public Map getRecordingOptions(long recording) throws IllegalArgumentException { - MBeanUtils.checkMonitor(); Recording r = getExistingRecording(recording); Map options = HashMap.newHashMap(10); options.put(OPTION_DUMP_ON_EXIT, String.valueOf(r.getDumpOnExit())); @@ -330,8 +285,7 @@ public Map getRecordingOptions(long recording) throws IllegalArg } @Override - public long cloneRecording(long id, boolean stop) throws IllegalStateException, SecurityException { - MBeanUtils.checkControl(); + public long cloneRecording(long id, boolean stop) throws IllegalStateException { return getRecording(id).copy(stop).getId(); } @@ -397,16 +351,11 @@ private static void validateOption(Map options, String na } @SuppressWarnings("removal") - private FlightRecorder getRecorder() throws SecurityException { + private FlightRecorder getRecorder() { // Synchronize on some private object that is always available synchronized (streamHandler) { if (recorder == null) { - recorder = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public FlightRecorder run() { - return FlightRecorder.getFlightRecorder(); - } - }, null, new FlightRecorderPermission("accessFlightRecorder")); + recorder = FlightRecorder.getFlightRecorder(); } return recorder; } @@ -425,13 +374,7 @@ private static MBeanNotificationInfo[] createNotificationInfo() { public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) { MXBeanListener mxbeanListener = new MXBeanListener(listener, filter, handback); listeners.add(mxbeanListener); - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run(){ - FlightRecorder.addListener(mxbeanListener); - return null; - } - }, null, new FlightRecorderPermission("accessFlightRecorder")); + FlightRecorder.addListener(mxbeanListener); super.addNotificationListener(listener, filter, handback); } diff --git a/src/jdk.management.jfr/share/classes/jdk/management/jfr/MBeanUtils.java b/src/jdk.management.jfr/share/classes/jdk/management/jfr/MBeanUtils.java index 05d2166329f71..cf05f840cbe10 100644 --- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/MBeanUtils.java +++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/MBeanUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 jdk.management.jfr; import java.io.IOException; -import java.lang.management.ManagementPermission; -import java.security.Permission; import java.time.DateTimeException; import java.time.Duration; import java.time.Instant; @@ -43,9 +41,6 @@ final class MBeanUtils { - private static final Permission monitor = new ManagementPermission("monitor"); - private static final Permission control = new ManagementPermission("control"); - static ObjectName createObjectName() { try { return new ObjectName(FlightRecorderMXBean.MXBEAN_NAME); @@ -54,22 +49,6 @@ static ObjectName createObjectName() { } } - static void checkControl() { - @SuppressWarnings("removal") - SecurityManager secManager = System.getSecurityManager(); - if (secManager != null) { - secManager.checkPermission(control); - } - } - - static void checkMonitor() { - @SuppressWarnings("removal") - SecurityManager secManager = System.getSecurityManager(); - if (secManager != null) { - secManager.checkPermission(monitor); - } - } - static List transformList(List source, Function function) { return source.stream().map(function).collect(Collectors.toList()); } diff --git a/src/jdk.management.jfr/share/classes/jdk/management/jfr/RemoteRecordingStream.java b/src/jdk.management.jfr/share/classes/jdk/management/jfr/RemoteRecordingStream.java index e6dc9700c00f2..662fe8912446d 100644 --- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/RemoteRecordingStream.java +++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/RemoteRecordingStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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 @@ -32,8 +32,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; -import java.security.AccessControlContext; -import java.security.AccessController; import java.time.Duration; import java.time.Instant; import java.util.ArrayList; @@ -44,7 +42,6 @@ import java.util.Objects; import java.util.concurrent.Future; import java.util.function.Consumer; -import java.security.AccessControlException; import javax.management.JMX; import javax.management.MBeanServerConnection; import javax.management.ObjectName; @@ -149,8 +146,6 @@ public void accept(Long endNanos) { final FlightRecorderMXBean mbean; final long recordingId; final EventStream stream; - @SuppressWarnings("removal") - final AccessControlContext accessControllerContext; final DiskRepository repository; final Instant creationTime; final Object lock = new Object(); @@ -205,9 +200,7 @@ public RemoteRecordingStream(MBeanServerConnection connection, Path directory) t private RemoteRecordingStream(MBeanServerConnection connection, Path directory, boolean delete) throws IOException { Objects.requireNonNull(connection, "connection"); Objects.requireNonNull(directory, "directory"); - accessControllerContext = AccessController.getContext(); - // Make sure users can't implement malicious version of a Path object. - path = Paths.get(directory.toString()); + path = directory; if (!Files.exists(path)) { throw new IOException("Download directory doesn't exist"); } @@ -219,7 +212,7 @@ private RemoteRecordingStream(MBeanServerConnection connection, Path directory, creationTime = Instant.now(); mbean = createProxy(connection); recordingId = createRecording(); - stream = ManagementSupport.newEventDirectoryStream(accessControllerContext, path, configurations(mbean)); + stream = ManagementSupport.newEventDirectoryStream(path, configurations(mbean)); stream.setStartTime(Instant.MIN); repository = new DiskRepository(path, delete); ManagementSupport.setOnChunkCompleteHandler(stream, new ChunkConsumer(repository)); diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java index 2780f396f0562..29e666a830c01 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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,12 +25,12 @@ import java.io.File; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import jdk.jfr.internal.Repository; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.Options; import jdk.test.lib.Asserts; import jdk.test.lib.Utils; @@ -131,17 +131,17 @@ private static void testRepository(){ try { JcmdHelper.jcmd("JFR.configure", REPOSITORYPATH_SETTING_1); - SafePath initialPath = Repository.getRepository().getRepositoryPath(); + Path initialPath = Repository.getRepository().getRepositoryPath(); JcmdHelper.jcmd("JFR.configure", REPOSITORYPATH_SETTING_1); - SafePath samePath = Repository.getRepository().getRepositoryPath(); + Path samePath = Repository.getRepository().getRepositoryPath(); Asserts.assertTrue(samePath.equals(initialPath)); List lines = Files.readAllLines(Paths.get(JFR_UNIFIED_LOG_FILE)); Asserts.assertTrue(lines.stream().anyMatch(l->l.contains(findWhat))); JcmdHelper.jcmd("JFR.configure", REPOSITORYPATH_SETTING_2); - SafePath changedPath = Repository.getRepository().getRepositoryPath(); + Path changedPath = Repository.getRepository().getRepositoryPath(); Asserts.assertFalse(changedPath.equals(initialPath)); diff --git a/test/jdk/jdk/jfr/jvm/MyCommitRegisteredFalseEvent.java b/test/jdk/jdk/jfr/jvm/MyCommitRegisteredFalseEvent.java index d09d3067dafa8..5da979ad6450b 100644 --- a/test/jdk/jdk/jfr/jvm/MyCommitRegisteredFalseEvent.java +++ b/test/jdk/jdk/jfr/jvm/MyCommitRegisteredFalseEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,7 +28,7 @@ @Registered(false) public class MyCommitRegisteredFalseEvent extends E implements Runnable { public void myCommit() { - PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter.getEventWriter(); throw new RuntimeException("Should not reach here"); } diff --git a/test/jdk/jdk/jfr/jvm/MyCommitRegisteredTrueEvent.java b/test/jdk/jdk/jfr/jvm/MyCommitRegisteredTrueEvent.java index 87014bcd72b48..0af8a8f41ccef 100644 --- a/test/jdk/jdk/jfr/jvm/MyCommitRegisteredTrueEvent.java +++ b/test/jdk/jdk/jfr/jvm/MyCommitRegisteredTrueEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,7 +28,7 @@ @Registered(true) public class MyCommitRegisteredTrueEvent extends E implements Runnable { public void myCommit() { - PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter.getEventWriter(); throw new RuntimeException("Should not reach here"); } diff --git a/test/jdk/jdk/jfr/jvm/NonEvent.java b/test/jdk/jdk/jfr/jvm/NonEvent.java index 9134d25c08c98..e98d995acdbff 100644 --- a/test/jdk/jdk/jfr/jvm/NonEvent.java +++ b/test/jdk/jdk/jfr/jvm/NonEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,7 +25,7 @@ // Class used by TestGetEventWriter public class NonEvent implements Runnable { public void commit() { - PlaceholderEventWriter ew = PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter ew = PlaceholderEventWriter.getEventWriter();; throw new RuntimeException("Should not reach here " + ew); } diff --git a/test/jdk/jdk/jfr/jvm/PlaceholderEventWriter.java b/test/jdk/jdk/jfr/jvm/PlaceholderEventWriter.java index 8f0c543334757..87cffc5127592 100644 --- a/test/jdk/jdk/jfr/jvm/PlaceholderEventWriter.java +++ b/test/jdk/jdk/jfr/jvm/PlaceholderEventWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -30,4 +30,8 @@ // will be replaced with "jdk.jfr.internal.event.EventWriter" public class PlaceholderEventWriter { + public static PlaceholderEventWriter getEventWriter() { + return null; + } + } diff --git a/test/jdk/jdk/jfr/jvm/PlaceholderEventWriterFactory.java b/test/jdk/jdk/jfr/jvm/PlaceholderEventWriterFactory.java deleted file mode 100644 index 8083bc16a53ba..0000000000000 --- a/test/jdk/jdk/jfr/jvm/PlaceholderEventWriterFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.jfr.jvm; - -// Purpose of this class is to have something to -// statically link against for TestGetEventWriter. -// -// When the class is loaded "jdk.jfr.jvm.PlaceholderEventWriterFactory" -// will be replaced with "jdk.jfr.internal.event.EventWriterFactory" -public class PlaceholderEventWriterFactory { - - public static PlaceholderEventWriter getEventWriter(long value) { - throw new RuntimeException("Test error, PlaceholderEventWriterFactory class should have been replaced with EventWriterFactory"); - } -} diff --git a/test/jdk/jdk/jfr/jvm/RegisteredFalseEvent.java b/test/jdk/jdk/jfr/jvm/RegisteredFalseEvent.java index 6174bace86628..d20a045450036 100644 --- a/test/jdk/jdk/jfr/jvm/RegisteredFalseEvent.java +++ b/test/jdk/jdk/jfr/jvm/RegisteredFalseEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,7 +28,7 @@ @Registered(false) public class RegisteredFalseEvent extends E { public void commit() { - PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter.getEventWriter(); throw new RuntimeException("Should not reach here"); } } \ No newline at end of file diff --git a/test/jdk/jdk/jfr/jvm/RegisteredTrueEvent.java b/test/jdk/jdk/jfr/jvm/RegisteredTrueEvent.java index 3fe2ce8a1190f..fb2964e68e9f8 100644 --- a/test/jdk/jdk/jfr/jvm/RegisteredTrueEvent.java +++ b/test/jdk/jdk/jfr/jvm/RegisteredTrueEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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,7 +28,7 @@ @Registered(true) public class RegisteredTrueEvent extends E { public void commit() { - PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter.getEventWriter(); throw new RuntimeException("Should not reach here"); } } \ No newline at end of file diff --git a/test/jdk/jdk/jfr/jvm/StaticCommitEvent.java b/test/jdk/jdk/jfr/jvm/StaticCommitEvent.java index 6adeb6cb9c51e..8c07c5bf9b6ae 100644 --- a/test/jdk/jdk/jfr/jvm/StaticCommitEvent.java +++ b/test/jdk/jdk/jfr/jvm/StaticCommitEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -30,7 +30,7 @@ public class StaticCommitEvent implements Runnable { int value; public static void commit(long start, long duration, String message, int value) { - PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter.getEventWriter(); throw new RuntimeException("Should not reach here"); } diff --git a/test/jdk/jdk/jfr/jvm/TestGetEventWriter.java b/test/jdk/jdk/jfr/jvm/TestGetEventWriter.java index 298114b14e14a..7920678b7f0e6 100644 --- a/test/jdk/jdk/jfr/jvm/TestGetEventWriter.java +++ b/test/jdk/jdk/jfr/jvm/TestGetEventWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -46,7 +46,6 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * * @compile PlaceholderEventWriter.java - * @compile PlaceholderEventWriterFactory.java * @compile E.java * @compile NonEvent.java * @compile RegisteredTrueEvent.java @@ -80,7 +79,6 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * * @compile PlaceholderEventWriter.java - * @compile PlaceholderEventWriterFactory.java * @compile E.java * @compile NonEvent.java * @compile RegisteredTrueEvent.java @@ -105,10 +103,10 @@ public static void main(String... args) throws Throwable { InitializationEvent e = new InitializationEvent(); e.commit(); } - // Make sure EventWriterFactory can be accessed. - Class clazz = Class.forName("jdk.jfr.internal.event.EventWriterFactory"); + // Make sure EventWriter class can be accessed. + Class clazz = Class.forName("jdk.jfr.internal.event.EventWriter"); if (clazz == null) { - throw new Exception("Test error, not able to access jdk.jfr.internal.event.EventWriterFactory class"); + throw new Exception("Test error, not able to access jdk.jfr.internal.event.EventWriter class"); } testRegisteredTrueEvent(); testRegisteredFalseEvent(); @@ -122,7 +120,7 @@ public static void main(String... args) throws Throwable { // The class does not inherit jdk.jfr.Event and, as such, does not implement the // API. It has its own stand-alone "commit()V", which is not an override, that - // attempts to resolve and link against EventWriterFactory. This user implementation + // attempts to resolve and link against EventWriter. This user implementation // is not blessed for linkage. private static void testNonEvent() throws Throwable { Runnable e = newEventObject("NonEvent"); @@ -178,7 +176,7 @@ private static void testRegisteredFalseEvent() throws Throwable { } // The user has implemented another method, "myCommit()V", not an override nor - // overload. that attempts to resolve and link EventWriterFactory. This will fail, + // overload. that attempts to resolve and link EventWriter. This will fail, // because "myCommit()V" is not blessed for linkage. private static void testMyCommitRegisteredTrue() throws Throwable { Runnable e = newEventObject("MyCommitRegisteredTrueEvent"); @@ -230,10 +228,9 @@ static class MethodHandleEvent extends Event { public void myCommit() throws Throwable { try { Class ew = Class.forName("jdk.jfr.internal.event.EventWriter"); - MethodType t = MethodType.methodType(ew, List.of(long.class)); - Class factory = Class.forName("jdk.jfr.internal.event.EventWriterFactory"); - MethodHandle mh = MethodHandles.lookup().findStatic(factory, "getEventWriter", t); - mh.invoke(Long.valueOf(4711)); // throws IllegalAccessException + MethodType t = MethodType.methodType(ew, List.of()); + MethodHandle mh = MethodHandles.lookup().findStatic(ew, "getEventWriter", t); + mh.invoke(); // throws IllegalAccessException } catch (ClassNotFoundException | SecurityException e) { throw new RuntimeException(e); } @@ -262,8 +259,8 @@ static class ReflectionEvent extends Event { public void myCommit() throws Throwable { Class c; try { - c = Class.forName("jdk.jfr.internal.event.EventWriterFactory"); - Method m = c.getMethod("getEventWriter", new Class[] {long.class}); + c = Class.forName("jdk.jfr.internal.event.EventWriter"); + Method m = c.getMethod("getEventWriter", new Class[0]); m.invoke(null, Long.valueOf(4711)); // throws InternalError } catch (ClassNotFoundException | SecurityException e) { throw new RuntimeException(e); @@ -283,7 +280,7 @@ private static void testReflectionEvent() throws Throwable { } catch (InternalError ie) { if (ie.getCause() instanceof IllegalAccessException iaex) { if (iaex.getCause() instanceof IllegalAccessError iae) { - if (iae.getMessage().contains("getEventWriter(long)")) { + if (iae.getMessage().contains("getEventWriter()")) { // OK, as expected return; } @@ -345,7 +342,6 @@ private static T newEventObject(String name) throws Throwable { byte[] bytes = is.readAllBytes(); is.close(); bytes = replace(bytes, "jdk/jfr/jvm/E", "jdk/jfr/Event"); - bytes = replace(bytes, "jdk/jfr/jvm/PlaceholderEventWriterFactory", "jdk/jfr/internal/event/EventWriterFactory"); bytes = replace(bytes, "jdk/jfr/jvm/PlaceholderEventWriter", "jdk/jfr/internal/event/EventWriter"); BytesClassLoader bc = new BytesClassLoader(bytes, fullName); Class clazz = bc.loadClass(fullName); @@ -372,7 +368,7 @@ private static void maybeCheckJVMCI(Class eventClass, String commitName) thro } /** - * Checks that JVMCI prevents unblessed access to {@code EventWriterFactory.getEventWriter(long)}. + * Checks that JVMCI prevents unblessed access to {@code EventWriter.getEventWriter()}. */ private static void checkJVMCI(Class eventClass, String commitName) throws Throwable { MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); @@ -380,7 +376,7 @@ private static void checkJVMCI(Class eventClass, String commitName) throws Th ConstantPool cp = commit.getConstantPool(); // Search for first INVOKESTATIC instruction in commit method which is expected - // to be the call to jdk.jfr.internal.event.EventWriterFactory.getEventWriter(long). + // to be the call to jdk.jfr.internal.event.EventWriter.getEventWriter(). final int INVOKESTATIC = 184; byte[] code = commit.getCode(); for (int bci = 0; bci < code.length; bci++) { diff --git a/test/jdk/jdk/jfr/tool/TestAssemble.java b/test/jdk/jdk/jfr/tool/TestAssemble.java index ccc95498de437..2ac90b535a526 100644 --- a/test/jdk/jdk/jfr/tool/TestAssemble.java +++ b/test/jdk/jdk/jfr/tool/TestAssemble.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -35,7 +35,6 @@ import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.consumer.RecordingFile; import jdk.jfr.internal.Repository; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -80,7 +79,7 @@ public static void main(String[] args) throws Throwable { expectedCount += countEventInRecording(tmp); } - SafePath repository = Repository.getRepository().getRepositoryPath(); + Path repository = Repository.getRepository().getRepositoryPath(); Path destinationPath = Paths.get("reconstructed.jfr"); String directory = repository.toString(); From c5c4efdaa1d04b1441fd96712b71cdb43e5d86df Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 10 Jan 2025 13:57:52 +0000 Subject: [PATCH 097/286] 8347120: Launchers should not have java headers on include path Reviewed-by: dholmes, ihse --- make/common/JdkNativeCompilation.gmk | 9 +++++++-- make/common/modules/LauncherCommon.gmk | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/make/common/JdkNativeCompilation.gmk b/make/common/JdkNativeCompilation.gmk index ca0f1429c6165..a4f48385f4189 100644 --- a/make/common/JdkNativeCompilation.gmk +++ b/make/common/JdkNativeCompilation.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, 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 @@ -266,6 +266,9 @@ JDK_RCFLAGS=$(RCFLAGS) \ # will be replaced with proper values for hotspot. # HEADERS_FROM_SRC -- if false, does not add source dirs automatically as # header include dirs. (Defaults to true.) +# JAVA_HEADERS -- if false, does not add the directory with the generated +# headers from the Java compilation of the current module to the search +# path for include files. (Defaults to true.) # JDK_LIBS -- libraries generated by the JDK build system to link against. # These take the form :. For the current module, the # module name and colon can be omitted. The basename should be specified @@ -385,7 +388,9 @@ define SetupJdkNativeCompilationBody # Add the module specific java header dir ifneq ($$(MODULE), ) - $1_SRC_HEADER_FLAGS += $$(addprefix -I, $$(call GetJavaHeaderDir, $$(MODULE))) + ifneq ($$($1_JAVA_HEADERS), false) + $1_SRC_HEADER_FLAGS += $$(addprefix -I, $$(call GetJavaHeaderDir, $$(MODULE))) + endif endif $1_JDK_LIBS += $$($1_JDK_LIBS_$$(OPENJDK_TARGET_OS)) diff --git a/make/common/modules/LauncherCommon.gmk b/make/common/modules/LauncherCommon.gmk index 38485283dcb98..eb8621092c0d5 100644 --- a/make/common/modules/LauncherCommon.gmk +++ b/make/common/modules/LauncherCommon.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, 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 @@ -145,6 +145,7 @@ define SetupBuildLauncherBody $$($1_CFLAGS), \ CFLAGS_windows := $$($1_CFLAGS_windows), \ EXTRA_HEADER_DIRS := java.base:libjvm, \ + JAVA_HEADERS := false, \ DISABLED_WARNINGS_gcc := unused-function unused-variable, \ DISABLED_WARNINGS_clang := unused-function, \ LDFLAGS := $$($1_LDFLAGS), \ From beb0e607d3b66b9e97c263cd8f2e23f447ebfc50 Mon Sep 17 00:00:00 2001 From: Peter Levart Date: Fri, 10 Jan 2025 14:47:01 +0000 Subject: [PATCH 098/286] 8347397: Cleanup of JDK-8169880 Reviewed-by: liach, alanb --- .../share/classes/java/lang/Class.java | 87 +++++++------------ 1 file changed, 31 insertions(+), 56 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 7929dd1a09f11..4250910c84b24 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2025, 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 @@ -1205,18 +1205,13 @@ public Class[] getInterfaces() { private Class[] getInterfaces(boolean cloneArray) { ReflectionData rd = reflectionData(); - if (rd == null) { - // no cloning required - return getInterfaces0(); - } else { - Class[] interfaces = rd.interfaces; - if (interfaces == null) { - interfaces = getInterfaces0(); - rd.interfaces = interfaces; - } - // defensively copy if requested - return cloneArray ? interfaces.clone() : interfaces; + Class[] interfaces = rd.interfaces; + if (interfaces == null) { + interfaces = getInterfaces0(); + rd.interfaces = interfaces; } + // defensively copy if requested + return cloneArray ? interfaces.clone() : interfaces; } private native Class[] getInterfaces0(); @@ -2922,18 +2917,14 @@ static byte[] getExecutableTypeAnnotationBytes(Executable ex) { private Field[] privateGetDeclaredFields(boolean publicOnly) { Field[] res; ReflectionData rd = reflectionData(); - if (rd != null) { - res = publicOnly ? rd.declaredPublicFields : rd.declaredFields; - if (res != null) return res; - } + res = publicOnly ? rd.declaredPublicFields : rd.declaredFields; + if (res != null) return res; // No cached value available; request value from VM res = Reflection.filterFields(this, getDeclaredFields0(publicOnly)); - if (rd != null) { - if (publicOnly) { - rd.declaredPublicFields = res; - } else { - rd.declaredFields = res; - } + if (publicOnly) { + rd.declaredPublicFields = res; + } else { + rd.declaredFields = res; } return res; } @@ -2944,10 +2935,8 @@ private Field[] privateGetDeclaredFields(boolean publicOnly) { private Field[] privateGetPublicFields() { Field[] res; ReflectionData rd = reflectionData(); - if (rd != null) { - res = rd.publicFields; - if (res != null) return res; - } + res = rd.publicFields; + if (res != null) return res; // Use a linked hash set to ensure order is preserved and // fields from common super interfaces are not duplicated @@ -2968,9 +2957,7 @@ private Field[] privateGetPublicFields() { } res = fields.toArray(new Field[0]); - if (rd != null) { - rd.publicFields = res; - } + rd.publicFields = res; return res; } @@ -2993,10 +2980,8 @@ private static void addAll(Collection c, Field[] o) { private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) { Constructor[] res; ReflectionData rd = reflectionData(); - if (rd != null) { - res = publicOnly ? rd.publicConstructors : rd.declaredConstructors; - if (res != null) return res; - } + res = publicOnly ? rd.publicConstructors : rd.declaredConstructors; + if (res != null) return res; // No cached value available; request value from VM if (isInterface()) { @SuppressWarnings("unchecked") @@ -3005,12 +2990,10 @@ private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) { } else { res = getDeclaredConstructors0(publicOnly); } - if (rd != null) { - if (publicOnly) { - rd.publicConstructors = res; - } else { - rd.declaredConstructors = res; - } + if (publicOnly) { + rd.publicConstructors = res; + } else { + rd.declaredConstructors = res; } return res; } @@ -3027,18 +3010,14 @@ private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) { private Method[] privateGetDeclaredMethods(boolean publicOnly) { Method[] res; ReflectionData rd = reflectionData(); - if (rd != null) { - res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods; - if (res != null) return res; - } + res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods; + if (res != null) return res; // No cached value available; request value from VM res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly)); - if (rd != null) { - if (publicOnly) { - rd.declaredPublicMethods = res; - } else { - rd.declaredMethods = res; - } + if (publicOnly) { + rd.declaredPublicMethods = res; + } else { + rd.declaredMethods = res; } return res; } @@ -3049,10 +3028,8 @@ private Method[] privateGetDeclaredMethods(boolean publicOnly) { private Method[] privateGetPublicMethods() { Method[] res; ReflectionData rd = reflectionData(); - if (rd != null) { - res = rd.publicMethods; - if (res != null) return res; - } + res = rd.publicMethods; + if (res != null) return res; // No cached value available; compute value recursively. // Start by fetching public declared methods... @@ -3078,9 +3055,7 @@ private Method[] privateGetPublicMethods() { } res = pms.toArray(); - if (rd != null) { - rd.publicMethods = res; - } + rd.publicMethods = res; return res; } From 1bf2f5c8a92b30eabb530737158f57c63a81fef6 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 10 Jan 2025 15:58:50 +0000 Subject: [PATCH 099/286] 8343510: JFR: Remove AccessControlContext from FlightRecorder::addListener specification Reviewed-by: mgronlun --- src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java index a7bf3976d14df..6ea6f87f2afff 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java @@ -241,8 +241,7 @@ public List getEventTypes() { } /** - * Adds a recorder listener and captures the {@code AccessControlContext} to - * use when invoking the listener. + * Adds a recorder listener. *

        * If Flight Recorder is already initialized when the listener is added, then the method * {@link FlightRecorderListener#recorderInitialized(FlightRecorder)} method is From 9cf7d42b65cfecfe27d0267f971acb743c02b675 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Fri, 10 Jan 2025 16:47:51 +0000 Subject: [PATCH 100/286] 8346184: C2: assert(has_node(i)) failed during split thru phi Reviewed-by: thartmann, chagedorn --- src/hotspot/share/opto/memnode.cpp | 25 +++---- .../compiler/c2/TestLoadSplitThruPhiNull.java | 68 +++++++++++++++++++ 2 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/c2/TestLoadSplitThruPhiNull.java diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index 78ffbe05ae492..ab57ee37cc6e2 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -2014,6 +2014,17 @@ const Type* LoadNode::Value(PhaseGVN* phase) const { assert(off != Type::OffsetTop, "case covered by TypePtr::empty"); Compile* C = phase->C; + // If we are loading from a freshly-allocated object, produce a zero, + // if the load is provably beyond the header of the object. + // (Also allow a variable load from a fresh array to produce zero.) + const TypeOopPtr* tinst = tp->isa_oopptr(); + bool is_instance = (tinst != nullptr) && tinst->is_known_instance_field(); + Node* value = can_see_stored_value(mem, phase); + if (value != nullptr && value->is_Con()) { + assert(value->bottom_type()->higher_equal(_type), "sanity"); + return value->bottom_type(); + } + // Try to guess loaded type from pointer type if (tp->isa_aryptr()) { const TypeAryPtr* ary = tp->is_aryptr(); @@ -2220,20 +2231,6 @@ const Type* LoadNode::Value(PhaseGVN* phase) const { } } - // If we are loading from a freshly-allocated object, produce a zero, - // if the load is provably beyond the header of the object. - // (Also allow a variable load from a fresh array to produce zero.) - const TypeOopPtr *tinst = tp->isa_oopptr(); - bool is_instance = (tinst != nullptr) && tinst->is_known_instance_field(); - bool is_boxed_value = (tinst != nullptr) && tinst->is_ptr_to_boxed_value(); - if (ReduceFieldZeroing || is_instance || is_boxed_value) { - Node* value = can_see_stored_value(mem,phase); - if (value != nullptr && value->is_Con()) { - assert(value->bottom_type()->higher_equal(_type),"sanity"); - return value->bottom_type(); - } - } - bool is_vect = (_type->isa_vect() != nullptr); if (is_instance && !is_vect) { // If we have an instance type and our memory input is the diff --git a/test/hotspot/jtreg/compiler/c2/TestLoadSplitThruPhiNull.java b/test/hotspot/jtreg/compiler/c2/TestLoadSplitThruPhiNull.java new file mode 100644 index 0000000000000..5c927fbefb1e4 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestLoadSplitThruPhiNull.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8346184 + * @summary C2: assert(has_node(i)) failed during split thru phi + * + * @run main/othervm -XX:-BackgroundCompilation TestLoadSplitThruPhiNull + * @run main/othervm -XX:-BackgroundCompilation -XX:-ReduceFieldZeroing TestLoadSplitThruPhiNull + * @run main TestLoadSplitThruPhiNull + * + */ + +public class TestLoadSplitThruPhiNull { + private static Object[] fieldArray; + private static Object fieldObject; + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test1(true); + test1(false); + } + } + + private static Object test1(boolean flag) { + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + for (int k = 0; k < 10; k++) { + + } + } + } + Object[] array = new Object[10]; + fieldArray = array; + int i; + for (i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + + } + } + Object v = array[i-10]; + if (flag) { + array[0] = new Object(); + } + return array[i-10]; + } +} From e7e8f60c9bedd5622525cc4339300b438eedc9fd Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Fri, 10 Jan 2025 16:50:21 +0000 Subject: [PATCH 101/286] 8347302: Mark test tools/jimage/JImageToolTest.java as flagless Reviewed-by: alanb, shade --- test/jdk/tools/jimage/JImageToolTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/jdk/tools/jimage/JImageToolTest.java b/test/jdk/tools/jimage/JImageToolTest.java index b1006c896794b..d7d1ee35ba1e0 100644 --- a/test/jdk/tools/jimage/JImageToolTest.java +++ b/test/jdk/tools/jimage/JImageToolTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -23,6 +23,7 @@ /* * @test * @library /test/lib + * @requires vm.flagless * @build jdk.test.lib.process.ProcessTools * @summary Test to check if jimage tool exists and is working * @run main/timeout=360 JImageToolTest From 46ba515c4989de7545d409570315274e0ea1c5ac Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Fri, 10 Jan 2025 17:59:27 +0000 Subject: [PATCH 102/286] 8346669: Increase abstraction in SetupBuildLauncher and remove extra args Reviewed-by: erikj --- make/StaticLibs.gmk | 3 +- make/common/modules/LauncherCommon.gmk | 40 +++++++-------- make/modules/java.base/Launcher.gmk | 7 ++- make/modules/jdk.compiler/Launcher.gmk | 4 +- make/modules/jdk.javadoc/Launcher.gmk | 2 +- make/modules/jdk.jconsole/Launcher.gmk | 2 +- make/modules/jdk.jdeps/Launcher.gmk | 8 +-- make/modules/jdk.jfr/Launcher.gmk | 2 +- make/modules/jdk.jlink/Launcher.gmk | 8 +-- make/modules/jdk.jshell/Launcher.gmk | 2 +- src/java.base/share/native/launcher/defines.h | 11 +--- src/java.base/share/native/launcher/main.c | 50 +++---------------- 12 files changed, 48 insertions(+), 91 deletions(-) diff --git a/make/StaticLibs.gmk b/make/StaticLibs.gmk index d54c67b50b3ea..900fbbbbad4f6 100644 --- a/make/StaticLibs.gmk +++ b/make/StaticLibs.gmk @@ -107,7 +107,8 @@ else endif $(eval $(call SetupBuildLauncher, java, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \ + ENABLE_ARG_FILES := true, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ EXTRA_RCFLAGS := $(JAVA_RCFLAGS), \ VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \ OPTIMIZATION := HIGH, \ diff --git a/make/common/modules/LauncherCommon.gmk b/make/common/modules/LauncherCommon.gmk index eb8621092c0d5..48b523428240a 100644 --- a/make/common/modules/LauncherCommon.gmk +++ b/make/common/modules/LauncherCommon.gmk @@ -48,15 +48,11 @@ JAVA_MANIFEST := $(TOPDIR)/src/java.base/windows/native/launcher/java.manifest # used as the name of the executable. # # Remaining parameters are named arguments. These include: -# MAIN_MODULE The module of the main class to launch if different from the -# current module # MAIN_CLASS The Java main class to launch -# JAVA_ARGS Processed into a -DJAVA_ARGS and added to CFLAGS -# EXTRA_JAVA_ARGS Processed into a -DEXTRA_JAVA_ARGS and is prepended -# before JAVA_ARGS to CFLAGS, primarily to allow long string literal -# compile time defines exceeding Visual Studio 2013 limitations. -# CFLAGS Additional CFLAGS -# CFLAGS_windows Additional CFLAGS_windows +# JAVA_ARGS Additional arguments to pass to Java when launching the main class +# EXPAND_CLASSPATH_WILDCARDS Set to true to pass EXPAND_CLASSPATH_WILDCARDS +# ENABLE_ARG_FILES Set to true to pass ENABLE_ARG_FILES +# WINDOWS_JAVAW Set to true to pass JAVAW on Windows # EXTRA_RCFLAGS Additional EXTRA_RCFLAGS # MACOSX_PRIVILEGED On macosx, allow to access other processes # OPTIMIZATION Override default optimization level (LOW) @@ -70,19 +66,25 @@ define SetupBuildLauncherBody $1_OPTIMIZATION := LOW endif - ifeq ($$($1_MAIN_MODULE), ) - $1_MAIN_MODULE := $(MODULE) - endif + $1_MAIN_MODULE := $(MODULE) ifneq ($$($1_MAIN_CLASS), ) $1_JAVA_ARGS += -Xms8m $1_LAUNCHER_CLASS := -m $$($1_MAIN_MODULE)/$$($1_MAIN_CLASS) endif - ifneq ($$($1_EXTRA_JAVA_ARGS), ) - $1_EXTRA_JAVA_ARGS_STR := '{ $$(strip $$(foreach a, \ - $$(addprefix -J, $$($1_EXTRA_JAVA_ARGS)), "$$a"$(COMMA) )) }' - $1_CFLAGS += -DEXTRA_JAVA_ARGS=$$($1_EXTRA_JAVA_ARGS_STR) + ifeq ($$($1_EXPAND_CLASSPATH_WILDCARDS), true) + $1_CFLAGS += -DEXPAND_CLASSPATH_WILDCARDS + endif + + ifeq ($$($1_ENABLE_ARG_FILES), true) + $1_CFLAGS += -DENABLE_ARG_FILES + endif + + ifeq ($(call isTargetOs, windows), true) + ifeq ($$($1_WINDOWS_JAVAW), true) + $1_CFLAGS += -DJAVAW + endif endif ifneq ($$($1_JAVA_ARGS), ) @@ -143,7 +145,6 @@ define SetupBuildLauncherBody -DLAUNCHER_NAME='"$$(LAUNCHER_NAME)"' \ -DPROGNAME='"$1"' \ $$($1_CFLAGS), \ - CFLAGS_windows := $$($1_CFLAGS_windows), \ EXTRA_HEADER_DIRS := java.base:libjvm, \ JAVA_HEADERS := false, \ DISABLED_WARNINGS_gcc := unused-function unused-variable, \ @@ -154,13 +155,6 @@ define SetupBuildLauncherBody LDFLAGS_FILTER_OUT := $$($1_LDFLAGS_FILTER_OUT), \ JDK_LIBS := $$($1_JDK_LIBS), \ JDK_LIBS_windows := $$($1_JDK_LIBS_windows), \ - LIBS := $$($1_LIBS), \ - LIBS_unix := $(LIBZ_LIBS), \ - LIBS_linux := $(LIBDL) -lpthread, \ - LIBS_macosx := \ - -framework ApplicationServices \ - -framework Cocoa \ - -framework Security, \ LINK_TYPE := $$($1_LINK_TYPE), \ OUTPUT_DIR := $$($1_OUTPUT_DIR), \ OBJECT_DIR := $$($1_OBJECT_DIR), \ diff --git a/make/modules/java.base/Launcher.gmk b/make/modules/java.base/Launcher.gmk index 024c1c4731b0c..246767f393718 100644 --- a/make/modules/java.base/Launcher.gmk +++ b/make/modules/java.base/Launcher.gmk @@ -38,7 +38,8 @@ JAVA_RCFLAGS ?= -I$(TOPDIR)/src/java.base/windows/native/launcher/icons ################################################################################ $(eval $(call SetupBuildLauncher, java, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \ + ENABLE_ARG_FILES := true, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ EXTRA_RCFLAGS := $(JAVA_RCFLAGS), \ VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \ OPTIMIZATION := HIGH, \ @@ -50,7 +51,9 @@ $(eval $(call SetupBuildLauncher, java, \ ifeq ($(call isTargetOs, windows), true) $(eval $(call SetupBuildLauncher, javaw, \ - CFLAGS := -DJAVAW -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \ + ENABLE_ARG_FILES := true, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ + WINDOWS_JAVAW := true, \ EXTRA_RCFLAGS := $(JAVA_RCFLAGS), \ VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \ )) diff --git a/make/modules/jdk.compiler/Launcher.gmk b/make/modules/jdk.compiler/Launcher.gmk index e80c31bcb18f3..e5c4bbe4b8cdb 100644 --- a/make/modules/jdk.compiler/Launcher.gmk +++ b/make/modules/jdk.compiler/Launcher.gmk @@ -32,7 +32,7 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, javac, \ MAIN_CLASS := com.sun.tools.javac.Main, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) ################################################################################ @@ -41,5 +41,5 @@ $(eval $(call SetupBuildLauncher, javac, \ $(eval $(call SetupBuildLauncher, serialver, \ MAIN_CLASS := sun.tools.serialver.SerialVer, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) diff --git a/make/modules/jdk.javadoc/Launcher.gmk b/make/modules/jdk.javadoc/Launcher.gmk index 30d714be30d6a..608468962f382 100644 --- a/make/modules/jdk.javadoc/Launcher.gmk +++ b/make/modules/jdk.javadoc/Launcher.gmk @@ -32,5 +32,5 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, javadoc, \ MAIN_CLASS := jdk.javadoc.internal.tool.Main, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) diff --git a/make/modules/jdk.jconsole/Launcher.gmk b/make/modules/jdk.jconsole/Launcher.gmk index 3e65c3cccc37a..35d93d6feb917 100644 --- a/make/modules/jdk.jconsole/Launcher.gmk +++ b/make/modules/jdk.jconsole/Launcher.gmk @@ -36,5 +36,5 @@ $(eval $(call SetupBuildLauncher, jconsole, \ --add-modules ALL-DEFAULT \ -Djconsole.showOutputViewer \ -Djdk.attach.allowAttachSelf=true, \ - CFLAGS_windows := -DJAVAW, \ + WINDOWS_JAVAW := true, \ )) diff --git a/make/modules/jdk.jdeps/Launcher.gmk b/make/modules/jdk.jdeps/Launcher.gmk index 1aa54e16f4564..812d690a91d34 100644 --- a/make/modules/jdk.jdeps/Launcher.gmk +++ b/make/modules/jdk.jdeps/Launcher.gmk @@ -31,7 +31,7 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, javap, \ MAIN_CLASS := com.sun.tools.javap.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) ################################################################################ @@ -40,7 +40,7 @@ $(eval $(call SetupBuildLauncher, javap, \ $(eval $(call SetupBuildLauncher, jdeps, \ MAIN_CLASS := com.sun.tools.jdeps.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) ################################################################################ @@ -49,7 +49,7 @@ $(eval $(call SetupBuildLauncher, jdeps, \ $(eval $(call SetupBuildLauncher, jdeprscan, \ MAIN_CLASS := com.sun.tools.jdeprscan.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) ################################################################################ @@ -58,5 +58,5 @@ $(eval $(call SetupBuildLauncher, jdeprscan, \ $(eval $(call SetupBuildLauncher, jnativescan, \ MAIN_CLASS := com.sun.tools.jnativescan.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) diff --git a/make/modules/jdk.jfr/Launcher.gmk b/make/modules/jdk.jfr/Launcher.gmk index 2dd3586a92072..ad07c839f9073 100644 --- a/make/modules/jdk.jfr/Launcher.gmk +++ b/make/modules/jdk.jfr/Launcher.gmk @@ -31,5 +31,5 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jfr, \ MAIN_CLASS := jdk.jfr.internal.tool.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) diff --git a/make/modules/jdk.jlink/Launcher.gmk b/make/modules/jdk.jlink/Launcher.gmk index d427906519357..ef6f5ad1665bd 100644 --- a/make/modules/jdk.jlink/Launcher.gmk +++ b/make/modules/jdk.jlink/Launcher.gmk @@ -31,7 +31,7 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jimage, \ MAIN_CLASS := jdk.tools.jimage.Main, \ - CFLAGS := -DENABLE_ARG_FILES, \ + ENABLE_ARG_FILES := true, \ )) ################################################################################ @@ -41,7 +41,8 @@ $(eval $(call SetupBuildLauncher, jimage, \ $(eval $(call SetupBuildLauncher, jlink, \ MAIN_CLASS := jdk.tools.jlink.internal.Main, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \ - CFLAGS := -DENABLE_ARG_FILES -DEXPAND_CLASSPATH_WILDCARDS, \ + ENABLE_ARG_FILES := true, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) ################################################################################ @@ -50,5 +51,6 @@ $(eval $(call SetupBuildLauncher, jlink, \ $(eval $(call SetupBuildLauncher, jmod, \ MAIN_CLASS := jdk.tools.jmod.Main, \ - CFLAGS := -DENABLE_ARG_FILES -DEXPAND_CLASSPATH_WILDCARDS, \ + ENABLE_ARG_FILES := true, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) diff --git a/make/modules/jdk.jshell/Launcher.gmk b/make/modules/jdk.jshell/Launcher.gmk index bf555d7f64c13..66da3a9e5fcae 100644 --- a/make/modules/jdk.jshell/Launcher.gmk +++ b/make/modules/jdk.jshell/Launcher.gmk @@ -31,5 +31,5 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jshell, \ MAIN_CLASS := jdk.internal.jshell.tool.JShellToolProvider, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) diff --git a/src/java.base/share/native/launcher/defines.h b/src/java.base/share/native/launcher/defines.h index ef0d6eecef9c6..a07a1db17a6fc 100644 --- a/src/java.base/share/native/launcher/defines.h +++ b/src/java.base/share/native/launcher/defines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -50,18 +50,9 @@ static const char* const_progname = PROGNAME; static char* const_progname = NULL; #endif static const char* const_jargs[] = JAVA_ARGS; -#ifdef EXTRA_JAVA_ARGS -static const char* const_extra_jargs[] = EXTRA_JAVA_ARGS; -#else -static const char** const_extra_jargs = NULL; -#endif #else /* !JAVA_ARGS */ -#ifdef EXTRA_JAVA_ARGS -#error "EXTRA_JAVA_ARGS defined without JAVA_ARGS" -#endif static const char* const_progname = "java"; static const char** const_jargs = NULL; -static const char** const_extra_jargs = NULL; #endif /* JAVA_ARGS */ #ifdef LAUNCHER_NAME diff --git a/src/java.base/share/native/launcher/main.c b/src/java.base/share/native/launcher/main.c index c504c13154f5b..4e42e03dfc7c6 100644 --- a/src/java.base/share/native/launcher/main.c +++ b/src/java.base/share/native/launcher/main.c @@ -44,10 +44,6 @@ char **__initenv; int WINAPI WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow) { - int margc; - char** margv; - int jargc; - char** jargv; const jboolean const_javaw = JNI_TRUE; __initenv = _environ; @@ -56,47 +52,17 @@ WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow) JNIEXPORT int main(int argc, char **argv) { - int margc; - char** margv; - int jargc; - char** jargv; const jboolean const_javaw = JNI_FALSE; #endif /* JAVAW */ - { - int i, main_jargc, extra_jargc; - JLI_List list; - - main_jargc = (sizeof(const_jargs) / sizeof(char *)) > 1 - ? sizeof(const_jargs) / sizeof(char *) - : 0; // ignore the null terminator index - - extra_jargc = (sizeof(const_extra_jargs) / sizeof(char *)) > 1 - ? sizeof(const_extra_jargs) / sizeof(char *) - : 0; // ignore the null terminator index - if (main_jargc > 0 && extra_jargc > 0) { // combine extra java args - jargc = main_jargc + extra_jargc; - list = JLI_List_new(jargc + 1); - - for (i = 0 ; i < extra_jargc; i++) { - JLI_List_add(list, JLI_StringDup(const_extra_jargs[i])); - } - - for (i = 0 ; i < main_jargc ; i++) { - JLI_List_add(list, JLI_StringDup(const_jargs[i])); - } + int margc; + char** margv; + int jargc; + const char** jargv = const_jargs; - // terminate the list - JLI_List_add(list, NULL); - jargv = list->elements; - } else if (extra_jargc > 0) { // should never happen - fprintf(stderr, "EXTRA_JAVA_ARGS defined without JAVA_ARGS"); - abort(); - } else { // no extra args, business as usual - jargc = main_jargc; - jargv = (char **) const_jargs; - } - } + jargc = (sizeof(const_jargs) / sizeof(char *)) > 1 + ? sizeof(const_jargs) / sizeof(char *) + : 0; // ignore the null terminator index JLI_InitArgProcessing(jargc > 0, const_disable_argfile); @@ -182,7 +148,7 @@ main(int argc, char **argv) } #endif /* WIN32 */ return JLI_Launch(margc, margv, - jargc, (const char**) jargv, + jargc, jargv, 0, NULL, VERSION_STRING, DOT_VERSION, From 4b554b52e627b3a0f5e15a623b12089bff6bfafa Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Fri, 10 Jan 2025 18:50:40 +0000 Subject: [PATCH 103/286] 8346722: (fs) Files.probeContentType throws ClassCastException with custom file system provider Reviewed-by: alanb --- .../unix/classes/sun/nio/fs/DefaultFileTypeDetector.java | 7 ++----- test/jdk/java/nio/file/spi/SetDefaultProvider.java | 3 ++- test/jdk/java/nio/file/spi/testapp/testapp/Main.java | 5 ++++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/java.base/unix/classes/sun/nio/fs/DefaultFileTypeDetector.java b/src/java.base/unix/classes/sun/nio/fs/DefaultFileTypeDetector.java index 295146d755e45..c3fa9a852e3f7 100644 --- a/src/java.base/unix/classes/sun/nio/fs/DefaultFileTypeDetector.java +++ b/src/java.base/unix/classes/sun/nio/fs/DefaultFileTypeDetector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, 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,15 +25,12 @@ package sun.nio.fs; -import java.nio.file.FileSystems; import java.nio.file.spi.FileTypeDetector; -import java.nio.file.spi.FileSystemProvider; public class DefaultFileTypeDetector { private DefaultFileTypeDetector() { } public static FileTypeDetector create() { - FileSystemProvider provider = FileSystems.getDefault().provider(); - return ((UnixFileSystemProvider)provider).getFileTypeDetector(); + return DefaultFileSystemProvider.instance().getFileTypeDetector(); } } diff --git a/test/jdk/java/nio/file/spi/SetDefaultProvider.java b/test/jdk/java/nio/file/spi/SetDefaultProvider.java index f4486885b6a7e..4d74c8fee934e 100644 --- a/test/jdk/java/nio/file/spi/SetDefaultProvider.java +++ b/test/jdk/java/nio/file/spi/SetDefaultProvider.java @@ -23,7 +23,8 @@ /* * @test - * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 8331467 8346573 + * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 8331467 + * 8346573 8346722 * @modules jdk.jartool jdk.jlink * @library /test/lib * @build testfsp/* testapp/* CustomSystemClassLoader diff --git a/test/jdk/java/nio/file/spi/testapp/testapp/Main.java b/test/jdk/java/nio/file/spi/testapp/testapp/Main.java index f9c3b1e273eff..6f61d431707e1 100644 --- a/test/jdk/java/nio/file/spi/testapp/testapp/Main.java +++ b/test/jdk/java/nio/file/spi/testapp/testapp/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, 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 @@ -58,5 +58,8 @@ public static void main(String[] args) throws Exception { throw new RuntimeException("'path' not in default file system"); if (!path.equals(foo)) throw new RuntimeException(path + " not equal to " + foo); + + // exercise the file type detector + String fileType = Files.probeContentType(Path.of(".")); } } From d69463e4bcbddd346b9486059c5ad3a1cb555632 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Fri, 10 Jan 2025 19:30:27 +0000 Subject: [PATCH 104/286] 8347300: Don't exclude the "PATH" var from the environment when running app launchers in jpackage tests Reviewed-by: almatvee --- .../helpers/jdk/jpackage/test/Executor.java | 19 +++++++++-------- .../helpers/jdk/jpackage/test/HelloApp.java | 21 ++++++++++++++----- .../jpackage/share/AppLauncherEnvTest.java | 6 ++++-- .../jpackage/windows/WinChildProcessTest.java | 8 ++++--- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java index 7a0878d826b43..706e26668b191 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -53,7 +53,6 @@ public static Executor of(String... cmdline) { public Executor() { saveOutputType = new HashSet<>(Set.of(SaveOutputType.NONE)); - removePathEnvVar = false; winEnglishOutput = false; } @@ -86,8 +85,8 @@ public Executor setExecutable(JavaTool v) { return setExecutable(v.getPath()); } - public Executor setRemovePathEnvVar(boolean value) { - removePathEnvVar = value; + public Executor removeEnvVar(String envVarName) { + removeEnvVars.add(Objects.requireNonNull(envVarName)); return this; } @@ -372,10 +371,12 @@ private Result runExecutable() throws IOException, InterruptedException { builder.directory(directory.toFile()); sb.append(String.format("; in directory [%s]", directory)); } - if (removePathEnvVar) { - // run this with cleared Path in Environment - TKit.trace("Clearing PATH in environment"); - builder.environment().remove("PATH"); + if (!removeEnvVars.isEmpty()) { + final var envComm = Comm.compare(builder.environment().keySet(), removeEnvVars); + builder.environment().keySet().removeAll(envComm.common()); + envComm.common().forEach(envVar -> { + TKit.trace(String.format("Clearing %s in environment", envVar)); + }); } trace("Execute " + sb.toString() + "..."); @@ -504,7 +505,7 @@ private static void trace(String msg) { private Path executable; private Set saveOutputType; private Path directory; - private boolean removePathEnvVar; + private Set removeEnvVars = new HashSet<>(); private boolean winEnglishOutput; private String winTmpDir = null; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java index 0c7476e863dc4..15fb41ca1e243 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -472,14 +472,14 @@ private Executor getExecutor(String...args) { } } - final List launcherArgs = List.of(args); - return new Executor() + final var executor = new Executor() .setDirectory(outputFile.getParent()) .saveOutput(saveOutput) .dumpOutput() - .setRemovePathEnvVar(removePathEnvVar) .setExecutable(executablePath) - .addArguments(launcherArgs); + .addArguments(List.of(args)); + + return configureEnvironment(executor); } private boolean launcherNoExit; @@ -496,6 +496,14 @@ public static AppOutputVerifier assertApp(Path helloAppLauncher) { return new AppOutputVerifier(helloAppLauncher); } + public static Executor configureEnvironment(Executor executor) { + if (CLEAR_JAVA_ENV_VARS) { + executor.removeEnvVar("JAVA_TOOL_OPTIONS"); + executor.removeEnvVar("_JAVA_OPTIONS"); + } + return executor; + } + static final String OUTPUT_FILENAME = "appOutput.txt"; private final JavaAppDesc appDesc; @@ -505,4 +513,7 @@ public static AppOutputVerifier assertApp(Path helloAppLauncher) { private static final String CLASS_NAME = HELLO_JAVA.getFileName().toString().split( "\\.", 2)[0]; + + private static final boolean CLEAR_JAVA_ENV_VARS = Optional.ofNullable( + TKit.getConfigProperty("clear-app-launcher-java-env-vars")).map(Boolean::parseBoolean).orElse(false); } diff --git a/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java b/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java index a16ff9c18f96d..52016e6f4ab6a 100644 --- a/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java +++ b/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, 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 @@ -30,6 +30,7 @@ import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Executor; +import static jdk.jpackage.test.HelloApp.configureEnvironment; import jdk.jpackage.test.TKit; /** @@ -53,6 +54,7 @@ public static void test() throws Exception { JPackageCommand cmd = JPackageCommand .helloAppImage(TEST_APP_JAVA + "*Hello") + .ignoreFakeRuntime() .addArguments("--java-options", "-D" + testAddDirProp + "=$APPDIR"); @@ -62,7 +64,7 @@ public static void test() throws Exception { final int attempts = 3; final int waitBetweenAttemptsSeconds = 5; - List output = new Executor() + List output = configureEnvironment(new Executor()) .saveOutput() .setExecutable(cmd.appLauncherPath().toAbsolutePath()) .addArguments("--print-env-var=" + envVarName) diff --git a/test/jdk/tools/jpackage/windows/WinChildProcessTest.java b/test/jdk/tools/jpackage/windows/WinChildProcessTest.java index 5565d3dc50352..5b0ff9b1f01b4 100644 --- a/test/jdk/tools/jpackage/windows/WinChildProcessTest.java +++ b/test/jdk/tools/jpackage/windows/WinChildProcessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, 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 @@ -40,6 +40,7 @@ import java.nio.file.Path; import jdk.jpackage.test.JPackageCommand; +import static jdk.jpackage.test.HelloApp.configureEnvironment; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Executor; import jdk.jpackage.test.TKit; @@ -54,14 +55,15 @@ public static void test() { long childPid = 0; try { JPackageCommand cmd = JPackageCommand - .helloAppImage(TEST_APP_JAVA + "*Hello"); + .helloAppImage(TEST_APP_JAVA + "*Hello") + .ignoreFakeRuntime(); // Create the image of the third party application launcher cmd.executeAndAssertImageCreated(); // Start the third party application launcher and dump and save the // output of the application - List output = new Executor().saveOutput().dumpOutput() + List output = configureEnvironment(new Executor()).saveOutput().dumpOutput() .setExecutable(cmd.appLauncherPath().toAbsolutePath()) .execute(0).getOutput(); String pidStr = output.get(0); From 01c8ba2cde881c3d483cb776ca17a5aa13123b23 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Fri, 10 Jan 2025 19:31:48 +0000 Subject: [PATCH 105/286] 8347298: Bug in JPackageCommand.ignoreFakeRuntime() Reviewed-by: almatvee --- .../helpers/jdk/jpackage/test/JPackageCommand.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index 68f26bfb261f1..bbf7d429f08cf 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -593,7 +593,7 @@ public Path appLauncherCfgPath(String launcherName) { } public boolean isFakeRuntime(String msg) { - if (isFakeRuntime()) { + if (isFakeRuntime(appRuntimeDirectory())) { // Fake runtime Path runtimeDir = appRuntimeDirectory(); TKit.trace(String.format( @@ -604,7 +604,7 @@ public boolean isFakeRuntime(String msg) { return false; } - private boolean isFakeRuntime() { + private static boolean isFakeRuntime(Path runtimeDir) { final Collection criticalRuntimeFiles; if (TKit.isWindows()) { criticalRuntimeFiles = WindowsHelper.CRITICAL_RUNTIME_FILES; @@ -616,7 +616,6 @@ private boolean isFakeRuntime() { throw TKit.throwUnknownPlatformError(); } - Path runtimeDir = appRuntimeDirectory(); return !criticalRuntimeFiles.stream().map(runtimeDir::resolve).allMatch( Files::exists); } @@ -690,10 +689,8 @@ public JPackageCommand ignoreDefaultRuntime(boolean v) { } public JPackageCommand ignoreFakeRuntime() { - if (isFakeRuntime()) { - ignoreDefaultRuntime(true); - } - return this; + return ignoreDefaultRuntime(Optional.ofNullable(DEFAULT_RUNTIME_IMAGE) + .map(JPackageCommand::isFakeRuntime).orElse(false)); } public JPackageCommand ignoreDefaultVerbose(boolean v) { From 10f7142dce296fedbb4d945378473d44ecde34b7 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Fri, 10 Jan 2025 19:32:05 +0000 Subject: [PATCH 106/286] 8347295: Fix WinResourceTest to make it work with WiX v4.0+ Reviewed-by: almatvee --- .../jdk/tools/jpackage/windows/WinResourceTest.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/jdk/tools/jpackage/windows/WinResourceTest.java b/test/jdk/tools/jpackage/windows/WinResourceTest.java index 72e805d0a48b5..db897e1aa694d 100644 --- a/test/jdk/tools/jpackage/windows/WinResourceTest.java +++ b/test/jdk/tools/jpackage/windows/WinResourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -30,6 +30,8 @@ import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Annotations.Parameters; import java.util.List; +import static jdk.jpackage.test.WindowsHelper.WixType.WIX3; +import static jdk.jpackage.test.WindowsHelper.getWixTypeFromVerboseJPackageOutput; /** * Test --resource-dir option. The test should set --resource-dir to point to @@ -83,11 +85,18 @@ public void test() throws IOException { .addBundleVerifier((cmd, result) -> { // Assert jpackage picked custom main.wxs and failed as expected by // examining its output + final String expectedWixErrorMsg; + if (getWixTypeFromVerboseJPackageOutput(result) == WIX3) { + expectedWixErrorMsg = "error CNDL0104 : Not a valid source file"; + } else { + expectedWixErrorMsg = "error WIX0104: Not a valid source file"; + } + TKit.assertTextStream(expectedLogMessage) .predicate(String::startsWith) .apply(JPackageCommand.stripTimestamps( result.getOutput().stream())); - TKit.assertTextStream("error CNDL0104 : Not a valid source file") + TKit.assertTextStream(expectedWixErrorMsg) .apply(result.getOutput().stream()); }) .setExpectedExitCode(1) From 6f1f2f2537cd921e2c13c333c78c2ad8c599dcc3 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Fri, 10 Jan 2025 21:23:50 +0000 Subject: [PATCH 107/286] 8347063: Add comments in ClassFileFormatVersion for class file format evolution history Reviewed-by: darcy, iris --- .../lang/reflect/ClassFileFormatVersion.java | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java b/src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java index b2fa39e166170..70eb921a12454 100644 --- a/src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java +++ b/src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -49,6 +49,47 @@ */ @SuppressWarnings("doclint:reference") // cross-module links public enum ClassFileFormatVersion { + /* + * Summary of class file format evolution; previews are listed for + * convenience, but they are not modeled by this enum. + * 1.1: InnerClasses, Synthetic, Deprecated attributes + * 1.2: ACC_STRICT modifier + * 1.3: no changes + * 1.4: no changes + * 1.5: Annotations (Runtime(Inv/V)isible(Parameter)Annotations attributes); + * Generics (Signature, LocalVariableTypeTable attributes); + * EnclosingMethod attribute + * 1.6: Verification by type checking (StackMapTable attribute) + * 1.7: Verification by type checking enforced (jsr and ret opcodes + * obsolete); java.lang.invoke support (JSR 292) (CONSTANT_MethodHandle, + * CONSTANT_MethodType, CONSTANT_InvokeDynamic constant pool entries, + * BoostrapMethods attribute); method must be ACC_STATIC + * 1.8: private, static, and non-abstract (default) methods in interfaces; + * Type Annotations (JEP 104) (Runtime(Inv/V)isibleTypeAnnotations + * attribute); MethodParameters attribute + * 9: JSR 376 - modules (JSR 376, JEP 261) (Module, ModuleMainClass, + * ModulePackages attributes, CONSTANT_Module, CONSTANT_Package + * constant pool entries, ACC_MODULE modifier) + * 10: minor tweak to requires_flags in Module attribute + * 11: Nest mates (JEP 181) (NestHost, NestMembers attributes); + * CONSTANT_Dynamic (JEP 309) constant pool entry + * 12: Preview Features (JEP 12) (minor version must be 0 or 65535) + * 13: no changes + * 14: no changes; (JEP 359 Records in Preview) + * 15: no changes; (JEP 384 Records in 2nd Preview, JEP 360 Sealed Classes + * in Preview) + * 16: Records (JEP 395) (Record attribute); (JEP 397 Sealed Classes in 2nd + * Preview) + * 17: Sealed Classes (JEP 409) (PermittedSubclasses attribute); ACC_STRICT + * modifier obsolete (JEP 306) + * 18: no changes + * 19: no changes + * 20: no changes + * 21: no changes + * 22: no changes + * 23: no changes + * 24: no changes + */ /** * The original version. From 761774a120f4aa326da3c55a000dacc5549762e9 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Fri, 10 Jan 2025 23:49:03 +0000 Subject: [PATCH 108/286] 8346143: add ClearAllFramePops function to speedup debugger single stepping in some cases Reviewed-by: cjplummer, amenkov --- src/hotspot/share/prims/jvmti.xml | 33 +++- src/hotspot/share/prims/jvmtiEnv.cpp | 29 ++- src/hotspot/share/prims/jvmtiEnvBase.cpp | 25 ++- src/hotspot/share/prims/jvmtiEnvBase.hpp | 17 +- .../share/prims/jvmtiEnvThreadState.cpp | 31 ++- .../share/prims/jvmtiEnvThreadState.hpp | 4 +- .../share/prims/jvmtiEventController.cpp | 18 +- .../share/prims/jvmtiEventController.hpp | 3 +- src/hotspot/share/prims/jvmtiExport.cpp | 7 +- .../ClearAllFramePops/ClearAllFramePops.java | 79 ++++++++ .../libClearAllFramePops.cpp | 176 ++++++++++++++++++ 11 files changed, 386 insertions(+), 36 deletions(-) create mode 100644 test/hotspot/jtreg/serviceability/jvmti/events/FramePop/ClearAllFramePops/ClearAllFramePops.java create mode 100644 test/hotspot/jtreg/serviceability/jvmti/events/FramePop/ClearAllFramePops/libClearAllFramePops.cpp diff --git a/src/hotspot/share/prims/jvmti.xml b/src/hotspot/share/prims/jvmti.xml index b63dfdfedb1aa..4bff3230c9ee3 100644 --- a/src/hotspot/share/prims/jvmti.xml +++ b/src/hotspot/share/prims/jvmti.xml @@ -1,7 +1,7 @@